Title: [225300] trunk/Source
Revision
225300
Author
commit-qu...@webkit.org
Date
2017-11-29 15:23:54 -0800 (Wed, 29 Nov 2017)

Log Message

Remove the ImageSource from the class hierarchy that connects BitmapImage to ImageFrame
https://bugs.webkit.org/show_bug.cgi?id=175595

Patch by Said Abou-Hallawa <sabouhall...@apple.com> on 2017-11-29
Reviewed by Darin Adler.

Source/WebCore:

The class hierarchy that connects BitmapImage to ImageFrame has been
troublesome. ImageSource does not have a clear responsibility other than
a bridge that connects BitmapIamge to ImageFrameCache. Sharing the
ImageDecoder between ImageSource and ImageFrameCache is ugly and caused
few crashes in the past.

This patch will do the first step for fixing this issue. First get rid of
ImageSource by moving its APIs to ImageFrameCache and BitmapImage. Replace
all the instances of ImageSource by ImageFrameCache. The next step will
be to rename ImageFrameCache to ImageSource. But this will be done in a
follow-up patch

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::BitmapImage):
(WebCore::BitmapImage::~BitmapImage):
(WebCore::BitmapImage::destroyDecodedData):
(WebCore::BitmapImage::destroyDecodedDataIfNecessary):
(WebCore::BitmapImage::dataChanged):
(WebCore::BitmapImage::frameImageAtIndexCacheIfNeeded):
(WebCore::BitmapImage::draw):
(WebCore::BitmapImage::canUseAsyncDecodingForLargeImages const):
(WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages const):
(WebCore::BitmapImage::subsamplingLevelForScaleFactor):
(WebCore::BitmapImage::canDestroyDecodedData):
(WebCore::BitmapImage::internalStartAnimation):
(WebCore::BitmapImage::stopAnimation):
(WebCore::BitmapImage::decode):
(WebCore::BitmapImage::imageFrameAvailableAtIndex):
(WebCore::BitmapImage::dump const):
* platform/graphics/BitmapImage.h:
* platform/graphics/GraphicsContext3D.h:
* platform/graphics/ImageFrameCache.cpp:
(WebCore::ImageFrameCache::ImageFrameCache):
(WebCore::ImageFrameCache::ensureDecoderAvailable):
(WebCore::ImageFrameCache::setData):
(WebCore::ImageFrameCache::resetData):
(WebCore::ImageFrameCache::dataChanged):
(WebCore::ImageFrameCache::isAllDataReceived):
(WebCore::ImageFrameCache::clearFrameBufferCache):
(WebCore::ImageFrameCache::canUseAsyncDecoding):
(WebCore::ImageFrameCache::maximumSubsamplingLevel):
(WebCore::ImageFrameCache::setTargetContext):
(WebCore::ImageFrameCache::createFrameImageAtIndex):
(WebCore::ImageFrameCache::dump):
(WebCore::ImageFrameCache::setDecoder): Deleted.
(WebCore::ImageFrameCache::decoder const): Deleted.
* platform/graphics/ImageFrameCache.h:
(WebCore::ImageFrameCache::create):
(WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex):
* platform/graphics/ImageSource.cpp: Removed.
* platform/graphics/ImageSource.h: Removed.
* platform/graphics/cairo/GraphicsContext3DCairo.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::~ImageExtractor):
(WebCore::GraphicsContext3D::ImageExtractor::extractImage):
* platform/graphics/cg/GraphicsContext3DCG.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::extractImage):
* platform/graphics/cg/ImageSourceCG.h:

Source/WebKitLegacy/mac:

* WebView/WebPreferences.mm:

Modified Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225299 => 225300)


--- trunk/Source/WebCore/ChangeLog	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/ChangeLog	2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,3 +1,70 @@
+2017-11-29  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        Remove the ImageSource from the class hierarchy that connects BitmapImage to ImageFrame
+        https://bugs.webkit.org/show_bug.cgi?id=175595
+
+        Reviewed by Darin Adler.
+
+        The class hierarchy that connects BitmapImage to ImageFrame has been
+        troublesome. ImageSource does not have a clear responsibility other than
+        a bridge that connects BitmapIamge to ImageFrameCache. Sharing the 
+        ImageDecoder between ImageSource and ImageFrameCache is ugly and caused
+        few crashes in the past.
+
+        This patch will do the first step for fixing this issue. First get rid of
+        ImageSource by moving its APIs to ImageFrameCache and BitmapImage. Replace
+        all the instances of ImageSource by ImageFrameCache. The next step will
+        be to rename ImageFrameCache to ImageSource. But this will be done in a
+        follow-up patch
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::BitmapImage):
+        (WebCore::BitmapImage::~BitmapImage):
+        (WebCore::BitmapImage::destroyDecodedData):
+        (WebCore::BitmapImage::destroyDecodedDataIfNecessary):
+        (WebCore::BitmapImage::dataChanged):
+        (WebCore::BitmapImage::frameImageAtIndexCacheIfNeeded):
+        (WebCore::BitmapImage::draw):
+        (WebCore::BitmapImage::canUseAsyncDecodingForLargeImages const):
+        (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages const):
+        (WebCore::BitmapImage::subsamplingLevelForScaleFactor):
+        (WebCore::BitmapImage::canDestroyDecodedData):
+        (WebCore::BitmapImage::internalStartAnimation):
+        (WebCore::BitmapImage::stopAnimation):
+        (WebCore::BitmapImage::decode):
+        (WebCore::BitmapImage::imageFrameAvailableAtIndex):
+        (WebCore::BitmapImage::dump const):
+        * platform/graphics/BitmapImage.h:
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/ImageFrameCache.cpp:
+        (WebCore::ImageFrameCache::ImageFrameCache):
+        (WebCore::ImageFrameCache::ensureDecoderAvailable):
+        (WebCore::ImageFrameCache::setData):
+        (WebCore::ImageFrameCache::resetData):
+        (WebCore::ImageFrameCache::dataChanged):
+        (WebCore::ImageFrameCache::isAllDataReceived):
+        (WebCore::ImageFrameCache::clearFrameBufferCache):
+        (WebCore::ImageFrameCache::canUseAsyncDecoding):
+        (WebCore::ImageFrameCache::maximumSubsamplingLevel):
+        (WebCore::ImageFrameCache::setTargetContext):
+        (WebCore::ImageFrameCache::createFrameImageAtIndex):
+        (WebCore::ImageFrameCache::dump):
+        (WebCore::ImageFrameCache::setDecoder): Deleted.
+        (WebCore::ImageFrameCache::decoder const): Deleted.
+        * platform/graphics/ImageFrameCache.h:
+        (WebCore::ImageFrameCache::create):
+        (WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex):
+        * platform/graphics/ImageSource.cpp: Removed.
+        * platform/graphics/ImageSource.h: Removed.
+        * platform/graphics/cairo/GraphicsContext3DCairo.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::~ImageExtractor):
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+        * platform/graphics/cg/GraphicsContext3DCG.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+        * platform/graphics/cg/ImageSourceCG.h:
+
 2017-11-29  Brady Eidson  <beid...@apple.com>
 
         When managing context startups, make ServiceWorkerJobDataIdentifier's optional.

