Title: [215900] trunk/Source
Revision
215900
Author
[email protected]
Date
2017-04-27 15:57:32 -0700 (Thu, 27 Apr 2017)

Log Message

REGRESSION(r213764): Async decoding of animated images is disabled for ImageDocument
https://bugs.webkit.org/show_bug.cgi?id=170333

Patch by Said Abou-Hallawa <[email protected]> on 2017-04-27
Reviewed by Simon Fraser.

Source/WebCore:

The way the image drawing settings are transfered from the Settings to
BitmapImage is problematic. The drawing settings are retrieved from the
CachedImageObserver which store them in the constructor only if the
CachedImage as a loader. In the case of ImageDocument, there isn't loader
set in CachedImage so the settings of ImageDocument are not set. Also
the CachedImage can be used after loading by another document which may
have a different drawing settings.

The fix is to make BitmapImage reads the drawing settings every time it
is drawn as a foreground or background image in a RenderElement.

* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawImage):
* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::CachedImageObserver::CachedImageObserver):
* loader/cache/CachedImage.h:
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::setDrawingSettings):
(WebCore::BitmapImage::draw):
(WebCore::BitmapImage::shouldUseAsyncDecodingForLargeImages): I was
trying to disable the async image decoding temporarily but this way will
even prevent testing it until it is enabled. Disable it through WK1 and
WK2 preferences.
(WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages):
(WebCore::BitmapImage::advanceAnimation):
* platform/graphics/BitmapImage.h:
* platform/graphics/ImageObserver.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintIntoRect):

Source/WebKit/mac:

Disbale the async decoding for large images for now.

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

Source/WebKit2:

Disbale the async decoding for large images for now.

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

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (215899 => 215900)


--- trunk/Source/WebCore/ChangeLog	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/ChangeLog	2017-04-27 22:57:32 UTC (rev 215900)
@@ -1,3 +1,42 @@
+2017-04-27  Said Abou-Hallawa  <[email protected]>
+
+        REGRESSION(r213764): Async decoding of animated images is disabled for ImageDocument
+        https://bugs.webkit.org/show_bug.cgi?id=170333
+
+        Reviewed by Simon Fraser.
+
+        The way the image drawing settings are transfered from the Settings to
+        BitmapImage is problematic. The drawing settings are retrieved from the
+        CachedImageObserver which store them in the constructor only if the
+        CachedImage as a loader. In the case of ImageDocument, there isn't loader
+        set in CachedImage so the settings of ImageDocument are not set. Also
+        the CachedImage can be used after loading by another document which may
+        have a different drawing settings.
+
+        The fix is to make BitmapImage reads the drawing settings every time it 
+        is drawn as a foreground or background image in a RenderElement.
+
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::drawImage):
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::CachedImageObserver::CachedImageObserver):
+        * loader/cache/CachedImage.h:
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::setDrawingSettings):
+        (WebCore::BitmapImage::draw):
+        (WebCore::BitmapImage::shouldUseAsyncDecodingForLargeImages): I was
+        trying to disable the async image decoding temporarily but this way will
+        even prevent testing it until it is enabled. Disable it through WK1 and
+        WK2 preferences.
+        (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages):
+        (WebCore::BitmapImage::advanceAnimation):
+        * platform/graphics/BitmapImage.h:
+        * platform/graphics/ImageObserver.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::paintIntoRect):
+
 2017-04-27  Wenson Hsieh  <[email protected]>
 
         Performing data interaction with plain text into a contenteditable does not insert any content

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (215899 => 215900)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2017-04-27 22:57:32 UTC (rev 215900)
@@ -1431,6 +1431,9 @@
         image->setContainerSize(imageRect.size());
     }
 
