Merge: a histogram that reads the sensor, beside the one that reads the frame
FR-CULL-3's other two bullets. What existed was a display histogram tagged FR-DSP-7, counting AdjustPass's 8-bit output with r == 255 clipping counters -- it says a highlight is gone precisely where this requirement needs it to say the highlight is recoverable. The new reduction runs over the demosaiced scene-linear texture on a stops-below-saturation axis: camera-native, unbalanced, unmatrixed, uncurved, normalised by the sensor's own black and white levels, so 1.0 is saturation by construction. Four series, and the fourth is the brightest channel rather than luma, because a weighted sum of unbalanced values is a number about nothing. Cached per photograph, not per frame: nothing downstream of the demosaic can move a count. Both readings are legitimate and answer different questions, so the panel offers a choice rather than replacing one with the other. ARCH 5.5 is amended to match. It specified a pre-demosaic reduction; retaining the CFA samples costs 48 MB at 24 MP and 120 MB at 60 MP resident on every photograph opened, whether or not anyone looks at the histogram, on the platform ARCH 6.2 exists for. The spec now records two reductions, why the more complete one was not worth its cost, and what the cheaper one cannot answer: it counts pixels not photosites, it cannot see above white, and it is measured after the CFA pattern is gone. Verified: clippy -D warnings clean, 98 dr-gpu tests, 556 dr-ui tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+33
-2
@@ -369,6 +369,10 @@ RawImage (sensor data, CPU)
|
||||
|
||||
Working precision is f16 in a linear wide-gamut space, quantising once at the output transform.
|
||||
|
||||
There is a second reduction that does not hang off the bottom of this chain. The raw histogram
|
||||
(FR-CULL-3) taps the demosaiced scene-linear texture directly — the box four rows from the top —
|
||||
because what it measures is the file rather than the render. See §5.5.
|
||||
|
||||
### 5.3 Tiling and scheduling
|
||||
|
||||
Work decomposes into tiles (default 256×256) scheduled by priority class:
|
||||
@@ -402,8 +406,35 @@ The histogram is a compute-shader reduction into a small storage buffer, read on
|
||||
most, and only the *bins* — never image data. A per-frame CPU readback of pixels would reintroduce
|
||||
exactly the stall §6.1 exists to prevent.
|
||||
|
||||
Raw-domain histograms for culling (FR-CULL-3) reduce over the pre-demosaic texture, which is why
|
||||
they can report headroom the embedded JPEG's histogram cannot.
|
||||
**Two reductions, not one.** The display histogram (FR-DSP-7) counts the frame the output transform
|
||||
produced: its axis is the output code value, and a clipped bin means a highlight that is gone as the
|
||||
image currently stands. The raw histogram for culling (FR-CULL-3) counts the **demosaiced
|
||||
scene-linear texture** — before white balance, the camera matrix, the base curve and the tone chain
|
||||
— on an axis of stops below sensor saturation, which is how it reports headroom the embedded JPEG's
|
||||
histogram cannot. A culling decision needs the second, an export decision needs the first, and
|
||||
neither answers for the other. Both are drawn by the same panel and chosen between.
|
||||
|
||||
**The raw reduction runs after the demosaic, not before it.** This section previously specified the
|
||||
pre-demosaic CFA samples, and that is the more complete instrument: it counts photosites rather than
|
||||
pixels, so no interpolation smears a clipped site across its neighbours, and it can name which
|
||||
channel of the mosaic saturated first. It was not worth its cost. `Demosaicer::run` uploads the
|
||||
packed sample buffer and drops it the moment the dispatch is encoded; retaining it is 48 MB at 24 MP
|
||||
and 120 MB at 60 MP, resident per open photograph whether or not anyone looks at the histogram, on a
|
||||
platform §6.2 exists because memory is scarce on. The record here is of the choice, not of the
|
||||
intent — a specification the code contradicts is worse than either of the two things it could say.
|
||||
|
||||
The texture that is reduced over instead is camera-native, unbalanced, unmatrixed and uncurved, and
|
||||
is normalised by the sensor's own black and white levels: 1.0 is saturation by construction, so the
|
||||
distribution below it is the headroom question with no calibration to carry and no origin to choose.
|
||||
What it cannot answer, and the CFA reduction could, is **which photosite** clipped rather than which
|
||||
pixel, and **how far above** the white level a sample reached — the demosaic clamps there, for its
|
||||
own good reasons, so "at saturation" and "a stop past it" share a bin. Both limits are stated again
|
||||
where the code is, in `core/dr-gpu/src/raw_histogram.rs`.
|
||||
|
||||
It is also the one reduction on this path that is not per frame. Nothing downstream of the demosaic
|
||||
can move a count in it, so it is computed once per photograph and cached — which is what makes it
|
||||
affordable during a cull, where the display histogram's per-frame cost would be paid three thousand
|
||||
times.
|
||||
|
||||
### 5.6 Device loss
|
||||
|
||||
|
||||
+21
-18
@@ -21,10 +21,10 @@ percentage. Where the honest answer is "this requirement should be amended rathe
|
||||
so — an unbuilt requirement that nobody intends to build is worse than a deferred one, because it
|
||||
keeps costing attention.
|
||||
|
||||
**Four of these are being built right now**, in parallel worktrees, and are marked **⟳ in
|
||||
progress** where they appear: focus peaking (part of FR-CULL-3), burst grouping (FR-CULL-5),
|
||||
Flatpak packaging (FR-PLAT-LIN-3), and Android platform integration (FR-PLAT-AND-2/4/5/6). Strike
|
||||
those lines as they land rather than rewriting around them.
|
||||
**Three of these are being built right now**, in parallel worktrees, and are marked **⟳ in
|
||||
progress** where they appear: burst grouping (FR-CULL-5), Flatpak packaging (FR-PLAT-LIN-3), and
|
||||
Android platform integration (FR-PLAT-AND-2/4/5/6). Strike those lines as they land rather than
|
||||
rewriting around them.
|
||||
|
||||
---
|
||||
|
||||
@@ -70,23 +70,26 @@ somebody reads the matrix.
|
||||
|
||||
## 2. Culling — the stated differentiator, half built
|
||||
|
||||
[D11](requirements.md) names culling "the core differentiator". FR-CULL-1, -2, -4 and -8 through -12
|
||||
are built. Four are not.
|
||||
[D11](requirements.md) names culling "the core differentiator". FR-CULL-1, -2, -3, -4 and -8 through
|
||||
-12 are built. Three are not.
|
||||
|
||||
**FR-CULL-3 — Raw-truth overlays. All three bullets, unbuilt.** Focus peaking does not exist
|
||||
anywhere; the string appears zero times in the tree.
|
||||
**FR-CULL-3 — Raw-truth overlays. Built, all three bullets.** Focus peaking is
|
||||
`core/dr-gpu/src/focus.rs` and `ui/dr-ui/src/peaking.rs`; the raw histogram and the raw clipping
|
||||
indicators are `core/dr-gpu/src/raw_histogram.rs` and the second reading of the panel in
|
||||
`histogram.slint`.
|
||||
|
||||
The other two are easy to mistake for present, and are not. A histogram and clipping indicators do
|
||||
exist — `dr-gpu/src/histogram.rs`, `ui/dr-ui/src/histogram.rs`, the panel in `histogram.slint` —
|
||||
but they are tagged FR-DSP-7 and they answer the opposite question. They read `AdjustPass`'s 8-bit
|
||||
output and count clipping as `r == 255`, which is to say they describe **the frame the display is
|
||||
about to show**, after the whole develop chain has run. FR-CULL-3 asks for the histogram of the
|
||||
*sensor data*, on the explicit grounds that a rendered image "systematically lies about what is
|
||||
recoverable in the raw". A readout that measures the render cannot answer that however it is
|
||||
presented, so this is not a matter of moving an existing widget into the culling view.
|
||||
Worth recording, because it is the thing this entry previously got wrong and the next reader will
|
||||
have to check again. The display histogram — `dr-gpu/src/histogram.rs`, `ui/dr-ui/src/histogram.rs`
|
||||
— is **not** this requirement and never was: it is tagged FR-DSP-7, it reads `AdjustPass`'s 8-bit
|
||||
output, it counts clipping as `r == 255`, and so it describes the frame the display is about to
|
||||
show, after the whole develop chain. FR-CULL-3 asks for the *sensor data*, on the explicit grounds
|
||||
that a rendered image "systematically lies about what is recoverable in the raw". The two now sit in
|
||||
one panel behind a chip row, which is the arrangement that keeps them from being mistaken for each
|
||||
other: they answer different questions and both are true.
|
||||
|
||||
The requirement exists because a culling decision made against a rendered preview is a decision made
|
||||
against the wrong image, and the whole of it is still to build. **⟳ in progress** (focus peaking).
|
||||
What the raw reduction cannot answer is written down rather than left to be discovered —
|
||||
[architecture.md §5.5](architecture.md) records why it reduces over the demosaiced texture instead
|
||||
of the CFA samples §5.5 originally specified, and what that costs in what it can say.
|
||||
|
||||
**FR-CULL-5 — Burst and near-duplicate grouping.** Absent. Worth knowing before it is built:
|
||||
`core/dr-face/src/calibrate.rs` already *assumes* it exists — "since FR-CULL-5 already groups
|
||||
|
||||
Reference in New Issue
Block a user