Modified: trunk/Source/WebCore/Sources.txt (225299 => 225300)


--- trunk/Source/WebCore/Sources.txt	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/Sources.txt	2017-11-29 23:23:54 UTC (rev 225300)
@@ -1526,7 +1526,6 @@
 platform/graphics/ImageFrame.cpp
 platform/graphics/ImageFrameCache.cpp
 platform/graphics/ImageOrientation.cpp
-platform/graphics/ImageSource.cpp
 platform/graphics/IntPoint.cpp
 platform/graphics/IntRect.cpp
 platform/graphics/IntSize.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (225299 => 225300)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-11-29 23:23:54 UTC (rev 225300)
@@ -3279,7 +3279,6 @@
 		B275356D0B053814002CE64F /* FloatSize.h in Headers */ = {isa = PBXBuildFile; fileRef = B275353F0B053814002CE64F /* FloatSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B275356E0B053814002CE64F /* Icon.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535400B053814002CE64F /* Icon.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B27535700B053814002CE64F /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535420B053814002CE64F /* Image.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		B27535710B053814002CE64F /* ImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535430B053814002CE64F /* ImageSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B27535720B053814002CE64F /* IntPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535440B053814002CE64F /* IntPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B27535740B053814002CE64F /* IntRect.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535460B053814002CE64F /* IntRect.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B27535750B053814002CE64F /* IntSize.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535470B053814002CE64F /* IntSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5367,7 +5366,6 @@
 		0F17747F1378B772009DA76A /* ScrollAnimatorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollAnimatorIOS.mm; sourceTree = "<group>"; };
 		0F36E7361BD1837A002DB891 /* LayoutPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutPoint.cpp; sourceTree = "<group>"; };
 		0F36E7381BD184B9002DB891 /* LayoutSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutSize.cpp; sourceTree = "<group>"; };
-		0F3C725D1974874B00AEDD0C /* ImageSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageSource.cpp; sourceTree = "<group>"; };
 		0F3DD44D12F5EA1B000D9190 /* ShadowBlur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowBlur.cpp; sourceTree = "<group>"; };
 		0F3DD44E12F5EA1B000D9190 /* ShadowBlur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowBlur.h; sourceTree = "<group>"; };
 		0F3F0E57157030C3006DA57F /* RenderGeometryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderGeometryMap.cpp; sourceTree = "<group>"; };
@@ -11743,7 +11741,6 @@
 		B27535400B053814002CE64F /* Icon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Icon.h; sourceTree = "<group>"; };
 		B27535410B053814002CE64F /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
 		B27535420B053814002CE64F /* Image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
-		B27535430B053814002CE64F /* ImageSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageSource.h; sourceTree = "<group>"; };
 		B27535440B053814002CE64F /* IntPoint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntPoint.h; sourceTree = "<group>"; };
 		B27535450B053814002CE64F /* IntRect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IntRect.cpp; sourceTree = "<group>"; };
 		B27535460B053814002CE64F /* IntRect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntRect.h; sourceTree = "<group>"; };
@@ -22717,8 +22714,6 @@
 				A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
 				A8748D6612CC3763001FBA41 /* ImageOrientation.h */,
 				49291E4A134172C800E753DE /* ImageRenderingMode.h */,
-				0F3C725D1974874B00AEDD0C /* ImageSource.cpp */,
-				B27535430B053814002CE64F /* ImageSource.h */,
 				5550CB411E955E3C00111AA0 /* ImageTypes.h */,
 				07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */,
 				07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */,

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-11-29 23:23:54 UTC (rev 225300)
@@ -39,18 +39,21 @@
 #include <wtf/Vector.h>
 #include <wtf/text/TextStream.h>
 #include <wtf/text/WTFString.h>
+#if USE(CG) && PLATFORM(WIN)
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#endif
 
 namespace WebCore {
 
 BitmapImage::BitmapImage(ImageObserver* observer)
     : Image(observer)
-    , m_source(this)
+    , m_source(ImageFrameCache::create(this))
 {
 }
 
 BitmapImage::BitmapImage(NativeImagePtr&& image, ImageObserver* observer)
     : Image(observer)
-    , m_source(WTFMove(image))
+    , m_source(ImageFrameCache::create(WTFMove(image)))
 {
 }
 
@@ -58,8 +61,8 @@
 {
     invalidatePlatformData();
     clearTimer();
-    m_source.clearImage();
-    m_source.stopAsyncDecodingQueue();
+    m_source->clearImage();
+    m_source->stopAsyncDecodingQueue();
 }
 
 void BitmapImage::updateFromSettings(const Settings& settings)
@@ -74,20 +77,20 @@
     LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().string().utf8().data());
 
     if (!destroyAll)
-        m_source.destroyDecodedDataBeforeFrame(m_currentFrame);
+        m_source->destroyDecodedDataBeforeFrame(m_currentFrame);
     else if (!canDestroyDecodedData())
-        m_source.destroyAllDecodedDataExcludeFrame(m_currentFrame);
+        m_source->destroyAllDecodedDataExcludeFrame(m_currentFrame);
     else {
-        m_source.destroyAllDecodedData();
+        m_source->destroyAllDecodedData();
         m_currentFrameDecodingStatus = DecodingStatus::Invalid;
     }
 
     // There's no need to throw away the decoder unless we're explicitly asked
     // to destroy all of the frames.
-    if (!destroyAll || m_source.hasAsyncDecodingQueue())
-        m_source.clearFrameBufferCache(m_currentFrame);
+    if (!destroyAll || m_source->hasAsyncDecodingQueue())
+        m_source->clearFrameBufferCache(m_currentFrame);
     else
-        m_source.resetData(data());
+        m_source->resetData(data());
 
     invalidatePlatformData();
 }
@@ -99,7 +102,7 @@
     if (!data() && frameCount())
         return;
 
-    if (m_source.decodedSize() < LargeAnimationCutoff)
+    if (m_source->decodedSize() < LargeAnimationCutoff)
         return;
 
     destroyDecodedData(destroyAll);
