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;