Title: [219548] trunk/Source/WebCore
Revision
219548
Author
[email protected]
Date
2017-07-16 14:36:54 -0700 (Sun, 16 Jul 2017)

Log Message

Make the decision for asynchronously decoding an image be in one place
https://bugs.webkit.org/show_bug.cgi?id=174479

Patch by Said Abou-Hallawa <[email protected]> on 2017-07-16
Reviewed by Tim Horton.

Move all the logic of whether a large image should be asynchronously decoded
or not be in one place: RenderBoxModelObject::decodingModeForImageDraw().

* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::addPendingImageDrawingClient): Fixing unrelated
spelling error.
* platform/RuntimeApplicationChecks.h:
* platform/cocoa/RuntimeApplicationChecksCocoa.mm:
(WebCore::IOSApplication::isIBooks):
(WebCore::IOSApplication::isIBooksStorytime):
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::updateFromSettings): Remove reading the setting
largeImageAsyncDecodingEnabled from this function because it will be read
by RenderBoxModelObject::decodingModeForImageDraw().
(WebCore::BitmapImage::dataChanged):
(WebCore::BitmapImage::draw):
(WebCore::BitmapImage::shouldAnimate):
(WebCore::BitmapImage::canAnimate):
(WebCore::BitmapImage::canUseAsyncDecodingForLargeImages):
(WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages):
(WebCore::BitmapImage::canDestroyDecodedData):
(WebCore::BitmapImage::shouldUseAsyncDecodingForLargeImages): Deleted.
* platform/graphics/BitmapImage.h:
* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::canUseAsyncDecoding): It is okay to keep the
decoded frame if canUseAsyncDecodingForLargeImages() is true by the setting
largeImageAsyncDecodingEnabled is false.
(WebCore::ImageSource::shouldUseAsyncDecoding): Deleted.
* platform/graphics/ImageSource.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::decodingModeForImageDraw): The plan is to
add a new Internal settings to force asynchronous image decoding regardless
of the image size and the settings.
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
* rendering/RenderBoxModelObject.h:
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintIntoRect):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (219547 => 219548)


--- trunk/Source/WebCore/ChangeLog	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/ChangeLog	2017-07-16 21:36:54 UTC (rev 219548)
@@ -1,3 +1,48 @@
+2017-07-16  Said Abou-Hallawa  <[email protected]>
+
+        Make the decision for asynchronously decoding an image be in one place
+        https://bugs.webkit.org/show_bug.cgi?id=174479
+
+        Reviewed by Tim Horton.
+
+        Move all the logic of whether a large image should be asynchronously decoded 
+        or not be in one place: RenderBoxModelObject::decodingModeForImageDraw().
+
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::addPendingImageDrawingClient): Fixing unrelated 
+        spelling error.
+        * platform/RuntimeApplicationChecks.h:
+        * platform/cocoa/RuntimeApplicationChecksCocoa.mm:
+        (WebCore::IOSApplication::isIBooks):
+        (WebCore::IOSApplication::isIBooksStorytime):
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::updateFromSettings): Remove reading the setting
+        largeImageAsyncDecodingEnabled from this function because it will be read
+        by RenderBoxModelObject::decodingModeForImageDraw().
+        (WebCore::BitmapImage::dataChanged):
+        (WebCore::BitmapImage::draw):
+        (WebCore::BitmapImage::shouldAnimate):
+        (WebCore::BitmapImage::canAnimate):
+        (WebCore::BitmapImage::canUseAsyncDecodingForLargeImages):
+        (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages):
+        (WebCore::BitmapImage::canDestroyDecodedData):
+        (WebCore::BitmapImage::shouldUseAsyncDecodingForLargeImages): Deleted.
+        * platform/graphics/BitmapImage.h:
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::canUseAsyncDecoding): It is okay to keep the 
+        decoded frame if canUseAsyncDecodingForLargeImages() is true by the setting
+        largeImageAsyncDecodingEnabled is false.
+        (WebCore::ImageSource::shouldUseAsyncDecoding): Deleted.
+        * platform/graphics/ImageSource.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::decodingModeForImageDraw): The plan is to
+        add a new Internal settings to force asynchronous image decoding regardless
+        of the image size and the settings.
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::paintIntoRect):
+
 2017-07-16  Michael Catanzaro  <[email protected]>
 
         [CMake] Raise minimum CMake requirement

Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (219547 => 219548)