@@ -107,11 +110,11 @@
 
 EncodedDataStatus BitmapImage::dataChanged(bool allDataReceived)
 {
-    if (m_source.decodedSize() && !canUseAsyncDecodingForLargeImages())
-        m_source.destroyIncompleteDecodedData();
+    if (m_source->decodedSize() && !canUseAsyncDecodingForLargeImages())
+        m_source->destroyIncompleteDecodedData();
 
     m_currentFrameDecodingStatus = DecodingStatus::Invalid;
-    return m_source.dataChanged(data(), allDataReceived);
+    return m_source->dataChanged(data(), allDataReceived);
 }
     
 void BitmapImage::setCurrentFrameDecodingStatusIfNecessary(DecodingStatus decodingStatus)
@@ -130,8 +133,12 @@
         LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel was %d, resampling]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(frameSubsamplingLevelAtIndex(index)));
         invalidatePlatformData();
     }
-
-    return m_source.frameImageAtIndexCacheIfNeeded(index, subsamplingLevel, targetContext);
+#if USE(DIRECT2D)
+    m_source->setTargetContext(targetContext);
+#else
+    UNUSED_PARAM(targetContext);
+#endif
+    return m_source->frameImageAtIndexCacheIfNeeded(index, subsamplingLevel);
 }
 
 NativeImagePtr BitmapImage::nativeImage(const GraphicsContext* targetContext)
@@ -189,7 +196,7 @@
     IntSize sizeForDrawing = expandedIntSize(size() * scaleFactorForDrawing);
     ImageDrawResult result = ImageDrawResult::DidDraw;
 
-    m_currentSubsamplingLevel = m_allowSubsampling ? m_source.subsamplingLevelForScaleFactor(context, scaleFactorForDrawing) : SubsamplingLevel::Default;
+    m_currentSubsamplingLevel = m_allowSubsampling ? 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;
@@ -204,7 +211,7 @@
         // it is currently being decoded. New data may have been received since the previous request was made.
         if ((!frameIsCompatible && !frameIsBeingDecoded) || m_currentFrameDecodingStatus == DecodingStatus::Invalid) {
             LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().string().utf8().data());
-            m_source.requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, sizeForDrawing);
+            m_source->requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, sizeForDrawing);
             m_currentFrameDecodingStatus = DecodingStatus::Decoding;
         }
 
@@ -231,7 +238,7 @@
         // If the decodingMode changes from asynchronous to synchronous and new data is received,
         // the current incomplete decoded frame has to be destroyed.
         if (m_currentFrameDecodingStatus == DecodingStatus::Invalid)
-            m_source.destroyIncompleteDecodedData();
+            m_source->destroyIncompleteDecodedData();
         
         bool frameIsCompatible = frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingOptions(sizeForDrawing));
         bool frameIsBeingDecoded = frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingMode::Asynchronous);
@@ -324,12 +331,12 @@
 
 bool BitmapImage::canUseAsyncDecodingForLargeImages() const
 {
-    return !canAnimate() && m_source.canUseAsyncDecoding();
+    return !canAnimate() && m_source->canUseAsyncDecoding();
 }
 
 bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages() const
 {
-    return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.canUseAsyncDecoding());
+    return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source->canUseAsyncDecoding());
 }
 
 void BitmapImage::clearTimer()
@@ -344,10 +351,30 @@
     m_frameTimer->startOneShot(delay);
 }
 
+SubsamplingLevel BitmapImage::subsamplingLevelForScaleFactor(GraphicsContext& context, const FloatSize& scaleFactor)
+{
+#if USE(CG)
+    // Never use subsampled images for drawing into PDF contexts.
+    if (CGContextGetType(context.platformContext()) == kCGContextTypePDF)
+        return SubsamplingLevel::Default;
+
+    float scale = std::min(float(1), std::max(scaleFactor.width(), scaleFactor.height()));
+    if (!(scale > 0 && scale <= 1))
+        return SubsamplingLevel::Default;
+
+    int result = std::ceil(std::log2(1 / scale));
+    return static_cast<SubsamplingLevel>(std::min(result, static_cast<int>(m_source->maximumSubsamplingLevel())));
+#else
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(scaleFactor);
+    return SubsamplingLevel::Default;
+#endif
+}
+
 bool BitmapImage::canDestroyDecodedData()
 {
     // Animated images should preserve the current frame till the next one finishes decoding.
-    if (m_source.hasAsyncDecodingQueue())
+    if (m_source->hasAsyncDecodingQueue())
         return false;
 
     // Small image should be decoded synchronously. Deleting its decoded frame is fine.
@@ -377,7 +404,7 @@
         // yet and our repetition count is potentially unset. The repetition count
         // in a GIF can potentially come after all the rest of the image data, so
         // wait on it.
-        if (!m_source.isAllDataReceived() && repetitionCount() == RepetitionCountOnce)
+        if (!m_source->isAllDataReceived() && repetitionCount() == RepetitionCountOnce)
             return StartAnimationStatus::IncompleteData;
 
         ++m_repetitionsComplete;
@@ -393,7 +420,7 @@
     }
 
     // Don't advance the animation to an incomplete frame.
-    if (!m_source.isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame))
+    if (!m_source->isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame))
         return StartAnimationStatus::IncompleteData;
 
     MonotonicTime time = MonotonicTime::now();
@@ -413,7 +440,7 @@
         if (frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(nextFrame, m_currentSubsamplingLevel, { }))
             LOG(Images, "BitmapImage::%s - %p - url: %s [cachedFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), ++m_cachedFrameCount, nextFrame);
         else {
-            m_source.requestFrameAsyncDecodingAtIndex(nextFrame, m_currentSubsamplingLevel);
+            m_source->requestFrameAsyncDecodingAtIndex(nextFrame, m_currentSubsamplingLevel);
             m_currentFrameDecodingStatus = DecodingStatus::Decoding;
             LOG(Images, "BitmapImage::%s - %p - url: %s [requesting async decoding for nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), nextFrame);
         }
@@ -420,7 +447,7 @@
 
         m_desiredFrameDecodeTimeForTesting = time + std::max(m_frameDecodingDurationForTesting, 0_s);
         if (m_clearDecoderAfterAsyncFrameRequestForTesting)
-            m_source.resetData(data());
+            m_source->resetData(data());
     }
 
     ASSERT(!m_frameTimer);
@@ -484,7 +511,7 @@
     // the timer unless all renderers have stopped drawing.
     clearTimer();
     if (canAnimate())
-        m_source.stopAsyncDecodingQueue();
+        m_source->stopAsyncDecodingQueue();
 }
 
 void BitmapImage::resetAnimation()