+    if (image->isBitmapImage())
+        downcast<BitmapImage>(*image).updateFromSettings(imageElement.document().settings());
+
     if (rectContainsCanvas(normalizedDstRect)) {
         c->drawImage(*image, normalizedDstRect, normalizedSrcRect, ImagePaintingOptions(op, blendMode));
         didDrawEntireCanvas();

Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (215899 => 215900)


--- trunk/Source/WebCore/loader/cache/CachedImage.cpp	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp	2017-04-27 22:57:32 UTC (rev 215900)
@@ -352,12 +352,6 @@
 {
     m_cachedImages.reserveInitialCapacity(1);
     m_cachedImages.append(&image);
-    if (auto* loader = image.loader()) {
-        m_allowSubsampling = loader->frameLoader()->frame().settings().imageSubsamplingEnabled();
-        m_allowLargeImageAsyncDecoding = loader->frameLoader()->frame().settings().largeImageAsyncDecodingEnabled();
-        m_allowAnimatedImageAsyncDecoding = loader->frameLoader()->frame().settings().animatedImageAsyncDecodingEnabled();
-        m_showDebugBackground = loader->frameLoader()->frame().settings().showDebugBorders();
-    }
 }
 
 void CachedImage::CachedImageObserver::decodedSizeChanged(const Image* image, long long delta)

Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (215899 => 215900)


--- trunk/Source/WebCore/loader/cache/CachedImage.h	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/loader/cache/CachedImage.h	2017-04-27 22:57:32 UTC (rev 215900)
@@ -128,10 +128,6 @@
 
         // ImageObserver API
         URL sourceUrl() const override { return m_cachedImages[0]->url(); }
-        bool allowSubsampling() const final { return m_allowSubsampling; }
-        bool allowLargeImageAsyncDecoding() const override { return m_allowLargeImageAsyncDecoding; }
-        bool allowAnimatedImageAsyncDecoding() const override { return m_allowAnimatedImageAsyncDecoding; }
-        bool showDebugBackground() const final { return m_showDebugBackground; }
         void decodedSizeChanged(const Image*, long long delta) final;
         void didDraw(const Image*) final;
 
@@ -139,15 +135,6 @@
         void changedInRect(const Image*, const IntRect*) final;
 
         Vector<CachedImage*> m_cachedImages;
-        // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp
-#if PLATFORM(IOS)
-        bool m_allowSubsampling { true };
-#else
-        bool m_allowSubsampling { false };
-#endif
-        bool m_allowLargeImageAsyncDecoding { false };
-        bool m_allowAnimatedImageAsyncDecoding { false };
-        bool m_showDebugBackground { false };
     };
 
     void decodedSizeChanged(const Image*, long long delta);

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (215899 => 215900)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-04-27 22:57:32 UTC (rev 215900)
@@ -33,6 +33,7 @@
 #include "ImageObserver.h"
 #include "IntRect.h"
 #include "Logging.h"
+#include "Settings.h"
 #include "TextStream.h"
 #include "Timer.h"
 #include <wtf/CurrentTime.h>
@@ -63,6 +64,14 @@
     stopAnimation();
 }
 
+void BitmapImage::updateFromSettings(const Settings& settings)
+{
+    m_allowSubsampling = settings.imageSubsamplingEnabled();
+    m_allowLargeImageAsyncDecoding = settings.largeImageAsyncDecodingEnabled();
+    m_allowAnimatedImageAsyncDecoding = settings.animatedImageAsyncDecodingEnabled();
+    m_showDebugBackground = settings.showDebugBorders();
+}
+
 void BitmapImage::destroyDecodedData(bool destroyAll)
 {
     LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().string().utf8().data());
@@ -166,7 +175,7 @@
     FloatSize scaleFactorForDrawing = context.scaleFactorForDrawing(destRect, srcRect);
     IntSize sizeForDrawing = expandedIntSize(size() * scaleFactorForDrawing);
     
-    m_currentSubsamplingLevel = allowSubsampling() ? m_source.subsamplingLevelForScaleFactor(context, scaleFactorForDrawing) : SubsamplingLevel::Default;
+    m_currentSubsamplingLevel = m_allowSubsampling ? m_source.subsamplingLevelForScaleFactor(context, scaleFactorForDrawing) : SubsamplingLevel::Default;
     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;
@@ -180,7 +189,7 @@
         }
 
         if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingMode::Asynchronous)) {
-            if (showDebugBackground())
+            if (m_showDebugBackground)
                 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op);
             return;
         }
@@ -191,7 +200,7 @@
         StartAnimationStatus status = internalStartAnimation();
         ASSERT_IMPLIES(status == StartAnimationStatus::DecodingActive, frameHasFullSizeNativeImageAtIndex(m_currentFrame, m_currentSubsamplingLevel));
 
-        if (status == StartAnimationStatus::DecodingActive && showDebugBackground()) {
+        if (status == StartAnimationStatus::DecodingActive && m_showDebugBackground) {
             fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op);
             return;
         }
@@ -198,7 +207,7 @@
 
         if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingMode::Asynchronous)) {
             // FIXME: instead of showing the yellow rectangle and returning we need to wait for this the frame to finish decoding.
-            if (showDebugBackground()) {
+            if (m_showDebugBackground) {
                 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op);
                 LOG(Images, "BitmapImage::%s - %p - url: %s [waiting for async decoding to finish]", __FUNCTION__, this, sourceURL().string().utf8().data());
             }
@@ -273,14 +282,12 @@
 
 bool BitmapImage::shouldUseAsyncDecodingForLargeImages()
 {
-    // FIXME: enable async image decoding after the flickering bug wk170640 is fixed.
-    // return !canAnimate() && allowLargeImageAsyncDecoding() && m_source.shouldUseAsyncDecoding();
-    return false;
+    return !canAnimate() && m_allowLargeImageAsyncDecoding && m_source.shouldUseAsyncDecoding();
 }
 
 bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages()
 {
-    return canAnimate() && allowAnimatedImageAsyncDecoding() && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.shouldUseAsyncDecoding());
+    return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.shouldUseAsyncDecoding());
 }
 
 void BitmapImage::clearTimer()