--- trunk/Source/WebCore/loader/cache/CachedImage.cpp	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp	2017-07-16 21:36:54 UTC (rev 219548)
@@ -145,7 +145,7 @@
     if (m_pendingImageDrawingClients.contains(&client))
         return;
     if (!m_clients.contains(&client)) {
-        // If the <html> element does not have its own background sepecfied, painting the root box
+        // If the <html> element does not have its own background specified, painting the root box
         // renderer uses the style of the <body> element, see RenderView::rendererForRootBackground().
         // In this case, the client we are asked to add is the root box renderer. Since we can't add
         // a client to m_pendingImageDrawingClients unless it is one of the m_clients, we are going

Modified: trunk/Source/WebCore/platform/RuntimeApplicationChecks.h (219547 => 219548)


--- trunk/Source/WebCore/platform/RuntimeApplicationChecks.h	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/platform/RuntimeApplicationChecks.h	2017-07-16 21:36:54 UTC (rev 219548)
@@ -73,6 +73,7 @@
 WEBCORE_EXPORT bool isWebApp();
 WEBCORE_EXPORT bool isWebProcess();
 bool isIBooks();
+bool isIBooksStorytime();
 WEBCORE_EXPORT bool isTheSecretSocietyHiddenMystery();
 
 } // IOSApplication

Modified: trunk/Source/WebCore/platform/cocoa/RuntimeApplicationChecksCocoa.mm (219547 => 219548)


--- trunk/Source/WebCore/platform/cocoa/RuntimeApplicationChecksCocoa.mm	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/platform/cocoa/RuntimeApplicationChecksCocoa.mm	2017-07-16 21:36:54 UTC (rev 219548)
@@ -216,8 +216,13 @@
 bool IOSApplication::isIBooks()
 {
     static bool isIBooks = applicationBundleIsEqualTo("com.apple.iBooks");
+    return isIBooks;
+}
+
+bool IOSApplication::isIBooksStorytime()
+{
     static bool isIBooksStorytime = applicationBundleIsEqualTo("com.apple.TVBooks");
-    return isIBooks || isIBooksStorytime;
+    return isIBooksStorytime;
 }
 
 bool IOSApplication::isTheSecretSocietyHiddenMystery()

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (219547 => 219548)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-07-16 21:36:54 UTC (rev 219548)
@@ -40,10 +40,6 @@
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
-#if PLATFORM(IOS)
-#include "RuntimeApplicationChecks.h"
-#endif
-
 namespace WebCore {
 
 BitmapImage::BitmapImage(ImageObserver* observer)
@@ -69,12 +65,6 @@
 void BitmapImage::updateFromSettings(const Settings& settings)
 {
     m_allowSubsampling = settings.imageSubsamplingEnabled();
-#if PLATFORM(IOS)
-    if (IOSApplication::isIBooks())
-        m_allowLargeImageAsyncDecoding = false;
-    else
-#endif
-        m_allowLargeImageAsyncDecoding = settings.largeImageAsyncDecodingEnabled();
     m_allowAnimatedImageAsyncDecoding = settings.animatedImageAsyncDecodingEnabled();
     m_showDebugBackground = settings.showDebugBorders();
 }
@@ -117,7 +107,7 @@
 
 EncodedDataStatus BitmapImage::dataChanged(bool allDataReceived)
 {
-    if (!shouldUseAsyncDecodingForLargeImages())
+    if (!canUseAsyncDecodingForLargeImages())
         m_source.destroyIncompleteDecodedData();
 
     m_currentFrameDecodingStatus = ImageFrame::DecodingStatus::Invalid;
@@ -193,7 +183,7 @@
     LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel = %d scaleFactorForDrawing = (%.4f, %.4f)]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(m_currentSubsamplingLevel), scaleFactorForDrawing.width(), scaleFactorForDrawing.height());
 
     NativeImagePtr image;
