Change the decoding for some animated images to be asynchronous
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Nov 2016 01:13:05 +0000 (01:13 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Nov 2016 01:13:05 +0000 (01:13 +0000)
commitcea670c0fb8e294e5f9f19bfe28e2e7ac5b3c59b
tree886937bb46bc30321aab768415fbd6135d97072b
parent84ef2dc6ad0a3efa2a3e67acf897f1adc15273e8
Change the decoding for some animated images to be asynchronous
https://bugs.webkit.org/show_bug.cgi?id=161566

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2016-11-09
Reviewed by Simon Fraser.

Source/WebCore:

Tests: fast/images/slower-animation-than-decoding-image.html
       fast/images/slower-decoding-than-animation-image.html
       fast/images/stopped-animation-deleted-image.html

Request the next frame before firing the animation timer. The asynchronous
image decoding work queue notifies the BitmapImage when the frame finishes
decoding. If the timer fires before the frame is decoded, no repaint will
be requested. Only when the image frame is ready, the animation will be
advanced and the image will be repainted.

* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::load): Cache the image settings in CachedImage.
(WebCore::CachedImage::createImage): No need to pass allowSubsampling to BitmapImage. It can be retrieved through Image::imageObserver().
(WebCore::CachedImage::changedInRect): Change the parameter to notifyObservers() to be a pointer.
* loader/cache/CachedImage.h: Cache the settings: allowSubsampling, allowAsyncImageDecoding and showDebugBackground through m_loader.
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::dataChanged): Fix a logging message.
(WebCore::BitmapImage::draw): Store the current SubsamplingLevel to be used when requesting decoding the image of the next frame.
Draw a debug rectangle if the next frame is missed because it is being decoded and the setting showDebugBackground is on.
(WebCore::BitmapImage::startAnimation): Deleted. Moved to the header file.
(WebCore::BitmapImage::internalStartAnimation): Added. Request asynchronous image decoding for the next frame if required. Return the
result of starting the animation.
(WebCore::BitmapImage::advanceAnimation): Call internalAdvanceAnimation() if the frame image is not being decoded. If it is being decoded
and the setting showDebugBackground is on, force repaint so the debug rectangle is drawn.
(WebCore::BitmapImage::internalAdvanceAnimation): This is the old body of advanceAnimation().
(WebCore::BitmapImage::stopAnimation): Stop the asynchronous image decoding if it is started.
(WebCore::BitmapImage::newFrameNativeImageAvailableAtIndex): This function is called from the async image decoding work queue when finishing decoding a native image frame.
* platform/graphics/BitmapImage.h:
(WebCore::BitmapImage::startAnimation): Added. It is now calls internalStartAnimation().
* platform/graphics/Color.h: Define a constant for the yellow color.
* platform/graphics/ImageFrameCache.cpp:
(WebCore::ImageFrameCache::clearMetadata): Delete unreferenced member.
(WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex): Return true if the frame is requested for async decoding.
* platform/graphics/ImageFrameCache.h:
* platform/graphics/ImageObserver.h:  Add virtual functions for allowSubsampling, allowAsyncImageDecoding and showDebugBackground.
* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::maximumSubsamplingLevel): Move checking allowSubsampling() to the caller BitmapImage::draw().
* platform/graphics/ImageSource.h: Remove the setting allowSubsampling(); it can be retrieved from imageObserver().
(WebCore::ImageSource::setAllowSubsampling): Deleted.
* rendering/RenderImageResource.cpp:
(WebCore::RenderImageResource::shutdown): Stop the animation of an image when shutting down the resource.
* rendering/RenderImageResourceStyleImage.cpp:
(WebCore::RenderImageResourceStyleImage::shutdown): Ditto.
svg/graphics/SVGImageClients.h: Change the parameter to ImageObserver::changedInRect() to be a pointer.
(WebCore::SVGImageChromeClient::invalidateContentsAndRootView):
* testing/Internals.cpp:
(WebCore::Internals::setImageFrameDecodingDuration): Sets a fixed frame decoding duration for testing.
* testing/Internals.h:
* testing/Internals.idl: Adds an internal option for ImageFrameDecodingDuration.

LayoutTests:

* fast/images/slower-animation-than-decoding-image-expected.txt: Added.
* fast/images/slower-animation-than-decoding-image.html: Added.
* fast/images/slower-decoding-than-animation-image-expected.txt: Added.
* fast/images/slower-decoding-than-animation-image.html: Added.
In these tests, CanvasRenderingContext2D.drawImage() is used to better
control advancing the animation of an animated image. A setTimeout() is
used instead of the frame duration to schedule when the drawing happens.
The first test ensures that faster decoding does not overrule the frame
duration; the setTimeout interval in this case. The second test ensures
the animation is not advanced unless decoding the next frame has finished.

* fast/images/stopped-animation-deleted-image-expected.txt: Added.
* fast/images/stopped-animation-deleted-image.html: Added.
This test ensures that if an animated image is removed from the document,
its draw() method won't be called even if the animation timer fires or the
decoding new frame availability notification is received.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208511 268f45cc-cd09-0410-ab3c-d52691b4dbfc
24 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/images/slower-animation-than-decoding-image-expected.txt [new file with mode: 0644]
LayoutTests/fast/images/slower-animation-than-decoding-image.html [new file with mode: 0644]
LayoutTests/fast/images/slower-decoding-than-animation-image-expected.txt [new file with mode: 0644]
LayoutTests/fast/images/slower-decoding-than-animation-image.html [new file with mode: 0644]
LayoutTests/fast/images/stopped-animation-deleted-image-expected.txt [new file with mode: 0644]
LayoutTests/fast/images/stopped-animation-deleted-image.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/loader/cache/CachedImage.cpp
Source/WebCore/loader/cache/CachedImage.h
Source/WebCore/platform/graphics/BitmapImage.cpp
Source/WebCore/platform/graphics/BitmapImage.h
Source/WebCore/platform/graphics/Color.h
Source/WebCore/platform/graphics/ImageFrameCache.cpp
Source/WebCore/platform/graphics/ImageFrameCache.h
Source/WebCore/platform/graphics/ImageObserver.h
Source/WebCore/platform/graphics/ImageSource.cpp
Source/WebCore/platform/graphics/ImageSource.h
Source/WebCore/rendering/RenderImageResource.cpp
Source/WebCore/rendering/RenderImageResourceStyleImage.cpp
Source/WebCore/svg/graphics/SVGImageClients.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl