RESOLVED FIXED 157500
REGRESSION (r199821): Large animated GIFs with slow network do not animate till the last frame
https://bugs.webkit.org/show_bug.cgi?id=157500
Summary REGRESSION (r199821): Large animated GIFs with slow network do not animate ti...
Said Abou-Hallawa
Reported 2016-05-09 19:40:35 PDT
In r199821, some of the image metadata were cached in the ImageSource object. The purpose of this change was to save time which we may encounter when calculating the maximumSubsamplingLevel on iOS. Having the image metadata and the image frames cached in the ImageSource is part of the asynchronous image decoding feature https://bugs.webkit.org/show_bug.cgi?id=155322. But because a flag is needed to indicate whether the image metadata has already cached or not, I used the cached frameCount for this purpose. The assumption was the image frameCount can be retrieved once the image size is available and it is not going to change. It turned out this assumption is wrong. A bug may happen with large GIFs where the frame count gets changed every time a new data block is decoded. Therefore the cached frameCount can be stale data and needs to be updated. A possible way to fix this bug is to invalidate the image metadata cache every time new data block is decoded. This will achieve the following goals: 1. We get the correct image metadata regardless they are final when decoding the first data block or they are going to change later. 2. We save time by calculating maximumSubsamplingLevel only once. 3. We do some work towards the asynchronous image decoding feature instead of rolling out r199821.
Attachments
Patch (7.02 KB, patch)
2016-05-09 20:58 PDT, Said Abou-Hallawa
no flags
Patch (14.03 KB, patch)
2016-05-11 15:31 PDT, Said Abou-Hallawa
no flags
Patch (14.02 KB, patch)
2016-05-11 15:36 PDT, Said Abou-Hallawa
no flags
Patch (900.84 KB, patch)
2016-05-12 11:31 PDT, Said Abou-Hallawa
no flags
Archive of layout-test-results from ews101 for mac-yosemite (1.21 MB, application/zip)
2016-05-12 11:59 PDT, Build Bot
no flags
Patch (900.84 KB, patch)
2016-05-12 12:05 PDT, Said Abou-Hallawa
no flags
Archive of layout-test-results from ews117 for mac-yosemite (1.48 MB, application/zip)
2016-05-12 13:03 PDT, Build Bot
no flags
Archive of layout-test-results from ews101 for mac-yosemite (925.37 KB, application/zip)
2016-05-12 13:08 PDT, Build Bot
no flags
Patch (900.84 KB, patch)
2016-05-12 13:08 PDT, Said Abou-Hallawa
no flags
Archive of layout-test-results from ews115 for mac-yosemite (1.44 MB, application/zip)
2016-05-12 14:07 PDT, Build Bot
no flags
Archive of layout-test-results from ews101 for mac-yosemite (1.35 MB, application/zip)
2016-05-12 14:33 PDT, Build Bot
no flags
Patch (928.46 KB, patch)
2016-05-12 15:05 PDT, Said Abou-Hallawa
no flags
Archive of layout-test-results from ews112 for mac-yosemite (1.44 MB, application/zip)
2016-05-12 16:07 PDT, Build Bot
no flags
Archive of layout-test-results from ews101 for mac-yosemite (922.40 KB, application/zip)
2016-05-12 17:33 PDT, Build Bot
no flags
Patch (701.93 KB, patch)
2016-05-13 15:36 PDT, Said Abou-Hallawa
no flags
Archive of layout-test-results from ews126 for ios-simulator-wk2 (807.89 KB, application/zip)
2016-05-13 16:15 PDT, Build Bot
no flags
Patch (701.93 KB, patch)
2016-05-13 16:17 PDT, Said Abou-Hallawa
no flags
Patch (702.00 KB, patch)
2016-05-13 17:28 PDT, Said Abou-Hallawa
no flags
Patch (701.99 KB, patch)
2016-05-13 18:57 PDT, Said Abou-Hallawa
no flags
Patch (702.43 KB, patch)
2016-05-15 23:48 PDT, Said Abou-Hallawa
no flags
Said Abou-Hallawa
Comment 1 2016-05-09 20:58:42 PDT
Simon Fraser (smfr)
Comment 2 2016-05-09 21:49:07 PDT
Comment on attachment 278474 [details] Patch What was the behavior before your change? Does this change cause more decoding of metadata than before the regression point? Can we only do this for animated images?
Said Abou-Hallawa
Comment 3 2016-05-10 17:30:30 PDT
(In reply to comment #2) > Comment on attachment 278474 [details] > Patch > > What was the behavior before your change? Does this change cause more > decoding of metadata than before the regression point? Can we only do this > for animated images? Before I started the asynchronous image decoding work, BitmapImage::m_frameCount was invalidated every time BitmapImage::dataChanged() is called. This was happening by setting BitmapImage::m_haveFrameCount to false. The next time BitmapImage::frameCount() is called, ImageSource::frameCount() was called and BitmapImage::m_haveFrameCount to true. Because ImageSource for CG was actually the image decoder, ImageSource::frameCount() was calling CGImageSourceGetCount(). In r199821, I partially moved getting the frameCount from BitmapImage to ImageSource but I assumed the frameCount is constant and will not change once the image size is available. This was enforcing calling CGImageSourceGetCount() only once for any image including large animated GIFs where the frameCount can change every time a data block is decoded. With this patch, we are back to the same behavior before r199821. Setting BitmapImage::m_haveFrameCount is left as is even though BitmapImage::m_haveFrameCount and BitmapImage::m_frameCount are not really needed anymore. ImageSource::frameCount() can be used directly to get the frameCount. With some other clean-up they can both deleted. ImageSource::m_needsUpdateMetadata is initialized with true expect for the case when BitmapImage is created for a single NativeImagePtr. Every time BitmapImage::dataChanged() is called, BitmapImage::m_haveFrameCount is set to false and ImageSource::m_needsUpdateMetadata is set to true. When BitmapImage::frameCount() is called and finds BitmapImage::m_haveFrameCount is false it calls ImageSource::frameCount() which finds also ImageSource::m_needsUpdateMetadata is true. In this case, it reevaluates ImageSource::m_frameCount by calling CGImageSourceGetCount(). Regarding reevaluating the frameCount only for the animated images, as far as I know the only way to know whether the image is animated or not is through its frameCount. If the frameCount == 1 and we received a new block of data, we can't know if calling CGImageSourceGetCount() after decoding this block is going to get 1 or more than 1. We can also roll out r199821 for now.
Simon Fraser (smfr)
Comment 4 2016-05-10 17:45:24 PDT
Comment on attachment 278474 [details] Patch OK, I think this is fine. Is it testable?
Darin Adler
Comment 5 2016-05-10 21:48:10 PDT
Comment on attachment 278474 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=278474&action=review > Source/WebCore/platform/graphics/ImageSource.cpp:113 > + if (!(needsUpdateMetadata() && isSizeAvailable())) Seems that this should look at the data member directly, not call the needsUpdateMetdata() function. > Source/WebCore/platform/graphics/ImageSource.cpp:120 > + setNeedsUpdateMetadata(false); Seems that this should set the data member directly, not call a function. > Source/WebCore/platform/graphics/ImageSource.h:113 > + bool needsUpdateMetadata() const { return m_needsUpdateMetadata; } I am not sure we should expose this function. > Source/WebCore/platform/graphics/ImageSource.h:114 > + void setNeedsUpdateMetadata(bool needsUpdateMetadata) { m_needsUpdateMetadata = needsUpdateMetadata; } I don’t think this function needs an argument. Should just set to true.
Said Abou-Hallawa
Comment 6 2016-05-11 15:31:37 PDT
Said Abou-Hallawa
Comment 7 2016-05-11 15:36:51 PDT
Said Abou-Hallawa
Comment 8 2016-05-12 11:31:36 PDT
Build Bot
Comment 9 2016-05-12 11:59:07 PDT
Comment on attachment 278739 [details] Patch Attachment 278739 [details] did not pass mac-ews (mac): Output: http://webkit-queues.webkit.org/results/1310625 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 10 2016-05-12 11:59:09 PDT
Created attachment 278743 [details] Archive of layout-test-results from ews101 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews101 Port: mac-yosemite Platform: Mac OS X 10.10.5
Said Abou-Hallawa
Comment 11 2016-05-12 12:05:43 PDT
Simon Fraser (smfr)
Comment 12 2016-05-12 12:06:35 PDT
Comment on attachment 278739 [details] Patch I really think it's worth making an http test with a slow-serving script to test this.
Simon Fraser (smfr)
Comment 13 2016-05-12 12:07:20 PDT
...or figure out why http/tests/misc/slow-loading-animated-image.html didn't spot the original regression.
Build Bot
Comment 14 2016-05-12 13:03:39 PDT
Comment on attachment 278745 [details] Patch Attachment 278745 [details] did not pass mac-debug-ews (mac): Output: http://webkit-queues.webkit.org/results/1310822 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 15 2016-05-12 13:03:42 PDT
Created attachment 278751 [details] Archive of layout-test-results from ews117 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews117 Port: mac-yosemite Platform: Mac OS X 10.10.5
Build Bot
Comment 16 2016-05-12 13:08:20 PDT
Comment on attachment 278745 [details] Patch Attachment 278745 [details] did not pass mac-ews (mac): Output: http://webkit-queues.webkit.org/results/1310876 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 17 2016-05-12 13:08:23 PDT
Created attachment 278752 [details] Archive of layout-test-results from ews101 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews101 Port: mac-yosemite Platform: Mac OS X 10.10.5
Said Abou-Hallawa
Comment 18 2016-05-12 13:08:48 PDT
Build Bot
Comment 19 2016-05-12 14:07:53 PDT
Comment on attachment 278753 [details] Patch Attachment 278753 [details] did not pass mac-debug-ews (mac): Output: http://webkit-queues.webkit.org/results/1311086 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 20 2016-05-12 14:07:57 PDT
Created attachment 278758 [details] Archive of layout-test-results from ews115 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews115 Port: mac-yosemite Platform: Mac OS X 10.10.5
Build Bot
Comment 21 2016-05-12 14:33:32 PDT
Comment on attachment 278753 [details] Patch Attachment 278753 [details] did not pass mac-ews (mac): Output: http://webkit-queues.webkit.org/results/1311230 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 22 2016-05-12 14:33:36 PDT
Created attachment 278763 [details] Archive of layout-test-results from ews101 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews101 Port: mac-yosemite Platform: Mac OS X 10.10.5
Said Abou-Hallawa
Comment 23 2016-05-12 15:05:03 PDT
Build Bot
Comment 24 2016-05-12 16:07:00 PDT
Comment on attachment 278766 [details] Patch Attachment 278766 [details] did not pass mac-debug-ews (mac): Output: http://webkit-queues.webkit.org/results/1311600 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 25 2016-05-12 16:07:03 PDT
Created attachment 278775 [details] Archive of layout-test-results from ews112 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews112 Port: mac-yosemite Platform: Mac OS X 10.10.5
Said Abou-Hallawa
Comment 26 2016-05-12 16:18:36 PDT
These failures happen in WK1 which also fails locally.
Build Bot
Comment 27 2016-05-12 17:33:09 PDT
Comment on attachment 278766 [details] Patch Attachment 278766 [details] did not pass mac-ews (mac): Output: http://webkit-queues.webkit.org/results/1312009 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 28 2016-05-12 17:33:12 PDT
Created attachment 278785 [details] Archive of layout-test-results from ews101 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews101 Port: mac-yosemite Platform: Mac OS X 10.10.5
Said Abou-Hallawa
Comment 29 2016-05-13 15:36:53 PDT
Build Bot
Comment 30 2016-05-13 16:15:20 PDT
Comment on attachment 278881 [details] Patch Attachment 278881 [details] did not pass ios-sim-ews (ios-simulator-wk2): Output: http://webkit-queues.webkit.org/results/1316985 New failing tests: http/tests/misc/slow-loading-animated-image.html
Build Bot
Comment 31 2016-05-13 16:15:25 PDT
Created attachment 278887 [details] Archive of layout-test-results from ews126 for ios-simulator-wk2 The attached test failures were seen while running run-webkit-tests on the ios-sim-ews. Bot: ews126 Port: ios-simulator-wk2 Platform: Mac OS X 10.11.4
Said Abou-Hallawa
Comment 32 2016-05-13 16:17:01 PDT
Said Abou-Hallawa
Comment 33 2016-05-13 16:20:08 PDT
The ios-simulator bot is slow. Animating 33 frames took 1000 ms. Add 500ms extra waiting time to be sure the last frame is displayed.
Said Abou-Hallawa
Comment 34 2016-05-13 17:28:02 PDT
Said Abou-Hallawa
Comment 35 2016-05-13 17:28:47 PDT
(In reply to comment #4) > Comment on attachment 278474 [details] > Patch > > OK, I think this is fine. Is it testable? A test was added but it takes 2.5 seconds to finish.
Said Abou-Hallawa
Comment 36 2016-05-13 17:30:21 PDT
Comment on attachment 278474 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=278474&action=review >> Source/WebCore/platform/graphics/ImageSource.cpp:113 >> + if (!(needsUpdateMetadata() && isSizeAvailable())) > > Seems that this should look at the data member directly, not call the needsUpdateMetdata() function. Done. >> Source/WebCore/platform/graphics/ImageSource.cpp:120 >> + setNeedsUpdateMetadata(false); > > Seems that this should set the data member directly, not call a function. Done. >> Source/WebCore/platform/graphics/ImageSource.h:113 >> + bool needsUpdateMetadata() const { return m_needsUpdateMetadata; } > > I am not sure we should expose this function. This functions was deleted. >> Source/WebCore/platform/graphics/ImageSource.h:114 >> + void setNeedsUpdateMetadata(bool needsUpdateMetadata) { m_needsUpdateMetadata = needsUpdateMetadata; } > > I don’t think this function needs an argument. Should just set to true. The parameter was removed.
Said Abou-Hallawa
Comment 37 2016-05-13 18:57:02 PDT
Darin Adler
Comment 38 2016-05-14 09:15:42 PDT
Comment on attachment 278907 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=278907&action=review > Source/WebCore/platform/graphics/BitmapImage.h:86 > + static IntSize sizeOfImage(const NativeImagePtr&); > + static bool alphaOfImage(const NativeImagePtr&); Why do these functions have "OfImage" in their names? They take an argument, so clearly they are the size of the thing that is passed in. Is there perhaps a conflict between these functions and others with the same names that prevents us from just calling them size and hasAlpha? It’s unclear what a function named “alpha” that returns a boolean means. It would be better to have a more precise name. Maybe hasAlpha is precise enough. Why doe these functions need to be members of BitmapImage rather than free functions? I think it’s good to have functions names size and hasAlpha that can be called on NativeImagePtr, but I don’t think they should necessarily be static function members of BitmapImage. > Source/WebCore/platform/graphics/ImageSource.cpp:48 > + , m_maximumSubsamplingLevel(-1) Can we use Optional to indicate we don’t have a level, rather than a magic number of -1?
Darin Adler
Comment 39 2016-05-14 09:16:31 PDT
Comment on attachment 278907 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=278907&action=review > Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp:61 > +bool FrameData::alphaOfImage(const RetainPtr<CGImageRef>&) > +{ > + return true; > +} Given this implementation, this function needs to be named mayHaveAlpha, I think, since it doesn’t really correctly answer the question.
Said Abou-Hallawa
Comment 40 2016-05-15 23:48:05 PDT
WebKit Commit Bot
Comment 41 2016-05-16 01:04:23 PDT
Comment on attachment 279003 [details] Patch Clearing flags on attachment: 279003 Committed r200939: <http://trac.webkit.org/changeset/200939>
WebKit Commit Bot
Comment 42 2016-05-16 01:04:30 PDT
All reviewed patches have been landed. Closing bug.
Said Abou-Hallawa
Comment 43 2016-05-16 01:17:32 PDT
Said Abou-Hallawa
Comment 44 2016-05-16 11:09:45 PDT
Comment on attachment 278907 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=278907&action=review >> Source/WebCore/platform/graphics/BitmapImage.h:86 >> + static bool alphaOfImage(const NativeImagePtr&); > > Why do these functions have "OfImage" in their names? They take an argument, so clearly they are the size of the thing that is passed in. Is there perhaps a conflict between these functions and others with the same names that prevents us from just calling them size and hasAlpha? > > It’s unclear what a function named “alpha” that returns a boolean means. It would be better to have a more precise name. Maybe hasAlpha is precise enough. > > Why doe these functions need to be members of BitmapImage rather than free functions? > > I think it’s good to have functions names size and hasAlpha that can be called on NativeImagePtr, but I don’t think they should necessarily be static function members of BitmapImage. Names were changed and the functions were moved out of the FrameData. To keep names as suggested, I put them in a namespace called "NativeImage" >> Source/WebCore/platform/graphics/ImageSource.cpp:48 >> + , m_maximumSubsamplingLevel(-1) > > Can we use Optional to indicate we don’t have a level, rather than a magic number of -1? Done. >> Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp:61 >> +} > > Given this implementation, this function needs to be named mayHaveAlpha, I think, since it doesn’t really correctly answer the question. I kept the name hasAlpha() but I added a FIXME comment because I realized that hasAlpha information can be calculated for CG by calling CGImageGetAlphaInfo().
Alexey Proskuryakov
Comment 45 2016-05-19 13:12:23 PDT
The new test is very flaky on iOS, filed bug 157916.
Note You need to log in before you can comment on or make changes to this bug.