diff --git a/docs/dev/display-and-extension.md b/docs/dev/display-and-extension.md index 3dec37a..8933e4d 100644 --- a/docs/dev/display-and-extension.md +++ b/docs/dev/display-and-extension.md @@ -22,7 +22,7 @@ and the reason is that some of the work is done and untagged. | FR-DSP-1 proxy rendering | **Done.** The develop view renders at viewport resolution, not source. | | FR-DSP-2 tiled computation | **Absent, and §2 now says it should stay that way.** Measured: the fused pass is inside the budget everywhere. See [frame-budget.md](frame-budget.md). | | FR-DSP-3 interactive latency | **Measured and asserted** for the fused path — `core/dr-gpu/tests/frame_budget.rs`. Missed by one operation, clarity, for the reason recorded as TD-4. | -| FR-DSP-4 progressive refinement | **Absent**, and §4's condition did not fire. Every render is full quality and can afford to be. | +| FR-DSP-4 progressive refinement | **Built** (0.15.0), although §4's condition did not fire on the fused path: a half-resolution draft while a gesture moves, one sharp frame 120 ms after it stops, the histogram dimmed while it lags, and the draft faded out over 150 ms — `ui/dr-ui/src/refine.rs`. See [frame-budget.md](frame-budget.md). | | FR-DSP-5 zoom and pan | **Done and tagged**, against tests that fail if the behaviour is removed — `core/dr-gpu/tests/zoom_resolution.rs`. `Framing::view` shrinks the sampled region while the render target keeps its size, so zooming *raises* the resolution the pipeline works at. That is FR-DSP-5's requirement, arrived at without tiles. | | FR-DSP-6 colour management | **Done.** Output space is a parameter of composition. | | FR-DSP-7 histogram and clipping | **Done**, GPU-side, no per-frame readback. | diff --git a/docs/dev/frame-budget.md b/docs/dev/frame-budget.md index 5981cb2..454197d 100644 --- a/docs/dev/frame-budget.md +++ b/docs/dev/frame-budget.md @@ -264,6 +264,14 @@ base, computed at reduced resolution and correct at any moment the user stops. "Render coarse while dragging, sharpen when it settles" would paper over the same 34 ms with a visible swap. Fix the stage. +> **Since, 0.15.0.** The stage was fixed (§ The reduced base, below), and the +> draft was built anyway, in the form this section would accept: the develop +> view renders at half resolution while a gesture moves and once at full +> resolution 120 ms after it stops (`ui/dr-ui/src/refine.rs`), the histogram +> dims while it describes an older frame, and the last draft fades out over +> 150 ms rather than being swapped. It is not a mask over a slow stage; it +> spares a drag the full-resolution frames it does not need. + --- ## Which GPU, on a machine with more than one @@ -431,3 +439,38 @@ difference between a quarter-scale and a half-scale base to 0.03 stops of peak excursion and 2% of frame reach. But it is a change in reach rather than only in cost, it is what a tile scheduler would be handed, and it is worth knowing that the number moved rather than discovering it later as a seam. + +--- + +## The fit view, again — 2026-09-25 + +**Status:** Measured in the commits named, not re-run for this file. + +Two changes to the fused path made the `fit` rows above cheaper again, +each with its before and after in its commit message. Both were measured +on the laptop RTX 3050 with its clocks held at 420/810 MHz by the power +cap, on the synthetic 60 MP source of `examples/frame_budget.rs`, median of +five alternated runs; both leave the rgba8 output bit-identical. + +**The source gather is read once per framing** (`1dc7b45`). At fit every +output pixel reads one texel on a stride through a source three or four +times its width, and that gather was most of the fused pass. The pass now +keeps a render-sized `rgba16float` cache of it, keyed on the framing, and +reads it back while only the adjustments move: + +| scene | before | after | +|---|---:|---:| +| neutral, 2560 × 1600 fit | 10.62 ms | 3.88 ms | +| neutral, 3840 × 2160 fit | 21.05 ms | 7.11 ms | +| clarity, 3840 × 2160 fit | 42.20 ms | 27.88 ms | +| neutral, 2560 × 1600 1:1 (control) | 3.83 ms | 3.84 ms | + +An interpolated read (straightening, lens warps, CA) is not cached, and the +cache is written on the second frame with a given key, so a crop or zoom +drag pays nothing for it. + +**A detail pass that changes nothing is dropped** (`d430ec9`). Capture +sharpening at a scale too coarse to draw its radius emits an empty pass, +which cost a full read and write when another neighbourhood operation +followed it: sharpen with clarity at 2560 × 1600 fit went from 18.66 ms to +14.16 ms, and at 3840 × 2160 from 37.93 ms to 27.88 ms. diff --git a/docs/dev/requirements.md b/docs/dev/requirements.md index dc231d3..e65b768 100644 --- a/docs/dev/requirements.md +++ b/docs/dev/requirements.md @@ -667,6 +667,12 @@ asynchronously, and the proxy result remains on screen until it is ready. quality or resolution, refining to full quality when interaction settles. Refinement is visually smooth, not a jarring swap. +*Status (2026-09-26).* Met in 0.15.0. A gesture renders half-resolution drafts, and the sharp frame +lands once, 120 ms after the last movement rather than on a timer counted from the first +(`ui/dr-ui/src/refine.rs`). While a draft is up the histogram's display reading is dimmed, since it +describes the last settled frame; the last draft is kept over the sharp one and faded out in +150 ms, so the refinement is not a swap. + **FR-DSP-5 — Zoom and pan.** Fit, 1:1, and arbitrary zoom levels. At 1:1 and above, the pipeline operates on the visible crop at full source resolution.