-
Notifications
You must be signed in to change notification settings - Fork 6k
Only overflow the cache for one required frame #7048
Conversation
|
|
|
Turns out the required frame dependencies are much more limited than what I originally thought and this PR can be hugely simplified, thanks @amirh. 🎉 Updated with a new patch to only cache one required frame over the limit at a time. This is also now ready to merge whenever it gets LGTM. |
|
Thanks Michael! great to see this simplified! What do you think about further simplifying by removing our initialization step of marking required frames? |
Just to make sure @amirh: you mean these two members in addition to the regular map of cached bitmaps within our decoded limit, right? Since we'd still want the frame-indexed cache for non-required frames after looping. If I'm understanding your suggestion right, I think this would work but it would end up taking more memory at runtime. I think we'd need to cache 2 frames over the limit instead of just 1 in cases where we were using required frames at all, and in cases where we weren't we'd always cache 1 frame over the limit instead of 0. We'd want to always cache the N-1 frame in case it ends up being required, even in GIFs that don't have any required frames at all or only one required frame. Since we'd no longer be saving this info about the frames at initialization, we'd need to assume the worst. In cases of overflow always caching N-1 would also mean inserting and deleting from the cache every frame, too. And then on top of that we'd always want to cache the actual last required frame (if it exists) in case a previously required frame is used again instead of the N-1 frame. I don't think it would be preferable to the initialization step since it would end up using more memory, and I don't think the initialization step is really costing us much. What do you think? |
|
We talked about this offline. So far the |
amirh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Previously codec.cc needed all required frames to already be decoded before it could decode any of their dependent frames. To accomplish this it would always cache required frames, regardless of cache limit. However both GIF and WEBP (the only currently supported animated image formats) only allow the image to depend on one decoded frame at a time. This means that there's no reason to cache all the required frames since it's only valid for the image formats to require one previously decoded frame at a time. (For example, frame 10 and frame 11 in a hypothetical animated image could all depend on frame 9. But no subsequent frame after frame 9 could depend on frames 0-8.) Warning: this logic will break if we decide to support more animated formats in the future.
This allows us to clean up some of the caching logic so that it's always consistent and straightforward, instead of it diverging to handle required frames. `DecodedFrame` struct has been removed and required frames are now just tracked in their own map. Frames are always added to the cache as long as they're under the limit, and never removed. Required frames are always stored as a seperate member on `MultiFrameCodec`.
flutter/engine@215ca15...d8c5ec0 git log 215ca15..d8c5ec0 --no-merges --oneline d8c5ec0 Roll src/third_party/skia f16825ed3c71..dc5863c4d665 (1 commits) (flutter/engine#7297) efb8a3f Roll src/third_party/skia 945a56644728..f16825ed3c71 (1 commits) (flutter/engine#7296) 67150a5 Roll src/third_party/skia 28bd882a1e40..945a56644728 (2 commits) (flutter/engine#7295) 3705a1e Roll src/third_party/skia ea8900e74ea7..28bd882a1e40 (1 commits) (flutter/engine#7294) 943ecfc Roll src/third_party/skia 13654b20ce5b..ea8900e74ea7 (1 commits) (flutter/engine#7293) 7b12ae2 Roll src/third_party/skia 12a6d452b126..13654b20ce5b (1 commits) (flutter/engine#7292) 1fe7e1f Roll src/third_party/skia c983480b117f..12a6d452b126 (1 commits) (flutter/engine#7291) a8b0d26 Roll src/third_party/skia 2e40d9886402..c983480b117f (1 commits) (flutter/engine#7290) c64f971 Roll src/third_party/skia 98a4e4a4135b..2e40d9886402 (1 commits) (flutter/engine#7289) 65420c2 Roll src/third_party/skia 2a0967383087..98a4e4a4135b (1 commits) (flutter/engine#7288) 770536a Only overflow the cache for one required frame (flutter/engine#7048) b6880bb Roll src/third_party/skia 9803b8f1d197..2a0967383087 (16 commits) (flutter/engine#7285) The AutoRoll server is located here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, please contact the current sheriff ([email protected]), and stop the roller if necessary.
Previously codec.cc needed all required frames to already be decoded
before it could decode any of their dependent frames. To accomplish this
it would always cache required frames, regardless of cache limit.
However both GIF and WEBP (the only currently supported animated image
formats) only allow the image to depend on one decoded frame at a time.
This means that there's no reason to cache all the required frames since
it's only valid for the image formats to require one previously decoded
frame at a time. (For example, frame 10 and frame 11 in a hypothetical
animated image could all depend on frame 9. But no subsequent frame
after frame 9 could depend on frames 0-8.)
Warning: this logic will break if we decide to support more animated
formats in the future.
Fixes flutter/flutter#24835.