@@ -390,7 +397,7 @@
         internalAdvanceAnimation();
     else {
         // Force repaint if showDebugBackground() is on.
-        if (showDebugBackground())
+        if (m_showDebugBackground)
             imageObserver()->changedInRect(this);
         LOG(Images, "BitmapImage::%s - %p - url: %s [lateFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), ++m_lateFrameCount, nextFrame);
     }

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (215899 => 215900)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-04-27 22:57:32 UTC (rev 215900)
@@ -49,6 +49,7 @@
 
 namespace WebCore {
 
+class Settings;
 class Timer;
 
 class BitmapImage final : public Image {
@@ -65,7 +66,9 @@
     WEBCORE_EXPORT static RefPtr<BitmapImage> create(HBITMAP);
 #endif
     virtual ~BitmapImage();
-    
+
+    void updateFromSettings(const Settings&);
+
     bool hasSingleSecurityOrigin() const override { return true; }
 
     EncodedDataStatus dataChanged(bool allDataReceived) override;
@@ -137,11 +140,6 @@
     NativeImagePtr frameImageAtIndex(size_t index) { return m_source.frameImageAtIndex(index); }
     NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr);
 
-    bool allowSubsampling() const { return imageObserver() && imageObserver()->allowSubsampling(); }
-    bool allowLargeImageAsyncDecoding() const { return imageObserver() && imageObserver()->allowLargeImageAsyncDecoding(); }
-    bool allowAnimatedImageAsyncDecoding() const { return imageObserver() && imageObserver()->allowAnimatedImageAsyncDecoding(); }
-    bool showDebugBackground() const { return imageObserver() && imageObserver()->showDebugBackground(); }
-
     // Called to invalidate cached data. When |destroyAll| is true, we wipe out
     // the entire frame buffer cache and tell the image source to destroy
     // everything; this is used when e.g. we want to free some room in the image
@@ -205,11 +203,24 @@
     std::unique_ptr<Timer> m_frameTimer;
     RepetitionCount m_repetitionsComplete { RepetitionCountNone }; // How many repetitions we've finished.
     MonotonicTime m_desiredFrameStartTime; // The system time at which we hope to see the next call to startAnimation().
-    bool m_animationFinished { false };
 
     Seconds m_frameDecodingDurationForTesting;
     MonotonicTime m_desiredFrameDecodeTimeForTesting;
+
+    bool m_animationFinished { false };
+
+    // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp
+#if PLATFORM(IOS)
+    bool m_allowSubsampling { true };
+#else
+    bool m_allowSubsampling { false };
+#endif
+    bool m_allowLargeImageAsyncDecoding { false };
+    bool m_allowAnimatedImageAsyncDecoding { false };
+    bool m_showDebugBackground { false };
+
     bool m_clearDecoderAfterAsyncFrameRequestForTesting { false };
+
 #if !LOG_DISABLED
     size_t m_lateFrameCount { 0 };
     size_t m_earlyFrameCount { 0 };

Modified: trunk/Source/WebCore/platform/graphics/ImageObserver.h (215899 => 215900)


--- trunk/Source/WebCore/platform/graphics/ImageObserver.h	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/platform/graphics/ImageObserver.h	2017-04-27 22:57:32 UTC (rev 215900)
@@ -39,16 +39,11 @@
     virtual ~ImageObserver() {}
 public:
     virtual URL sourceUrl() const = 0;
-    virtual bool allowSubsampling() const = 0;
-    virtual bool allowLargeImageAsyncDecoding() const = 0;
-    virtual bool allowAnimatedImageAsyncDecoding() const = 0;
-    virtual bool showDebugBackground() const = 0;
     virtual void decodedSizeChanged(const Image*, long long delta) = 0;
 
     virtual void didDraw(const Image*) = 0;
 
     virtual void animationAdvanced(const Image*) = 0;
-
     virtual void changedInRect(const Image*, const IntRect* changeRect = nullptr) = 0;
 };
 

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (215899 => 215900)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2017-04-27 22:57:32 UTC (rev 215900)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "RenderBoxModelObject.h"
 
+#include "BitmapImage.h"
 #include "BorderEdge.h"
 #include "FloatRoundedRect.h"
 #include "Frame.h"
@@ -877,6 +878,9 @@
             auto compositeOp = op == CompositeSourceOver ? bgLayer.composite() : op;
             context.setDrawLuminanceMask(bgLayer.maskSourceType() == MaskLuminance);
 
+            if (is<BitmapImage>(image.get()))
+                downcast<BitmapImage>(*image).updateFromSettings(settings());
+
             auto interpolation = chooseInterpolationQuality(context, *image, &bgLayer, geometry.tileSize());
             context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer.blendMode(), DecodingMode::Asynchronous, ImageOrientationDescription(), interpolation));
         }

Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (215899 => 215900)


