Diff
Modified: trunk/Source/WebCore/ChangeLog (225299 => 225300)
--- trunk/Source/WebCore/ChangeLog 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/ChangeLog 2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,3 +1,70 @@
+2017-11-29 Said Abou-Hallawa <sabouhall...@apple.com>
+
+ Remove the ImageSource from the class hierarchy that connects BitmapImage to ImageFrame
+ https://bugs.webkit.org/show_bug.cgi?id=175595
+
+ Reviewed by Darin Adler.
+
+ The class hierarchy that connects BitmapImage to ImageFrame has been
+ troublesome. ImageSource does not have a clear responsibility other than
+ a bridge that connects BitmapIamge to ImageFrameCache. Sharing the
+ ImageDecoder between ImageSource and ImageFrameCache is ugly and caused
+ few crashes in the past.
+
+ This patch will do the first step for fixing this issue. First get rid of
+ ImageSource by moving its APIs to ImageFrameCache and BitmapImage. Replace
+ all the instances of ImageSource by ImageFrameCache. The next step will
+ be to rename ImageFrameCache to ImageSource. But this will be done in a
+ follow-up patch
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ (WebCore::BitmapImage::~BitmapImage):
+ (WebCore::BitmapImage::destroyDecodedData):
+ (WebCore::BitmapImage::destroyDecodedDataIfNecessary):
+ (WebCore::BitmapImage::dataChanged):
+ (WebCore::BitmapImage::frameImageAtIndexCacheIfNeeded):
+ (WebCore::BitmapImage::draw):
+ (WebCore::BitmapImage::canUseAsyncDecodingForLargeImages const):
+ (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages const):
+ (WebCore::BitmapImage::subsamplingLevelForScaleFactor):
+ (WebCore::BitmapImage::canDestroyDecodedData):
+ (WebCore::BitmapImage::internalStartAnimation):
+ (WebCore::BitmapImage::stopAnimation):
+ (WebCore::BitmapImage::decode):
+ (WebCore::BitmapImage::imageFrameAvailableAtIndex):
+ (WebCore::BitmapImage::dump const):
+ * platform/graphics/BitmapImage.h:
+ * platform/graphics/GraphicsContext3D.h:
+ * platform/graphics/ImageFrameCache.cpp:
+ (WebCore::ImageFrameCache::ImageFrameCache):
+ (WebCore::ImageFrameCache::ensureDecoderAvailable):
+ (WebCore::ImageFrameCache::setData):
+ (WebCore::ImageFrameCache::resetData):
+ (WebCore::ImageFrameCache::dataChanged):
+ (WebCore::ImageFrameCache::isAllDataReceived):
+ (WebCore::ImageFrameCache::clearFrameBufferCache):
+ (WebCore::ImageFrameCache::canUseAsyncDecoding):
+ (WebCore::ImageFrameCache::maximumSubsamplingLevel):
+ (WebCore::ImageFrameCache::setTargetContext):
+ (WebCore::ImageFrameCache::createFrameImageAtIndex):
+ (WebCore::ImageFrameCache::dump):
+ (WebCore::ImageFrameCache::setDecoder): Deleted.
+ (WebCore::ImageFrameCache::decoder const): Deleted.
+ * platform/graphics/ImageFrameCache.h:
+ (WebCore::ImageFrameCache::create):
+ (WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex):
+ * platform/graphics/ImageSource.cpp: Removed.
+ * platform/graphics/ImageSource.h: Removed.
+ * platform/graphics/cairo/GraphicsContext3DCairo.cpp:
+ (WebCore::GraphicsContext3D::ImageExtractor::~ImageExtractor):
+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+ * platform/graphics/cg/GraphicsContext3DCG.cpp:
+ (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+ * platform/graphics/cg/ImageSourceCG.h:
+
2017-11-29 Brady Eidson <beid...@apple.com>
When managing context startups, make ServiceWorkerJobDataIdentifier's optional.
Modified: trunk/Source/WebCore/Sources.txt (225299 => 225300)
--- trunk/Source/WebCore/Sources.txt 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/Sources.txt 2017-11-29 23:23:54 UTC (rev 225300)
@@ -1526,7 +1526,6 @@
platform/graphics/ImageFrame.cpp
platform/graphics/ImageFrameCache.cpp
platform/graphics/ImageOrientation.cpp
-platform/graphics/ImageSource.cpp
platform/graphics/IntPoint.cpp
platform/graphics/IntRect.cpp
platform/graphics/IntSize.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (225299 => 225300)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-11-29 23:23:54 UTC (rev 225300)
@@ -3279,7 +3279,6 @@
B275356D0B053814002CE64F /* FloatSize.h in Headers */ = {isa = PBXBuildFile; fileRef = B275353F0B053814002CE64F /* FloatSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
B275356E0B053814002CE64F /* Icon.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535400B053814002CE64F /* Icon.h */; settings = {ATTRIBUTES = (Private, ); }; };
B27535700B053814002CE64F /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535420B053814002CE64F /* Image.h */; settings = {ATTRIBUTES = (Private, ); }; };
- B27535710B053814002CE64F /* ImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535430B053814002CE64F /* ImageSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
B27535720B053814002CE64F /* IntPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535440B053814002CE64F /* IntPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
B27535740B053814002CE64F /* IntRect.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535460B053814002CE64F /* IntRect.h */; settings = {ATTRIBUTES = (Private, ); }; };
B27535750B053814002CE64F /* IntSize.h in Headers */ = {isa = PBXBuildFile; fileRef = B27535470B053814002CE64F /* IntSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5367,7 +5366,6 @@
0F17747F1378B772009DA76A /* ScrollAnimatorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollAnimatorIOS.mm; sourceTree = "<group>"; };
0F36E7361BD1837A002DB891 /* LayoutPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutPoint.cpp; sourceTree = "<group>"; };
0F36E7381BD184B9002DB891 /* LayoutSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutSize.cpp; sourceTree = "<group>"; };
- 0F3C725D1974874B00AEDD0C /* ImageSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageSource.cpp; sourceTree = "<group>"; };
0F3DD44D12F5EA1B000D9190 /* ShadowBlur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowBlur.cpp; sourceTree = "<group>"; };
0F3DD44E12F5EA1B000D9190 /* ShadowBlur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowBlur.h; sourceTree = "<group>"; };
0F3F0E57157030C3006DA57F /* RenderGeometryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderGeometryMap.cpp; sourceTree = "<group>"; };
@@ -11743,7 +11741,6 @@
B27535400B053814002CE64F /* Icon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Icon.h; sourceTree = "<group>"; };
B27535410B053814002CE64F /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
B27535420B053814002CE64F /* Image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
- B27535430B053814002CE64F /* ImageSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageSource.h; sourceTree = "<group>"; };
B27535440B053814002CE64F /* IntPoint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntPoint.h; sourceTree = "<group>"; };
B27535450B053814002CE64F /* IntRect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IntRect.cpp; sourceTree = "<group>"; };
B27535460B053814002CE64F /* IntRect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntRect.h; sourceTree = "<group>"; };
@@ -22717,8 +22714,6 @@
A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
A8748D6612CC3763001FBA41 /* ImageOrientation.h */,
49291E4A134172C800E753DE /* ImageRenderingMode.h */,
- 0F3C725D1974874B00AEDD0C /* ImageSource.cpp */,
- B27535430B053814002CE64F /* ImageSource.h */,
5550CB411E955E3C00111AA0 /* ImageTypes.h */,
07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */,
07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */,
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2017-11-29 23:23:54 UTC (rev 225300)
@@ -39,18 +39,21 @@
#include <wtf/Vector.h>
#include <wtf/text/TextStream.h>
#include <wtf/text/WTFString.h>
+#if USE(CG) && PLATFORM(WIN)
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#endif
namespace WebCore {
BitmapImage::BitmapImage(ImageObserver* observer)
: Image(observer)
- , m_source(this)
+ , m_source(ImageFrameCache::create(this))
{
}
BitmapImage::BitmapImage(NativeImagePtr&& image, ImageObserver* observer)
: Image(observer)
- , m_source(WTFMove(image))
+ , m_source(ImageFrameCache::create(WTFMove(image)))
{
}
@@ -58,8 +61,8 @@
{
invalidatePlatformData();
clearTimer();
- m_source.clearImage();
- m_source.stopAsyncDecodingQueue();
+ m_source->clearImage();
+ m_source->stopAsyncDecodingQueue();
}
void BitmapImage::updateFromSettings(const Settings& settings)
@@ -74,20 +77,20 @@
LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().string().utf8().data());
if (!destroyAll)
- m_source.destroyDecodedDataBeforeFrame(m_currentFrame);
+ m_source->destroyDecodedDataBeforeFrame(m_currentFrame);
else if (!canDestroyDecodedData())
- m_source.destroyAllDecodedDataExcludeFrame(m_currentFrame);
+ m_source->destroyAllDecodedDataExcludeFrame(m_currentFrame);
else {
- m_source.destroyAllDecodedData();
+ m_source->destroyAllDecodedData();
m_currentFrameDecodingStatus = DecodingStatus::Invalid;
}
// There's no need to throw away the decoder unless we're explicitly asked
// to destroy all of the frames.
- if (!destroyAll || m_source.hasAsyncDecodingQueue())
- m_source.clearFrameBufferCache(m_currentFrame);
+ if (!destroyAll || m_source->hasAsyncDecodingQueue())
+ m_source->clearFrameBufferCache(m_currentFrame);
else
- m_source.resetData(data());
+ m_source->resetData(data());
invalidatePlatformData();
}
@@ -99,7 +102,7 @@
if (!data() && frameCount())
return;
- if (m_source.decodedSize() < LargeAnimationCutoff)
+ if (m_source->decodedSize() < LargeAnimationCutoff)
return;
destroyDecodedData(destroyAll);
@@ -107,11 +110,11 @@
EncodedDataStatus BitmapImage::dataChanged(bool allDataReceived)
{
- if (m_source.decodedSize() && !canUseAsyncDecodingForLargeImages())
- m_source.destroyIncompleteDecodedData();
+ if (m_source->decodedSize() && !canUseAsyncDecodingForLargeImages())
+ m_source->destroyIncompleteDecodedData();
m_currentFrameDecodingStatus = DecodingStatus::Invalid;
- return m_source.dataChanged(data(), allDataReceived);
+ return m_source->dataChanged(data(), allDataReceived);
}
void BitmapImage::setCurrentFrameDecodingStatusIfNecessary(DecodingStatus decodingStatus)
@@ -130,8 +133,12 @@
LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel was %d, resampling]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(frameSubsamplingLevelAtIndex(index)));
invalidatePlatformData();
}
-
- return m_source.frameImageAtIndexCacheIfNeeded(index, subsamplingLevel, targetContext);
+#if USE(DIRECT2D)
+ m_source->setTargetContext(targetContext);
+#else
+ UNUSED_PARAM(targetContext);
+#endif
+ return m_source->frameImageAtIndexCacheIfNeeded(index, subsamplingLevel);
}
NativeImagePtr BitmapImage::nativeImage(const GraphicsContext* targetContext)
@@ -189,7 +196,7 @@
IntSize sizeForDrawing = expandedIntSize(size() * scaleFactorForDrawing);
ImageDrawResult result = ImageDrawResult::DidDraw;
- m_currentSubsamplingLevel = m_allowSubsampling ? m_source.subsamplingLevelForScaleFactor(context, scaleFactorForDrawing) : SubsamplingLevel::Default;
+ m_currentSubsamplingLevel = m_allowSubsampling ? subsamplingLevelForScaleFactor(context, scaleFactorForDrawing) : SubsamplingLevel::Default;
LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel = %d scaleFactorForDrawing = (%.4f, %.4f)]", __FUNCTION__, this, sourceURL().string().utf8().data(), static_cast<int>(m_currentSubsamplingLevel), scaleFactorForDrawing.width(), scaleFactorForDrawing.height());
NativeImagePtr image;
@@ -204,7 +211,7 @@
// it is currently being decoded. New data may have been received since the previous request was made.
if ((!frameIsCompatible && !frameIsBeingDecoded) || m_currentFrameDecodingStatus == DecodingStatus::Invalid) {
LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().string().utf8().data());
- m_source.requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, sizeForDrawing);
+ m_source->requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, sizeForDrawing);
m_currentFrameDecodingStatus = DecodingStatus::Decoding;
}
@@ -231,7 +238,7 @@
// If the decodingMode changes from asynchronous to synchronous and new data is received,
// the current incomplete decoded frame has to be destroyed.
if (m_currentFrameDecodingStatus == DecodingStatus::Invalid)
- m_source.destroyIncompleteDecodedData();
+ m_source->destroyIncompleteDecodedData();
bool frameIsCompatible = frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingOptions(sizeForDrawing));
bool frameIsBeingDecoded = frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingMode::Asynchronous);
@@ -324,12 +331,12 @@
bool BitmapImage::canUseAsyncDecodingForLargeImages() const
{
- return !canAnimate() && m_source.canUseAsyncDecoding();
+ return !canAnimate() && m_source->canUseAsyncDecoding();
}
bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages() const
{
- return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.canUseAsyncDecoding());
+ return canAnimate() && m_allowAnimatedImageAsyncDecoding && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source->canUseAsyncDecoding());
}
void BitmapImage::clearTimer()
@@ -344,10 +351,30 @@
m_frameTimer->startOneShot(delay);
}
+SubsamplingLevel BitmapImage::subsamplingLevelForScaleFactor(GraphicsContext& context, const FloatSize& scaleFactor)
+{
+#if USE(CG)
+ // Never use subsampled images for drawing into PDF contexts.
+ if (CGContextGetType(context.platformContext()) == kCGContextTypePDF)
+ return SubsamplingLevel::Default;
+
+ float scale = std::min(float(1), std::max(scaleFactor.width(), scaleFactor.height()));
+ if (!(scale > 0 && scale <= 1))
+ return SubsamplingLevel::Default;
+
+ int result = std::ceil(std::log2(1 / scale));
+ return static_cast<SubsamplingLevel>(std::min(result, static_cast<int>(m_source->maximumSubsamplingLevel())));
+#else
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(scaleFactor);
+ return SubsamplingLevel::Default;
+#endif
+}
+
bool BitmapImage::canDestroyDecodedData()
{
// Animated images should preserve the current frame till the next one finishes decoding.
- if (m_source.hasAsyncDecodingQueue())
+ if (m_source->hasAsyncDecodingQueue())
return false;
// Small image should be decoded synchronously. Deleting its decoded frame is fine.
@@ -377,7 +404,7 @@
// yet and our repetition count is potentially unset. The repetition count
// in a GIF can potentially come after all the rest of the image data, so
// wait on it.
- if (!m_source.isAllDataReceived() && repetitionCount() == RepetitionCountOnce)
+ if (!m_source->isAllDataReceived() && repetitionCount() == RepetitionCountOnce)
return StartAnimationStatus::IncompleteData;
++m_repetitionsComplete;
@@ -393,7 +420,7 @@
}
// Don't advance the animation to an incomplete frame.
- if (!m_source.isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame))
+ if (!m_source->isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame))
return StartAnimationStatus::IncompleteData;
MonotonicTime time = MonotonicTime::now();
@@ -413,7 +440,7 @@
if (frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(nextFrame, m_currentSubsamplingLevel, { }))
LOG(Images, "BitmapImage::%s - %p - url: %s [cachedFrameCount = %ld nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), ++m_cachedFrameCount, nextFrame);
else {
- m_source.requestFrameAsyncDecodingAtIndex(nextFrame, m_currentSubsamplingLevel);
+ m_source->requestFrameAsyncDecodingAtIndex(nextFrame, m_currentSubsamplingLevel);
m_currentFrameDecodingStatus = DecodingStatus::Decoding;
LOG(Images, "BitmapImage::%s - %p - url: %s [requesting async decoding for nextFrame = %ld]", __FUNCTION__, this, sourceURL().string().utf8().data(), nextFrame);
}
@@ -420,7 +447,7 @@
m_desiredFrameDecodeTimeForTesting = time + std::max(m_frameDecodingDurationForTesting, 0_s);
if (m_clearDecoderAfterAsyncFrameRequestForTesting)
- m_source.resetData(data());
+ m_source->resetData(data());
}
ASSERT(!m_frameTimer);
@@ -484,7 +511,7 @@
// the timer unless all renderers have stopped drawing.
clearTimer();
if (canAnimate())
- m_source.stopAsyncDecodingQueue();
+ m_source->stopAsyncDecodingQueue();
}
void BitmapImage::resetAnimation()
@@ -519,7 +546,7 @@
if (frameIsCompatible)
internalStartAnimation();
else if (!frameIsBeingDecoded) {
- m_source.requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
+ m_source->requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
m_currentFrameDecodingStatus = DecodingStatus::Decoding;
}
return;
@@ -531,7 +558,7 @@
if (frameIsCompatible)
callDecodingCallbacks();
else if (!frameIsBeingDecoded) {
- m_source.requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
+ m_source->requestFrameAsyncDecodingAtIndex(m_currentFrame, m_currentSubsamplingLevel, std::optional<IntSize>());
m_currentFrameDecodingStatus = DecodingStatus::Decoding;
}
}
@@ -567,8 +594,8 @@
}
ASSERT(index == m_currentFrame && !m_currentFrame);
- if (m_source.isAsyncDecodingQueueIdle())
- m_source.stopAsyncDecodingQueue();
+ if (m_source->isAsyncDecodingQueueIdle())
+ m_source->stopAsyncDecodingQueue();
DecodingStatus decodingStatus = frameDecodingStatusAtIndex(m_currentFrame);
setCurrentFrameDecodingStatusIfNecessary(decodingStatus);
@@ -596,7 +623,7 @@
if (isAnimated())
ts.dumpProperty("current-frame", m_currentFrame);
- m_source.dump(ts);
+ m_source->dump(ts);
}
}
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.h 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h 2017-11-29 23:23:54 UTC (rev 225300)
@@ -29,9 +29,9 @@
#include "Image.h"
#include "Color.h"
+#include "ImageFrameCache.h"
#include "ImageObserver.h"
#include "ImageOrientation.h"
-#include "ImageSource.h"
#include "IntSize.h"
#if USE(CG) || USE(APPKIT)
@@ -71,31 +71,31 @@
bool hasSingleSecurityOrigin() const override { return true; }
EncodedDataStatus dataChanged(bool allDataReceived) override;
- unsigned decodedSize() const { return m_source.decodedSize(); }
+ unsigned decodedSize() const { return m_source->decodedSize(); }
- EncodedDataStatus encodedDataStatus() const { return m_source.encodedDataStatus(); }
- size_t frameCount() const { return m_source.frameCount(); }
- RepetitionCount repetitionCount() const { return m_source.repetitionCount(); }
- String uti() const override { return m_source.uti(); }
- String filenameExtension() const override { return m_source.filenameExtension(); }
- std::optional<IntPoint> hotSpot() const override { return m_source.hotSpot(); }
+ EncodedDataStatus encodedDataStatus() const { return m_source->encodedDataStatus(); }
+ size_t frameCount() const { return m_source->frameCount(); }
+ RepetitionCount repetitionCount() const { return m_source->repetitionCount(); }
+ String uti() const override { return m_source->uti(); }
+ String filenameExtension() const override { return m_source->filenameExtension(); }
+ std::optional<IntPoint> hotSpot() const override { return m_source->hotSpot(); }
// FloatSize due to override.
- FloatSize size() const override { return m_source.size(); }
- IntSize sizeRespectingOrientation() const { return m_source.sizeRespectingOrientation(); }
- Color singlePixelSolidColor() const override { return m_source.singlePixelSolidColor(); }
- bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) const { return m_source.frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); }
- DecodingStatus frameDecodingStatusAtIndex(size_t index) const { return m_source.frameDecodingStatusAtIndex(index); }
+ FloatSize size() const override { return m_source->size(); }
+ IntSize sizeRespectingOrientation() const { return m_source->sizeRespectingOrientation(); }
+ Color singlePixelSolidColor() const override { return m_source->singlePixelSolidColor(); }
+ bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) const { return m_source->frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); }
+ DecodingStatus frameDecodingStatusAtIndex(size_t index) const { return m_source->frameDecodingStatusAtIndex(index); }
bool frameIsCompleteAtIndex(size_t index) const { return frameDecodingStatusAtIndex(index) == DecodingStatus::Complete; }
- bool frameHasAlphaAtIndex(size_t index) const { return m_source.frameHasAlphaAtIndex(index); }
+ bool frameHasAlphaAtIndex(size_t index) const { return m_source->frameHasAlphaAtIndex(index); }
- bool frameHasFullSizeNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) { return m_source.frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); }
- bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_source.frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); }
+ bool frameHasFullSizeNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) { return m_source->frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); }
+ bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_source->frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); }
- SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) const { return m_source.frameSubsamplingLevelAtIndex(index); }
+ SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) const { return m_source->frameSubsamplingLevelAtIndex(index); }
- Seconds frameDurationAtIndex(size_t index) const { return m_source.frameDurationAtIndex(index); }
- ImageOrientation frameOrientationAtIndex(size_t index) const { return m_source.frameOrientationAtIndex(index); }
+ Seconds frameDurationAtIndex(size_t index) const { return m_source->frameDurationAtIndex(index); }
+ ImageOrientation frameOrientationAtIndex(size_t index) const { return m_source->frameOrientationAtIndex(index); }
size_t currentFrame() const { return m_currentFrame; }
bool currentFrameKnownToBeOpaque() const override { return !frameHasAlphaAtIndex(currentFrame()); }
@@ -142,7 +142,7 @@
WEBCORE_EXPORT BitmapImage(NativeImagePtr&&, ImageObserver* = nullptr);
WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr);
- NativeImagePtr frameImageAtIndex(size_t index) { return m_source.frameImageAtIndex(index); }
+ NativeImagePtr frameImageAtIndex(size_t index) { return m_source->frameImageAtIndex(index); }
NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr);
// Called to invalidate cached data. When |destroyAll| is true, we wipe out
@@ -165,7 +165,7 @@
// Animation.
enum class StartAnimationStatus { CannotStart, IncompleteData, TimerActive, DecodingActive, Started };
- bool isAnimated() const override { return m_source.frameCount() > 1; }
+ bool isAnimated() const override { return m_source->frameCount() > 1; }
bool shouldAnimate() const;
void startAnimation() override { internalStartAnimation(); }
StartAnimationStatus internalStartAnimation();
@@ -193,6 +193,7 @@
private:
void clearTimer();
void startTimer(Seconds delay);
+ SubsamplingLevel subsamplingLevelForScaleFactor(GraphicsContext&, const FloatSize& scaleFactor);
bool canDestroyDecodedData();
void setCurrentFrameDecodingStatusIfNecessary(DecodingStatus);
bool isBitmapImage() const override { return true; }
@@ -204,7 +205,7 @@
// Animated images over a certain size are considered large enough that we'll only hang on to one frame at a time.
static const unsigned LargeAnimationCutoff = 30 * 1024 * 1024;
- mutable ImageSource m_source;
+ mutable Ref<ImageFrameCache> m_source;
size_t m_currentFrame { 0 }; // The index of the current frame of animation.
SubsamplingLevel m_currentSubsamplingLevel { SubsamplingLevel::Default };
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-11-29 23:23:54 UTC (rev 225300)
@@ -94,7 +94,6 @@
class HostWindow;
class Image;
class ImageBuffer;
-class ImageSource;
class ImageData;
class IntRect;
class IntSize;
@@ -1262,7 +1261,6 @@
bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
#if USE(CAIRO)
- ImageSource* m_decoder;
RefPtr<cairo_surface_t> m_imageSurface;
#elif USE(CG)
RetainPtr<CGImageRef> m_cgImage;
Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp 2017-11-29 23:23:54 UTC (rev 225300)
@@ -47,8 +47,10 @@
namespace WebCore {
-ImageFrameCache::ImageFrameCache(Image* image)
+ImageFrameCache::ImageFrameCache(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
: m_image(image)
+ , m_alphaOption(alphaOption)
+ , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
{
}
@@ -73,23 +75,54 @@
ASSERT(!hasAsyncDecodingQueue());
}
-void ImageFrameCache::setDecoder(ImageDecoder* decoder)
+bool ImageFrameCache::ensureDecoderAvailable(SharedBuffer* data)
{
- if (m_decoder == decoder)
- return;
+ if (!data || isDecoderAvailable())
+ return true;
+ m_decoder = ImageDecoder::create(*data, mimeType(), m_alphaOption, m_gammaAndColorProfileOption);
+ if (!isDecoderAvailable())
+ return false;
+
+ if (auto expectedContentSize = expectedContentLength())
+ m_decoder->setExpectedContentSize(expectedContentSize);
+
// Changing the decoder has to stop the decoding thread. The current frame will
// continue decoding safely because the decoding thread has its own
// reference of the old decoder.
stopAsyncDecodingQueue();
- m_decoder = decoder;
+ return true;
}
-ImageDecoder* ImageFrameCache::decoder() const
+void ImageFrameCache::setData(SharedBuffer* data, bool allDataReceived)
{
- return m_decoder.get();
+ if (!data || !ensureDecoderAvailable(data))
+ return;
+
+ m_decoder->setData(*data, allDataReceived);
}
+void ImageFrameCache::resetData(SharedBuffer* data)
+{
+ m_decoder = nullptr;
+ setData(data, isAllDataReceived());
+}
+
+EncodedDataStatus ImageFrameCache::dataChanged(SharedBuffer* data, bool allDataReceived)
+{
+ setData(data, allDataReceived);
+ clearMetadata();
+ EncodedDataStatus status = encodedDataStatus();
+ if (status >= EncodedDataStatus::SizeAvailable)
+ growFrames();
+ return status;
+}
+
+bool ImageFrameCache::isAllDataReceived()
+{
+ return isDecoderAvailable() ? m_decoder->isAllDataReceived() : frameCount();
+}
+
void ImageFrameCache::destroyDecodedData(size_t frameCount, size_t excludeFrame)
{
unsigned decodedSize = 0;
@@ -119,6 +152,13 @@
decodedSizeDecreased(decodedSize);
}
+void ImageFrameCache::clearFrameBufferCache(size_t beforeFrame)
+{
+ if (!isDecoderAvailable())
+ return;
+ m_decoder->clearFrameBufferCache(beforeFrame);
+}
+
void ImageFrameCache::decodedSizeChanged(long long decodedSize)
{
if (!decodedSize || !m_image || !m_image->imageObserver())
@@ -278,6 +318,14 @@
return *m_frameRequestQueue;
}
+bool ImageFrameCache::canUseAsyncDecoding()
+{
+ if (!isDecoderAvailable())
+ return false;
+ // FIXME: figure out the best heuristic for enabling async image decoding.
+ return size().area() * sizeof(RGBA32) >= (frameCount() > 1 ? 100 * KB : 500 * KB);
+}
+
void ImageFrameCache::startAsyncDecodingQueue()
{
if (hasAsyncDecodingQueue() || !isDecoderAvailable())
@@ -510,6 +558,29 @@
return frameMetadataAtIndexCacheIfNeeded<Color>(0, (&ImageFrame::singlePixelSolidColor), &m_singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage);
}
+SubsamplingLevel ImageFrameCache::maximumSubsamplingLevel()
+{
+ if (m_maximumSubsamplingLevel)
+ return m_maximumSubsamplingLevel.value();
+
+ if (!isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0))
+ return SubsamplingLevel::Default;
+
+ // FIXME: this value was chosen to be appropriate for iOS since the image
+ // subsampling is only enabled by default on iOS. Choose a different value
+ // if image subsampling is enabled on other platform.
+ const int maximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
+ SubsamplingLevel level = SubsamplingLevel::First;
+
+ for (; level < SubsamplingLevel::Last; ++level) {
+ if (frameSizeAtIndex(0, level).area().unsafeGet() < maximumImageAreaBeforeSubsampling)
+ break;
+ }
+
+ m_maximumSubsamplingLevel = level;
+ return m_maximumSubsamplingLevel.value();
+}
+
bool ImageFrameCache::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions)
{
auto it = std::find_if(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [index, &decodingOptions](const ImageFrameRequest& frameRequest) {
@@ -563,6 +634,19 @@
return frameMetadataAtIndexCacheIfNeeded<ImageOrientation>(index, (&ImageFrame::orientation), nullptr, ImageFrame::Caching::Metadata);
}
+#if USE(DIRECT2D)
+void ImageFrameCache::setTargetContext(const GraphicsContext* targetContext)
+{
+ if (isDecoderAvailable() && targetContext)
+ m_decoder->setTargetContext(targetContext->platformContext())
+}
+#endif
+
+NativeImagePtr ImageFrameCache::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+{
+ return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
+}
+
NativeImagePtr ImageFrameCache::frameImageAtIndex(size_t index)
{
return frameMetadataAtIndex<NativeImagePtr>(index, (&ImageFrame::nativeImage));
@@ -573,4 +657,16 @@
return frameMetadataAtIndexCacheIfNeeded<NativeImagePtr>(index, (&ImageFrame::nativeImage), nullptr, ImageFrame::Caching::MetadataAndImage, subsamplingLevel);
}
+void ImageFrameCache::dump(TextStream& ts)
+{
+ ts.dumpProperty("type", filenameExtension());
+ ts.dumpProperty("frame-count", frameCount());
+ ts.dumpProperty("repetitions", repetitionCount());
+ ts.dumpProperty("solid-color", singlePixelSolidColor());
+
+ ImageOrientation orientation = frameOrientationAtIndex(0);
+ if (orientation != OriginTopLeft)
+ ts.dumpProperty("orientation", orientation);
}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/ImageFrameCache.h (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/ImageFrameCache.h 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageFrameCache.h 2017-11-29 23:23:54 UTC (rev 225300)
@@ -31,6 +31,7 @@
#include <wtf/Optional.h>
#include <wtf/SynchronizedFixedQueue.h>
#include <wtf/WorkQueue.h>
+#include <wtf/text/TextStream.h>
namespace WebCore {
@@ -40,11 +41,15 @@
class URL;
class ImageFrameCache : public ThreadSafeRefCounted<ImageFrameCache> {
- friend class ImageSource;
+ friend class BitmapImage;
public:
- static Ref<ImageFrameCache> create(Image* image)
+ ImageFrameCache(Image*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
+ ImageFrameCache(NativeImagePtr&&);
+ ~ImageFrameCache();
+
+ static Ref<ImageFrameCache> create(Image* image, AlphaOption alphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption gammaAndColorProfileOption = GammaAndColorProfileOption::Applied)
{
- return adoptRef(*new ImageFrameCache(image));
+ return adoptRef(*new ImageFrameCache(image, alphaOption, gammaAndColorProfileOption));
}
static Ref<ImageFrameCache> create(NativeImagePtr&& nativeImage)
@@ -52,16 +57,17 @@
return adoptRef(*new ImageFrameCache(WTFMove(nativeImage)));
}
- ~ImageFrameCache();
+ void setData(SharedBuffer* data, bool allDataReceived);
+ void resetData(SharedBuffer* data);
+ EncodedDataStatus dataChanged(SharedBuffer* data, bool allDataReceived);
+ bool isAllDataReceived();
- void setDecoder(ImageDecoder*);
- ImageDecoder* decoder() const;
-
unsigned decodedSize() const { return m_decodedSize; }
void destroyAllDecodedData() { destroyDecodedData(frameCount(), frameCount()); }
void destroyAllDecodedDataExcludeFrame(size_t excludeFrame) { destroyDecodedData(frameCount(), excludeFrame); }
void destroyDecodedDataBeforeFrame(size_t beforeFrame) { destroyDecodedData(beforeFrame, beforeFrame); }
void destroyIncompleteDecodedData();
+ void clearFrameBufferCache(size_t beforeFrame);
void growFrames();
void clearMetadata();
@@ -71,8 +77,9 @@
long long expectedContentLength() const;
// Asynchronous image decoding
+ bool canUseAsyncDecoding();
void startAsyncDecodingQueue();
- void requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>&);
+ void requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>& = { });
void stopAsyncDecodingQueue();
bool hasAsyncDecodingQueue() const { return m_decodingQueue; }
bool isAsyncDecodingQueueIdle() const;
@@ -90,8 +97,8 @@
// Image metadata which is calculated from the first ImageFrame.
IntSize size();
IntSize sizeRespectingOrientation();
-
Color singlePixelSolidColor();
+ SubsamplingLevel maximumSubsamplingLevel();
// ImageFrame metadata which does not require caching the ImageFrame.
bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t, const DecodingOptions&);
@@ -108,13 +115,14 @@
Seconds frameDurationAtIndex(size_t);
ImageOrientation frameOrientationAtIndex(size_t);
+#if USE(DIRECT2D)
+ void setTargetContext(const GraphicsContext*);
+#endif
+ NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
NativeImagePtr frameImageAtIndex(size_t);
- NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel);
+ NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default);
private:
- ImageFrameCache(Image*);
- ImageFrameCache(NativeImagePtr&&);
-
template<typename T, T (ImageDecoder::*functor)() const>
T metadata(const T& defaultValue, std::optional<T>* cachedValue = nullptr);
@@ -124,6 +132,7 @@
template<typename T, typename... Args>
T frameMetadataAtIndexCacheIfNeeded(size_t, T (ImageFrame::*functor)() const, std::optional<T>* cachedValue, Args&&...);
+ bool ensureDecoderAvailable(SharedBuffer* data);
bool isDecoderAvailable() const { return m_decoder; }
void destroyDecodedData(size_t frameCount, size_t excludeFrame);
void decodedSizeChanged(long long decodedSize);
@@ -144,11 +153,15 @@
const ImageFrame& frameAtIndexCacheIfNeeded(size_t, ImageFrame::Caching, const std::optional<SubsamplingLevel>& = { });
+ void dump(TextStream&);
+
Image* m_image { nullptr };
RefPtr<ImageDecoder> m_decoder;
+ AlphaOption m_alphaOption { AlphaOption::Premultiplied };
+ GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileOption::Applied };
+
unsigned m_decodedSize { 0 };
unsigned m_decodedPropertiesSize { 0 };
-
Vector<ImageFrame, 1> m_frames;
// Asynchronous image decoding.
@@ -180,6 +193,7 @@
std::optional<IntSize> m_size;
std::optional<IntSize> m_sizeRespectingOrientation;
std::optional<Color> m_singlePixelSolidColor;
+ std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
};
}
Deleted: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp 2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Alp Toker <alp.to...@collabora.co.uk>
- * Copyright (C) 2008, Google Inc. All rights reserved.
- * Copyright (C) 2007-2009 Torch Mobile, Inc
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ImageSource.h"
-
-#include "GraphicsContext.h"
-
-#if USE(CG)
-#include "ImageDecoderCG.h"
-#if PLATFORM(WIN)
-#include <WebKitSystemInterface/WebKitSystemInterface.h>
-#endif
-#elif USE(DIRECT2D)
-#include "ImageDecoderDirect2D.h"
-#else
-#include "ImageDecoder.h"
-#endif
-
-#include "ImageOrientation.h"
-#include <wtf/CurrentTime.h>
-
-namespace WebCore {
-
-ImageSource::ImageSource(NativeImagePtr&& nativeImage)
- : m_frameCache(ImageFrameCache::create(WTFMove(nativeImage)))
-{
-}
-
-ImageSource::ImageSource(Image* image, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
- : m_frameCache(ImageFrameCache::create(image))
- , m_alphaOption(alphaOption)
- , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
-{
-}
-
-ImageSource::~ImageSource() = default;
-
-void ImageSource::clearFrameBufferCache(size_t clearBeforeFrame)
-{
- if (!isDecoderAvailable())
- return;
- m_decoder->clearFrameBufferCache(clearBeforeFrame);
-}
-
-bool ImageSource::ensureDecoderAvailable(SharedBuffer* data)
-{
- if (!data || isDecoderAvailable())
- return true;
-
- m_decoder = ImageDecoder::create(*data, m_frameCache->mimeType(), m_alphaOption, m_gammaAndColorProfileOption);
- if (!isDecoderAvailable())
- return false;
-
- if (auto expectedContentLength = m_frameCache->expectedContentLength())
- m_decoder->setExpectedContentSize(expectedContentLength);
-
- m_frameCache->setDecoder(m_decoder.get());
- return true;
-}
-
-void ImageSource::setDecoderTargetContext(const GraphicsContext* targetContext)
-{
-#if USE(DIRECT2D)
- if (!isDecoderAvailable())
- return;
-
- if (targetContext)
- m_decoder->setTargetContext(targetContext->platformContext());
-#else
- UNUSED_PARAM(targetContext);
-#endif
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
- if (!data || !ensureDecoderAvailable(data))
- return;
-
- m_decoder->setData(*data, allDataReceived);
-}
-
-void ImageSource::resetData(SharedBuffer* data)
-{
- m_decoder = nullptr;
- m_frameCache->setDecoder(nullptr);
- setData(data, isAllDataReceived());
-}
-
-EncodedDataStatus ImageSource::dataChanged(SharedBuffer* data, bool allDataReceived)
-{
- setData(data, allDataReceived);
- m_frameCache->clearMetadata();
-
- EncodedDataStatus status = encodedDataStatus();
- if (status >= EncodedDataStatus::SizeAvailable)
- m_frameCache->growFrames();
-
- return status;
-}
-
-bool ImageSource::isAllDataReceived()
-{
- return isDecoderAvailable() ? m_decoder->isAllDataReceived() : m_frameCache->frameCount();
-}
-
-bool ImageSource::canUseAsyncDecoding()
-{
- if (!isDecoderAvailable())
- return false;
- // FIXME: figure out the best heuristic for enabling async image decoding.
- return size().area() * sizeof(RGBA32) >= (frameCount() > 1 ? 100 * KB : 500 * KB);
-}
-
-SubsamplingLevel ImageSource::maximumSubsamplingLevel()
-{
- if (m_maximumSubsamplingLevel)
- return m_maximumSubsamplingLevel.value();
-
- if (!isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0))
- return SubsamplingLevel::Default;
-
- // FIXME: this value was chosen to be appropriate for iOS since the image
- // subsampling is only enabled by default on iOS. Choose a different value
- // if image subsampling is enabled on other platform.
- const int maximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
- SubsamplingLevel level = SubsamplingLevel::First;
-
- for (; level < SubsamplingLevel::Last; ++level) {
- if (frameSizeAtIndex(0, level).area().unsafeGet() < maximumImageAreaBeforeSubsampling)
- break;
- }
-
- m_maximumSubsamplingLevel = level;
- return m_maximumSubsamplingLevel.value();
-}
-
-SubsamplingLevel ImageSource::subsamplingLevelForScaleFactor(GraphicsContext& context, const FloatSize& scaleFactor)
-{
-#if USE(CG)
- // Never use subsampled images for drawing into PDF contexts.
- if (CGContextGetType(context.platformContext()) == kCGContextTypePDF)
- return SubsamplingLevel::Default;
-
- float scale = std::min(float(1), std::max(scaleFactor.width(), scaleFactor.height()));
- if (!(scale > 0 && scale <= 1))
- return SubsamplingLevel::Default;
-
- int result = std::ceil(std::log2(1 / scale));
- return static_cast<SubsamplingLevel>(std::min(result, static_cast<int>(maximumSubsamplingLevel())));
-#else
- UNUSED_PARAM(context);
- UNUSED_PARAM(scaleFactor);
- return SubsamplingLevel::Default;
-#endif
-}
-
-NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
-{
- return isDecoderAvailable() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
-}
-
-NativeImagePtr ImageSource::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext)
-{
- setDecoderTargetContext(targetContext);
- return m_frameCache->frameImageAtIndexCacheIfNeeded(index, subsamplingLevel);
-}
-
-void ImageSource::dump(TextStream& ts)
-{
- ts.dumpProperty("type", filenameExtension());
- ts.dumpProperty("frame-count", frameCount());
- ts.dumpProperty("repetitions", repetitionCount());
- ts.dumpProperty("solid-color", singlePixelSolidColor());
-
- ImageOrientation orientation = frameOrientationAtIndex(0);
- if (orientation != OriginTopLeft)
- ts.dumpProperty("orientation", orientation);
-}
-
-}
Deleted: trunk/Source/WebCore/platform/graphics/ImageSource.h (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/ImageSource.h 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h 2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2010, 2012, 2014, 2016 Apple Inc. All rights reserved.
- * Copyright (C) 2007-2008 Torch Mobile, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include "ImageFrame.h"
-#include "ImageFrameCache.h"
-#include "ImageOrientation.h"
-#include "IntPoint.h"
-#include "NativeImage.h"
-#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/Optional.h>
-#include <wtf/text/TextStream.h>
-
-namespace WebCore {
-
-class GraphicsContext;
-class ImageDecoder;
-class ImageOrientation;
-class IntPoint;
-class IntSize;
-class SharedBuffer;
-
-class ImageSource {
- WTF_MAKE_NONCOPYABLE(ImageSource);
- friend class BitmapImage;
-public:
- ImageSource(NativeImagePtr&&);
- ImageSource(Image*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
- ~ImageSource();
-
- void destroyAllDecodedData() { m_frameCache->destroyAllDecodedData(); }
- void destroyAllDecodedDataExcludeFrame(size_t excludeFrame) { m_frameCache->destroyAllDecodedDataExcludeFrame(excludeFrame); }
- void destroyDecodedDataBeforeFrame(size_t beforeFrame) { m_frameCache->destroyDecodedDataBeforeFrame(beforeFrame); }
- void destroyIncompleteDecodedData() { m_frameCache->destroyIncompleteDecodedData(); }
- void clearImage() { m_frameCache->clearImage(); }
- void clearFrameBufferCache(size_t);
-
- bool ensureDecoderAvailable(SharedBuffer*);
- bool isDecoderAvailable() const { return m_decoder.get(); }
-
- void setData(SharedBuffer* data, bool allDataReceived);
- void resetData(SharedBuffer* data);
- EncodedDataStatus dataChanged(SharedBuffer* data, bool allDataReceived);
-
- unsigned decodedSize() const { return m_frameCache->decodedSize(); }
- bool isAllDataReceived();
-
- bool canUseAsyncDecoding();
- void requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing = { }) { m_frameCache->requestFrameAsyncDecodingAtIndex(index, subsamplingLevel, sizeForDrawing); }
- bool hasAsyncDecodingQueue() const { return m_frameCache->hasAsyncDecodingQueue(); }
- bool isAsyncDecodingQueueIdle() const { return m_frameCache->isAsyncDecodingQueueIdle(); }
- void stopAsyncDecodingQueue() { m_frameCache->stopAsyncDecodingQueue(); }
-
- // Image metadata which is calculated by the decoder or can deduced by the case of the memory NativeImage.
- EncodedDataStatus encodedDataStatus() { return m_frameCache->encodedDataStatus(); }
- size_t frameCount() { return m_frameCache->frameCount(); }
- RepetitionCount repetitionCount() { return m_frameCache->repetitionCount(); }
- String uti() { return m_frameCache->uti(); }
- String filenameExtension() { return m_frameCache->filenameExtension(); }
- std::optional<IntPoint> hotSpot() { return m_frameCache->hotSpot(); }
-
- // Image metadata which is calculated from the first ImageFrame.
- IntSize size() { return m_frameCache->size(); }
- IntSize sizeRespectingOrientation() { return m_frameCache->sizeRespectingOrientation(); }
- Color singlePixelSolidColor() { return m_frameCache->singlePixelSolidColor(); }
-
- // ImageFrame metadata which does not require caching the ImageFrame.
- bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) { return m_frameCache->frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); }
- DecodingStatus frameDecodingStatusAtIndex(size_t index) { return m_frameCache->frameDecodingStatusAtIndex(index); }
- bool frameHasAlphaAtIndex(size_t index) { return m_frameCache->frameHasAlphaAtIndex(index); }
- bool frameHasImageAtIndex(size_t index) { return m_frameCache->frameHasImageAtIndex(index); }
- bool frameHasFullSizeNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel) { return m_frameCache->frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); }
- bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_frameCache->frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); }
- SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) { return m_frameCache->frameSubsamplingLevelAtIndex(index); }
-
- // ImageFrame metadata which forces caching or re-caching the ImageFrame.
- IntSize frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache->frameSizeAtIndex(index, subsamplingLevel); }
- unsigned frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default) { return m_frameCache->frameBytesAtIndex(index, subsamplingLevel); }
- Seconds frameDurationAtIndex(size_t index) { return m_frameCache->frameDurationAtIndex(index); }
- ImageOrientation frameOrientationAtIndex(size_t index) { return m_frameCache->frameOrientationAtIndex(index); }
-
- NativeImagePtr frameImageAtIndex(size_t index) { return m_frameCache->frameImageAtIndex(index); }
- NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr);
-
- SubsamplingLevel maximumSubsamplingLevel();
- SubsamplingLevel subsamplingLevelForScaleFactor(GraphicsContext&, const FloatSize& scaleFactor);
- NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
-
-private:
- void dump(WTF::TextStream&);
-
- void setDecoderTargetContext(const GraphicsContext*);
-
- Ref<ImageFrameCache> m_frameCache;
- RefPtr<ImageDecoder> m_decoder;
-
- std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
-
- AlphaOption m_alphaOption { AlphaOption::Premultiplied };
- GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileOption::Applied };
-};
-
-}
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp 2017-11-29 23:23:54 UTC (rev 225300)
@@ -35,7 +35,7 @@
#include "CairoUtilities.h"
#include "GraphicsContext3DPrivate.h"
#include "Image.h"
-#include "ImageSource.h"
+#include "ImageFrameCache.h"
#include "NotImplemented.h"
#include "PlatformContextCairo.h"
#include "RefPtrCairo.h"
@@ -277,8 +277,6 @@
GraphicsContext3D::ImageExtractor::~ImageExtractor()
{
- if (m_decoder)
- delete m_decoder;
}
bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
@@ -288,12 +286,7 @@
// We need this to stay in scope because the native image is just a shallow copy of the data.
AlphaOption alphaOption = premultiplyAlpha ? AlphaOption::Premultiplied : AlphaOption::NotPremultiplied;
GammaAndColorProfileOption gammaAndColorProfileOption = ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied;
- m_decoder = new ImageSource(nullptr, alphaOption, gammaAndColorProfileOption);
-
- if (!m_decoder)
- return false;
-
- ImageSource& decoder = *m_decoder;
+ ImageFrameCache decoder(nullptr, alphaOption, gammaAndColorProfileOption);
m_alphaOp = AlphaDoNothing;
if (m_image->data()) {
Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp 2017-11-29 23:23:54 UTC (rev 225300)
@@ -325,7 +325,7 @@
return false;
bool hasAlpha = !m_image->currentFrameKnownToBeOpaque();
if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
- ImageSource decoder(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
+ ImageFrameCache decoder(nullptr, AlphaOption::NotPremultiplied, ignoreGammaAndColorProfile ? GammaAndColorProfileOption::Ignored : GammaAndColorProfileOption::Applied);
decoder.setData(m_image->data(), true);
if (!decoder.frameCount())
return false;
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.h (225299 => 225300)
--- trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.h 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.h 2017-11-29 23:23:54 UTC (rev 225300)
@@ -26,7 +26,6 @@
#ifndef ImageSourceCG_h
#define ImageSourceCG_h
-#include "ImageSource.h"
#include <wtf/Forward.h>
namespace WebCore {
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (225299 => 225300)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2017-11-29 23:23:54 UTC (rev 225300)
@@ -1,3 +1,12 @@
+2017-11-29 Said Abou-Hallawa <sabouhall...@apple.com>
+
+ Remove the ImageSource from the class hierarchy that connects BitmapImage to ImageFrame
+ https://bugs.webkit.org/show_bug.cgi?id=175595
+
+ Reviewed by Darin Adler.
+
+ * WebView/WebPreferences.mm:
+
2017-11-27 Tim Horton <timothy_hor...@apple.com>
One too many zeroes in macOS version number in FeatureDefines
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm (225299 => 225300)
--- trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm 2017-11-29 23:16:20 UTC (rev 225299)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm 2017-11-29 23:23:54 UTC (rev 225300)
@@ -58,7 +58,6 @@
#import <AudioToolbox/AudioSession.h>
#import <WebCore/Device.h>
#import <WebCore/GraphicsContext.h>
-#import <WebCore/ImageSource.h>
#import <WebCore/WebCoreThreadMessage.h>
#endif