Give memory back in the order the user will miss it least
FR-PLAT-AND-5. Android asks for memory back through onTrimMemory and kills the process if it is not given; until now nothing listened, so the answer was always "no". A tiered registry answers instead: GPU caches first, then proxies, then thumbnails, driven from android_main on MainEvent::LowMemory and MainEvent::Stop. The order is the argument. A backgrounded app has no window to draw and therefore no use for a render pipeline, while its thumbnails are exactly what the user will be looking at half a second after they come back -- so going into the background frees only the GPU tier, and only being measured against death frees everything. Sinks register beside the cache they free and hold weak handles, so the registry cannot keep a controller -- and every decoded portrait in it -- alive past the interface it belonged to. `try_borrow_mut` and skip: a warning can land mid-render, freeing textures under the code drawing with them is worse than missing one, and a warning not acted on is always followed by another. The GPU test is the one that matters: an eviction must change no pixel. A freed intermediate pool whose `colour_key` promise still stands renders an empty texture, and nothing else would have caught it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2943,6 +2943,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
|
||||
|
||||
Reference in New Issue
Block a user