Title: [225428] trunk/Source/WebCore
Revision
225428
Author
[email protected]
Date
2017-12-01 16:01:54 -0800 (Fri, 01 Dec 2017)

Log Message

Rename ImageFrameCache to ImageSource
https://bugs.webkit.org/show_bug.cgi?id=180172

Patch by Said Abou-Hallawa <[email protected]> on 2017-12-01
Reviewed by Per Arne Vollan.

This is a follow-up for r225300. ImageSource is the intended name after
merging ImageFrameCache and ImageSource.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::BitmapImage):
* platform/graphics/BitmapImage.h:
* platform/graphics/ImageFrame.h:
* platform/graphics/ImageFrameCache.cpp: Removed.
* platform/graphics/ImageFrameCache.h: Removed.
* platform/graphics/ImageSource.cpp: Added.
(WebCore::ImageSource::ImageSource):
(WebCore::ImageSource::~ImageSource):
(WebCore::ImageSource::ensureDecoderAvailable):
(WebCore::ImageSource::setData):
(WebCore::ImageSource::resetData):
(WebCore::ImageSource::dataChanged):
(WebCore::ImageSource::isAllDataReceived):
(WebCore::ImageSource::destroyDecodedData):
(WebCore::ImageSource::destroyIncompleteDecodedData):
(WebCore::ImageSource::clearFrameBufferCache):
(WebCore::ImageSource::decodedSizeChanged):
(WebCore::ImageSource::decodedSizeIncreased):
(WebCore::ImageSource::decodedSizeDecreased):
(WebCore::ImageSource::decodedSizeReset):
(WebCore::ImageSource::didDecodeProperties):
(WebCore::ImageSource::growFrames):
(WebCore::ImageSource::setNativeImage):
(WebCore::ImageSource::cacheMetadataAtIndex):
(WebCore::ImageSource::cacheNativeImageAtIndex):
(WebCore::ImageSource::cacheNativeImageAtIndexAsync):
(WebCore::ImageSource::decodingQueue):
(WebCore::ImageSource::frameRequestQueue):
(WebCore::ImageSource::canUseAsyncDecoding):
(WebCore::ImageSource::startAsyncDecodingQueue):
(WebCore::ImageSource::requestFrameAsyncDecodingAtIndex):
(WebCore::ImageSource::isAsyncDecodingQueueIdle const):
(WebCore::ImageSource::stopAsyncDecodingQueue):
(WebCore::ImageSource::frameAtIndexCacheIfNeeded):
(WebCore::ImageSource::clearMetadata):
(WebCore::ImageSource::sourceURL const):
(WebCore::ImageSource::mimeType const):
(WebCore::ImageSource::expectedContentLength const):
(WebCore::ImageSource::metadata):
(WebCore::ImageSource::frameMetadataAtIndex):
(WebCore::ImageSource::frameMetadataAtIndexCacheIfNeeded):
(WebCore::ImageSource::encodedDataStatus):
(WebCore::ImageSource::frameCount):
(WebCore::ImageSource::repetitionCount):
(WebCore::ImageSource::uti):
(WebCore::ImageSource::filenameExtension):
(WebCore::ImageSource::hotSpot):
(WebCore::ImageSource::size):
(WebCore::ImageSource::sizeRespectingOrientation):
(WebCore::ImageSource::singlePixelSolidColor):
(WebCore::ImageSource::maximumSubsamplingLevel):
(WebCore::ImageSource::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex):
(WebCore::ImageSource::frameDecodingStatusAtIndex):
(WebCore::ImageSource::frameHasAlphaAtIndex):
(WebCore::ImageSource::frameHasFullSizeNativeImageAtIndex):
(WebCore::ImageSource::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex):
(WebCore::ImageSource::frameSubsamplingLevelAtIndex):
(WebCore::ImageSource::frameSizeAtIndex):
(WebCore::ImageSource::frameBytesAtIndex):
(WebCore::ImageSource::frameDurationAtIndex):
(WebCore::ImageSource::frameOrientationAtIndex):
(WebCore::ImageSource::setTargetContext):
(WebCore::ImageSource::createFrameImageAtIndex):
(WebCore::ImageSource::frameImageAtIndex):
(WebCore::ImageSource::frameImageAtIndexCacheIfNeeded):
(WebCore::ImageSource::dump):
* platform/graphics/ImageSource.h: Added.
(WebCore::ImageSource::create):
(WebCore::ImageSource::decodedSize const):
(WebCore::ImageSource::destroyAllDecodedData):
(WebCore::ImageSource::destroyAllDecodedDataExcludeFrame):
(WebCore::ImageSource::destroyDecodedDataBeforeFrame):
(WebCore::ImageSource::clearImage):
(WebCore::ImageSource::requestFrameAsyncDecodingAtIndex):
(WebCore::ImageSource::hasAsyncDecodingQueue const):
(WebCore::ImageSource::isSizeAvailable):
(WebCore::ImageSource::isDecoderAvailable const):
(WebCore::ImageSource::frameAtIndexCacheIfNeeded):
(WebCore::ImageSource::ImageFrameRequest::operator== const):
* platform/graphics/cairo/GraphicsContext3DCairo.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::extractImage):
* platform/graphics/cg/GraphicsContext3DCG.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::extractImage):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225427 => 225428)


--- trunk/Source/WebCore/ChangeLog	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/ChangeLog	2017-12-02 00:01:54 UTC (rev 225428)
@@ -1,3 +1,100 @@
+2017-12-01  Said Abou-Hallawa  <[email protected]>
+
+        Rename ImageFrameCache to ImageSource
+        https://bugs.webkit.org/show_bug.cgi?id=180172
+
+        Reviewed by Per Arne Vollan.
+
+        This is a follow-up for r225300. ImageSource is the intended name after
+        merging ImageFrameCache and ImageSource.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::BitmapImage):
+        * platform/graphics/BitmapImage.h:
+        * platform/graphics/ImageFrame.h:
+        * platform/graphics/ImageFrameCache.cpp: Removed.
+        * platform/graphics/ImageFrameCache.h: Removed.
+        * platform/graphics/ImageSource.cpp: Added.
+        (WebCore::ImageSource::ImageSource):
+        (WebCore::ImageSource::~ImageSource):
+        (WebCore::ImageSource::ensureDecoderAvailable):
+        (WebCore::ImageSource::setData):
+        (WebCore::ImageSource::resetData):
+        (WebCore::ImageSource::dataChanged):
+        (WebCore::ImageSource::isAllDataReceived):
+        (WebCore::ImageSource::destroyDecodedData):
+        (WebCore::ImageSource::destroyIncompleteDecodedData):
+        (WebCore::ImageSource::clearFrameBufferCache):
+        (WebCore::ImageSource::decodedSizeChanged):
+        (WebCore::ImageSource::decodedSizeIncreased):
+        (WebCore::ImageSource::decodedSizeDecreased):
+        (WebCore::ImageSource::decodedSizeReset):
+        (WebCore::ImageSource::didDecodeProperties):
+        (WebCore::ImageSource::growFrames):
+        (WebCore::ImageSource::setNativeImage):
+        (WebCore::ImageSource::cacheMetadataAtIndex):
+        (WebCore::ImageSource::cacheNativeImageAtIndex):
+        (WebCore::ImageSource::cacheNativeImageAtIndexAsync):
+        (WebCore::ImageSource::decodingQueue):
+        (WebCore::ImageSource::frameRequestQueue):
+        (WebCore::ImageSource::canUseAsyncDecoding):
+        (WebCore::ImageSource::startAsyncDecodingQueue):
+        (WebCore::ImageSource::requestFrameAsyncDecodingAtIndex):
+        (WebCore::ImageSource::isAsyncDecodingQueueIdle const):
+        (WebCore::ImageSource::stopAsyncDecodingQueue):
+        (WebCore::ImageSource::frameAtIndexCacheIfNeeded):
+        (WebCore::ImageSource::clearMetadata):
+        (WebCore::ImageSource::sourceURL const):
+        (WebCore::ImageSource::mimeType const):
+        (WebCore::ImageSource::expectedContentLength const):
+        (WebCore::ImageSource::metadata):
+        (WebCore::ImageSource::frameMetadataAtIndex):
+        (WebCore::ImageSource::frameMetadataAtIndexCacheIfNeeded):
+        (WebCore::ImageSource::encodedDataStatus):
+        (WebCore::ImageSource::frameCount):
+        (WebCore::ImageSource::repetitionCount):
+        (WebCore::ImageSource::uti):
+        (WebCore::ImageSource::filenameExtension):
+        (WebCore::ImageSource::hotSpot):
+        (WebCore::ImageSource::size):
+        (WebCore::ImageSource::sizeRespectingOrientation):
+        (WebCore::ImageSource::singlePixelSolidColor):
+        (WebCore::ImageSource::maximumSubsamplingLevel):
+        (WebCore::ImageSource::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex):
+        (WebCore::ImageSource::frameDecodingStatusAtIndex):
+        (WebCore::ImageSource::frameHasAlphaAtIndex):
+        (WebCore::ImageSource::frameHasFullSizeNativeImageAtIndex):
+        (WebCore::ImageSource::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex):
+        (WebCore::ImageSource::frameSubsamplingLevelAtIndex):
+        (WebCore::ImageSource::frameSizeAtIndex):
+        (WebCore::ImageSource::frameBytesAtIndex):
+        (WebCore::ImageSource::frameDurationAtIndex):
+        (WebCore::ImageSource::frameOrientationAtIndex):
+        (WebCore::ImageSource::setTargetContext):
+        (WebCore::ImageSource::createFrameImageAtIndex):
+        (WebCore::ImageSource::frameImageAtIndex):
+        (WebCore::ImageSource::frameImageAtIndexCacheIfNeeded):
+        (WebCore::ImageSource::dump):
+        * platform/graphics/ImageSource.h: Added.
+        (WebCore::ImageSource::create):
+        (WebCore::ImageSource::decodedSize const):
+        (WebCore::ImageSource::destroyAllDecodedData):
+        (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame):
+        (WebCore::ImageSource::destroyDecodedDataBeforeFrame):
+        (WebCore::ImageSource::clearImage):
+        (WebCore::ImageSource::requestFrameAsyncDecodingAtIndex):
+        (WebCore::ImageSource::hasAsyncDecodingQueue const):
+        (WebCore::ImageSource::isSizeAvailable):
+        (WebCore::ImageSource::isDecoderAvailable const):
+        (WebCore::ImageSource::frameAtIndexCacheIfNeeded):
+        (WebCore::ImageSource::ImageFrameRequest::operator== const):
+        * platform/graphics/cairo/GraphicsContext3DCairo.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+        * platform/graphics/cg/GraphicsContext3DCG.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+
 2017-12-01  Youenn Fablet  <[email protected]>
 
         Implement https://w3c.github.io/ServiceWorker/#clients-get

