Do not delete asynchronously decoded frames for large images if their clients are...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 May 2017 05:14:50 +0000 (05:14 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 May 2017 05:14:50 +0000 (05:14 +0000)
commita5ec1124f12070069df7706d6dfd84fa24f9c09b
tree777a16f3e07556a9f49c4814f62876394baa75e7
parent483089792b19487702851d96f8f5112062f63207
Do not delete asynchronously decoded frames for large images if their clients are in the viewport
https://bugs.webkit.org/show_bug.cgi?id=170640

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2017-05-15
Reviewed by Simon Fraser.

Source/WebCore:

The image flickering problem happens when a large image is visible in the
view port and for some reason, the decoded frame gets destroyed. When this
image is repainted, BitmapImage::draw() does not find a valid decoded frame
for that image. It then requests an async decoding for the image and just
draws nothing in the image rectangle. Drawing no content between two drawing
phases in which the image is drawn causes the unwanted flickering.

To fix this issue we need to protect the decoded frames of all the images
in the view port from being destroyed. When BitmapImage::destroyDecodedData()
is called, it is going to check, through the ImageObserver, whether any
of its clients is visible. And if so, the current decoded frame won't be
destroyed.

Tests: Modifying existing tests.

* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::CachedImageObserver::decodedSizeChanged):
(WebCore::CachedImage::CachedImageObserver::didDraw):
(WebCore::CachedImage::CachedImageObserver::canDestroyDecodedData):
(WebCore::CachedImage::CachedImageObserver::imageFrameAvailable):
(WebCore::CachedImage::CachedImageObserver::changedInRect):
(WebCore::CachedImage::decodedSizeChanged):
(WebCore::CachedImage::didDraw):
(WebCore::CachedImage::canDestroyDecodedData): Finds out whether it's okay
to discard the image decoded data or not.
(WebCore::CachedImage::imageFrameAvailable):
(WebCore::CachedImage::changedInRect):
* loader/cache/CachedImage.h:
* loader/cache/CachedImageClient.h:
(WebCore::CachedImageClient::canDestroyDecodedData):
* loader/cache/MemoryCache.cpp:
(WebCore::MemoryCache::destroyDecodedDataForAllImages): This function is
currently not used. Use in the internal destroyDecodedDataForAllImages()
but unlike what CachedImage::destroyDecodedData() does, make it destroy
the decoded frames without deleting the image itself.
* loader/cache/MemoryCache.h:
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::destroyDecodedData):
(WebCore::BitmapImage::draw):
(WebCore::BitmapImage::canDestroyCurrentFrameDecodedData):
(WebCore::BitmapImage::advanceAnimation):
(WebCore::BitmapImage::internalAdvanceAnimation):
(WebCore::BitmapImage::imageFrameAvailableAtIndex):
* platform/graphics/BitmapImage.h:
* platform/graphics/GraphicsContext3D.cpp:
(WebCore::GraphicsContext3D::packImageData):
* platform/graphics/ImageFrameCache.cpp:
(WebCore::ImageFrameCache::decodedSizeChanged):
(ImageFrameCache::cacheAsyncFrameNativeImageAtIndex): The assertion in this
function is wrong. frameIsCompleteAtIndex() can be false when the an image
decoding is requested but can be true when the decoding finishes.
* platform/graphics/ImageObserver.h:
* platform/graphics/cairo/ImageCairo.cpp:
(WebCore::Image::drawPattern):
* platform/graphics/cg/ImageCG.cpp:
(WebCore::Image::drawPattern):
* platform/graphics/cg/ImageDecoderCG.cpp:
(WebCore::ImageDecoder::frameIsCompleteAtIndex):
* platform/graphics/cg/PDFDocumentImage.cpp:
(WebCore::PDFDocumentImage::decodedSizeChanged):
(WebCore::PDFDocumentImage::draw):
* platform/graphics/texmap/TextureMapperTiledBackingStore.cpp:
(WebCore::TextureMapperTiledBackingStore::updateContentsFromImageIfNeeded):
* platform/graphics/win/ImageDirect2D.cpp:
(WebCore::Image::drawPattern):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::isVisibleInDocumentRect):
(WebCore::RenderElement::isVisibleInViewport):
(WebCore::RenderElement::imageFrameAvailable):
(WebCore::RenderElement::repaintForPausedImageAnimationsIfNeeded):
(WebCore::RenderElement::shouldRepaintInVisibleRect): Deleted. Function
is renamed to isVisibleInViewport() for better readability.
* rendering/RenderElement.h:
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::draw):
* svg/graphics/SVGImageClients.h:
* testing/Internals.cpp:
(WebCore::Internals::destroyDecodedDataForAllImages):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit/mac:

Enable the async decoding for large images.

* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

Source/WebKit2:

Enable the async decoding for large images.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):

LayoutTests:

* fast/images/async-image-background-image-repeated.html:
* fast/images/async-image-background-image.html:
* fast/images/sprite-sheet-image-draw.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@216901 268f45cc-cd09-0410-ab3c-d52691b4dbfc
32 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/images/async-image-background-image-repeated.html
LayoutTests/fast/images/async-image-background-image.html
LayoutTests/fast/images/sprite-sheet-image-draw.html
Source/WebCore/ChangeLog
Source/WebCore/loader/cache/CachedImage.cpp
Source/WebCore/loader/cache/CachedImage.h
Source/WebCore/loader/cache/CachedImageClient.h
Source/WebCore/loader/cache/MemoryCache.cpp
Source/WebCore/loader/cache/MemoryCache.h
Source/WebCore/platform/graphics/BitmapImage.cpp
Source/WebCore/platform/graphics/BitmapImage.h
Source/WebCore/platform/graphics/GraphicsContext3D.cpp
Source/WebCore/platform/graphics/ImageFrameCache.cpp
Source/WebCore/platform/graphics/ImageObserver.h
Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
Source/WebCore/platform/graphics/cg/ImageCG.cpp
Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp
Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperTiledBackingStore.cpp
Source/WebCore/platform/graphics/win/ImageDirect2D.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/svg/graphics/SVGImage.cpp
Source/WebCore/svg/graphics/SVGImageClients.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/WebPage.cpp