@@ -519,7 +546,7 @@
         if (frameIsCompatible)
             internalStartAnimation();
         else if (!frameIsBeingDecoded) {
-            m_source.requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
+            m_source->requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
             m_currentFrameDecodingStatus = DecodingStatus::Decoding;
         }
         return;
@@ -531,7 +558,7 @@
     if (frameIsCompatible)
         callDecodingCallbacks();
     else if (!frameIsBeingDecoded) {
-        m_source.requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
+        m_source->requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
         m_currentFrameDecodingStatus = DecodingStatus::Decoding;
     }
 }
@@ -567,8 +594,8 @@
     }
 
     ASSERT(index == m_currentFrame && !m_currentFrame);
-    if (m_source.isAsyncDecodingQueueIdle())
-        m_source.stopAsyncDecodingQueue();
+    if (m_source->isAsyncDecodingQueueIdle())
+        m_source->stopAsyncDecodingQueue();
 
     DecodingStatus decodingStatus = frameDecodingStatusAtIndex(m_currentFrame);
     setCurrentFrameDecodingStatusIfNecessary(decodingStatus);
@@ -596,7 +623,7 @@
     if (isAnimated())
         ts.dumpProperty("current-frame", m_currentFrame);
     
-    m_source.dump(ts);
+    m_source->dump(ts);
 }
 
 }

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-11-29 23:23:54 UTC (rev 225300)
@@ -29,9 +29,9 @@
 
 #include "Image.h"
 #include "Color.h"
+#include "ImageFrameCache.h"
 #include "ImageObserver.h"
 #include "ImageOrientation.h"
-#include "ImageSource.h"
 #include "IntSize.h"
 
 #if USE(CG) || USE(APPKIT)
@@ -71,31 +71,31 @@
     bool hasSingleSecurityOrigin() const override { return true; }
 
     EncodedDataStatus dataChanged(bool allDataReceived) override;
-    unsigned decodedSize() const { return m_source.decodedSize(); }
+    unsigned decodedSize() const { return m_source->decodedSize(); }
 
-    EncodedDataStatus encodedDataStatus() const { return m_source.encodedDataStatus(); }
-    size_t frameCount() const { return m_source.frameCount(); }
-    RepetitionCount repetitionCount() const { return m_source.repetitionCount(); }
-    String uti() const override { return m_source.uti(); }
-    String filenameExtension() const override { return m_source.filenameExtension(); }
-    std::optional<IntPoint> hotSpot() const override { return m_source.hotSpot(); }
+    EncodedDataStatus encodedDataStatus() const { return m_source->encodedDataStatus(); }
+    size_t frameCount() const { return m_source->frameCount(); }
+    RepetitionCount repetitionCount() const { return m_source->repetitionCount(); }
+    String uti() const override { return m_source->uti(); }
+    String filenameExtension() const override { return m_source->filenameExtension(); }
+    std::optional<IntPoint> hotSpot() const override { return m_source->hotSpot(); }
 
     // FloatSize due to override.
-    FloatSize size() const override { return m_source.size(); }
-    IntSize sizeRespectingOrientation() const { return m_source.sizeRespectingOrientation(); }
-    Color singlePixelSolidColor() const override { return m_source.singlePixelSolidColor(); }
-    bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) const { return m_source.frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); }
-    DecodingStatus frameDecodingStatusAtIndex(size_t index) const { return m_source.frameDecodingStatusAtIndex(index); }
+    FloatSize size() const override { return m_source->size(); }
+    IntSize sizeRespectingOrientation() const { return m_source->sizeRespectingOrientation(); }
+    Color singlePixelSolidColor() const override { return m_source->singlePixelSolidColor(); }
+    bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) const { return m_source->frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); }
+    DecodingStatus frameDecodingStatusAtIndex(size_t index) const { return m_source->frameDecodingStatusAtIndex(index); }
     bool frameIsCompleteAtIndex(size_t index) const { return frameDecodingStatusAtIndex(index) == DecodingStatus::Complete; }
-    bool frameHasAlphaAtIndex(size_t index) const { return m_source.frameHasAlphaAtIndex(index); }
+    bool frameHasAlphaAtIndex(size_t index) const { return m_source->frameHasAlphaAtIndex(index); }
 
-    bool frameHasFullSizeNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) { return m_source.frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); }
-    bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_source.frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); }
+    bool frameHasFullSizeNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) { return m_source->frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); }
+    bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_source->frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); }
 
-    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) const { return m_source.frameSubsamplingLevelAtIndex(index); }
+    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) const { return m_source->frameSubsamplingLevelAtIndex(index); }
 
-    Seconds frameDurationAtIndex(size_t index) const { return m_source.frameDurationAtIndex(index); }
-    ImageOrientation frameOrientationAtIndex(size_t index) const { return m_source.frameOrientationAtIndex(index); }
+    Seconds frameDurationAtIndex(size_t index) const { return m_source->frameDurationAtIndex(index); }
+    ImageOrientation frameOrientationAtIndex(size_t index) const { return m_source->frameOrientationAtIndex(index); }
 
     size_t currentFrame() const { return m_currentFrame; }
     bool currentFrameKnownToBeOpaque() const override { return !frameHasAlphaAtIndex(currentFrame()); }
@@ -142,7 +142,7 @@
     WEBCORE_EXPORT BitmapImage(NativeImagePtr&&, ImageObserver* = nullptr);
     WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr);
 
-    NativeImagePtr frameImageAtIndex(size_t index) { return m_source.frameImageAtIndex(index); }
+    NativeImagePtr frameImageAtIndex(size_t index) { return m_source->frameImageAtIndex(index); }
     NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr);
 
     // Called to invalidate cached data. When |destroyAll| is true, we wipe out
@@ -165,7 +165,7 @@
 
     // Animation.
     enum class StartAnimationStatus { CannotStart, IncompleteData, TimerActive, DecodingActive, Started };
-    bool isAnimated() const override { return m_source.frameCount() > 1; }
+    bool isAnimated() const override { return m_source->frameCount() > 1; }
     bool shouldAnimate() const;
     void startAnimation() override { internalStartAnimation(); }
     StartAnimationStatus internalStartAnimation();
@@ -193,6 +193,7 @@
 private:
     void clearTimer();
     void startTimer(Seconds delay);
+    SubsamplingLevel subsamplingLevelForScaleFactor(GraphicsContext&, const FloatSize& scaleFactor);
     bool canDestroyDecodedData();
     void setCurrentFrameDecodingStatusIfNecessary(DecodingStatus);
     bool isBitmapImage() const override { return true; }
