Jank displaying big looping animated gif with many frames |
||||||
Issue descriptionb/26173128 Sample gif: http://www.wired.com/wp-content/uploads/2015/12/StarWarsPoster.gif Sample trace attached. The CompositorTileWorker thread is very busy. About 1/3 to 1/2 time of each frame is for decoding the image frame, the other 1/2 to 2/3 time is for rasterization to tiles. There might be two problems: 1. We decode a frame each time we display it. The caching mechanism doesn't work for the case because of memory limit: We cache several recent frames, but evict old frames from memory. Have no idea how to fix this except to increase memory limit for cached images. 2. Slowness of rasterization. TileTaskWorkerPool::PlaybackToMemory of each tile takes about 3ms. bsalomon@ can you look at the rasterization slowness or reassign? Thanks.
,
Mar 31 2016
Adding folks working on the image pipeline. (Probably, the issue is not contained entirely within Skia so bsalomon@ isn't the best owner.)
,
Oct 4 2016
Chris, I'm guessing this can be duped to some existing gif work?
,
Oct 4 2016
,
Oct 4 2016
This may be a dupe of an existing issue. I'll check on that later, once I know what the root cause is and how to resolve it. But first, what is TileTaskWorkerPool::PlaybackToMemory? I'm looking in Code Search and not really finding it. I see that name in tests but not in the normal code. I also see TileTask and TileTaskManager. And I see TaskGraphRunner and TaskGraphWorkQueue. I assume TileTaskWorkerPool is another name for tile tasks in the TaskGraphWorkQueue. I see the slow decodes in the trace. That is what I will focus on in my investigation. But like #1 said, a decode is followed by several calls to TileTaskWorkerPool::PlaybackToMemory. Those calls aren't THAT slow. But there are many of them. So the collection of them is slow. Even if I fix the decode time, I will need to know what that does. It is just as important. It's just as slow.
,
Oct 4 2016
re TileTaskWorkerPool::PlaybackToMemory, this was probably renamed to RasterBufferProvider::PlaybackToMemory. In other words, that's "raster", so whatever the slice for that is called :)
,
Oct 5 2016
Issue 651817 has been merged into this issue.
,
Oct 5 2016
Re #6 So when I see multiple TileTaskWorkerPool::PlaybackToMemory for each pending tree (and after a decode) I can read that as the tiles being rastered with that animation frame? In the trace it looks like a lot of tiles that take quite a long time to raster. Longer than I would have expected.
,
Oct 5 2016
I wouldn't worry too much about the existing trace - from looking at things, this was before the ImageDecodeController went in. It'd probably be more interesting to take a new trace and see if we still see issues.
,
Oct 5 2016
Yeah, when I tested on my MacBook Pro last night it was silky smooth. I'm building now to test Linux ToT and get a new trace.
,
Oct 5 2016
While trying to setup the trace (got the wrong categories at first) I noticed one run-through that was VERY janky and another run-through that was very smooth. Attached is a trace of the smooth run-through. You'll notice the decode is only ~8-10 ms. This can probably be improved later but for now that is great. Another thing that might be improved is SoftwareImageDecodeController::DecodeImage() sometimes spends up to ~5 ms before getting to DecodingImageGenerator::getPixels(). But all of that is fine for now. None of it is what is causing the jank. I have a theory. I think once a little jank starts we get stuck in catch-up. We are behind on presenting the current frame, and we have to decode several frames to catch up. Decoding several frames takes a long time, which causes us to once again be several frames behind. This continues on and on. If we have all of the decoded frames cached then this will fix once we loop. But if we purge the decoded frames, we continue. We exit this catch-up burden by decoding faster than a presentation requires. However, if the gif has a 10 ms delay between frames and we are taking ~10 ms to decode, we won't escape. I'll try to get a trace which shows this theory.
,
Oct 5 2016
I was able to get a janky animation from the original page: https://www.wired.com/2015/12/star-wars-force-awakens-animation/ The original, source cause of the jank isn't the image decoder. Our catch-up behavior is the symptom that perpetuates the jank. The original jank is from JavaScript running, which blocked our animation and took too long. Once that JavaScript finished, we attempted to catch up. At 71.9 s into the attached trace you will see a decode which took 236 ms. It was decoding frame 25. Because it took so long, it then caused us to miss the next few frames. The animation looped around to the beginning and we next requested frame 11. This still required decoding 11 frames so we spent 110 ms, and missed the next frame. The next frame requested was 18, which took 56 ms to produce. As you can see, once JavaScript introduces jank we have to spend a while catching up. During our cascading catch-up we continue to jank. The jank gets less and less bad until it disappears. I really, really want to get rid of this catch-up behavior. Safari mobile and Edge desktop (I didn't test Edge mobile) don't do it. And without it, we wouldn't have this eventually-stop-janking behavior.
,
Nov 8 2016
,
Jan 10 2017
|
||||||
►
Sign in to add a comment |
||||||
Comment 1 by wangxianzhu@chromium.org
, Mar 31 2016Labels: -Pri-3 OS-Android Pri-2