--- trunk/Source/WebCore/rendering/RenderImage.cpp	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp	2017-04-27 22:57:32 UTC (rev 215900)
@@ -580,6 +580,9 @@
         downcast<PDFDocumentImage>(*image).setPdfImageCachingPolicy(settings().pdfImageCachingPolicy());
 #endif
 
+    if (is<BitmapImage>(image))
+        downcast<BitmapImage>(*image).updateFromSettings(settings());
+
     ImageOrientationDescription orientationDescription(shouldRespectImageOrientation(), style().imageOrientation());
     context.drawImage(*img, rect, ImagePaintingOptions(compositeOperator, BlendModeNormal, DecodingMode::Asynchronous, orientationDescription, interpolation));
 }

Modified: trunk/Source/WebKit/mac/ChangeLog (215899 => 215900)


--- trunk/Source/WebKit/mac/ChangeLog	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebKit/mac/ChangeLog	2017-04-27 22:57:32 UTC (rev 215900)
@@ -1,3 +1,15 @@
+2017-04-27  Said Abou-Hallawa  <[email protected]>
+
+        REGRESSION(r213764): Async decoding of animated images is disabled for ImageDocument
+        https://bugs.webkit.org/show_bug.cgi?id=170333
+
+        Reviewed by Simon Fraser.
+
+        Disbale the async decoding for large images for now.
+
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]):
+
 2017-04-27  Alex Christensen  <[email protected]>
 
         Modernize Frame.h

Modified: trunk/Source/WebKit/mac/WebView/WebView.mm (215899 => 215900)


--- trunk/Source/WebKit/mac/WebView/WebView.mm	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebKit/mac/WebView/WebView.mm	2017-04-27 22:57:32 UTC (rev 215900)
@@ -3084,7 +3084,9 @@
 
     settings.setShouldConvertInvalidURLsToBlank(shouldConvertInvalidURLsToBlank());
 
-    settings.setLargeImageAsyncDecodingEnabled([preferences largeImageAsyncDecodingEnabled]);
+    // FIXME: enable async image decoding after the flickering bug wk170640 is fixed.
+    // settings.setLargeImageAsyncDecodingEnabled([preferences largeImageAsyncDecodingEnabled]);
+    settings.setLargeImageAsyncDecodingEnabled(false);
     settings.setAnimatedImageAsyncDecodingEnabled([preferences animatedImageAsyncDecodingEnabled]);
 }
 

Modified: trunk/Source/WebKit2/ChangeLog (215899 => 215900)


--- trunk/Source/WebKit2/ChangeLog	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebKit2/ChangeLog	2017-04-27 22:57:32 UTC (rev 215900)
@@ -1,3 +1,15 @@
+2017-04-27  Said Abou-Hallawa  <[email protected]>
+
+        REGRESSION(r213764): Async decoding of animated images is disabled for ImageDocument
+        https://bugs.webkit.org/show_bug.cgi?id=170333
+
+        Reviewed by Simon Fraser.
+
+        Disbale the async decoding for large images for now.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+
 2017-04-27  Brent Fulgham  <[email protected]>
 
         [WK2][macOS] Allow multi-touch related iokit-get-properties

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (215899 => 215900)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2017-04-27 22:45:53 UTC (rev 215899)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2017-04-27 22:57:32 UTC (rev 215900)
@@ -3364,7 +3364,9 @@
     m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints);
     setForceAlwaysUserScalable(m_forceAlwaysUserScalable || store.getBoolValueForKey(WebPreferencesKey::forceAlwaysUserScalableKey()));
 #endif
-    settings.setLargeImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::largeImageAsyncDecodingEnabledKey()));
+    // FIXME: enable async image decoding after the flickering bug wk170640 is fixed.
+    // settings.setLargeImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::largeImageAsyncDecodingEnabledKey()));
+    settings.setLargeImageAsyncDecodingEnabled(false);
     settings.setAnimatedImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::animatedImageAsyncDecodingEnabledKey()));
     settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(store.getBoolValueForKey(WebPreferencesKey::shouldSuppressKeyboardInputDuringProvisionalNavigationKey()));
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to