@@ -204,7 +205,7 @@
     // Animated images over a certain size are considered large enough that we'll only hang on to one frame at a time.
     static const unsigned LargeAnimationCutoff = 30 * 1024 * 1024;
 
-    mutable ImageSource m_source;
+    mutable Ref<ImageFrameCache> m_source;
 
     size_t m_currentFrame { 0 }; // The index of the current frame of animation.
     SubsamplingLevel m_currentSubsamplingLevel { SubsamplingLevel::Default };

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-11-29 23:23:54 UTC (rev 225300)
@@ -94,7 +94,6 @@
 class HostWindow;
 class Image;
 class ImageBuffer;
-class ImageSource;
 class ImageData;
 class IntRect;
 class IntSize;
@@ -1262,7 +1261,6 @@
         bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
 
 #if USE(CAIRO)
-        ImageSource* m_decoder;
         RefPtr<cairo_surface_t> m_imageSurface;
 #elif USE(CG)
         RetainPtr<CGImageRef> m_cgImage;

Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp	2017-11-29 23:23:54 UTC (rev 225300)
@@ -47,8 +47,10 @@
 
 namespace WebCore {
 
-ImageFrameCache::ImageFrameCache(Image* image)
+ImageFrameCache::ImageFrameCache(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
     : m_image(image)
+    , m_alphaOption(alphaOption)
+    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
 {
 }
 
@@ -73,23 +75,54 @@
     ASSERT(!hasAsyncDecodingQueue());
 }
 
-void ImageFrameCache::setDecoder(ImageDecoder* decoder)
+bool ImageFrameCache::ensureDecoderAvailable(SharedBuffer* data)
 {
-    if (m_decoder == decoder)
-        return;
+    if (!data || isDecoderAvailable())
+        return true;
 
+    m_decoder = ImageDecoder::create(*data, mimeType(), m_alphaOption, m_gammaAndColorProfileOption);
+    if (!isDecoderAvailable())
+        return false;
+    
+    if (auto expectedContentSize = expectedContentLength())
+        m_decoder->setExpectedContentSize(expectedContentSize);
+
     // Changing the decoder has to stop the decoding thread. The current frame will
     // continue decoding safely because the decoding thread has its own
     // reference of the old decoder.
     stopAsyncDecodingQueue();
-    m_decoder = decoder;
+    return true;
 }
 
-ImageDecoder* ImageFrameCache::decoder() const
+void ImageFrameCache::setData(SharedBuffer* data, bool allDataReceived)
 {
-    return m_decoder.get();
+    if (!data || !ensureDecoderAvailable(data))
+        return;
+
+    m_decoder->setData(*data, allDataReceived);
 }
 
+void ImageFrameCache::resetData(SharedBuffer* data)
+{
+    m_decoder = nullptr;
+    setData(data, isAllDataReceived());
+}
+
+EncodedDataStatus ImageFrameCache::dataChanged(SharedBuffer* data, bool allDataReceived)
+{
+    setData(data, allDataReceived);
+    clearMetadata();
+    EncodedDataStatus status = encodedDataStatus();
+    if (status >= EncodedDataStatus::SizeAvailable)
+        growFrames();
+    return status;
+}
+
+bool ImageFrameCache::isAllDataReceived()
+{
+    return isDecoderAvailable() ? m_decoder->isAllDataReceived() : frameCount();
+}
+
 void ImageFrameCache::destroyDecodedData(size_t frameCount, size_t excludeFrame)
 {
     unsigned decodedSize = 0;
@@ -119,6 +152,13 @@
     decodedSizeDecreased(decodedSize);
 }
 
+void ImageFrameCache::clearFrameBufferCache(size_t beforeFrame)
+{
+    if (!isDecoderAvailable())
+        return;
+    m_decoder->clearFrameBufferCache(beforeFrame);
+}
+
 void ImageFrameCache::decodedSizeChanged(long long decodedSize)
 {
     if (!decodedSize || !m_image || !m_image->imageObserver())
@@ -278,6 +318,14 @@
     return *m_frameRequestQueue;
 }
 
+bool ImageFrameCache::canUseAsyncDecoding()
+{
+    if (!isDecoderAvailable())
+        return false;
+    // FIXME: figure out the best heuristic for enabling async image decoding.
+    return size().area() * sizeof(RGBA32) >= (frameCount() > 1 ? 100 * KB : 500 * KB);
+}
+
 void ImageFrameCache::startAsyncDecodingQueue()
 {
     if (hasAsyncDecodingQueue() || !isDecoderAvailable())
@@ -510,6 +558,29 @@
     return frameMetadataAtIndexCacheIfNeeded<Color>(0, (&ImageFrame::singlePixelSolidColor), &m_singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage);
 }
 
+SubsamplingLevel ImageFrameCache::maximumSubsamplingLevel()
+{
+    if (m_maximumSubsamplingLevel)
+        return m_maximumSubsamplingLevel.value();
+
+    if (!isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0))
+        return SubsamplingLevel::Default;
+
+    // FIXME: this value was chosen to be appropriate for iOS since the image
+    // subsampling is only enabled by default on iOS. Choose a different value
+    // if image subsampling is enabled on other platform.
+    const int maximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
+    SubsamplingLevel level = SubsamplingLevel::First;
+
+    for (; level < SubsamplingLevel::Last; ++level) {
+        if (frameSizeAtIndex(0, level).area().unsafeGet() < maximumImageAreaBeforeSubsampling)
+            break;
+    }
+
+    m_maximumSubsamplingLevel = level;
+    return m_maximumSubsamplingLevel.value();
+}
+
 bool ImageFrameCache::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions)
 {
     auto it = std::find_if(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [index, &decodingOptions](const ImageFrameRequest& frameRequest) {
@@ -563,6 +634,19 @@
     return frameMetadataAtIndexCacheIfNeeded<ImageOrientation>(index, (&ImageFrame::orientation), nullptr, ImageFrame::Caching::Metadata);
 }
 
+#if USE(DIRECT2D)
+void ImageFrameCache::setTargetContext(const GraphicsContext* targetContext)
+{
+    if (isDecoderAvailable() && targetContext)
+        m_decoder->setTargetContext(targetContext->platformContext())
+}
+#endif
+
+NativeImagePtr ImageFrameCache::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+{
+    return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
+}
+
 NativeImagePtr ImageFrameCache::frameImageAtIndex(size_t index)
 {
     return frameMetadataAtIndex<NativeImagePtr>(index, (&ImageFrame::nativeImage));
@@ -573,4 +657,16 @@
     return frameMetadataAtIndexCacheIfNeeded<NativeImagePtr>(index, (&ImageFrame::nativeImage), nullptr, ImageFrame::Caching::MetadataAndImage, subsamplingLevel);
 }
 
+void ImageFrameCache::dump(TextStream& ts)
+{
+    ts.dumpProperty("type", filenameExtension());
+    ts.dumpProperty("frame-count", frameCount());
+    ts.dumpProperty("repetitions", repetitionCount());
+    ts.dumpProperty("solid-color", singlePixelSolidColor());
+
+    ImageOrientation orientation = frameOrientationAtIndex(0);
+    if (orientation != OriginTopLeft)
+        ts.dumpProperty("orientation", orientation);
 }
+
+}

Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.h (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.h	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.h	2017-11-29 23:23:54 UTC (rev 225300)
@@ -31,6 +31,7 @@
 #include <wtf/Optional.h>
 #include <wtf/SynchronizedFixedQueue.h>
 #include <wtf/WorkQueue.h>
+#include <wtf/text/TextStream.h>
 
 namespace WebCore {
 
@@ -40,11 +41,15 @@
 class URL;
 
 class ImageFrameCache : public ThreadSafeRefCounted<ImageFrameCache> {
-    friend class ImageSource;
+    friend class BitmapImage;
 public:
-    static Ref<ImageFrameCache> create(Image* image)
+    ImageFrameCache(Image*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
+    ImageFrameCache(NativeImagePtr&&);
+    ~ImageFrameCache();
+
+    static Ref<ImageFrameCache> create(Image* image, AlphaOption alphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption gammaAndColorProfileOption = GammaAndColorProfileOption::Applied)
     {
-        return adoptRef(*new ImageFrameCache(image));
+        return adoptRef(*new ImageFrameCache(image, alphaOption, gammaAndColorProfileOption));
     }
 
     static Ref<ImageFrameCache> create(NativeImagePtr&& nativeImage)
@@ -52,16 +57,17 @@
         return adoptRef(*new ImageFrameCache(WTFMove(nativeImage)));
     }
 
-    ~ImageFrameCache();
+    void setData(SharedBuffer* data, bool allDataReceived);
+    void resetData(SharedBuffer* data);
+    EncodedDataStatus dataChanged(SharedBuffer* data, bool allDataReceived);
+    bool isAllDataReceived();
 
-    void setDecoder(ImageDecoder*);
-    ImageDecoder* decoder() const;
-
     unsigned decodedSize() const { return m_decodedSize; }
     void destroyAllDecodedData() { destroyDecodedData(frameCount(), frameCount()); }
     void destroyAllDecodedDataExcludeFrame(size_t excludeFrame) { destroyDecodedData(frameCount(), excludeFrame); }
     void destroyDecodedDataBeforeFrame(size_t beforeFrame) { destroyDecodedData(beforeFrame, beforeFrame); }
     void destroyIncompleteDecodedData();
+    void clearFrameBufferCache(size_t beforeFrame);
 
     void growFrames();
     void clearMetadata();
@@ -71,8 +77,9 @@
     long long expectedContentLength() const;
 
     // Asynchronous image decoding
+    bool canUseAsyncDecoding();
     void startAsyncDecodingQueue();
-    void requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>&);
+    void requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>& = { });
     void stopAsyncDecodingQueue();
     bool hasAsyncDecodingQueue() const { return m_decodingQueue; }
     bool isAsyncDecodingQueueIdle() const;
@@ -90,8 +97,8 @@
     // Image metadata which is calculated from the first ImageFrame.
     IntSize size();
     IntSize sizeRespectingOrientation();
-
     Color singlePixelSolidColor();
+    SubsamplingLevel maximumSubsamplingLevel();
 
     // ImageFrame metadata which does not require caching the ImageFrame.
     bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t, const DecodingOptions&);
@@ -108,13 +115,14 @@
     Seconds frameDurationAtIndex(size_t);
     ImageOrientation frameOrientationAtIndex(size_t);
 
+#if USE(DIRECT2D)
+    void setTargetContext(const GraphicsContext*);
+#endif
+    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
     NativeImagePtr frameImageAtIndex(size_t);
-    NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel);
+    NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default);
 
 private:
