Title: [216471] trunk/Source/WebCore
Revision
216471
Author
s...@apple.com
Date
2017-05-08 18:53:54 -0700 (Mon, 08 May 2017)

Log Message

The Incomplete asynchronously decoded image frame should be decoded every time it's drawn
https://bugs.webkit.org/show_bug.cgi?id=170836

Reviewed by Tim Horton.

The asynchronously decoded image frames has to be cached to prevent flickering,
but we have to keep requesting new decoding for the incomplete frame every time
it's drawn. This is to avoid drawing an incomplete image frame even after all
its encoded data is received.

* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::draw):
* platform/graphics/ImageFrameCache.cpp:
(WebCore::ImageFrameCache::cacheAsyncFrameNativeImageAtIndex):
(WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (216470 => 216471)


--- trunk/Source/WebCore/ChangeLog	2017-05-09 01:45:20 UTC (rev 216470)
+++ trunk/Source/WebCore/ChangeLog	2017-05-09 01:53:54 UTC (rev 216471)
@@ -1,3 +1,21 @@
+2017-05-08  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        The Incomplete asynchronously decoded image frame should be decoded every time it's drawn
+        https://bugs.webkit.org/show_bug.cgi?id=170836
+
+        Reviewed by Tim Horton.
+
+        The asynchronously decoded image frames has to be cached to prevent flickering,
+        but we have to keep requesting new decoding for the incomplete frame every time
+        it's drawn. This is to avoid drawing an incomplete image frame even after all
+        its encoded data is received.
+
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::draw):
+        * platform/graphics/ImageFrameCache.cpp:
+        (WebCore::ImageFrameCache::cacheAsyncFrameNativeImageAtIndex):
+        (WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex):
+
 2017-05-08  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Guard DragController::cleanupAfterSystemDrag to only clear drag state on Mac

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (216470 => 216471)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-05-09 01:45:20 UTC (rev 216470)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-05-09 01:53:54 UTC (rev 216471)
@@ -183,10 +183,15 @@
     if (decodingMode == DecodingMode::Asynchronous && shouldUseAsyncDecodingForLargeImages()) {
         ASSERT(!canAnimate() && !m_currentFrame);
 
-        if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingOptions(sizeForDrawing))
-            && !frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingOptions(sizeForDrawing))) {
+        bool frameIsCompatible = frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingOptions(sizeForDrawing));
+        bool frameIsBeingDecoded = frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingOptions(sizeForDrawing));
+        bool frameIsComplete = frameIsCompleteAtIndex(m_currentFrame);
+
+        // If the current frame is incomplete, a new request for decoding this frame has to be made even if
+        // it is currently being decoded. New data may have been received since the previous request was made.
+        if ((!frameIsCompatible && !frameIsBeingDecoded) || !frameIsComplete) {
             LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().string().utf8().data());
-            m_source.requestFrameAsyncDecodingAtIndex(0, m_currentSubsamplingLevel, sizeForDrawing);
+            frameIsBeingDecoded = m_source.requestFrameAsyncDecodingAtIndex(0, m_currentSubsamplingLevel, sizeForDrawing);
         }
 
         if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingMode::Asynchronous)) {
@@ -196,6 +201,7 @@
         }
 
         image = frameImageAtIndex(m_currentFrame);
+        ASSERT_IMPLIES(encodedDataStatus() == EncodedDataStatus::Complete, frameIsBeingDecoded || frameIsComplete);
         LOG(Images, "BitmapImage::%s - %p - url: %s [a decoded image frame is available for drawing]", __FUNCTION__, this, sourceURL().string().utf8().data());
     } else {
         StartAnimationStatus status = internalStartAnimation();

Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp (216470 => 216471)


--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp	2017-05-09 01:45:20 UTC (rev 216470)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp	2017-05-09 01:53:54 UTC (rev 216471)
@@ -247,7 +247,7 @@
         return;
 
     ASSERT(index < m_frames.size());
-    ASSERT(!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions));
+    ASSERT(!frameIsCompleteAtIndex(index) || !frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions));
 
     // Clean the old native image and set a new one
     cacheFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, decodingOptions);
@@ -310,17 +310,19 @@
     if (!isDecoderAvailable())
         return false;
 
+    // Allow new requests for the same frame if the frame is incomplete.
     ASSERT(index < m_frames.size());
+    if (frameIsCompleteAtIndex(index)) {
+        // We need to coalesce multiple requests for decoding the same ImageFrame while it
+        // is still being decoded. This may happen if the image rectangle is repainted
+        // multiple times while the ImageFrame has not finished decoding.
+        if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, sizeForDrawing))
+            return true;
 
-    // We need to coalesce multiple requests for decoding the same ImageFrame while it
-    // is still being decoded. This may happen if the image rectangle is repainted
-    // multiple times while the ImageFrame has not finished decoding.
-    if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, sizeForDrawing))
-        return true;
+        if (frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, sizeForDrawing))
+            return false;
+    }
 
-    if (frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, sizeForDrawing))
-        return false;
-
     if (!hasAsyncDecodingQueue())
         startAsyncDecodingQueue();
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to