-    if (decodingMode == DecodingMode::Asynchronous && shouldUseAsyncDecodingForLargeImages()) {
+    if (decodingMode == DecodingMode::Asynchronous && !canAnimate()) {
         ASSERT(!canAnimate());
         ASSERT(!m_currentFrame || m_animationFinished);
 
@@ -299,24 +289,24 @@
     m_cachedImage->drawPattern(ctxt, destRect, tileRect, transform, phase, spacing, op, blendMode);
 }
 
-bool BitmapImage::shouldAnimate()
+bool BitmapImage::shouldAnimate() const
 {
     return repetitionCount() && !m_animationFinished && imageObserver();
 }
 
-bool BitmapImage::canAnimate()
+bool BitmapImage::canAnimate() const
 {
     return shouldAnimate() && frameCount() > 1;
 }
 
-bool BitmapImage::shouldUseAsyncDecodingForLargeImages()
+bool BitmapImage::canUseAsyncDecodingForLargeImages() const
 {
-    return !canAnimate() && m_allowLargeImageAsyncDecoding && m_source.shouldUseAsyncDecoding();
+    return !canAnimate() && m_source.canUseAsyncDecoding();
 }
 
-bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages()
+bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages() const
 {
-    return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.shouldUseAsyncDecoding());
+    return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.canUseAsyncDecoding());
 }
 
 void BitmapImage::clearTimer()
@@ -338,7 +328,7 @@
         return false;
 
     // Small image should be decoded synchronously. Deleting its decoded frame is fine.
-    if (!shouldUseAsyncDecodingForLargeImages())
+    if (!canUseAsyncDecodingForLargeImages())
         return true;
 
     return !imageObserver() || imageObserver()->canDestroyDecodedData(*this);

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (219547 => 219548)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-07-16 21:36:54 UTC (rev 219548)
@@ -100,11 +100,12 @@
     size_t currentFrame() const { return m_currentFrame; }
     bool currentFrameKnownToBeOpaque() const override { return !frameHasAlphaAtIndex(currentFrame()); }
     ImageOrientation orientationForCurrentFrame() const override { return frameOrientationAtIndex(currentFrame()); }
+    bool canAnimate() const;
 
     bool shouldUseAsyncDecodingForAnimatedImagesForTesting() const { return m_frameDecodingDurationForTesting > 0_s; }
     void setFrameDecodingDurationForTesting(Seconds duration) { m_frameDecodingDurationForTesting = duration; }
-    bool shouldUseAsyncDecodingForLargeImages();
-    bool shouldUseAsyncDecodingForAnimatedImages();
+    bool canUseAsyncDecodingForLargeImages() const;
+    bool shouldUseAsyncDecodingForAnimatedImages() const;
     void setClearDecoderAfterAsyncFrameRequestForTesting(bool value) { m_clearDecoderAfterAsyncFrameRequestForTesting = value; }
 
     WEBCORE_EXPORT unsigned decodeCountForTesting() const;
@@ -163,8 +164,7 @@
     // Animation.
     enum class StartAnimationStatus { CannotStart, IncompleteData, TimerActive, DecodingActive, Started };
     bool isAnimated() const override { return m_source.frameCount() > 1; }
-    bool shouldAnimate();
-    bool canAnimate();
+    bool shouldAnimate() const;
     void startAnimation() override { internalStartAnimation(); }
     StartAnimationStatus internalStartAnimation();
     void advanceAnimation();
@@ -219,7 +219,6 @@
 #else
     bool m_allowSubsampling { false };
 #endif
-    bool m_allowLargeImageAsyncDecoding { false };
     bool m_allowAnimatedImageAsyncDecoding { false };
     bool m_showDebugBackground { false };
 

Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (219547 => 219548)


--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2017-07-16 21:36:54 UTC (rev 219548)
@@ -149,7 +149,7 @@
     return isDecoderAvailable() ? m_decoder->isAllDataReceived() : m_frameCache->frameCount();
 }
 
-bool ImageSource::shouldUseAsyncDecoding()
+bool ImageSource::canUseAsyncDecoding()
 {
     if (!isDecoderAvailable())
         return false;

Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (219547 => 219548)


--- trunk/Source/WebCore/platform/graphics/ImageSource.h	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h	2017-07-16 21:36:54 UTC (rev 219548)
@@ -70,7 +70,7 @@
     unsigned decodedSize() const { return m_frameCache->decodedSize(); }
     bool isAllDataReceived();
 
-    bool shouldUseAsyncDecoding();
+    bool canUseAsyncDecoding();
     void requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing = { }) { m_frameCache->requestFrameAsyncDecodingAtIndex(index, subsamplingLevel, sizeForDrawing); }
     bool hasAsyncDecodingQueue() const { return m_frameCache->hasAsyncDecodingQueue(); }
     bool isAsyncDecodingQueueIdle() const  { return m_frameCache->isAsyncDecodingQueueIdle(); }

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (219547 => 219548)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2017-07-16 21:36:54 UTC (rev 219548)
@@ -63,6 +63,10 @@
 #include <wtf/SetForScope.h>
 #endif
 