-    ImageFrameCache(Image*);
-    ImageFrameCache(NativeImagePtr&&);
-
     template<typename T, T (ImageDecoder::*functor)() const>
     T metadata(const T& defaultValue, std::optional<T>* cachedValue = nullptr);
 
@@ -124,6 +132,7 @@
     template<typename T, typename... Args>
     T frameMetadataAtIndexCacheIfNeeded(size_t, T (ImageFrame::*functor)() const,  std::optional<T>* cachedValue, Args&&...);
 
+    bool ensureDecoderAvailable(SharedBuffer* data);
     bool isDecoderAvailable() const { return m_decoder; }
     void destroyDecodedData(size_t frameCount, size_t excludeFrame);
     void decodedSizeChanged(long long decodedSize);
@@ -144,11 +153,15 @@
 
     const ImageFrame& frameAtIndexCacheIfNeeded(size_t, ImageFrame::Caching, const std::optional<SubsamplingLevel>& = { });
 
+    void dump(TextStream&);
+
     Image* m_image { nullptr };
     RefPtr<ImageDecoder> m_decoder;
+    AlphaOption m_alphaOption { AlphaOption::Premultiplied };
+    GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileOption::Applied };
+
     unsigned m_decodedSize { 0 };
     unsigned m_decodedPropertiesSize { 0 };
-
     Vector<ImageFrame, 1> m_frames;
 
     // Asynchronous image decoding.
@@ -180,6 +193,7 @@
     std::optional<IntSize> m_size;
     std::optional<IntSize> m_sizeRespectingOrientation;
     std::optional<Color> m_singlePixelSolidColor;
+    std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
 };
     
 }

