Every background job reported into a window property of its own — library-thumbs-done, library-pin-total, library-syncing — which only the grid ever read. A pin download that outlived the view it was started from drew nothing at all once the user opened an image, and there was no answer anywhere to "what is this busy with", because the answer was spread across eight properties nothing collected. They report to one register now (ui/dr-ui/src/activity.rs). It publishes an aggregate, which draws a three-pixel bar across the top of the shell in every view, and a row per job, which the settings page lists: scans, thumbnail batches, pin and open downloads, sidecar uploads, the sync and the trash. Failures stay on the list until they are cleared; routine successes do not, or a scroll would bury them. The handle removes a still-running job when it drops, so a worker that dies mid-transfer takes its row with it rather than leaving the bar sweeping for the rest of the session. Also carries in-flight work from a parallel session — the drawn icon set and the dr-pipeline ops split. dr-pipeline's build script does not compile at this commit; ui/dr-ui does, with clippy clean and its tests passing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
58 lines
1.5 KiB
YAML
58 lines
1.5 KiB
YAML
# TRACES: FR-DEV-3a | FR-DEV-3c
|
|
id: exposure
|
|
label: op.exposure
|
|
order: 20
|
|
|
|
doc: |
|
|
Exposure — a linear gain, expressed in stops.
|
|
|
|
The simplest operation in the pipeline and the one that most justifies
|
|
working in linear light: a stop is a doubling, so exposure is a single
|
|
multiply. Applied to gamma-encoded data it would be neither a doubling nor
|
|
reversible, which is why this stage sits where it does (ARCH §5.2).
|
|
|
|
placement: |
|
|
A correction to how the scene was captured, so it precedes every operation
|
|
that interprets tone.
|
|
|
|
params:
|
|
exposure:
|
|
label: param.exposure
|
|
kind: stops
|
|
min: -5
|
|
max: 5
|
|
doc: |
|
|
±5 stops. Wider than most edits need, but recovering a badly
|
|
underexposed frame is a real use and raw data often supports it.
|
|
|
|
uniforms:
|
|
gain:
|
|
value: exp2(exposure)
|
|
doc: The linear gain for the current setting.
|
|
|
|
wgsl: |
|
|
c = c * gain;
|
|
|
|
tests:
|
|
- name: one_stop_is_a_doubling
|
|
why: |
|
|
The definition of a stop. If this is wrong, every exposure adjustment is
|
|
subtly off and no test of "looks right" would catch it.
|
|
set: { exposure: 1 }
|
|
expect: { gain: 2.0 }
|
|
|
|
- name: one_stop_down_is_a_halving
|
|
set: { exposure: -1 }
|
|
expect: { gain: 0.5 }
|
|
|
|
- name: stops_compose_additively
|
|
why: +2 stops must equal +1 applied twice.
|
|
set: { exposure: 2 }
|
|
expect: { gain: 4.0 }
|
|
|
|
- name: neutral_is_unity_gain
|
|
why: |
|
|
An unedited image must be the image, not an interpretation of it.
|
|
expect: { gain: 1.0 }
|
|
expect_active: false
|