Modified: trunk/Source/WebCore/Sources.txt (225427 => 225428)


--- trunk/Source/WebCore/Sources.txt	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/Sources.txt	2017-12-02 00:01:54 UTC (rev 225428)
@@ -1524,8 +1524,8 @@
 platform/graphics/ImageBuffer.cpp
 platform/graphics/ImageDecoder.cpp
 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 (225427 => 225428)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-12-02 00:01:54 UTC (rev 225428)
@@ -1606,11 +1606,11 @@
 		53ED3FDE167A88E7006762E6 /* JSInternalSettingsGenerated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53ED3FDC167A88E7006762E6 /* JSInternalSettingsGenerated.cpp */; };
 		53ED3FDF167A88E7006762E6 /* JSInternalSettingsGenerated.h in Headers */ = {isa = PBXBuildFile; fileRef = 53ED3FDD167A88E7006762E6 /* JSInternalSettingsGenerated.h */; };
 		550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		5546757B1FD212A9003B10B0 /* ImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 554675781FD1FC1A003B10B0 /* ImageSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5550CB421E955E3C00111AA0 /* ImageTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5550CB411E955E3C00111AA0 /* ImageTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		555130011E7CCCCB00A69E38 /* DecodingOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 555130001E7CCCCA00A69E38 /* DecodingOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */; };
 		5576A5651D88A70800CCC04C /* ImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 5576A5631D88A70800CCC04C /* ImageFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		5597F8271D91C3130066BC21 /* ImageFrameCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5597F8251D91C3130066BC21 /* ImageFrameCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
 		55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		55AF14E61EAAC59B0026EEAA /* UTIRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 55AF14E41EAAC59B0026EEAA /* UTIRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -8051,6 +8051,8 @@
 		53ED3FDD167A88E7006762E6 /* JSInternalSettingsGenerated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalSettingsGenerated.h; sourceTree = "<group>"; };
 		550A0BC7085F6039007353D6 /* QualifiedName.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifiedName.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
 		550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+		554675771FD1FC1A003B10B0 /* ImageSource.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageSource.cpp; sourceTree = "<group>"; };
+		554675781FD1FC1A003B10B0 /* ImageSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageSource.h; sourceTree = "<group>"; };
 		5550CB411E955E3C00111AA0 /* ImageTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageTypes.h; sourceTree = "<group>"; };
 		555130001E7CCCCA00A69E38 /* DecodingOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecodingOptions.h; sourceTree = "<group>"; };
 		555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = "<group>"; };
@@ -8057,8 +8059,6 @@
 		555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = "<group>"; };
 		5576A5621D88A70800CCC04C /* ImageFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrame.cpp; sourceTree = "<group>"; };
 		5576A5631D88A70800CCC04C /* ImageFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrame.h; sourceTree = "<group>"; };
-		5597F8241D91C3130066BC21 /* ImageFrameCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrameCache.cpp; sourceTree = "<group>"; };
-		5597F8251D91C3130066BC21 /* ImageFrameCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrameCache.h; sourceTree = "<group>"; };
 		55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
 		55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = "<group>"; };
 		55AF14E31EAAC59B0026EEAA /* UTIRegistry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UTIRegistry.cpp; sourceTree = "<group>"; };
@@ -22711,12 +22711,12 @@
 				CD19FEA61F573972000C42FB /* ImageDecoder.h */,
 				5576A5621D88A70800CCC04C /* ImageFrame.cpp */,
 				5576A5631D88A70800CCC04C /* ImageFrame.h */,
-				5597F8241D91C3130066BC21 /* ImageFrameCache.cpp */,
-				5597F8251D91C3130066BC21 /* ImageFrameCache.h */,
 				BC7F44A70B9E324E00A9D081 /* ImageObserver.h */,
 				A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
 				A8748D6612CC3763001FBA41 /* ImageOrientation.h */,
 				49291E4A134172C800E753DE /* ImageRenderingMode.h */,
+				554675771FD1FC1A003B10B0 /* ImageSource.cpp */,
+				554675781FD1FC1A003B10B0 /* ImageSource.h */,
 				5550CB411E955E3C00111AA0 /* ImageTypes.h */,
 				07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */,
 				07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */,
@@ -27190,7 +27190,6 @@
 				555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */,
 				97205AB61239291000B17380 /* ImageDocument.h in Headers */,
 				5576A5651D88A70800CCC04C /* ImageFrame.h in Headers */,
-				5597F8271D91C3130066BC21 /* ImageFrameCache.h in Headers */,
 				F55B3DC21251F12D003EF269 /* ImageInputType.h in Headers */,
 				089582560E857A7E00F82C83 /* ImageLoader.h in Headers */,
 				BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */,
@@ -27198,6 +27197,7 @@
 				B51A2F3F17D7D3AE0072517A /* ImageQualityController.h in Headers */,
 				49291E4B134172C800E753DE /* ImageRenderingMode.h in Headers */,
 				7C193BC11F5E0EED0088F3E6 /* ImageSmoothingQuality.h in Headers */,