Deleted: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Alp Toker <alp.to...@collabora.co.uk>
- * Copyright (C) 2008, Google Inc. All rights reserved.
- * Copyright (C) 2007-2009 Torch Mobile, Inc
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ImageSource.h"
-
-#include "GraphicsContext.h"
-
-#if USE(CG)
-#include "ImageDecoderCG.h"
-#if PLATFORM(WIN)
-#include <WebKitSystemInterface/WebKitSystemInterface.h>
-#endif
-#elif USE(DIRECT2D)
-#include "ImageDecoderDirect2D.h"
-#else
-#include "ImageDecoder.h"
-#endif
-
-#include "ImageOrientation.h"
-#include <wtf/CurrentTime.h>
-
-namespace WebCore {
-
-ImageSource::ImageSource(NativeImagePtr&& nativeImage)
-    : m_frameCache(ImageFrameCache::create(WTFMove(nativeImage)))
-{
-}
-    
-ImageSource::ImageSource(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
-    : m_frameCache(ImageFrameCache::create(image))
-    , m_alphaOption(alphaOption)
-    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
-{
-}
-
-ImageSource::~ImageSource() = default;
-
-void ImageSource::clearFrameBufferCache(size_t clearBeforeFrame)
-{
-    if (!isDecoderAvailable())
-        return;
-    m_decoder->clearFrameBufferCache(clearBeforeFrame);
-}
-
-bool ImageSource::ensureDecoderAvailable(SharedBuffer* data)
-{
-    if (!data || isDecoderAvailable())
-        return true;
-
-    m_decoder = ImageDecoder::create(*data, m_frameCache->mimeType(), m_alphaOption, m_gammaAndColorProfileOption);
-    if (!isDecoderAvailable())
-        return false;
-
-    if (auto expectedContentLength = m_frameCache->expectedContentLength())
-        m_decoder->setExpectedContentSize(expectedContentLength);
-
-    m_frameCache->setDecoder(m_decoder.get());
-    return true;
-}
-
-void ImageSource::setDecoderTargetContext(const GraphicsContext* targetContext)
-{
-#if USE(DIRECT2D)
-    if (!isDecoderAvailable())
-        return;
-
-    if (targetContext)
-        m_decoder->setTargetContext(targetContext->platformContext());
-#else
-    UNUSED_PARAM(targetContext);
-#endif
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
-    if (!data || !ensureDecoderAvailable(data))
-        return;
-
-    m_decoder->setData(*data, allDataReceived);
-}
-
-void ImageSource::resetData(SharedBuffer* data)
-{
-    m_decoder = nullptr;
-    m_frameCache->setDecoder(nullptr);
-    setData(data, isAllDataReceived());
-}
-
-EncodedDataStatus ImageSource::dataChanged(SharedBuffer* data, bool allDataReceived)
-{
-    setData(data, allDataReceived);
-    m_frameCache->clearMetadata();
-
-    EncodedDataStatus status = encodedDataStatus();
-    if (status >= EncodedDataStatus::SizeAvailable)
-        m_frameCache->growFrames();
-
-    return status;
-}
-
-bool ImageSource::isAllDataReceived()
-{
-    return isDecoderAvailable() ? m_decoder->isAllDataReceived() : m_frameCache->frameCount();
-}
-
-bool ImageSource::canUseAsyncDecoding()
-{
-    if (!isDecoderAvailable())
-        return false;
-    // FIXME: figure out the best heuristic for enabling async image decoding.
-    return size().area() * sizeof(RGBA32) >= (frameCount() > 1 ? 100 * KB : 500 * KB);
-}
-
-SubsamplingLevel ImageSource::maximumSubsamplingLevel()
-{
-    if (m_maximumSubsamplingLevel)
-        return m_maximumSubsamplingLevel.value();
-
-    if (!isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0))
-        return SubsamplingLevel::Default;
-
-    // FIXME: this value was chosen to be appropriate for iOS since the image
-    // subsampling is only enabled by default on iOS. Choose a different value
-    // if image subsampling is enabled on other platform.
-    const int maximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
-    SubsamplingLevel level = SubsamplingLevel::First;
-
-    for (; level < SubsamplingLevel::Last; ++level) {
-        if (frameSizeAtIndex(0, level).area().unsafeGet() < maximumImageAreaBeforeSubsampling)
-            break;
-    }
-
-    m_maximumSubsamplingLevel = level;
-    return m_maximumSubsamplingLevel.value();
-}
-
-SubsamplingLevel ImageSource::subsamplingLevelForScaleFactor(GraphicsContext& context, const FloatSize& scaleFactor)
-{
-#if USE(CG)
-    // Never use subsampled images for drawing into PDF contexts.
-    if (CGContextGetType(context.platformContext()) == kCGContextTypePDF)
-        return SubsamplingLevel::Default;
-
-    float scale = std::min(float(1), std::max(scaleFactor.width(), scaleFactor.height()));
-    if (!(scale > 0 && scale <= 1))
-        return SubsamplingLevel::Default;
-
-    int result = std::ceil(std::log2(1 / scale));
-    return static_cast<SubsamplingLevel>(std::min(result, static_cast<int>(maximumSubsamplingLevel())));
-#else
-    UNUSED_PARAM(context);
-    UNUSED_PARAM(scaleFactor);
-    return SubsamplingLevel::Default;
-#endif
-}
-
-NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
-{
-    return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
-}
-
-NativeImagePtr ImageSource::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext)
-{
-    setDecoderTargetContext(targetContext);
-    return m_frameCache->frameImageAtIndexCacheIfNeeded(index, subsamplingLevel);
-}
-
-void ImageSource::dump(TextStream& ts)
-{
-    ts.dumpProperty("type", filenameExtension());
-    ts.dumpProperty("frame-count", frameCount());
-    ts.dumpProperty("repetitions", repetitionCount());
-    ts.dumpProperty("solid-color", singlePixelSolidColor());
-
-    ImageOrientation orientation = frameOrientationAtIndex(0);
-    if (orientation != OriginTopLeft)
-        ts.dumpProperty("orientation", orientation);
-}
-
-}

