mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-12 00:42:44 -06:00
Merge main into LR-EXP-COLORSPACE / LR-EXP-BITDEPTH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ mode ([mcp.md](mcp.md)) is a thin layer over this channel. Implementation:
|
||||
| `engine.commands` | — | Engine + UI commands: id, label, menu, shortcut, params doc, enabled |
|
||||
| `ui.menu.list` | — | Menu entries (flat: id, label, menu path, shortcut, enabled) |
|
||||
| `ui.menu.tree` | — | The menu bar as shown (File … Help): items `{id, params?, label, shortcut?, enabled, checked?}`, separators, submenus — the model behind the native macOS menu bar and the in-window menus |
|
||||
| `ui.inspect` | — | UI state, window, canvas/image rects, active photo, selection, perf, status |
|
||||
| `ui.inspect` | — | UI state, window, canvas/image rects, active photo, selection, perf, status, memory (bytes per cache, see `library.memory`; plus stage caches and textures) |
|
||||
| `ui.widgets` | `{filter?}` | On-screen widgets `{id, rect: [x, y, w, h]}` (screen points) |
|
||||
| `ui.clickWidget` / `ui.dragWidget` | `{id, count?, fx?, fy?}` / `{id, toX?, toY?, dx?, dy?, steps?}` | Real egui input on a widget |
|
||||
| `ui.move` / `ui.click` / `ui.drag` | `{x, y, count?, button?}` / `{x, y, toX, toY, steps?}` | Raw pointer input, screen points |
|
||||
|
||||
@@ -88,6 +88,33 @@ the device on their first GPU render. `lightcraft_gpu::ready()` asks without blo
|
||||
one is rendered (decoded source kept, view render cached): stepping through photos shows the
|
||||
developed image in ~50 ms.
|
||||
|
||||
## Memory (M5.6)
|
||||
- `library.memory` reports what the engine's caches hold (decoded thumbnail / preview / full-size
|
||||
sources, rendered previews) and the GPU renderer's device buffers (allocated, of which pooled
|
||||
and retired); `ui.inspect` → `memory` adds the loupe's stage caches (CPU images, GPU buffers)
|
||||
and the textures.
|
||||
- Heap profile: build `lightcraft-cli` with `--features dhat-heap`; `library.memory` then also
|
||||
reports live/peak heap bytes and the run writes `dhat-heap.json` (`LIGHTCRAFT_DHAT_FILE`), whose
|
||||
allocation sites at the peak (`t-gmax`) show who holds the memory.
|
||||
- Measuring the scenario (import 14 raws from `corpus/raw`, open the loupe, step 12 times):
|
||||
`/usr/bin/time -l lightcraft-cli snapshot <files> --script steps.jsonl -o out.png` → "maximum
|
||||
resident set size" and "peak memory footprint". Run it several times: the high-water mark is
|
||||
noisy (allocator caching, scheduling). On Apple silicon GPU buffers count in the footprint.
|
||||
- Imports read raw headers only (`lightcraft_raw::probe_info`): no pixel data is decompressed.
|
||||
- One budget (`memory::budget`, default min(25 % of RAM, 1.5 GiB); `LIGHTCRAFT_MEMORY_MB` or
|
||||
`app.memoryBudget {mb}`): half for the engine caches (decoded thumbnail / preview / full
|
||||
sources and rendered previews, evicted least recently used *across* them; the photo on screen
|
||||
stays), a quarter for decodes in flight (`memory::work_gate`: grid thumbnails, neighbour
|
||||
prefetch and import probes wait for room, loupe and export loads never wait), an eighth for the
|
||||
GPU buffer pool (reuse by best fit within 25 %; freed after 3 s idle).
|
||||
- Decodes free the file's bytes and the raw samples as soon as they are consumed and colour /
|
||||
crop / orient in place. macOS keeps freed large blocks resident ("reusable") until the system
|
||||
is short of memory, so the resident size climbed with every photo decoded; the apps install
|
||||
`malloc_zone_pressure_relief` as `memory::set_release_hook`, called after each decode, import
|
||||
and idle trim.
|
||||
- Result (M4 Pro, 14 raws, loupe, 12 steps): peak RSS 1.9–2.3 GB → 0.83–0.99 GB, peak footprint
|
||||
2.5–2.6 GB → 0.91–0.96 GB, heap peak 930 → ~600 MB; stepping median ~13 ms (unchanged).
|
||||
|
||||
## Open items
|
||||
- Keep the loupe texture on the GPU (render into an `egui-wgpu` texture on eframe's device instead of
|
||||
reading back); share the device with eframe.
|
||||
|
||||
+17
-27
@@ -39,7 +39,7 @@ and prints the summary; `cargo xtask parity --write` refreshes the summary table
|
||||
| P. Enhance (ENH) | 0 | 0 | 2 | 0 | — | — |
|
||||
| Q. HDR (HDR) | 0 | 0 | 5 | 0 | — | — |
|
||||
| R. Video (VID) | 0 | 0 | 5 | 1 | — | 0/2 (0%) |
|
||||
| S. Export (EXP) | 4 | 6 | 8 | 0 | 2/7 (29%) | 2/7 (29%) |
|
||||
| S. Export (EXP) | 6 | 6 | 6 | 0 | 3/7 (43%) | 3/7 (43%) |
|
||||
| T. Share (SHARE) | 0 | 0 | 0 | 4 | — | — |
|
||||
| U. Map & location (MAP) | 0 | 1 | 1 | 0 | — | 0/1 (0%) |
|
||||
| V. Preferences (PREF) | 0 | 3 | 5 | 3 | 0/1 (0%) | 0/4 (0%) |
|
||||
@@ -48,46 +48,36 @@ and prints the summary; `cargo xtask parity --write` refreshes the summary table
|
||||
| Y. Menus | 46 | 18 | 21 | 8 | 37/47 (79%) | 7/23 (30%) |
|
||||
| Z. Keyboard shortcuts (desktop) | 46 | 16 | 18 | 1 | 39/52 (75%) | 7/23 (30%) |
|
||||
| Lightroom Classic extras | 4 | 19 | 56 | 9 | — | 3/21 (14%) |
|
||||
| **Total** | 208 | 103 | 189 | 37 | 152/198 (77%) | 48/144 (33%) |
|
||||
| **Total** | 210 | 103 | 187 | 37 | 153/198 (77%) | 49/144 (34%) |
|
||||
<!-- /parity:summary -->
|
||||
|
||||
## Top gaps
|
||||
|
||||
Ordered by tier, then user value, then (low) effort. Take the first one nobody is working on.
|
||||
|
||||
1. **LR-EXP-PREVIOUS + LR-EXP-DIALOG presets** (P0) — remember the last export settings (⌘E "export with previous")
|
||||
and offer built-in export presets (small JPEG, full JPEG, TIFF). Medium value, low effort.
|
||||
2. **LR-LIB-SHOWFINDER** (P0) — reveal the original in Finder/Explorer/file manager. Medium value, low effort.
|
||||
3. **LR-EDIT-EFFECTS-VIGNETTE** (P0) — the vignette style (highlight priority / colour priority / paint overlay) is
|
||||
rendered but has no UI. Low effort.
|
||||
4. **LR-VIEW-BEFOREAFTER** (P0) — add top/bottom and split top/bottom layouts (⌥Y). Low effort.
|
||||
5. **LR-MASK-OVERLAY + LR-MASK-PINS** (P0/P1) — show the evaluated mask alpha as a coloured overlay (all mask
|
||||
1. **LR-MASK-OVERLAY + LR-MASK-PINS** (P0/P1) — show the evaluated mask alpha as a coloured overlay (all mask
|
||||
kinds, colour/opacity choice), not just brush dabs and outlines. High value, medium effort.
|
||||
6. **LR-MASK-BRUSH + LR-MASK-SLIDERS** (P0) — apply the stored Auto Mask flag (edge-aware brush) and the local
|
||||
2. **LR-MASK-BRUSH + LR-MASK-SLIDERS** (P0) — apply the stored Auto Mask flag (edge-aware brush) and the local
|
||||
Noise / Moiré / Defringe sliders, which are stored but not rendered. High value, medium effort.
|
||||
7. **LR-REM-SPOT-EDIT + LR-REM-BRUSH-PARAMS** (P0) — select a spot pin, move target/source, delete with ⌫,
|
||||
3. **LR-REM-SPOT-EDIT + LR-REM-BRUSH-PARAMS** (P0) — select a spot pin, move target/source, delete with ⌫,
|
||||
feather/opacity sliders, `[`/`]` size keys. Medium effort.
|
||||
8. **LR-VIEW-PHOTOGRID** (P0) — group the justified grid by capture date with headers. Low–medium effort.
|
||||
9. **LR-CROP-STRAIGHTEN** (P0) — draw-along-the-horizon straighten tool (+ double-click auto). Low effort.
|
||||
10. **LR-PRE-CREATE + LR-PRE-PANEL + LR-BEHAV-PREVIEW-HOVER** (P0/P1) — per-group checkboxes in Create Preset;
|
||||
4. **LR-VIEW-PHOTOGRID** (P0) — group the justified grid by capture date with headers. Low–medium effort.
|
||||
5. **LR-PRE-CREATE + LR-PRE-PANEL + LR-BEHAV-PREVIEW-HOVER** (P0/P1) — per-group checkboxes in Create Preset;
|
||||
live preview while hovering presets/profiles/versions. Medium effort.
|
||||
11. **LR-PROF-DROPDOWN** (P0) — favourites/recent in the profile menu (and later a browser, LR-PROF-BROWSER).
|
||||
12. **LR-LIB-KEYWORD** (P0) — rename/delete a keyword library-wide; keyword list in the left panel for browsing.
|
||||
13. **LR-PREF-GENERAL + LR-IMP-RAWDEFAULT** (P0/P1) — a Settings dialog: raw defaults (preset or camera-specific),
|
||||
6. **LR-PROF-DROPDOWN** (P0) — favourites/recent in the profile menu (and later a browser, LR-PROF-BROWSER).
|
||||
7. **LR-LIB-KEYWORD** (P0) — rename/delete a keyword library-wide; keyword list in the left panel for browsing.
|
||||
8. **LR-PREF-GENERAL + LR-IMP-RAWDEFAULT** (P0/P1) — a Settings dialog: raw defaults (preset or camera-specific),
|
||||
XMP prefs, cache, GPU. Medium effort.
|
||||
14. **LR-IMP-ADD-DIALOG + LR-IMP-LOCAL** (P0) — an import review grid with per-photo checkboxes and destination
|
||||
9. **LR-IMP-ADD-DIALOG + LR-IMP-LOCAL** (P0) — an import review grid with per-photo checkboxes and destination
|
||||
album; browse folders before adding. Medium effort.
|
||||
15. **LR-EXP-TYPE + LR-EXP-DIM** (P0) — Original (+XMP) and DNG export (writer exists in
|
||||
10. **LR-EXP-TYPE + LR-EXP-DIM** (P0) — Original (+XMP) and DNG export (writer exists in
|
||||
`crates/raw/src/dngwrite.rs`), short edge / width / height / megapixels, "don't enlarge", ppi.
|
||||
16. **LR-IMP-FORMATS** (P0) — CR3, compressed NEF/RAF/ORF, RW2 v4 (preview only today); HEIC/AVIF decode (no
|
||||
11. **LR-IMP-FORMATS** (P0) — CR3, compressed NEF/RAF/ORF, RW2 v4 (preview only today); HEIC/AVIF decode (no
|
||||
permissive pure-Rust decoder yet). High value, high effort (clean sources needed).
|
||||
17. **LR-VIEW-FULLSCREEN + LR-VIEW-NAVIGATOR + LR-VIEW-INFOOVERLAY** (P1) — view modes. Medium effort.
|
||||
18. **LR-LIB-RENAME + LR-LIB-CAPTURETIME + LR-LIB-LABEL UI** (P1) — batch rename, capture-time edit, label menu/names.
|
||||
19. **LR-EYE-RED** (P1) — red-eye correction (panel placeholder exists; no render).
|
||||
20. **LR-EDIT-COLOR-POINTCOLOR, LR-EDIT-CALIB, LR-EDIT-LIGHT-CURVE-TAT, LR-EDIT-LIGHT-CURVE-REFINESAT** (P1) —
|
||||
missing develop controls (calibration matters for XMP interop).
|
||||
21. **LR-EXP-COMPRESSION** (P1) — TIFF compression choice (None / LZW / Deflate; the encoder supports all three).
|
||||
22. **LR-EDIT-OPTICS-PROFILE** (P1) — a lens-profile database of our own (embedded DNG/maker corrections work today).
|
||||
12. **LR-VIEW-FULLSCREEN + LR-VIEW-NAVIGATOR + LR-VIEW-INFOOVERLAY** (P1) — view modes. Medium effort.
|
||||
13. **LR-LIB-RENAME + LR-LIB-CAPTURETIME + LR-LIB-LABEL UI** (P1) — batch rename, capture-time edit, label menu/names.
|
||||
14. **LR-EXP-COMPRESSION** (P1) — TIFF compression choice (None / LZW / Deflate; the encoder supports all three).
|
||||
15. **LR-EDIT-OPTICS-PROFILE** (P1) — a lens-profile database of our own (embedded DNG/maker corrections work today).
|
||||
|
||||
## Shortcuts: conflicts and missing bindings
|
||||
|
||||
|
||||
Reference in New Issue
Block a user