Merge: answer Android's memory warnings, and stop reporting a lost root as an empty library

FR-PLAT-AND-5 in full, FR-PLAT-AND-2 in part -- the recovery is built and
live for Nextcloud roots, the SAF cause it names does not exist yet.

FR-PLAT-AND-4 and FR-PLAT-AND-6 are not here, both blocked behind the
same gap: assemble-apk.sh compiles no Java, so the APK cannot carry a
Service or a FileProvider. The container has JDK 17 and build-tools 36;
the build step is what is missing.

Verified: fmt, clippy --workspace --all-targets -D warnings, and 1043
tests across dr-catalog, dr-sync, dr-sync-folder, dr-sync-nextcloud,
dr-plat and dr-ui. The aarch64 target was checked before the branch was
finished but not after; no device was available.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-29 22:19:46 +02:00
co-authored by Claude Opus 5
16 changed files with 1002 additions and 39 deletions
+27
View File
@@ -3066,6 +3066,33 @@ impl DevelopSession {
Ok((image, rw, rh))
}
/// TRACES: FR-PLAT-AND-5 | NFR-RES-1
/// Give back the GPU memory this session is holding only to be fast.
///
/// The edit is untouched: the graph and its history are CPU-side by
/// design (ARCH §6.1), so the photograph, the undo stack and the viewport
/// all survive and the next frame simply costs what the first one did.
///
/// # What is not released, and what it is waiting on
///
/// The demosaiced source is the largest single allocation a session holds
/// — a 24 MP frame is about 190 MB of `Rgba16Float` — and it is
/// deliberately kept. Dropping it would need the session to be able to
/// rebuild itself from the file, and rebuilding a session from a durable
/// record is FR-PLAT-AND-3, which is not built. Freeing it now would not
/// be an eviction; it would be closing the photograph without telling
/// anyone. Likewise the subject distance fields and the segmentation map:
/// each is guarded by a key recording what it was built from, and freeing
/// one without invalidating its key is the failure `AdjustPass` documents
/// under `colour_key`.
///
/// So this is the part of the GPU tier that can be given back and asked
/// for again with no other machinery, which is exactly as far as an
/// eviction should go.
pub fn release_gpu_caches(&mut self) {
self.adjust.release_caches();
}
/// The displayed size, for sizing the viewport.
///
/// The *framed* size, not the sensor's: cropping and quarter turns change