Deleted: trunk/Source/WebCore/platform/graphics/ImageSource.h (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/ImageSource.h	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h	2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2010, 2012, 2014, 2016 Apple Inc.  All rights reserved.
- * Copyright (C) 2007-2008 Torch Mobile, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#pragma once
-
-#include "ImageFrame.h"
-#include "ImageFrameCache.h"
-#include "ImageOrientation.h"
-#include "IntPoint.h"
-#include "NativeImage.h"
-#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/Optional.h>
-#include <wtf/text/TextStream.h>
-
-namespace WebCore {
-
-class GraphicsContext;
-class ImageDecoder;
-class ImageOrientation;
-class IntPoint;
-class IntSize;
-class SharedBuffer;
-
-class ImageSource {
-    WTF_MAKE_NONCOPYABLE(ImageSource);
-    friend class BitmapImage;
-public:
-    ImageSource(NativeImagePtr&&);
-    ImageSource(Image*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
-    ~ImageSource();
-
-    void destroyAllDecodedData() { m_frameCache->destroyAllDecodedData(); }
-    void destroyAllDecodedDataExcludeFrame(size_t excludeFrame) { m_frameCache->destroyAllDecodedDataExcludeFrame(excludeFrame); }
-    void destroyDecodedDataBeforeFrame(size_t beforeFrame) { m_frameCache->destroyDecodedDataBeforeFrame(beforeFrame); }
-    void destroyIncompleteDecodedData() { m_frameCache->destroyIncompleteDecodedData(); }
-    void clearImage() { m_frameCache->clearImage(); }
-    void clearFrameBufferCache(size_t);
-
-    bool ensureDecoderAvailable(SharedBuffer*);
-    bool isDecoderAvailable() const { return m_decoder.get(); }
-
-    void setData(SharedBuffer* data, bool allDataReceived);
-    void resetData(SharedBuffer* data);
-    EncodedDataStatus dataChanged(SharedBuffer* data, bool allDataReceived);
-
-    unsigned decodedSize() const { return m_frameCache->decodedSize(); }
-    bool isAllDataReceived();
-
-    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(); }
-    void stopAsyncDecodingQueue() { m_frameCache->stopAsyncDecodingQueue(); }
-
-    // Image metadata which is calculated by the decoder or can deduced by the case of the memory NativeImage.
-    EncodedDataStatus encodedDataStatus() { return m_frameCache->encodedDataStatus(); }
-    size_t frameCount() { return m_frameCache->frameCount(); }
-    RepetitionCount repetitionCount() { return m_frameCache->repetitionCount(); }
-    String uti() { return m_frameCache->uti(); }
-    String filenameExtension() { return m_frameCache->filenameExtension(); }
-    std::optional<IntPoint> hotSpot() { return m_frameCache->hotSpot(); }
-
-    // Image metadata which is calculated from the first ImageFrame.
-    IntSize size() { return m_frameCache->size(); }
-    IntSize sizeRespectingOrientation() { return m_frameCache->sizeRespectingOrientation(); }
-    Color singlePixelSolidColor() { return m_frameCache->singlePixelSolidColor(); }
-
-    // ImageFrame metadata which does not require caching the ImageFrame.
-    bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) { return m_frameCache->frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); }
-    DecodingStatus frameDecodingStatusAtIndex(size_t index) { return m_frameCache->frameDecodingStatusAtIndex(index); }
-    bool frameHasAlphaAtIndex(size_t index) { return m_frameCache->frameHasAlphaAtIndex(index); }
-    bool frameHasImageAtIndex(size_t index) { return m_frameCache->frameHasImageAtIndex(index); }
-    bool frameHasFullSizeNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel) { return m_frameCache->frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); }
-    bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_frameCache->frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); }
-    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) { return m_frameCache->frameSubsamplingLevelAtIndex(index); }
-
-    // ImageFrame metadata which forces caching or re-caching the ImageFrame.
-    IntSize frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache->frameSizeAtIndex(index, subsamplingLevel); }
-    unsigned frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache->frameBytesAtIndex(index, subsamplingLevel); }
-    Seconds frameDurationAtIndex(size_t index) { return m_frameCache->frameDurationAtIndex(index); }
-    ImageOrientation frameOrientationAtIndex(size_t index) { return m_frameCache->frameOrientationAtIndex(index); }
-
-    NativeImagePtr frameImageAtIndex(size_t index) { return m_frameCache->frameImageAtIndex(index); }
-    NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr);
-
-    SubsamplingLevel maximumSubsamplingLevel();
-    SubsamplingLevel subsamplingLevelForScaleFactor(GraphicsContext&, const FloatSize& scaleFactor);
-    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
-
-private:
-    void dump(WTF::TextStream&);
-
-    void setDecoderTargetContext(const GraphicsContext*);
-
-    Ref<ImageFrameCache> m_frameCache;
-    RefPtr<ImageDecoder> m_decoder;
-
-    std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
-
-    AlphaOption m_alphaOption { AlphaOption::Premultiplied };
-    GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileOption::Applied };
-};
-
-}

Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp	2017-11-29 23:23:54 UTC (rev 225300)
@@ -35,7 +35,7 @@
 #include "CairoUtilities.h"
 #include "GraphicsContext3DPrivate.h"
 #include "Image.h"
-#include "ImageSource.h"
+#include "ImageFrameCache.h"
 #include "NotImplemented.h"
 #include "PlatformContextCairo.h"
 #include "RefPtrCairo.h"
@@ -277,8 +277,6 @@
 
 GraphicsContext3D::ImageExtractor::~ImageExtractor()
 {
-    if (m_decoder)
-        delete m_decoder;
 }
 
 bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
@@ -288,12 +286,7 @@
     // We need this to stay in scope because the native image is just a shallow copy of the data.
     AlphaOption alphaOption = premultiplyAlpha ? AlphaOption::Premultiplied : AlphaOption::NotPremultiplied;
     GammaAndColorProfileOption gammaAndColorProfileOption = ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied;
-    m_decoder = new ImageSource(nullptr, alphaOption, gammaAndColorProfileOption);
-    
-    if (!m_decoder)
-        return false;
-
-    ImageSource& decoder = *m_decoder;
+    ImageFrameCache decoder(nullptr, alphaOption, gammaAndColorProfileOption);
     m_alphaOp = AlphaDoNothing;
 
     if (m_image->data()) {

Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp	2017-11-29 23:23:54 UTC (rev 225300)
@@ -325,7 +325,7 @@
         return false;
     bool hasAlpha = !m_image->currentFrameKnownToBeOpaque();
     if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
-        ImageSource decoder(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
+        ImageFrameCache decoder(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
         decoder.setData(m_image->data(), true);
         if (!decoder.frameCount())
             return false;

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.h (225299 => 225300)


--- trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.h	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.h	2017-11-29 23:23:54 UTC (rev 225300)
@@ -26,7 +26,6 @@
 #ifndef ImageSourceCG_h
 #define ImageSourceCG_h
 
-#include "ImageSource.h"
 #include <wtf/Forward.h>
 
 namespace WebCore {

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (225299 => 225300)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,3 +1,12 @@
+2017-11-29  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        Remove the ImageSource from the class hierarchy that connects BitmapImage to ImageFrame
+        https://bugs.webkit.org/show_bug.cgi?id=175595
+
+        Reviewed by Darin Adler.
+
+        * WebView/WebPreferences.mm:
+
 2017-11-27  Tim Horton  <timothy_hor...@apple.com>
 
         One too many zeroes in macOS version number in FeatureDefines

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm (225299 => 225300)


--- trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm	2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm	2017-11-29 23:23:54 UTC (rev 225300)
@@ -58,7 +58,6 @@
 #import <AudioToolbox/AudioSession.h>
 #import <WebCore/Device.h>
 #import <WebCore/GraphicsContext.h>
-#import <WebCore/ImageSource.h>
 #import <WebCore/WebCoreThreadMessage.h>
 #endif
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to