+#if PLATFORM(IOS)
+#include "RuntimeApplicationChecks.h"
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -303,10 +307,29 @@
     return false;
 }
 
-DecodingMode RenderBoxModelObject::decodingModeForImageDraw(const PaintInfo& paintInfo) const
+DecodingMode RenderBoxModelObject::decodingModeForImageDraw(const Image& image, const PaintInfo& paintInfo) const
 {
+    if (!is<BitmapImage>(image))
+        return DecodingMode::Synchronous;
+    
+    const BitmapImage& bitmapImage = downcast<BitmapImage>(image);
+    if (bitmapImage.canAnimate()) {
+        // The DecodingMode for the current frame has to be Synchronous. The DecodingMode
+        // for the next frame will be calculated in BitmapImage::internalStartAnimation().
+        return DecodingMode::Synchronous;
+    }
+
+    // Large image case.
+#if PLATFORM(IOS)
+    if (IOSApplication::isIBooksStorytime())
+        return DecodingMode::Synchronous;
+#endif
     if (document().isImageDocument())
         return DecodingMode::Synchronous;
+    if (!settings().largeImageAsyncDecodingEnabled())
+        return DecodingMode::Synchronous;
+    if (!bitmapImage.canUseAsyncDecodingForLargeImages())
+        return DecodingMode::Synchronous;
     if (paintInfo.paintBehavior & PaintBehaviorAllowAsyncImageDecoding)
         return DecodingMode::Asynchronous;
     return DecodingMode::Synchronous;
@@ -892,7 +915,8 @@
                 downcast<BitmapImage>(*image).updateFromSettings(settings());
 
             auto interpolation = chooseInterpolationQuality(context, *image, &bgLayer, geometry.tileSize());
-            auto drawResult = context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer.blendMode(), decodingModeForImageDraw(paintInfo), ImageOrientationDescription(), interpolation));
+            auto decodingMode = decodingModeForImageDraw(*image, paintInfo);
+            auto drawResult = context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer.blendMode(), decodingMode, ImageOrientationDescription(), interpolation));
             if (drawResult == ImageDrawResult::DidRequestDecoding) {
                 ASSERT(bgImage->isCachedImage());
                 bgImage->cachedImage()->addPendingImageDrawingClient(*this);

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (219547 => 219548)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2017-07-16 21:36:54 UTC (rev 219548)
@@ -267,7 +267,7 @@
 
     bool hasAutoHeightOrContainingBlockWithAutoHeight() const;
 
-    DecodingMode decodingModeForImageDraw(const PaintInfo&) const;
+    DecodingMode decodingModeForImageDraw(const Image&, const PaintInfo&) const;
 
 public:
     // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments

Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (219547 => 219548)


--- trunk/Source/WebCore/rendering/RenderImage.cpp	2017-07-16 14:28:12 UTC (rev 219547)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp	2017-07-16 21:36:54 UTC (rev 219548)
@@ -584,8 +584,8 @@
         downcast<BitmapImage>(*image).updateFromSettings(settings());
 
     ImageOrientationDescription orientationDescription(shouldRespectImageOrientation(), style().imageOrientation());
-
-    auto drawResult = paintInfo.context().drawImage(*img, rect, ImagePaintingOptions(compositeOperator, BlendModeNormal, decodingModeForImageDraw(paintInfo), orientationDescription, interpolation));
+    auto decodingMode = decodingModeForImageDraw(*image, paintInfo);
+    auto drawResult = paintInfo.context().drawImage(*img, rect, ImagePaintingOptions(compositeOperator, BlendModeNormal, decodingMode, orientationDescription, interpolation));
     if (drawResult == ImageDrawResult::DidRequestDecoding)
         imageResource().cachedImage()->addPendingImageDrawingClient(*this);
     return drawResult;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to