Repository navigation
Commit 489ea5e
committed
Many animated images in the web page can freeze its rendering
https://bugs.webkit.org/show_bug.cgi?id=308730
Reviewed by NOBODY (OOPS!).
Each BitmapImageSource that decoded asynchronously created its own WorkQueue. That queue ran
one work item that looped on a blocking SynchronizedFixedQueue::dequeue() until stop(). The
queue is stopped only when it is idle and the image is static or its animation has stopped.
So every animating image, and every removed image with a pending frame request, held a thread
that waited for future frames. With many animated images, these waiting workers accumulate
until later images can no longer be decoded and the page stops rendering new frames.
AVIF decoding also uses GCD internally. Allowing an unbounded number of image decodes
can exhaust the available GCD worker threads when the platform decoder dispatches its
own work, preventing decoding from making progress. Bound concurrent image decoding
as well as eliminating workers that wait for future frame requests.
Replace the long-running loop with one finite work item per decode request:
- Requests for a single image still run serially, including across stop() and restart.
- A shared scheduler runs ready images on at most 8 reusable WorkQueue workers, giving other
ready images a turn between frames. An empty image queue never keeps a worker waiting, and
queue pressure never turns into unbounded concurrent decodes.
- stop() increments a generation counter. Stale requests skip decoding, and their completions
are ignored. A completion is still posted to the creation thread, so the source and the
work queue are released there.
- ImageFrameWorkQueue keeps the decoder between requests until stop(), as the old loop did.
- The minimum decoding duration for testing is captured at dispatch time instead of being
read on the decoding thread.
Also, when pruning decoded data, keep an already decoded next frame while the animation
timer is pending. Otherwise the frame would be decoded synchronously when the timer fires.
Keep the decoder while decoded frames are still in use.
Tests: fast/images/async-image-decoding-concurrent-images.html
fast/images/async-image-decoding-removed-images.html
* LayoutTests/TestExpectations:
* LayoutTests/fast/images/async-image-decoding-concurrent-images-expected.txt: Added.
* LayoutTests/fast/images/async-image-decoding-concurrent-images.html: Added.
* LayoutTests/fast/images/async-image-decoding-removed-images-expected.txt: Added.
* LayoutTests/fast/images/async-image-decoding-removed-images.html: Added.
* Source/WebCore/platform/graphics/BitmapImageSource.cpp:
(WebCore::BitmapImageSource::destroyDecodedFrames):
(WebCore::BitmapImageSource::destroyDecodedData):
* Source/WebCore/platform/graphics/ImageFrameAnimator.h:
(WebCore::ImageFrameAnimator::nextFrameIndex const):
* Source/WebCore/platform/graphics/ImageFrameWorkQueue.cpp:
(WebCore::ImageDecodingQueue::create):
(WebCore::ImageDecodingQueue::WTF_GUARDED_BY_LOCK):
(WebCore::ImageDecodingScheduler::singleton):
(WebCore::ImageDecodingScheduler::dispatch):
(WebCore::ImageDecodingScheduler::WTF_GUARDED_BY_LOCK):
(WebCore::ImageDecodingQueue::dispatch):
(WebCore::ImageDecodingQueue::runOneRequest):
(WebCore::ImageFrameWorkQueue::ImageFrameWorkQueue):
(WebCore::ImageFrameWorkQueue::dispatch):
(WebCore::ImageFrameWorkQueue::stop):
(WebCore::ImageFrameWorkQueue::requestQueue): Deleted.
(WebCore::ImageFrameWorkQueue::start): Deleted.
* Source/WebCore/platform/graphics/ImageFrameWorkQueue.h:
(WebCore::ImageFrameWorkQueue::minimumDecodingDurationForTesting const): Deleted.1 parent 88858fa commit 489ea5e
9 files changed
Lines changed: 289 additions & 75 deletions
File tree
- LayoutTests
- fast/images
- Source/WebCore/platform/graphics
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
344 | 344 | | |
345 | 345 | | |
346 | 346 | | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
347 | 350 | | |
348 | 351 | | |
349 | 352 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
135 | 138 | | |
136 | 139 | | |
137 | 140 | | |
138 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
139 | 144 | | |
140 | 145 | | |
141 | 146 | | |
| |||
151 | 156 | | |
152 | 157 | | |
153 | 158 | | |
154 | | - | |
155 | | - | |
156 | | - | |
| 159 | + | |
| 160 | + | |
157 | 161 | | |
158 | 162 | | |
159 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
| 61 | + | |
61 | 62 | | |
62 | 63 | | |
63 | 64 | | |
| |||
68 | 69 | | |
69 | 70 | | |
70 | 71 | | |
71 | | - | |
72 | | - | |
73 | 72 | | |
74 | 73 | | |
75 | 74 | | |
| |||
0 commit comments