+				5546757B1FD212A9003B10B0 /* ImageSource.h in Headers */,
 				4B3480940EEF50D400AC1B41 /* ImageSourceCG.h in Headers */,
 				5550CB421E955E3C00111AA0 /* ImageTypes.h in Headers */,
 				26F756B31B3B66F70005DD79 /* ImmutableNFA.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (225427 => 225428)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2017-12-02 00:01:54 UTC (rev 225428)
@@ -47,13 +47,13 @@
 
 BitmapImage::BitmapImage(ImageObserver* observer)
     : Image(observer)
-    , m_source(ImageFrameCache::create(this))
+    , m_source(ImageSource::create(this))
 {
 }
 
 BitmapImage::BitmapImage(NativeImagePtr&& image, ImageObserver* observer)
     : Image(observer)
-    , m_source(ImageFrameCache::create(WTFMove(image)))
+    , m_source(ImageSource::create(WTFMove(image)))
 {
 }
 

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (225427 => 225428)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h	2017-12-02 00:01:54 UTC (rev 225428)
@@ -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)
@@ -205,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 Ref<ImageFrameCache> m_source;
+    mutable Ref<ImageSource> 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/ImageFrame.h (225427 => 225428)


--- trunk/Source/WebCore/platform/graphics/ImageFrame.h	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/ImageFrame.h	2017-12-02 00:01:54 UTC (rev 225428)
@@ -37,7 +37,7 @@
 namespace WebCore {
 
 class ImageFrame {
-    friend class ImageFrameCache;
+    friend class ImageSource;
 public:
     enum class Caching { Metadata, MetadataAndImage };
 

Deleted: trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp (225427 => 225428)


--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp	2017-12-02 00:01:54 UTC (rev 225428)
@@ -1,672 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc.  All rights reserved.
- *
- * 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 "ImageFrameCache.h"
-
-#include "Image.h"
-#include "ImageObserver.h"
-#include "Logging.h"
-#include "URL.h"
-#include <wtf/SystemTracing.h>
-
-#if USE(CG)
-#include "ImageDecoderCG.h"
-#elif USE(DIRECT2D)
-#include "ImageDecoderDirect2D.h"
-#include <WinCodec.h>
-#else
-#include "ImageDecoder.h"
-#endif
-
-#include <wtf/CheckedArithmetic.h>
-#include <wtf/MainThread.h>
-#include <wtf/RunLoop.h>
-
-namespace WebCore {
-
-ImageFrameCache::ImageFrameCache(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
-    : m_image(image)
-    , m_alphaOption(alphaOption)
-    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
-{
-}
-
-ImageFrameCache::ImageFrameCache(NativeImagePtr&& nativeImage)
-{
-    m_frameCount = 1;
-    m_encodedDataStatus = EncodedDataStatus::Complete;
-    growFrames();
-
-    setNativeImage(WTFMove(nativeImage));
-
-    m_decodedSize = m_frames[0].frameBytes();
-
-    // The assumption is the memory image will be displayed with the default
-    // orientation. So set m_sizeRespectingOrientation to be the same as m_size.
-    m_size = m_frames[0].size();
-    m_sizeRespectingOrientation = m_size;
-}
-
-ImageFrameCache::~ImageFrameCache()
-{
-    ASSERT(!hasAsyncDecodingQueue());
-}
-
-bool ImageFrameCache::ensureDecoderAvailable(SharedBuffer* data)
-{
-    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();
-    return true;
-}
-
-void ImageFrameCache::setData(SharedBuffer* data, bool allDataReceived)
-{
-    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;
-
-    ASSERT(frameCount <= m_frames.size());
-
-    for (size_t index = 0; index < frameCount; ++index) {
-        if (index == excludeFrame)
-            continue;
-        decodedSize += m_frames[index].clearImage();
-    }
-
-    decodedSizeReset(decodedSize);
-}
-
-void ImageFrameCache::destroyIncompleteDecodedData()
-{
-    unsigned decodedSize = 0;
-    
-    for (auto& frame : m_frames) {
-        if (!frame.hasMetadata() || frame.isComplete())
-            continue;
-        
-        decodedSize += frame.clear();
-    }
-
-    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())
-        return;
-    
-    m_image->imageObserver()->decodedSizeChanged(*m_image, decodedSize);
-}
-
-void ImageFrameCache::decodedSizeIncreased(unsigned decodedSize)
-{
-    if (!decodedSize)
-        return;
-    
-    m_decodedSize += decodedSize;
-    
-    // The fully-decoded frame will subsume the partially decoded data used
-    // to determine image properties.
-    long long changeSize = static_cast<long long>(decodedSize) - m_decodedPropertiesSize;
-    m_decodedPropertiesSize = 0;
-    decodedSizeChanged(changeSize);
-}
-
-void ImageFrameCache::decodedSizeDecreased(unsigned decodedSize)
-{
-    if (!decodedSize)
-        return;
-
-    ASSERT(m_decodedSize >= decodedSize);
-    m_decodedSize -= decodedSize;
-    decodedSizeChanged(-static_cast<long long>(decodedSize));
-}
-
-void ImageFrameCache::decodedSizeReset(unsigned decodedSize)
-{
-    ASSERT(m_decodedSize >= decodedSize);
-    m_decodedSize -= decodedSize;
-
-    // Clearing the ImageSource destroys the extra decoded data used for
-    // determining image properties.
-    decodedSize += m_decodedPropertiesSize;
-    m_decodedPropertiesSize = 0;
-    decodedSizeChanged(-static_cast<long long>(decodedSize));
-}
-
-void ImageFrameCache::didDecodeProperties(unsigned decodedPropertiesSize)
-{
-    if (m_decodedSize)
-        return;
-
-    long long decodedSize = static_cast<long long>(decodedPropertiesSize) - m_decodedPropertiesSize;
-    m_decodedPropertiesSize = decodedPropertiesSize;
-    decodedSizeChanged(decodedSize);
-}
-
-void ImageFrameCache::growFrames()
-{
-    ASSERT(isSizeAvailable());
-    auto newSize = frameCount();
-    if (newSize > m_frames.size())
-        m_frames.grow(newSize);
-}
-
-void ImageFrameCache::setNativeImage(NativeImagePtr&& nativeImage)
-{
-    ASSERT(m_frames.size() == 1);
-    ImageFrame& frame = m_frames[0];
-
-    ASSERT(!isDecoderAvailable());
-
-    frame.m_nativeImage = WTFMove(nativeImage);
-
-    frame.m_decodingStatus = DecodingStatus::Complete;
-    frame.m_size = nativeImageSize(frame.m_nativeImage);
-    frame.m_hasAlpha = nativeImageHasAlpha(frame.m_nativeImage);
-}
-
-void ImageFrameCache::cacheMetadataAtIndex(size_t index, SubsamplingLevel subsamplingLevel, DecodingStatus decodingStatus)
-{
-    ASSERT(index < m_frames.size());
-    ImageFrame& frame = m_frames[index];
-
-    ASSERT(isDecoderAvailable());
-    if (decodingStatus == DecodingStatus::Invalid)
-        frame.m_decodingStatus = m_decoder->frameIsCompleteAtIndex(index) ? DecodingStatus::Complete : DecodingStatus::Partial;
-    else
-        frame.m_decodingStatus = decodingStatus;
-
-    if (frame.hasMetadata())
-        return;
-    
-    frame.m_subsamplingLevel = subsamplingLevel;
-
-    if (frame.m_decodingOptions.hasSizeForDrawing()) {
-        ASSERT(frame.hasNativeImage());
-        frame.m_size = nativeImageSize(frame.nativeImage());
-    } else
-        frame.m_size = m_decoder->frameSizeAtIndex(index, subsamplingLevel);
-
-    frame.m_orientation = m_decoder->frameOrientationAtIndex(index);
-    frame.m_hasAlpha = m_decoder->frameHasAlphaAtIndex(index);
-
-    if (repetitionCount())
-        frame.m_duration = m_decoder->frameDurationAtIndex(index);
-}
-
-void ImageFrameCache::cacheNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions, DecodingStatus decodingStatus)
-{
-    ASSERT(index < m_frames.size());
-    ImageFrame& frame = m_frames[index];
-
-    // Clear the current image frame and update the observer with this clearance.
-    decodedSizeDecreased(frame.clear());
-
-    // Do not cache the NativeImage if adding its frameByes to the MemoryCache will cause numerical overflow.
-    size_t frameBytes = size().unclampedArea() * sizeof(RGBA32);
-    if (!WTF::isInBounds<unsigned>(frameBytes + decodedSize()))
-        return;
-
-    // Move the new image to the cache.
-    frame.m_nativeImage = WTFMove(nativeImage);
-    frame.m_decodingOptions = decodingOptions;
-    cacheMetadataAtIndex(index, subsamplingLevel, decodingStatus);
-
-    // Update the observer with the new image frame bytes.
-    decodedSizeIncreased(frame.frameBytes());
-}
-
-void ImageFrameCache::cacheNativeImageAtIndexAsync(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions, DecodingStatus decodingStatus)
-{
-    if (!isDecoderAvailable())
-        return;
-
-    ASSERT(index < m_frames.size());
-
-    // Clean the old native image and set a new one
-    cacheNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, decodingOptions, decodingStatus);
-    LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld has been cached]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
-
-    // Notify the image with the readiness of the new frame NativeImage.
-    if (m_image)
-        m_image->imageFrameAvailableAtIndex(index);
-}
-
-WorkQueue& ImageFrameCache::decodingQueue()
-{
-    if (!m_decodingQueue)
-        m_decodingQueue = WorkQueue::create("org.webkit.ImageDecoder", WorkQueue::Type::Serial, WorkQueue::QOS::Default);
-    
-    return *m_decodingQueue;
-}
-
-ImageFrameCache::FrameRequestQueue& ImageFrameCache::frameRequestQueue()
-{
-    if (!m_frameRequestQueue)
-        m_frameRequestQueue = FrameRequestQueue::create();
-    
-    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())
-        return;
-
-    // We need to protect this, m_decodingQueue and m_decoder from being deleted while we are in the decoding loop.
-    decodingQueue().dispatch([protectedThis = makeRef(*this), protectedDecodingQueue = makeRef(decodingQueue()), protectedFrameRequestQueue = makeRef(frameRequestQueue()), protectedDecoder = makeRef(*m_decoder), sourceURL = sourceURL().string().isolatedCopy()] {
-        ImageFrameRequest frameRequest;
-
-        while (protectedFrameRequestQueue->dequeue(frameRequest)) {
-            TraceScope tracingScope(AsyncImageDecodeStart, AsyncImageDecodeEnd);
-
-            // Get the frame NativeImage on the decoding thread.
-            NativeImagePtr nativeImage = protectedDecoder->createFrameImageAtIndex(frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions);
-            if (nativeImage)
-                LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld has been decoded]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
-            else {
-                LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding for frame %ld has failed]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
-                continue;
-            }
-
-            // Update the cached frames on the main thread to avoid updating the MemoryCache from a different thread.
-            callOnMainThread([protectedThis = protectedThis.copyRef(), protectedQueue = protectedDecodingQueue.copyRef(), protectedDecoder = protectedDecoder.copyRef(), sourceURL = sourceURL.isolatedCopy(), nativeImage = WTFMove(nativeImage), frameRequest] () mutable {
-                // The queue may have been closed if after we got the frame NativeImage, stopAsyncDecodingQueue() was called.
-                if (protectedQueue.ptr() == protectedThis->m_decodingQueue && protectedDecoder.ptr() == protectedThis->m_decoder) {
-                    ASSERT(protectedThis->m_frameCommitQueue.first() == frameRequest);
-                    protectedThis->m_frameCommitQueue.removeFirst();
-                    protectedThis->cacheNativeImageAtIndexAsync(WTFMove(nativeImage), frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions, frameRequest.decodingStatus);
-                } else
-                    LOG(Images, "ImageFrameCache::%s - %p - url: %s [frame %ld will not cached]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
-            });
-        }
-    });
-}
-
-void ImageFrameCache::requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing)
-{
-    ASSERT(isDecoderAvailable());
-    if (!hasAsyncDecodingQueue())
-        startAsyncDecodingQueue();
-    
-    ASSERT(index < m_frames.size());
-    DecodingStatus decodingStatus = m_decoder->frameIsCompleteAtIndex(index) ? DecodingStatus::Complete : DecodingStatus::Partial;
-
-    LOG(Images, "ImageFrameCache::%s - %p - url: %s [enqueuing frame %ld for decoding]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
-    m_frameRequestQueue->enqueue({ index, subsamplingLevel, sizeForDrawing, decodingStatus });
-    m_frameCommitQueue.append({ index, subsamplingLevel, sizeForDrawing, decodingStatus });
-}
-
-bool ImageFrameCache::isAsyncDecodingQueueIdle() const
-{
-    return m_frameCommitQueue.isEmpty();
-}
-    
-void ImageFrameCache::stopAsyncDecodingQueue()
-{
-    if (!hasAsyncDecodingQueue())
-        return;
-    
-    std::for_each(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [this](const ImageFrameRequest& frameRequest) {
-        ImageFrame& frame = m_frames[frameRequest.index];
-        if (!frame.isInvalid()) {
-            LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding has been cancelled for frame %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), frameRequest.index);
-            frame.clear();
-        }
-    });
-
-    // Close m_frameRequestQueue then set it to nullptr. A new decoding thread might start and a
-    // new m_frameRequestQueue will be created. So the terminating thread will not have access to it.
-    m_frameRequestQueue->close();
-    m_frameRequestQueue = nullptr;
-    m_frameCommitQueue.clear();
-    m_decodingQueue = nullptr;
-    LOG(Images, "ImageFrameCache::%s - %p - url: %s [decoding has been stopped]", __FUNCTION__, this, sourceURL().string().utf8().data());
-}
-
-const ImageFrame& ImageFrameCache::frameAtIndexCacheIfNeeded(size_t index, ImageFrame::Caching caching, const std::optional<SubsamplingLevel>& subsamplingLevel)
-{
-    ASSERT(index < m_frames.size());
-    ImageFrame& frame = m_frames[index];
-    if (!isDecoderAvailable() || frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, DecodingMode::Asynchronous))
-        return frame;
-    
-    SubsamplingLevel subsamplingLevelValue = subsamplingLevel ? subsamplingLevel.value() : frame.subsamplingLevel();
-
-    switch (caching) {
-    case ImageFrame::Caching::Metadata:
-        // Retrieve the metadata from ImageDecoder if the ImageFrame isn't complete.
-        if (frame.isComplete())
-            break;
-        cacheMetadataAtIndex(index, subsamplingLevelValue);
-        break;
-            
-    case ImageFrame::Caching::MetadataAndImage:
-        // Cache the image and retrieve the metadata from ImageDecoder only if there was not valid image stored.
-        if (frame.hasFullSizeNativeImage(subsamplingLevel))
-            break;
-        // We have to perform synchronous image decoding in this code. 
-        NativeImagePtr nativeImage = m_decoder->createFrameImageAtIndex(index, subsamplingLevelValue);
-        // Clean the old native image and set a new one.
-        cacheNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevelValue, DecodingMode::Synchronous);
-        break;
-    }
-
-    return frame;
-}
-
-void ImageFrameCache::clearMetadata()
-{
-    m_frameCount = std::nullopt;
-    m_repetitionCount = std::nullopt;
-    m_singlePixelSolidColor = std::nullopt;
-    m_encodedDataStatus = std::nullopt;
-    m_uti = std::nullopt;
-}
-
-URL ImageFrameCache::sourceURL() const
-{
-    return m_image ? m_image->sourceURL() : URL();
-}
-
-String ImageFrameCache::mimeType() const
-{
-    return m_image ? m_image->mimeType() : emptyString();
-}
-
-long long ImageFrameCache::expectedContentLength() const
-{
-    return m_image ? m_image->expectedContentLength() : 0;
-}
-
-template<typename T, T (ImageDecoder::*functor)() const>
-T ImageFrameCache::metadata(const T& defaultValue, std::optional<T>* cachedValue)
-{
-    if (cachedValue && *cachedValue)
-        return cachedValue->value();
-
-    if (!isDecoderAvailable() || !m_decoder->isSizeAvailable())
-        return defaultValue;
-
-    if (!cachedValue)
-        return (*m_decoder.*functor)();
-
-    *cachedValue = (*m_decoder.*functor)();
-    didDecodeProperties(m_decoder->bytesDecodedToDetermineProperties());
-    return cachedValue->value();
-}
-
-template<typename T, typename... Args>
-T ImageFrameCache::frameMetadataAtIndex(size_t index, T (ImageFrame::*functor)(Args...) const, Args&&... args)
-{
-    const ImageFrame& frame = index < m_frames.size() ? m_frames[index] : ImageFrame::defaultFrame();
-    return (frame.*functor)(std::forward<Args>(args)...);
-}
-
-template<typename T, typename... Args>
-T ImageFrameCache::frameMetadataAtIndexCacheIfNeeded(size_t index, T (ImageFrame::*functor)() const, std::optional<T>* cachedValue, Args&&... args)
-{
-    if (cachedValue && *cachedValue)
-        return cachedValue->value();
-
-    const ImageFrame& frame = index < m_frames.size() ? frameAtIndexCacheIfNeeded(index, std::forward<Args>(args)...) : ImageFrame::defaultFrame();
-
-    // Don't cache any unavailable frame metadata.
-    if (!frame.hasMetadata() || !cachedValue)
-        return (frame.*functor)();
-
-    *cachedValue = (frame.*functor)();
-    return cachedValue->value();
-}
-
-EncodedDataStatus ImageFrameCache::encodedDataStatus()
-{
-    return metadata<EncodedDataStatus, (&ImageDecoder::encodedDataStatus)>(EncodedDataStatus::Unknown, &m_encodedDataStatus);
-}
-
-size_t ImageFrameCache::frameCount()
-{
-    return metadata<size_t, (&ImageDecoder::frameCount)>(m_frames.size(), &m_frameCount);
-}
-
-RepetitionCount ImageFrameCache::repetitionCount()
-{
-    return metadata<RepetitionCount, (&ImageDecoder::repetitionCount)>(RepetitionCountNone, &m_repetitionCount);
-}
-    
-String ImageFrameCache::uti()
-{
-#if USE(CG)
-    return metadata<String, (&ImageDecoder::uti)>(String(), &m_uti);
-#else
-    return String();
-#endif
-}
-
-String ImageFrameCache::filenameExtension()
-{
-    return metadata<String, (&ImageDecoder::filenameExtension)>(String(), &m_filenameExtension);
-}
-
-std::optional<IntPoint> ImageFrameCache::hotSpot()
-{
-    return metadata<std::optional<IntPoint>, (&ImageDecoder::hotSpot)>(std::nullopt, &m_hotSpot);
-}
-
-IntSize ImageFrameCache::size()
-{
-#if !USE(CG)
-    // It's possible that we have decoded the metadata, but not frame contents yet. In that case ImageDecoder claims to
-    // have the size available, but the frame cache is empty. Return the decoder size without caching in such case.
-    if (m_frames.isEmpty() && isDecoderAvailable())
-        return m_decoder->size();
-#endif
-    return frameMetadataAtIndexCacheIfNeeded<IntSize>(0, (&ImageFrame::size), &m_size, ImageFrame::Caching::Metadata, SubsamplingLevel::Default);
-}
-
-IntSize ImageFrameCache::sizeRespectingOrientation()
-{
-    return frameMetadataAtIndexCacheIfNeeded<IntSize>(0, (&ImageFrame::sizeRespectingOrientation), &m_sizeRespectingOrientation, ImageFrame::Caching::Metadata, SubsamplingLevel::Default);
-}
-
-Color ImageFrameCache::singlePixelSolidColor()
-{
-    if (!m_singlePixelSolidColor && (size() != IntSize(1, 1) || frameCount() != 1))
-        m_singlePixelSolidColor = Color();
-
-    if (m_singlePixelSolidColor)
-        return m_singlePixelSolidColor.value();
-
-    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) {
-        return frameRequest.index == index && frameRequest.decodingOptions.isAsynchronousCompatibleWith(decodingOptions);
-    });
-    return it != m_frameCommitQueue.end();
-}
-
-DecodingStatus ImageFrameCache::frameDecodingStatusAtIndex(size_t index)
-{
-    return frameMetadataAtIndex<DecodingStatus>(index, (&ImageFrame::decodingStatus));
-}
-
-bool ImageFrameCache::frameHasAlphaAtIndex(size_t index)
-{
-    return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasAlpha));
-}
-
-bool ImageFrameCache::frameHasFullSizeNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel)
-{
-    return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasFullSizeNativeImage), subsamplingLevel);
-}
-
-bool ImageFrameCache::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions)
-{
-    return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasDecodedNativeImageCompatibleWithOptions), subsamplingLevel, decodingOptions);
-}
-    
-SubsamplingLevel ImageFrameCache::frameSubsamplingLevelAtIndex(size_t index)
-{
-    return frameMetadataAtIndex<SubsamplingLevel>(index, (&ImageFrame::subsamplingLevel));
-}
-
-IntSize ImageFrameCache::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
-{
-    return frameMetadataAtIndexCacheIfNeeded<IntSize>(index, (&ImageFrame::size), nullptr, ImageFrame::Caching::Metadata, subsamplingLevel);
-}
-
-unsigned ImageFrameCache::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
-{
-    return frameMetadataAtIndexCacheIfNeeded<unsigned>(index, (&ImageFrame::frameBytes), nullptr, ImageFrame::Caching::Metadata, subsamplingLevel);
-}
-
-Seconds ImageFrameCache::frameDurationAtIndex(size_t index)
-{
-    return frameMetadataAtIndexCacheIfNeeded<Seconds>(index, (&ImageFrame::duration), nullptr, ImageFrame::Caching::Metadata);
-}
-
-ImageOrientation ImageFrameCache::frameOrientationAtIndex(size_t index)
-{
-    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));
-}
-
-NativeImagePtr ImageFrameCache::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel)
-{
-    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);
-}
-
-}

Deleted: trunk/Source/WebCore/platform/graphics/ImageFrameCache.h (225427 => 225428)


--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.h	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.h	2017-12-02 00:01:54 UTC (rev 225428)
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc.  All rights reserved.
- *
- * 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 <wtf/Forward.h>
-#include <wtf/Optional.h>
-#include <wtf/SynchronizedFixedQueue.h>
-#include <wtf/WorkQueue.h>
-#include <wtf/text/TextStream.h>
-
-namespace WebCore {
-
-class GraphicsContext;
-class Image;
-class ImageDecoder;
-class URL;
-
-class ImageFrameCache : public ThreadSafeRefCounted<ImageFrameCache> {
-    friend class BitmapImage;
-public:
-    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, alphaOption, gammaAndColorProfileOption));
-    }
-
-    static Ref<ImageFrameCache> create(NativeImagePtr&& nativeImage)
-    {
-        return adoptRef(*new ImageFrameCache(WTFMove(nativeImage)));
-    }
-
-    void setData(SharedBuffer* data, bool allDataReceived);
-    void resetData(SharedBuffer* data);
-    EncodedDataStatus dataChanged(SharedBuffer* data, bool allDataReceived);
-    bool isAllDataReceived();
-
-    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();
-    void clearImage() { m_image = nullptr; }
-    URL sourceURL() const;
-    String mimeType() const;
-    long long expectedContentLength() const;
-
-    // Asynchronous image decoding
-    bool canUseAsyncDecoding();
-    void startAsyncDecodingQueue();
-    void requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>& = { });
-    void stopAsyncDecodingQueue();
-    bool hasAsyncDecodingQueue() const { return m_decodingQueue; }
-    bool isAsyncDecodingQueueIdle() const;
-
-    // Image metadata which is calculated either by the ImageDecoder or directly
-    // from the NativeImage if this class was created for a memory image.
-    EncodedDataStatus encodedDataStatus();
-    bool isSizeAvailable() { return encodedDataStatus() >= EncodedDataStatus::SizeAvailable; }
-    size_t frameCount();
-    RepetitionCount repetitionCount();
-    String uti();
-    String filenameExtension();
-    std::optional<IntPoint> hotSpot();
-
-    // 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&);
-    DecodingStatus frameDecodingStatusAtIndex(size_t);
-    bool frameHasAlphaAtIndex(size_t);
-    bool frameHasImageAtIndex(size_t);
-    bool frameHasFullSizeNativeImageAtIndex(size_t, const std::optional<SubsamplingLevel>&);
-    bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t, const std::optional<SubsamplingLevel>&, const DecodingOptions&);
-    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t);
-
-    // ImageFrame metadata which forces caching or re-caching the ImageFrame.
-    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
-    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
-    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 = SubsamplingLevel::Default);
-
-private:
-    template<typename T, T (ImageDecoder::*functor)() const>
-    T metadata(const T& defaultValue, std::optional<T>* cachedValue = nullptr);
-
-    template<typename T, typename... Args>
-    T frameMetadataAtIndex(size_t, T (ImageFrame::*functor)(Args...) const, Args&&...);
-
-    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);
-    void didDecodeProperties(unsigned decodedPropertiesSize);
-    void decodedSizeIncreased(unsigned decodedSize);
-    void decodedSizeDecreased(unsigned decodedSize);
-    void decodedSizeReset(unsigned decodedSize);
-
-    void setNativeImage(NativeImagePtr&&);
-    void cacheMetadataAtIndex(size_t, SubsamplingLevel, DecodingStatus = DecodingStatus::Invalid);
-    void cacheNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&, DecodingStatus = DecodingStatus::Invalid);
-    void cacheNativeImageAtIndexAsync(NativeImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&, DecodingStatus);
-
-    struct ImageFrameRequest;
-    static const int BufferSize = 8;
-    WorkQueue& decodingQueue();
-    SynchronizedFixedQueue<ImageFrameRequest, BufferSize>& frameRequestQueue();
-
-    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.
-    struct ImageFrameRequest {
-        size_t index;
-        SubsamplingLevel subsamplingLevel;
-        DecodingOptions decodingOptions;
-        DecodingStatus decodingStatus;
-        bool operator==(const ImageFrameRequest& other) const
-        {
-            return index == other.index && subsamplingLevel == other.subsamplingLevel && decodingOptions == other.decodingOptions && decodingStatus == other.decodingStatus;
-        }
-    };
-    using FrameRequestQueue = SynchronizedFixedQueue<ImageFrameRequest, BufferSize>;
-    using FrameCommitQueue = Deque<ImageFrameRequest, BufferSize>;
-    RefPtr<FrameRequestQueue> m_frameRequestQueue;
-    FrameCommitQueue m_frameCommitQueue;
-    RefPtr<WorkQueue> m_decodingQueue;
-
-    // Image metadata.
-    std::optional<EncodedDataStatus> m_encodedDataStatus;
-    std::optional<size_t> m_frameCount;
-    std::optional<RepetitionCount> m_repetitionCount;
-    std::optional<String> m_uti;
-    std::optional<String> m_filenameExtension;
-    std::optional<std::optional<IntPoint>> m_hotSpot;
-
-    // Image metadata which is calculated from the first ImageFrame.
-    std::optional<IntSize> m_size;
-    std::optional<IntSize> m_sizeRespectingOrientation;
-    std::optional<Color> m_singlePixelSolidColor;
-    std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
-};
-    
-}

Copied: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (from rev 225427, trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp) (0 => 225428)


--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2017-12-02 00:01:54 UTC (rev 225428)
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
+ *
+ * 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 "Image.h"
+#include "ImageObserver.h"
+#include "Logging.h"
+#include "URL.h"
+#include <wtf/SystemTracing.h>
+
+#if USE(CG)
+#include "ImageDecoderCG.h"
+#elif USE(DIRECT2D)
+#include "ImageDecoderDirect2D.h"
+#include <WinCodec.h>
+#else
+#include "ImageDecoder.h"
+#endif
+
+#include <wtf/CheckedArithmetic.h>
+#include <wtf/MainThread.h>
+#include <wtf/RunLoop.h>
+
+namespace WebCore {
+
+ImageSource::ImageSource(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
+    : m_image(image)
+    , m_alphaOption(alphaOption)
+    , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
+{
+}
+
+ImageSource::ImageSource(NativeImagePtr&& nativeImage)
+{
+    m_frameCount = 1;
+    m_encodedDataStatus = EncodedDataStatus::Complete;
+    growFrames();
+
+    setNativeImage(WTFMove(nativeImage));
+
+    m_decodedSize = m_frames[0].frameBytes();
+
+    // The assumption is the memory image will be displayed with the default
+    // orientation. So set m_sizeRespectingOrientation to be the same as m_size.
+    m_size = m_frames[0].size();
+    m_sizeRespectingOrientation = m_size;
+}
+
+ImageSource::~ImageSource()
+{
+    ASSERT(!hasAsyncDecodingQueue());
+}
+
+bool ImageSource::ensureDecoderAvailable(SharedBuffer* data)
+{
+    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();
+    return true;
+}
+
+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;
+    setData(data, isAllDataReceived());
+}
+
+EncodedDataStatus ImageSource::dataChanged(SharedBuffer* data, bool allDataReceived)
+{
+    setData(data, allDataReceived);
+    clearMetadata();
+    EncodedDataStatus status = encodedDataStatus();
+    if (status >= EncodedDataStatus::SizeAvailable)
+        growFrames();
+    return status;
+}
+
+bool ImageSource::isAllDataReceived()
+{
+    return isDecoderAvailable() ? m_decoder->isAllDataReceived() : frameCount();
+}
+
+void ImageSource::destroyDecodedData(size_t frameCount, size_t excludeFrame)
+{
+    unsigned decodedSize = 0;
+
+    ASSERT(frameCount <= m_frames.size());
+
+    for (size_t index = 0; index < frameCount; ++index) {
+        if (index == excludeFrame)
+            continue;
+        decodedSize += m_frames[index].clearImage();
+    }
+
+    decodedSizeReset(decodedSize);
+}
+
+void ImageSource::destroyIncompleteDecodedData()
+{
+    unsigned decodedSize = 0;
+
+    for (auto& frame : m_frames) {
+        if (!frame.hasMetadata() || frame.isComplete())
+            continue;
+
+        decodedSize += frame.clear();
+    }
+
+    decodedSizeDecreased(decodedSize);
+}
+
+void ImageSource::clearFrameBufferCache(size_t beforeFrame)
+{
+    if (!isDecoderAvailable())
+        return;
+    m_decoder->clearFrameBufferCache(beforeFrame);
+}
+
+void ImageSource::decodedSizeChanged(long long decodedSize)
+{
+    if (!decodedSize || !m_image || !m_image->imageObserver())
+        return;
+
+    m_image->imageObserver()->decodedSizeChanged(*m_image, decodedSize);
+}
+
+void ImageSource::decodedSizeIncreased(unsigned decodedSize)
+{
+    if (!decodedSize)
+        return;
+
+    m_decodedSize += decodedSize;
+
+    // The fully-decoded frame will subsume the partially decoded data used
+    // to determine image properties.
+    long long changeSize = static_cast<long long>(decodedSize) - m_decodedPropertiesSize;
+    m_decodedPropertiesSize = 0;
+    decodedSizeChanged(changeSize);
+}
+
+void ImageSource::decodedSizeDecreased(unsigned decodedSize)
+{
+    if (!decodedSize)
+        return;
+
+    ASSERT(m_decodedSize >= decodedSize);
+    m_decodedSize -= decodedSize;
+    decodedSizeChanged(-static_cast<long long>(decodedSize));
+}
+
+void ImageSource::decodedSizeReset(unsigned decodedSize)
+{
+    ASSERT(m_decodedSize >= decodedSize);
+    m_decodedSize -= decodedSize;
+
+    // Clearing the ImageSource destroys the extra decoded data used for
+    // determining image properties.
+    decodedSize += m_decodedPropertiesSize;
+    m_decodedPropertiesSize = 0;
+    decodedSizeChanged(-static_cast<long long>(decodedSize));
+}
+
+void ImageSource::didDecodeProperties(unsigned decodedPropertiesSize)
+{
+    if (m_decodedSize)
+        return;
+
+    long long decodedSize = static_cast<long long>(decodedPropertiesSize) - m_decodedPropertiesSize;
+    m_decodedPropertiesSize = decodedPropertiesSize;
+    decodedSizeChanged(decodedSize);
+}
+
+void ImageSource::growFrames()
+{
+    ASSERT(isSizeAvailable());
+    auto newSize = frameCount();
+    if (newSize > m_frames.size())
+        m_frames.grow(newSize);
+}
+
+void ImageSource::setNativeImage(NativeImagePtr&& nativeImage)
+{
+    ASSERT(m_frames.size() == 1);
+    ImageFrame& frame = m_frames[0];
+
+    ASSERT(!isDecoderAvailable());
+
+    frame.m_nativeImage = WTFMove(nativeImage);
+
+    frame.m_decodingStatus = DecodingStatus::Complete;
+    frame.m_size = nativeImageSize(frame.m_nativeImage);
+    frame.m_hasAlpha = nativeImageHasAlpha(frame.m_nativeImage);
+}
+
+void ImageSource::cacheMetadataAtIndex(size_t index, SubsamplingLevel subsamplingLevel, DecodingStatus decodingStatus)
+{
+    ASSERT(index < m_frames.size());
+    ImageFrame& frame = m_frames[index];
+
+    ASSERT(isDecoderAvailable());
+    if (decodingStatus == DecodingStatus::Invalid)
+        frame.m_decodingStatus = m_decoder->frameIsCompleteAtIndex(index) ? DecodingStatus::Complete : DecodingStatus::Partial;
+    else
+        frame.m_decodingStatus = decodingStatus;
+
+    if (frame.hasMetadata())
+        return;
+
+    frame.m_subsamplingLevel = subsamplingLevel;
+
+    if (frame.m_decodingOptions.hasSizeForDrawing()) {
+        ASSERT(frame.hasNativeImage());
+        frame.m_size = nativeImageSize(frame.nativeImage());
+    } else
+        frame.m_size = m_decoder->frameSizeAtIndex(index, subsamplingLevel);
+
+    frame.m_orientation = m_decoder->frameOrientationAtIndex(index);
+    frame.m_hasAlpha = m_decoder->frameHasAlphaAtIndex(index);
+
+    if (repetitionCount())
+        frame.m_duration = m_decoder->frameDurationAtIndex(index);
+}
+
+void ImageSource::cacheNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions, DecodingStatus decodingStatus)
+{
+    ASSERT(index < m_frames.size());
+    ImageFrame& frame = m_frames[index];
+
+    // Clear the current image frame and update the observer with this clearance.
+    decodedSizeDecreased(frame.clear());
+
+    // Do not cache the NativeImage if adding its frameByes to the MemoryCache will cause numerical overflow.
+    size_t frameBytes = size().unclampedArea() * sizeof(RGBA32);
+    if (!WTF::isInBounds<unsigned>(frameBytes + decodedSize()))
+        return;
+
+    // Move the new image to the cache.
+    frame.m_nativeImage = WTFMove(nativeImage);
+    frame.m_decodingOptions = decodingOptions;
+    cacheMetadataAtIndex(index, subsamplingLevel, decodingStatus);
+
+    // Update the observer with the new image frame bytes.
+    decodedSizeIncreased(frame.frameBytes());
+}
+
+void ImageSource::cacheNativeImageAtIndexAsync(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions, DecodingStatus decodingStatus)
+{
+    if (!isDecoderAvailable())
+        return;
+
+    ASSERT(index < m_frames.size());
+
+    // Clean the old native image and set a new one
+    cacheNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, decodingOptions, decodingStatus);
+    LOG(Images, "ImageSource::%s - %p - url: %s [frame %ld has been cached]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
+
+    // Notify the image with the readiness of the new frame NativeImage.
+    if (m_image)
+        m_image->imageFrameAvailableAtIndex(index);
+}
+
+WorkQueue& ImageSource::decodingQueue()
+{
+    if (!m_decodingQueue)
+        m_decodingQueue = WorkQueue::create("org.webkit.ImageDecoder", WorkQueue::Type::Serial, WorkQueue::QOS::Default);
+
+    return *m_decodingQueue;
+}
+
+ImageSource::FrameRequestQueue& ImageSource::frameRequestQueue()
+{
+    if (!m_frameRequestQueue)
+        m_frameRequestQueue = FrameRequestQueue::create();
+
+    return *m_frameRequestQueue;
+}
+
+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);
+}
+
+void ImageSource::startAsyncDecodingQueue()
+{
+    if (hasAsyncDecodingQueue() || !isDecoderAvailable())
+        return;
+
+    // We need to protect this, m_decodingQueue and m_decoder from being deleted while we are in the decoding loop.
+    decodingQueue().dispatch([protectedThis = makeRef(*this), protectedDecodingQueue = makeRef(decodingQueue()), protectedFrameRequestQueue = makeRef(frameRequestQueue()), protectedDecoder = makeRef(*m_decoder), sourceURL = sourceURL().string().isolatedCopy()] {
+        ImageFrameRequest frameRequest;
+
+        while (protectedFrameRequestQueue->dequeue(frameRequest)) {
+            TraceScope tracingScope(AsyncImageDecodeStart, AsyncImageDecodeEnd);
+
+            // Get the frame NativeImage on the decoding thread.
+            NativeImagePtr nativeImage = protectedDecoder->createFrameImageAtIndex(frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions);
+            if (nativeImage)
+                LOG(Images, "ImageSource::%s - %p - url: %s [frame %ld has been decoded]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
+            else {
+                LOG(Images, "ImageSource::%s - %p - url: %s [decoding for frame %ld has failed]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
+                continue;
+            }
+
+            // Update the cached frames on the main thread to avoid updating the MemoryCache from a different thread.
+            callOnMainThread([protectedThis = protectedThis.copyRef(), protectedQueue = protectedDecodingQueue.copyRef(), protectedDecoder = protectedDecoder.copyRef(), sourceURL = sourceURL.isolatedCopy(), nativeImage = WTFMove(nativeImage), frameRequest] () mutable {
+                // The queue may have been closed if after we got the frame NativeImage, stopAsyncDecodingQueue() was called.
+                if (protectedQueue.ptr() == protectedThis->m_decodingQueue && protectedDecoder.ptr() == protectedThis->m_decoder) {
+                    ASSERT(protectedThis->m_frameCommitQueue.first() == frameRequest);
+                    protectedThis->m_frameCommitQueue.removeFirst();
+                    protectedThis->cacheNativeImageAtIndexAsync(WTFMove(nativeImage), frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions, frameRequest.decodingStatus);
+                } else
+                    LOG(Images, "ImageSource::%s - %p - url: %s [frame %ld will not cached]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
+            });
+        }
+    });
+}
+
+void ImageSource::requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing)
+{
+    ASSERT(isDecoderAvailable());
+    if (!hasAsyncDecodingQueue())
+        startAsyncDecodingQueue();
+
+    ASSERT(index < m_frames.size());
+    DecodingStatus decodingStatus = m_decoder->frameIsCompleteAtIndex(index) ? DecodingStatus::Complete : DecodingStatus::Partial;
+
+    LOG(Images, "ImageSource::%s - %p - url: %s [enqueuing frame %ld for decoding]", __FUNCTION__, this, sourceURL().string().utf8().data(), index);
+    m_frameRequestQueue->enqueue({ index, subsamplingLevel, sizeForDrawing, decodingStatus });
+    m_frameCommitQueue.append({ index, subsamplingLevel, sizeForDrawing, decodingStatus });
+}
+
+bool ImageSource::isAsyncDecodingQueueIdle() const
+{
+    return m_frameCommitQueue.isEmpty();
+}
+
+void ImageSource::stopAsyncDecodingQueue()
+{
+    if (!hasAsyncDecodingQueue())
+        return;
+
+    std::for_each(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [this](const ImageFrameRequest& frameRequest) {
+        ImageFrame& frame = m_frames[frameRequest.index];
+        if (!frame.isInvalid()) {
+            LOG(Images, "ImageSource::%s - %p - url: %s [decoding has been cancelled for frame %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), frameRequest.index);
+            frame.clear();
+        }
+    });
+
+    // Close m_frameRequestQueue then set it to nullptr. A new decoding thread might start and a
+    // new m_frameRequestQueue will be created. So the terminating thread will not have access to it.
+    m_frameRequestQueue->close();
+    m_frameRequestQueue = nullptr;
+    m_frameCommitQueue.clear();
+    m_decodingQueue = nullptr;
+    LOG(Images, "ImageSource::%s - %p - url: %s [decoding has been stopped]", __FUNCTION__, this, sourceURL().string().utf8().data());
+}
+
+const ImageFrame& ImageSource::frameAtIndexCacheIfNeeded(size_t index, ImageFrame::Caching caching, const std::optional<SubsamplingLevel>& subsamplingLevel)
+{
+    ASSERT(index < m_frames.size());
+    ImageFrame& frame = m_frames[index];
+    if (!isDecoderAvailable() || frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, DecodingMode::Asynchronous))
+        return frame;
+
+    SubsamplingLevel subsamplingLevelValue = subsamplingLevel ? subsamplingLevel.value() : frame.subsamplingLevel();
+
+    switch (caching) {
+    case ImageFrame::Caching::Metadata:
+        // Retrieve the metadata from ImageDecoder if the ImageFrame isn't complete.
+        if (frame.isComplete())
+            break;
+        cacheMetadataAtIndex(index, subsamplingLevelValue);
+        break;
+
+    case ImageFrame::Caching::MetadataAndImage:
+        // Cache the image and retrieve the metadata from ImageDecoder only if there was not valid image stored.
+        if (frame.hasFullSizeNativeImage(subsamplingLevel))
+            break;
+        // We have to perform synchronous image decoding in this code.
+        NativeImagePtr nativeImage = m_decoder->createFrameImageAtIndex(index, subsamplingLevelValue);
+        // Clean the old native image and set a new one.
+        cacheNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevelValue, DecodingMode::Synchronous);
+        break;
+    }
+
+    return frame;
+}
+
+void ImageSource::clearMetadata()
+{
+    m_frameCount = std::nullopt;
+    m_repetitionCount = std::nullopt;
+    m_singlePixelSolidColor = std::nullopt;
+    m_encodedDataStatus = std::nullopt;
+    m_uti = std::nullopt;
+}
+
+URL ImageSource::sourceURL() const
+{
+    return m_image ? m_image->sourceURL() : URL();
+}
+
+String ImageSource::mimeType() const
+{
+    return m_image ? m_image->mimeType() : emptyString();
+}
+
+long long ImageSource::expectedContentLength() const
+{
+    return m_image ? m_image->expectedContentLength() : 0;
+}
+
+template<typename T, T (ImageDecoder::*functor)() const>
+T ImageSource::metadata(const T& defaultValue, std::optional<T>* cachedValue)
+{
+    if (cachedValue && *cachedValue)
+        return cachedValue->value();
+
+    if (!isDecoderAvailable() || !m_decoder->isSizeAvailable())
+        return defaultValue;
+
+    if (!cachedValue)
+        return (*m_decoder.*functor)();
+
+    *cachedValue = (*m_decoder.*functor)();
+    didDecodeProperties(m_decoder->bytesDecodedToDetermineProperties());
+    return cachedValue->value();
+}
+
+template<typename T, typename... Args>
+T ImageSource::frameMetadataAtIndex(size_t index, T (ImageFrame::*functor)(Args...) const, Args&&... args)
+{
+    const ImageFrame& frame = index < m_frames.size() ? m_frames[index] : ImageFrame::defaultFrame();
+    return (frame.*functor)(std::forward<Args>(args)...);
+}
+
+template<typename T, typename... Args>
+T ImageSource::frameMetadataAtIndexCacheIfNeeded(size_t index, T (ImageFrame::*functor)() const, std::optional<T>* cachedValue, Args&&... args)
+{
+    if (cachedValue && *cachedValue)
+        return cachedValue->value();
+
+    const ImageFrame& frame = index < m_frames.size() ? frameAtIndexCacheIfNeeded(index, std::forward<Args>(args)...) : ImageFrame::defaultFrame();
+
+    // Don't cache any unavailable frame metadata.
+    if (!frame.hasMetadata() || !cachedValue)
+        return (frame.*functor)();
+
+    *cachedValue = (frame.*functor)();
+    return cachedValue->value();
+}
+
+EncodedDataStatus ImageSource::encodedDataStatus()
+{
+    return metadata<EncodedDataStatus, (&ImageDecoder::encodedDataStatus)>(EncodedDataStatus::Unknown, &m_encodedDataStatus);
+}
+
+size_t ImageSource::frameCount()
+{
+    return metadata<size_t, (&ImageDecoder::frameCount)>(m_frames.size(), &m_frameCount);
+}
+
+RepetitionCount ImageSource::repetitionCount()
+{
+    return metadata<RepetitionCount, (&ImageDecoder::repetitionCount)>(RepetitionCountNone, &m_repetitionCount);
+}
+
+String ImageSource::uti()
+{
+#if USE(CG)
+    return metadata<String, (&ImageDecoder::uti)>(String(), &m_uti);
+#else
+    return String();
+#endif
+}
+
+String ImageSource::filenameExtension()
+{
+    return metadata<String, (&ImageDecoder::filenameExtension)>(String(), &m_filenameExtension);
+}
+
+std::optional<IntPoint> ImageSource::hotSpot()
+{
+    return metadata<std::optional<IntPoint>, (&ImageDecoder::hotSpot)>(std::nullopt, &m_hotSpot);
+}
+
+IntSize ImageSource::size()
+{
+#if !USE(CG)
+    // It's possible that we have decoded the metadata, but not frame contents yet. In that case ImageDecoder claims to
+    // have the size available, but the frame cache is empty. Return the decoder size without caching in such case.
+    if (m_frames.isEmpty() && isDecoderAvailable())
+        return m_decoder->size();
+#endif
+    return frameMetadataAtIndexCacheIfNeeded<IntSize>(0, (&ImageFrame::size), &m_size, ImageFrame::Caching::Metadata, SubsamplingLevel::Default);
+}
+
+IntSize ImageSource::sizeRespectingOrientation()
+{
+    return frameMetadataAtIndexCacheIfNeeded<IntSize>(0, (&ImageFrame::sizeRespectingOrientation), &m_sizeRespectingOrientation, ImageFrame::Caching::Metadata, SubsamplingLevel::Default);
+}
+
+Color ImageSource::singlePixelSolidColor()
+{
+    if (!m_singlePixelSolidColor && (size() != IntSize(1, 1) || frameCount() != 1))
+        m_singlePixelSolidColor = Color();
+
+    if (m_singlePixelSolidColor)
+        return m_singlePixelSolidColor.value();
+
+    return frameMetadataAtIndexCacheIfNeeded<Color>(0, (&ImageFrame::singlePixelSolidColor), &m_singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage);
+}
+
+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();
+}
+
+bool ImageSource::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions)
+{
+    auto it = std::find_if(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [index, &decodingOptions](const ImageFrameRequest& frameRequest) {
+        return frameRequest.index == index && frameRequest.decodingOptions.isAsynchronousCompatibleWith(decodingOptions);
+    });
+    return it != m_frameCommitQueue.end();
+}
+
+DecodingStatus ImageSource::frameDecodingStatusAtIndex(size_t index)
+{
+    return frameMetadataAtIndex<DecodingStatus>(index, (&ImageFrame::decodingStatus));
+}
+
+bool ImageSource::frameHasAlphaAtIndex(size_t index)
+{
+    return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasAlpha));
+}
+
+bool ImageSource::frameHasFullSizeNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel)
+{
+    return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasFullSizeNativeImage), subsamplingLevel);
+}
+
+bool ImageSource::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions)
+{
+    return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasDecodedNativeImageCompatibleWithOptions), subsamplingLevel, decodingOptions);
+}
+
+SubsamplingLevel ImageSource::frameSubsamplingLevelAtIndex(size_t index)
+{
+    return frameMetadataAtIndex<SubsamplingLevel>(index, (&ImageFrame::subsamplingLevel));
+}
+
+IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+{
+    return frameMetadataAtIndexCacheIfNeeded<IntSize>(index, (&ImageFrame::size), nullptr, ImageFrame::Caching::Metadata, subsamplingLevel);
+}
+
+unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+{
+    return frameMetadataAtIndexCacheIfNeeded<unsigned>(index, (&ImageFrame::frameBytes), nullptr, ImageFrame::Caching::Metadata, subsamplingLevel);
+}
+
+Seconds ImageSource::frameDurationAtIndex(size_t index)
+{
+    return frameMetadataAtIndexCacheIfNeeded<Seconds>(index, (&ImageFrame::duration), nullptr, ImageFrame::Caching::Metadata);
+}
+
+ImageOrientation ImageSource::frameOrientationAtIndex(size_t index)
+{
+    return frameMetadataAtIndexCacheIfNeeded<ImageOrientation>(index, (&ImageFrame::orientation), nullptr, ImageFrame::Caching::Metadata);
+}
+
+#if USE(DIRECT2D)
+void ImageSource::setTargetContext(const GraphicsContext* targetContext)
+{
+    if (isDecoderAvailable() && targetContext)
+        m_decoder->setTargetContext(targetContext->platformContext())
+}
+#endif
+
+NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+{
+    return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
+}
+
+NativeImagePtr ImageSource::frameImageAtIndex(size_t index)
+{
+    return frameMetadataAtIndex<NativeImagePtr>(index, (&ImageFrame::nativeImage));
+}
+
+NativeImagePtr ImageSource::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel)
+{
+    return frameMetadataAtIndexCacheIfNeeded<NativeImagePtr>(index, (&ImageFrame::nativeImage), nullptr, ImageFrame::Caching::MetadataAndImage, 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);
+}
+
+}

Copied: trunk/Source/WebCore/platform/graphics/ImageSource.h (from rev 225427, trunk/Source/WebCore/platform/graphics/ImageFrameCache.h) (0 => 225428)


--- trunk/Source/WebCore/platform/graphics/ImageSource.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h	2017-12-02 00:01:54 UTC (rev 225428)
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
+ *
+ * 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 <wtf/Forward.h>
+#include <wtf/Optional.h>
+#include <wtf/SynchronizedFixedQueue.h>
+#include <wtf/WorkQueue.h>
+#include <wtf/text/TextStream.h>
+
+namespace WebCore {
+
+class GraphicsContext;
+class Image;
+class ImageDecoder;
+class URL;
+
+class ImageSource : public ThreadSafeRefCounted<ImageSource> {
+    friend class BitmapImage;
+public:
+    ImageSource(Image*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
+    ImageSource(NativeImagePtr&&);
+    ~ImageSource();
+
+    static Ref<ImageSource> create(Image* image, AlphaOption alphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption gammaAndColorProfileOption = GammaAndColorProfileOption::Applied)
+    {
+        return adoptRef(*new ImageSource(image, alphaOption, gammaAndColorProfileOption));
+    }
+
+    static Ref<ImageSource> create(NativeImagePtr&& nativeImage)
+    {
+        return adoptRef(*new ImageSource(WTFMove(nativeImage)));
+    }
+
+    void setData(SharedBuffer* data, bool allDataReceived);
+    void resetData(SharedBuffer* data);
+    EncodedDataStatus dataChanged(SharedBuffer* data, bool allDataReceived);
+    bool isAllDataReceived();
+
+    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();
+    void clearImage() { m_image = nullptr; }
+    URL sourceURL() const;
+    String mimeType() const;
+    long long expectedContentLength() const;
+
+    // Asynchronous image decoding
+    bool canUseAsyncDecoding();
+    void startAsyncDecodingQueue();
+    void requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>& = { });
+    void stopAsyncDecodingQueue();
+    bool hasAsyncDecodingQueue() const { return m_decodingQueue; }
+    bool isAsyncDecodingQueueIdle() const;
+
+    // Image metadata which is calculated either by the ImageDecoder or directly
+    // from the NativeImage if this class was created for a memory image.
+    EncodedDataStatus encodedDataStatus();
+    bool isSizeAvailable() { return encodedDataStatus() >= EncodedDataStatus::SizeAvailable; }
+    size_t frameCount();
+    RepetitionCount repetitionCount();
+    String uti();
+    String filenameExtension();
+    std::optional<IntPoint> hotSpot();
+
+    // 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&);
+    DecodingStatus frameDecodingStatusAtIndex(size_t);
+    bool frameHasAlphaAtIndex(size_t);
+    bool frameHasImageAtIndex(size_t);
+    bool frameHasFullSizeNativeImageAtIndex(size_t, const std::optional<SubsamplingLevel>&);
+    bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t, const std::optional<SubsamplingLevel>&, const DecodingOptions&);
+    SubsamplingLevel frameSubsamplingLevelAtIndex(size_t);
+
+    // ImageFrame metadata which forces caching or re-caching the ImageFrame.
+    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
+    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
+    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 = SubsamplingLevel::Default);
+
+private:
+    template<typename T, T (ImageDecoder::*functor)() const>
+    T metadata(const T& defaultValue, std::optional<T>* cachedValue = nullptr);
+
+    template<typename T, typename... Args>
+    T frameMetadataAtIndex(size_t, T (ImageFrame::*functor)(Args...) const, Args&&...);
+
+    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);
+    void didDecodeProperties(unsigned decodedPropertiesSize);
+    void decodedSizeIncreased(unsigned decodedSize);
+    void decodedSizeDecreased(unsigned decodedSize);
+    void decodedSizeReset(unsigned decodedSize);
+
+    void setNativeImage(NativeImagePtr&&);
+    void cacheMetadataAtIndex(size_t, SubsamplingLevel, DecodingStatus = DecodingStatus::Invalid);
+    void cacheNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&, DecodingStatus = DecodingStatus::Invalid);
+    void cacheNativeImageAtIndexAsync(NativeImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&, DecodingStatus);
+
+    struct ImageFrameRequest;
+    static const int BufferSize = 8;
+    WorkQueue& decodingQueue();
+    SynchronizedFixedQueue<ImageFrameRequest, BufferSize>& frameRequestQueue();
+
+    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.
+    struct ImageFrameRequest {
+        size_t index;
+        SubsamplingLevel subsamplingLevel;
+        DecodingOptions decodingOptions;
+        DecodingStatus decodingStatus;
+        bool operator==(const ImageFrameRequest& other) const
+        {
+            return index == other.index && subsamplingLevel == other.subsamplingLevel && decodingOptions == other.decodingOptions && decodingStatus == other.decodingStatus;
+        }
+    };
+    using FrameRequestQueue = SynchronizedFixedQueue<ImageFrameRequest, BufferSize>;
+    using FrameCommitQueue = Deque<ImageFrameRequest, BufferSize>;
+    RefPtr<FrameRequestQueue> m_frameRequestQueue;
+    FrameCommitQueue m_frameCommitQueue;
+    RefPtr<WorkQueue> m_decodingQueue;
+
+    // Image metadata.
+    std::optional<EncodedDataStatus> m_encodedDataStatus;
+    std::optional<size_t> m_frameCount;
+    std::optional<RepetitionCount> m_repetitionCount;
+    std::optional<String> m_uti;
+    std::optional<String> m_filenameExtension;
+    std::optional<std::optional<IntPoint>> m_hotSpot;
+
+    // Image metadata which is calculated from the first ImageFrame.
+    std::optional<IntSize> m_size;
+    std::optional<IntSize> m_sizeRespectingOrientation;
+    std::optional<Color> m_singlePixelSolidColor;
+    std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
+};
+
+}

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


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp	2017-12-02 00:01:54 UTC (rev 225428)
@@ -35,7 +35,7 @@
 #include "CairoUtilities.h"
 #include "GraphicsContext3DPrivate.h"
 #include "Image.h"
-#include "ImageFrameCache.h"
+#include "ImageSource.h"
 #include "NotImplemented.h"
 #include "PlatformContextCairo.h"
 #include "RefPtrCairo.h"
@@ -286,14 +286,14 @@
     // 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;
-    ImageFrameCache decoder(nullptr, alphaOption, gammaAndColorProfileOption);
+    ImageSource source(nullptr, alphaOption, gammaAndColorProfileOption);
     m_alphaOp = AlphaDoNothing;
 
     if (m_image->data()) {
-        decoder.setData(m_image->data(), true);
-        if (!decoder.frameCount())
+        source.setData(m_image->data(), true);
+        if (!source.frameCount())
             return false;
-        m_imageSurface = decoder.createFrameImageAtIndex(0);
+        m_imageSurface = source.createFrameImageAtIndex(0);
     } else {
         m_imageSurface = m_image->nativeImageForCurrentFrame();
         // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel,

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


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp	2017-12-02 00:00:40 UTC (rev 225427)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp	2017-12-02 00:01:54 UTC (rev 225428)
@@ -325,12 +325,12 @@
         return false;
     bool hasAlpha = !m_image->currentFrameKnownToBeOpaque();
     if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
-        ImageFrameCache decoder(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
-        decoder.setData(m_image->data(), true);
-        if (!decoder.frameCount())
+        ImageSource source(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
+        source.setData(m_image->data(), true);
+        if (!source.frameCount())
             return false;
 
-        m_decodedImage = decoder.createFrameImageAtIndex(0);
+        m_decodedImage = source.createFrameImageAtIndex(0);
         m_cgImage = m_decodedImage;
     } else
         m_cgImage = m_image->nativeImageForCurrentFrame();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to