WebKit Bugzilla
Attachment 342614 Details for
Bug 186336
: TileFirstPaint strategy for async image decoding should be disabled for non root RenderLayers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186336-20180612173714.patch (text/plain), 12.26 KB, created by
Said Abou-Hallawa
on 2018-06-12 17:37:15 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Said Abou-Hallawa
Created:
2018-06-12 17:37:15 PDT
Size:
12.26 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 232780) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,34 @@ >+2018-06-12 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ TileFirstPaint strategy for async image decoding should be disabled for non root RenderLayers >+ https://bugs.webkit.org/show_bug.cgi?id=186336 >+ <rdar://problem/40808099> >+ >+ Reviewed by Simon Fraser. >+ >+ When showing a composited RenderLayer for the first time, the images in >+ this layer have to be decoded synchronously to avoid unwanted flashing. >+ >+ To create a layout test for this patch, FrameDecodingDurationForTesting >+ needs to be generalized for large and animated images. The decoding thread >+ now forces the decoding time to be at least equal to >+ FrameDecodingDurationForTesting. >+ >+ Test: fast/images/async-image-composited-show.html >+ >+ * platform/graphics/BitmapImage.cpp: >+ (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages const): >+ (WebCore::BitmapImage::internalStartAnimation): >+ (WebCore::BitmapImage::advanceAnimation): >+ * platform/graphics/BitmapImage.h: >+ * platform/graphics/ImageSource.cpp: >+ (WebCore::ImageSource::startAsyncDecodingQueue): >+ * platform/graphics/ImageSource.h: >+ (WebCore::ImageSource::setFrameDecodingDurationForTesting): >+ (WebCore::ImageSource::frameDecodingDurationForTesting const): >+ * rendering/RenderLayer.cpp: >+ (WebCore::RenderLayer::paintLayerContents): >+ > 2018-06-12 Ryosuke Niwa <rniwa@webkit.org> > > iOS WK1: Occasional crash in FrameView::setScrollPosition >Index: Source/WebCore/platform/graphics/BitmapImage.cpp >=================================================================== >--- Source/WebCore/platform/graphics/BitmapImage.cpp (revision 232780) >+++ Source/WebCore/platform/graphics/BitmapImage.cpp (working copy) >@@ -340,7 +340,7 @@ bool BitmapImage::canUseAsyncDecodingFor > > bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages() const > { >- return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source->canUseAsyncDecoding()); >+ return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForTesting() || m_source->canUseAsyncDecoding()); > } > > void BitmapImage::clearTimer() >@@ -449,7 +449,6 @@ BitmapImage::StartAnimationStatus Bitmap > LOG(Images, "BitmapImage::%s - %p - url: %s [requesting async decoding for nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), nextFrame); > } > >- m_desiredFrameDecodeTimeForTesting = time + std::max(m_frameDecodingDurationForTesting, 0_s); > if (m_clearDecoderAfterAsyncFrameRequestForTesting) > m_source->resetData(data()); > } >@@ -463,17 +462,6 @@ void BitmapImage::advanceAnimation() > { > clearTimer(); > >- // Pretend as if decoding nextFrame has taken m_frameDecodingDurationForTesting from >- // the time this decoding was requested. >- if (shouldUseAsyncDecodingForAnimatedImagesForTesting()) { >- MonotonicTime time = MonotonicTime::now(); >- // Start a timer with the remaining time from now till the m_desiredFrameDecodeTime. >- if (m_desiredFrameDecodeTimeForTesting > std::max(time, m_desiredFrameStartTime)) { >- startTimer(m_desiredFrameDecodeTimeForTesting - time); >- return; >- } >- } >- > // Don't advance to nextFrame unless its decoding has finished or was not required. > size_t nextFrame = (m_currentFrame + 1) % frameCount(); > if (!frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(nextFrame, DecodingOptions(DecodingMode::Asynchronous))) >Index: Source/WebCore/platform/graphics/BitmapImage.h >=================================================================== >--- Source/WebCore/platform/graphics/BitmapImage.h (revision 232780) >+++ Source/WebCore/platform/graphics/BitmapImage.h (working copy) >@@ -102,8 +102,8 @@ public: > ImageOrientation orientationForCurrentFrame() const { return frameOrientationAtIndex(currentFrame()); } > bool canAnimate() const; > >- bool shouldUseAsyncDecodingForAnimatedImagesForTesting() const { return m_frameDecodingDurationForTesting > 0_s; } >- void setFrameDecodingDurationForTesting(Seconds duration) { m_frameDecodingDurationForTesting = duration; } >+ bool shouldUseAsyncDecodingForTesting() const { return m_source->frameDecodingDurationForTesting() > 0_s; } >+ void setFrameDecodingDurationForTesting(Seconds duration) { m_source->setFrameDecodingDurationForTesting(duration); } > bool canUseAsyncDecodingForLargeImages() const; > bool shouldUseAsyncDecodingForAnimatedImages() const; > void setClearDecoderAfterAsyncFrameRequestForTesting(bool value) { m_clearDecoderAfterAsyncFrameRequestForTesting = value; } >@@ -216,8 +216,6 @@ private: > MonotonicTime m_desiredFrameStartTime; // The system time at which we hope to see the next call to startAnimation(). > > std::unique_ptr<Vector<Function<void()>, 1>> m_decodingCallbacks; >- Seconds m_frameDecodingDurationForTesting; >- MonotonicTime m_desiredFrameDecodeTimeForTesting; > > bool m_animationFinished { false }; > >Index: Source/WebCore/platform/graphics/ImageSource.cpp >=================================================================== >--- Source/WebCore/platform/graphics/ImageSource.cpp (revision 232780) >+++ Source/WebCore/platform/graphics/ImageSource.cpp (working copy) >@@ -325,10 +325,15 @@ void ImageSource::startAsyncDecodingQueu > // We need to protect this, m_decodingQueue and m_decoder from being deleted while we are in the decoding loop. > decodingQueue().dispatch([protectedThis = makeRef(*this), protectedDecodingQueue = makeRef(decodingQueue()), protectedFrameRequestQueue = makeRef(frameRequestQueue()), protectedDecoder = makeRef(*m_decoder), sourceURL = sourceURL().string().isolatedCopy()] { > ImageFrameRequest frameRequest; >+ Seconds minDecodingDuration = protectedThis->frameDecodingDurationForTesting(); > > while (protectedFrameRequestQueue->dequeue(frameRequest)) { > TraceScope tracingScope(AsyncImageDecodeStart, AsyncImageDecodeEnd); > >+ MonotonicTime startingTime; >+ if (minDecodingDuration > 0_s) >+ startingTime = MonotonicTime::now(); >+ > // Get the frame NativeImage on the decoding thread. > NativeImagePtr nativeImage = protectedDecoder->createFrameImageAtIndex(frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions); > if (nativeImage) >@@ -338,6 +343,10 @@ void ImageSource::startAsyncDecodingQueu > continue; > } > >+ // Pretend as if the decoding takes minDecodingDuration. >+ if (minDecodingDuration > 0_s) >+ sleep(minDecodingDuration - (MonotonicTime::now() - startingTime)); >+ > // Update the cached frames on the main thread to avoid updating the MemoryCache from a different thread. > callOnMainThread([protectedThis = protectedThis.copyRef(), protectedQueue = protectedDecodingQueue.copyRef(), protectedDecoder = protectedDecoder.copyRef(), sourceURL = sourceURL.isolatedCopy(), nativeImage = WTFMove(nativeImage), frameRequest] () mutable { > // The queue may have been closed if after we got the frame NativeImage, stopAsyncDecodingQueue() was called. >Index: Source/WebCore/platform/graphics/ImageSource.h >=================================================================== >--- Source/WebCore/platform/graphics/ImageSource.h (revision 232780) >+++ Source/WebCore/platform/graphics/ImageSource.h (working copy) >@@ -81,6 +81,8 @@ public: > void stopAsyncDecodingQueue(); > bool hasAsyncDecodingQueue() const { return m_decodingQueue; } > bool isAsyncDecodingQueueIdle() const; >+ void setFrameDecodingDurationForTesting(Seconds duration) { m_frameDecodingDurationForTesting = duration; } >+ Seconds frameDecodingDurationForTesting() const { return m_frameDecodingDurationForTesting; } > > // Image metadata which is calculated either by the ImageDecoder or directly > // from the NativeImage if this class was created for a memory image. >@@ -181,6 +183,7 @@ private: > RefPtr<FrameRequestQueue> m_frameRequestQueue; > FrameCommitQueue m_frameCommitQueue; > RefPtr<WorkQueue> m_decodingQueue; >+ Seconds m_frameDecodingDurationForTesting; > > // Image metadata. > std::optional<EncodedDataStatus> m_encodedDataStatus; >Index: Source/WebCore/rendering/RenderLayer.cpp >=================================================================== >--- Source/WebCore/rendering/RenderLayer.cpp (revision 232780) >+++ Source/WebCore/rendering/RenderLayer.cpp (working copy) >@@ -4350,7 +4350,7 @@ void RenderLayer::paintLayerContents(Gra > if (paintingInfo.paintBehavior & PaintBehaviorSnapshotting) > paintBehavior |= PaintBehaviorSnapshotting; > >- if (paintingInfo.paintBehavior & PaintBehaviorTileFirstPaint) >+ if ((paintingInfo.paintBehavior & PaintBehaviorTileFirstPaint) && isRenderViewLayer()) > paintBehavior |= PaintBehaviorTileFirstPaint; > > if (paintingInfo.paintBehavior & PaintBehaviorExcludeSelection) >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 232780) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,14 @@ >+2018-06-12 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ TileFirstPaint strategy for async image decoding should be disabled for non root RenderLayers >+ https://bugs.webkit.org/show_bug.cgi?id=186336 >+ <rdar://problem/40808099> >+ >+ Reviewed by Simon Fraser. >+ >+ * fast/images/async-image-composited-show-expected.html: Added. >+ * fast/images/async-image-composited-show.html: Added. >+ > 2018-06-12 Said Abou-Hallawa <sabouhallawa@apple.com> > > Unreviewed followup for r232736 >Index: LayoutTests/fast/images/async-image-composited-show-expected.html >=================================================================== >--- LayoutTests/fast/images/async-image-composited-show-expected.html (nonexistent) >+++ LayoutTests/fast/images/async-image-composited-show-expected.html (working copy) >@@ -0,0 +1,16 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <style> >+ .container { >+ position: relative; >+ width: 400px; >+ height: 400px; >+ background-color: green; >+ } >+ </style> >+</head> >+<body> >+ <div class="container"></div> >+</body> >+</html> >Index: LayoutTests/fast/images/async-image-composited-show.html >=================================================================== >--- LayoutTests/fast/images/async-image-composited-show.html (nonexistent) >+++ LayoutTests/fast/images/async-image-composited-show.html (working copy) >@@ -0,0 +1,52 @@ >+<style> >+ .container { >+ position: relative; >+ width: 400px; >+ height: 400px; >+ background-color: #ff0000; >+ } >+ .composited { >+ position: absolute; >+ top: 0; >+ left: 0; >+ width: 100%; >+ height: 100%; >+ background-repeat: no-repeat; >+ z-index: 0; >+ } >+ body { >+ opacity: 0; >+ background: rgba(0, 0, 0, 0); >+ } >+ body.background-loaded { >+ opacity: 1; >+ } >+</style> >+<body> >+ <div class="container"> >+ <div class="composited"></div> >+ </div> >+ <script> >+ if (window.testRunner) { >+ internals.clearMemoryCache(); >+ internals.settings.setLargeImageAsyncDecodingEnabled(true); >+ testRunner.waitUntilDone(); >+ } >+ >+ var image = new Image(); >+ image.onload = function() { >+ // Force very long async image decoding for this image. >+ if (window.internals) >+ internals.setImageFrameDecodingDuration(image, 5000); >+ >+ // Change the background of the element. >+ let element = document.querySelector(".composited"); >+ element.style.backgroundImage = 'url(' + image.src + ')'; >+ >+ // Show the body element and end the test. >+ document.body.classList.add("background-loaded"); >+ testRunner.notifyDone(); >+ }; >+ image.src = "resources/green-400x400.png"; >+ </script> >+</body>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186336
:
342025
|
342178
|
342179
|
342590
| 342614