Repository navigation
perf(video-editor): give back the memory that camera and editor sessions kept - #10306
Conversation
After camera and editor sessions the app kept up to ~500 MB more graphics memory on Android, and on iOS the footprint grew by ~340 MB without coming back. The holder was Flutter's image cache, filled with thumbnails of clips that no longer exist until its 256 MB budget was full; Impeller stores each image with a full mip chain, so the GPU cost is about twice the budget. On iOS a later clear does not give the footprint back, so the cache is now emptied each time the camera or editor route closes instead of relying on background or memory-pressure trims. The timeline tile fallback also decoded the 640 px clip thumbnail at full size for a 64 dp tile; it now decodes at tile height.
This comment has been minimized.
This comment has been minimized.
roborev: Combined Review (
|
The doc comment said that on iOS a later image-cache clear gave almost none of the footprint back. A follow-up measurement showed the memory does come back once Flutter draws its next frame (824 -> 552 MB); the earlier reading came from a run where no new frame followed. Releasing on close is still needed because the background and memory-pressure trims never run while the user stays in the app.
This comment has been minimized.
This comment has been minimized.
…-flow-images # Conflicts: # mobile/lib/constants/app_constants.dart
…r helper main now has clearDecodedImageCache(), which schedules a frame after the clear because ImageCache only frees the images it drops once a frame is drawn. Closing the camera or editor uses it too, so the release does not depend on the pop animation drawing that frame.
This comment has been minimized.
This comment has been minimized.
…-flow-images # Conflicts: # mobile/test/router/routes/video_routes_test.dart
Mobile PR PreviewPreview refreshed for Last refresh:
|
NotThatKindOfDrLiz
left a comment
There was a problem hiding this comment.
No blocking code findings. Reviewed the route disposal wrappers, shared cache-clearing helper, live-image retention, thumbnail decode sizing, and regression tests. Analysis and all eight test shards ran successfully on this head; I did not rerun tests locally or reproduce the reported device measurements.
Before merge, record the authoring-model declaration and establish the independent-review provenance required by the shared review policy. This approval records the code-review conclusion and does not waive that requirement.
Agent-Model: openai/gpt-6
Agent-Effort: unknown
Agent-Harness: codex/unknown
Agent-Context: fresh
Initiated-By: @NotThatKindOfDrLiz
rabble
left a comment
There was a problem hiding this comment.
No actionable code findings in the complete eight-file diff at 00fcd03. Approved for the code-review conclusion.
Checked the recorder/editor route disposal scopes, shared cache-clearing helper, retention of live images, thumbnail decode sizing, and regression coverage. Actual Analyze and all eight Flutter test-shard execution steps succeeded on this head in Mobile CI run 39306344733. I did not rerun tests locally or reproduce the device memory measurements.
Before merge, the author must add the required authoring-model declaration and establish independent-review provenance. The declaration is absent, so distinct model lineage cannot currently be established; this approval does not waive that requirement. The author retains the merge decision.
Agent-Model: openai/gpt-6
Agent-Effort: unknown
Agent-Harness: codex/unknown
Agent-Context: fresh
Initiated-By: @rabble
Description
After a stretch of recording and editing, the app kept a lot more memory than it started with, and leaving the camera or editor did not give it back. After 50 camera → editor → camera round trips a Galaxy S26 held ~500 MB more graphics memory on the home screen, and an iPhone 12 Pro's footprint had grown by ~340 MB without coming back. On phones with less RAM that makes a kill during the next export, or in the background, more likely.
Cause. The memory was Flutter's decoded-image cache. Every editor visit decoded the clip thumbnail twice (full size for the timeline tile fallback, 1080 px for the editor poster) plus timeline strip thumbnails, and those entries stayed after the clips were gone until the cache's 256 MB budget was full. Impeller keeps each decoded image as a GPU texture with a full mip chain, so a full cache measured as about twice its budget in graphics memory. Emptying the cache on Android brought graphics memory straight back to the baseline, so nothing else was holding it.
Fix.
ReleaseCachedImagesOnDispose). Waiting for the existing trims is not enough: the app empties the cache when it goes to the background or the OS reports memory pressure, but neither happens while the user stays in the app, so a user who records, edits and exports again carries the full cache into the next export. Images still on screen are live and stay.Related Issue: Closes #10301
Out of Scope
clearDecodedImageCache), which this PR uses when the camera or editor closes.Verification
flutter analyze lib test integration_test,dart format, and the affected tests:release_cached_images_on_dispose_test.dart,video_editor_timeline_clip_strip_test.dart,test/router/routes/.Full numbers and the attribution are in #10301.
Type of Change