docs: record Θ-W7, the arc-and-spline antialiasing fix, and file the scaled-fallback deferral
This commit is contained in:
@@ -613,3 +613,59 @@ reset semantics unit-testable; `editor_controls.cpp` dropped 469→293 lines.
|
|||||||
All visual outcomes remain **pending Daniel's by-eye sign-off on `dev`** — sizes,
|
All visual outcomes remain **pending Daniel's by-eye sign-off on `dev`** — sizes,
|
||||||
arc weight, and whether the waveform stroke improves or thickens the docked panel.
|
arc weight, and whether the waveform stroke improves or thickens the docked panel.
|
||||||
Not recorded as accepted.
|
Not recorded as accepted.
|
||||||
|
|
||||||
|
### Θ-W7-T1 — arc-and-spline-aa
|
||||||
|
|
||||||
|
Two defects Daniel found by eye once Θ-W6-T1's antialiasing pass shipped — diagnosing
|
||||||
|
both corrected the initial reading of each.
|
||||||
|
|
||||||
|
- **Arcs never reached opacity.** `LICE_Arc` rasterizes a whole circle clipped per 90°
|
||||||
|
chunk and splits ink across two pixels by the fractional part of the radius;
|
||||||
|
`rOuter = radius - 0.5f` is half-integer, so no pixel in the ring was ever opaque —
|
||||||
|
measured peak alpha 138/255. The three stacked radii also did not tile: spacing
|
||||||
|
dilates from 1.0 px to 1.41 px at 45°, leaving partial-coverage holes. It read as
|
||||||
|
fuzz, but it was a stroke that never fully inked.
|
||||||
|
- **Splines were fully aliased, not gapped.** The apparent dotting was not missing
|
||||||
|
ink: `LICE_ThickFLine` steps the major axis and structurally cannot gap. The paint
|
||||||
|
loop passed **integer** `cx`/`cy`, so LICE had no sub-pixel position to interpolate
|
||||||
|
— every pixel was full or empty with no AA fringe, and integer `cy` quantized the
|
||||||
|
slope into an alternating 1/2 px staircase that reads as beading at 100%.
|
||||||
|
- **The cheap fix was rejected.** Float endpoints plus `LICE_ThickFLine` fixes
|
||||||
|
opacity and the staircase, but `ThickFLine` lays width along the *minor* axis, so
|
||||||
|
perpendicular weight is `wid·cosθ` — a measured 42% ripple dipping at every 45°
|
||||||
|
diagonal.
|
||||||
|
- **What landed:** one pure analytic thick-stroke rasterizer. Coverage is
|
||||||
|
distance-to-polyline, accumulated with `max()` into a scratch buffer and blended
|
||||||
|
**once** — the single blend is what structurally prevents the compositing fringe
|
||||||
|
build-up behind the first defect. An arc is just a polyline, so one code path
|
||||||
|
replaces the stacked arcs, both spline traces, and the two needles. Pure coverage
|
||||||
|
math in a new `core/ui/stroke_aa`; the blend loop in a new
|
||||||
|
`shell/instrument/editor_stroke`. `shell/panel/draw_kit` was deliberately **not**
|
||||||
|
touched, keeping the docked bank panel and browse cards entirely out of the blast
|
||||||
|
radius.
|
||||||
|
- **Measured, before → after:** arc peak alpha 138/255 → 255/255; arc perpendicular
|
||||||
|
weight 1.62–3.24 px (67% ripple) → 2.95–3.11 px (5%); spline weight 1.41–2.00 px
|
||||||
|
(29%) → 1.95–2.01 px (3%). Cost: **+0.09 ms per full editor repaint** (30 arcs
|
||||||
|
0.113 → 0.169 ms; 500 px contour 0.013 → 0.047 ms), a knowing regression on an
|
||||||
|
interaction-driven surface, measured in Release against real LICE in an
|
||||||
|
uncommitted harness.
|
||||||
|
- **`velocity_curve` gained `subpixelFromPoint`** — sub-pixel y was unavoidable since
|
||||||
|
integer `cy` was the root cause. The existing integer map now *rounds* the new
|
||||||
|
float map rather than forking a second formula, so hit-testing is unchanged.
|
||||||
|
- **Daniel then ruled that every sub-2 px stroker width be enlarged**, because the
|
||||||
|
stroker can only guarantee an opaque core at width >= 2 px (an opaque pixel needs
|
||||||
|
`d <= halfWidth − 0.5`, and the worst-case pixel-centre-to-centreline distance is
|
||||||
|
0.5). The knob track arc, the inner-dial needle, and the deck's mini velocity trace
|
||||||
|
all moved 1.0 → 2.0 px. A test pinning the sub-opaque behaviour at 1 px was kept as
|
||||||
|
a guard against reintroduction.
|
||||||
|
- **The audit's method was the root failure, not its output.**
|
||||||
|
`docs/product/visual-design-language.md` §8 had claimed stacked 1 px `LICE_Arc`
|
||||||
|
calls "keep every ring antialiased" — false. The Θ-W6 audit verified *which
|
||||||
|
primitive was called* rather than *what it rasterized*, which is how both surfaces
|
||||||
|
were signed off clean while never producing an opaque pixel. That sentence is
|
||||||
|
deleted, the rows are re-dispositioned with measurements, and the methodological
|
||||||
|
lesson is recorded in §8 as a standing blockquote.
|
||||||
|
|
||||||
|
All visual outcomes remain **pending Daniel's by-eye sign-off on `dev`** — nothing was
|
||||||
|
verified in a live REAPER window; all measurement was against an offscreen bitmap in a
|
||||||
|
standalone harness. Not recorded as accepted.
|
||||||
|
|||||||
+41
-5
@@ -115,8 +115,10 @@ drag/drop defects that block getting captures into it.
|
|||||||
|
|
||||||
**Consolidates items** 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16.
|
**Consolidates items** 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16.
|
||||||
|
|
||||||
**All six waves have landed — Phase Θ is complete.** W1 through W6 each carry their own
|
**All seven waves have landed — Phase Θ is complete.** W1 through W7 each carry their own
|
||||||
landed note above; see `docs/COMPLETED.md` for every track's full narrative.
|
landed note above; see `docs/COMPLETED.md` for every track's full narrative. Θ-W7 was
|
||||||
|
opened after Θ-W6-T1 shipped, to fix two rendering defects Daniel found by eye; it did not
|
||||||
|
exist in the plan when this phase was originally scoped.
|
||||||
|
|
||||||
**The organizing constraint.** Three surfaces in the instrument are single-writer by
|
**The organizing constraint.** Three surfaces in the instrument are single-writer by
|
||||||
nature and dictate the wave shape:
|
nature and dictate the wave shape:
|
||||||
@@ -283,6 +285,33 @@ All visual outcomes remain pending Daniel's by-eye sign-off on `dev`.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Θ-W7 — Arc-and-spline antialiasing fix
|
||||||
|
|
||||||
|
**Depends on W6 for:** a drawn surface to find a defect on — this wave did not exist in
|
||||||
|
the plan; it was opened after Daniel found two rendering defects by eye once Θ-W6-T1
|
||||||
|
shipped, so the audit's own output is what surfaced them.
|
||||||
|
|
||||||
|
**One track.**
|
||||||
|
|
||||||
|
**Θ-W7-T1 has landed** — `arc-and-spline-aa` — see `docs/COMPLETED.md` for the full
|
||||||
|
narrative. The stacked-`LICE_Arc` knob and dial rings never reached an opaque core (peak
|
||||||
|
alpha measured 138/255), and the staged/spline envelope and velocity-curve traces were
|
||||||
|
fully aliased rather than gapped, from integer `cy` quantizing the slope. Both defects,
|
||||||
|
plus the two needles, now route through one pure analytic thick-stroke rasterizer —
|
||||||
|
coverage in a new `core/ui/stroke_aa`, the single LICE blend in a new
|
||||||
|
`shell/instrument/editor_stroke` — replacing `LICE_Arc` and `LICE_ThickFLine` outright.
|
||||||
|
Measured: arc peak alpha 138/255 → 255/255, arc perpendicular-weight ripple 67% → 5%,
|
||||||
|
spline weight ripple 29% → 3%, at a cost of +0.09 ms per full editor repaint. Daniel then
|
||||||
|
ruled every sub-2 px stroker width up to 2 px, since the stroker only guarantees an
|
||||||
|
opaque core at width ≥ 2 px; the knob track arc, the inner-dial needle, and the deck's
|
||||||
|
mini velocity trace each moved 1.0 → 2.0 px. `docs/product/visual-design-language.md` §8
|
||||||
|
is corrected — a false "keeps every ring antialiased" claim is deleted, the rows are
|
||||||
|
re-dispositioned with measurements, and the audit's methodological lesson (verifying
|
||||||
|
which primitive was called is not verifying what it rasterized) is recorded as a standing
|
||||||
|
blockquote. All visual outcomes remain pending Daniel's by-eye sign-off on `dev`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Phase Ξ — The resample loop
|
## Phase Ξ — The resample loop
|
||||||
|
|
||||||
**Ships:** one consolidated, fully robust provenance/usage tracking system, and on top of
|
**Ships:** one consolidated, fully robust provenance/usage tracking system, and on top of
|
||||||
@@ -300,7 +329,7 @@ independent of the editor chain — which is what makes Ξ-W1 concurrency-safe w
|
|||||||
bakes — "filtering, pitching, amp all set up nice" is the instrument items 1, 2, 3, and 14
|
bakes — "filtering, pitching, amp all set up nice" is the instrument items 1, 2, 3, and 14
|
||||||
build — and its settled reset scope enumerates the filter parameters, the spline contours,
|
build — and its settled reset scope enumerates the filter parameters, the spline contours,
|
||||||
and the loop points by name. Baking a processing chain that does not exist yet is not a
|
and the loop points by name. Baking a processing chain that does not exist yet is not a
|
||||||
schedule preference; the feature is not expressible. Phase Θ landed as of Θ-W6-T1 (see
|
schedule preference; the feature is not expressible. Phase Θ landed as of Θ-W7-T1 (see
|
||||||
`docs/COMPLETED.md`); this gate is satisfied.
|
`docs/COMPLETED.md`); this gate is satisfied.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -616,8 +645,13 @@ work that did not come from the source doc has no row, and inventing one would w
|
|||||||
proof it exists to give.
|
proof it exists to give.
|
||||||
|
|
||||||
- **Θ-W3-T1 — `live-parameter-delivery`** (`pth-w3-t1-live-parameter-delivery`). Arose
|
- **Θ-W3-T1 — `live-parameter-delivery`** (`pth-w3-t1-live-parameter-delivery`). Arose
|
||||||
from Θ-W2-T1's implementation review, not from `TODO-1.0.md`. It is the only such track
|
from Θ-W2-T1's implementation review, not from `TODO-1.0.md`. The first such track in
|
||||||
in this plan today; if others appear, they belong on this list rather than in the table.
|
this plan; see Θ-W7-T1 below for the second.
|
||||||
|
- **Θ-W7-T1 — `arc-and-spline-aa`** (`pth-w7-t1-arc-and-spline-aa`). Opened after
|
||||||
|
Θ-W6-T1 shipped, when Daniel found two rendering defects by eye in the editor — not
|
||||||
|
from `TODO-1.0.md`, and not a track this plan originally scoped. The second such track
|
||||||
|
in this plan today; if others appear, they belong on this list rather than in the
|
||||||
|
table.
|
||||||
|
|
||||||
### Deliberate compressions
|
### Deliberate compressions
|
||||||
|
|
||||||
@@ -672,6 +706,8 @@ Phase Θ — ReaSampler 9000: one parameter set, filter, shapeable envelopes, le
|
|||||||
T1 spline-egs .............................. 3
|
T1 spline-egs .............................. 3
|
||||||
W6 Editor legibility pass
|
W6 Editor legibility pass
|
||||||
T1 legibility-and-antialiasing ............. 10, 13
|
T1 legibility-and-antialiasing ............. 10, 13
|
||||||
|
W7 Arc-and-spline antialiasing fix
|
||||||
|
T1 arc-and-spline-aa ....................... (not one of the seventeen)
|
||||||
|
|
||||||
Phase Ξ — The resample loop (W1 concurrency-safe with Θ from Θ-W2 onward)
|
Phase Ξ — The resample loop (W1 concurrency-safe with Θ from Θ-W2 onward)
|
||||||
W1 Consolidated tracking, and the programmed-note model
|
W1 Consolidated tracking, and the programmed-note model
|
||||||
|
|||||||
@@ -309,3 +309,35 @@ been observed to be wrong, only unverified.
|
|||||||
**Done looks like.** Either `IPlugViewContentScaleSupport` is implemented and the
|
**Done looks like.** Either `IPlugViewContentScaleSupport` is implemented and the
|
||||||
AA/uniform-width guarantees are re-verified at a scaled client size, or a decision is
|
AA/uniform-width guarantees are re-verified at a scaled client size, or a decision is
|
||||||
recorded that host-side resampling of the rasterized output is an accepted tradeoff.
|
recorded that host-side resampling of the rasterized output is an accepted tradeoff.
|
||||||
|
|
||||||
|
## The analytic stroker's scaled fallback path is unexercised
|
||||||
|
|
||||||
|
**Context (what shipped — Θ-W7-T1, arc-and-spline-aa).** `blendCanvas`
|
||||||
|
(`shell/instrument/editor_stroke.cpp`) guards against `LICE_EXT_GET_SCALING` being
|
||||||
|
active by falling back to a per-pixel `LICE_PutPixel` path, because the primary raw-bits
|
||||||
|
path derives its geometry from logical width/height while writing through
|
||||||
|
`getRowSpan()` — under an active scale that would misplace the stroke or write past the
|
||||||
|
DIB allocation.
|
||||||
|
|
||||||
|
**The wart.** Nothing calls `SET_SCALING` today, so the fallback path never runs. Under
|
||||||
|
an active scale it would rasterize the coverage mask at *logical* resolution with each
|
||||||
|
logical pixel expanded to a scale-sized block — geometrically correct but blocky rather
|
||||||
|
than resolution-independent. This connects to the already-filed high-DPI host-scaling
|
||||||
|
deferral above; cross-referenced here rather than duplicated.
|
||||||
|
|
||||||
|
**Intended fix.** Not proposed — same shape as the host-scaling deferral above:
|
||||||
|
implementing (or verifying) genuine scale-aware rasterization is the shape of a fix, not
|
||||||
|
yet scoped.
|
||||||
|
|
||||||
|
**The constraint the fix MUST handle.** Not yet known — no design work has started, and
|
||||||
|
none can usefully start before the host-scaling deferral above is resolved, since that
|
||||||
|
is what would first exercise this path.
|
||||||
|
|
||||||
|
**Priority / risk.** Low / deferred. Recorded as a gap, not a defect: the fallback is
|
||||||
|
guarded, correct-but-blocky rather than wrong, and unreached by anything in the tree
|
||||||
|
today.
|
||||||
|
|
||||||
|
**Done looks like.** Either the fallback path is exercised under a genuinely scaled
|
||||||
|
bitmap and confirmed to place the stroke correctly, or it is redesigned to rasterize at
|
||||||
|
physical rather than logical resolution once `IPlugViewContentScaleSupport` (or
|
||||||
|
equivalent) makes scaling real.
|
||||||
|
|||||||
Reference in New Issue
Block a user