Changeset 214450 in webkit
- Timestamp:
- Mar 27, 2017, 7:23:10 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 42 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r214441 r214450 1 2017-03-27 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 REGRESSION(213764): Large images should not be decoded asynchronously when they are drawn on a canvas 4 https://bugs.webkit.org/show_bug.cgi?id=169771 5 6 Reviewed by Simon Fraser. 7 8 * fast/images/animated-image-different-dest-size-expected.html: Added. 9 * fast/images/animated-image-different-dest-size.html: Added. 10 This test crashes without this patch. 11 12 * fast/images/animated-image-loop-count.html: 13 Clear the memory cache so the test can be not flaky. Running it with -repeat-each was failing. 14 15 * fast/images/async-image-background-image-expected.html: Added. 16 * fast/images/async-image-background-image.html: Added. 17 Ensures the background image can be drawn asynchronously if it is large. 18 19 * fast/images/async-image-canvas-draw-image-expected.html: Added. 20 * fast/images/async-image-canvas-draw-image.html: Added. 21 Ensures the image is drawn synchronously on the canvas regardless of its size. 22 23 * fast/images/ordered-animated-image-frames.html: 24 Clear the memory cache so the test can be not flaky. Running it with -repeat-each was failing. 25 26 * fast/images/reset-image-animation-expected.txt: 27 * fast/images/reset-image-animation.html: 28 Change how the steps of the test are ordered so the test can be not flaky. 29 Running it with -repeat-each was failing. 30 31 * fast/images/resources/red-green-blue-900-300.png: Added. 32 1 33 2017-03-27 Youenn Fablet <youenn@apple.com> 2 34 -
trunk/LayoutTests/fast/images/animated-image-loop-count.html
r210951 r214450 58 58 59 59 (function() { 60 if (window.internals) 61 internals.clearMemoryCache(); 62 60 63 if (window.testRunner) 61 64 testRunner.waitUntilDone(); -
trunk/LayoutTests/fast/images/ordered-animated-image-frames.html
r207386 r214450 10 10 <canvas id="canvas"></canvas> 11 11 <script> 12 if (window.internals) 13 internals.clearMemoryCache(); 14 12 15 if (window.testRunner) 13 16 testRunner.waitUntilDone(); -
trunk/LayoutTests/fast/images/reset-image-animation-expected.txt
r209131 r214450 4 4 5 5 6 PASS internals.imageFrameIndex(image) is 0 7 PASS internals.imageFrameIndex(image) is 1 8 The animation of the image was reset. 9 PASS internals.imageFrameIndex(image) is 0 6 10 PASS internals.imageFrameIndex(image) is 1 7 11 PASS internals.imageFrameIndex(image) is 2 -
trunk/LayoutTests/fast/images/reset-image-animation.html
r209131 r214450 7 7 <canvas id="canvas"></canvas> 8 8 <script> 9 description("Ensure the image animation is played in order after the animation is reset.");10 jsTestIsAsync = true;11 12 internals.clearMemoryCache();13 14 9 var image = new Image; 15 image.onload = imageLoaded; 16 image.src = "resources/animated-red-green-blue.gif"; 17 18 function imageLoaded() 19 { 20 if (!window.internals) 21 return; 22 internals.setImageFrameDecodingDuration(image, 0.040); 23 drawImage(); 24 drawLoop(); 10 11 function drawFrame(expectedFrame) { 12 return new Promise((resolve) => { 13 let canvas = document.getElementById("canvas"); 14 let context = canvas.getContext("2d"); 15 context.drawImage(image, 0, 0, canvas.width, canvas.height); 16 shouldBe("internals.imageFrameIndex(image)", expectedFrame.toString()); 17 setTimeout(() => { 18 resolve(expectedFrame + 1); 19 }, 30); 20 }); 25 21 } 26 22 27 function drawImage( )28 {29 if (drawImage.count == undefined)30 drawImage.count = 0;31 var canvas = document.getElementById("canvas");32 var ctx = canvas.getContext("2d");33 ctx.drawImage(image, 0, 0, canvas.width, canvas.height);34 return ++drawImage.count;23 function drawImage(frameCount, expectedFrame) { 24 let promise = drawFrame(expectedFrame); 25 for (let frame = 1; frame < frameCount; ++frame) { 26 promise = promise.then((expectedFrame) => { 27 return drawFrame(expectedFrame); 28 }); 29 } 30 return promise; 35 31 } 32 33 function loadImage(src, frameCount) { 34 return new Promise((resolve) => { 35 image.onload = (() => { 36 if (window.internals) 37 internals.setImageFrameDecodingDuration(image, 0.020); 38 drawImage(Math.ceil(frameCount / 2), 0).then(() => { 39 internals.resetImageAnimation(image); 40 debug("The animation of the image was reset."); 41 drawImage(frameCount, 0).then(resolve); 42 }); 43 }); 44 image.src = src; 45 }); 46 } 47 48 (function() { 49 if (window.internals) 50 internals.clearMemoryCache(); 51 52 description("Ensure the image animation is played in order after the animation is reset."); 53 jsTestIsAsync = true; 36 54 37 function drawLoop() 38 { 39 setTimeout(function() { 40 switch (drawImage()) { 41 case 2: 42 shouldBe("internals.imageFrameIndex(image)", "1"); 43 internals.resetImageAnimation(image); 44 drawLoop(); 45 break; 46 47 case 5: 48 // The animation was reset at drawCount = 2. Three more 49 // drawings should make current_frame = 2. 50 shouldBe("internals.imageFrameIndex(image)", "2"); 51 finishJSTest(); 52 break; 53 54 default: 55 drawLoop(); 56 } 57 }, 50); 58 } 55 loadImage("resources/animated-red-green-blue.gif", 3).then(() => { 56 finishJSTest(); 57 }); 58 })(); 59 59 </script> 60 60 <script src="../../resources/js-test-post.js"></script> -
trunk/Source/WebCore/ChangeLog
r214445 r214450 1 2017-03-27 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 REGRESSION(213764): Large images should not be decoded asynchronously when they are drawn on a canvas 4 https://bugs.webkit.org/show_bug.cgi?id=169771 5 6 Reviewed by Simon Fraser. 7 8 Sometimes we have to draw the image immediately like when a canvas calls 9 drawImage. In this case we have to decode the image synchronously to guarantee 10 the drawing. Other times we need to decode with the native size of the image. 11 The animated images have to be decoded with native size always. Otherwise 12 the frame cache will be messed up if the same image is animated with different 13 sizes. Currently we always decode asynchronously with sizeForDrawing. We need 14 to decouple the decoding mode from the sizeForDrawing. 15 16 This patch introduce the DecodingOptions class which can store and compare the 17 following four cases: 18 -- Synchronous: The frame has be decoded with native size only. 19 -- Asynchronous + anySize: This is passed from the Image::draw() callers. 20 -- Asynchronous + fullSize: The image has to be decoded with its full size. 21 -- Asynchronous + sizeForDrawing: The image can be decoded with sizeForDrawing unless 22 it was decoded with either a full size or sizeForDrawing which is larger than the 23 requested sizeForDrawing. 24 25 A new argument of type DecodingMode will be added to Image::draw() function. 26 Only when the drawing comes from the render tree, it will be Asynchronous. 27 Otherwise it will be Synchronous. 28 29 Tests: fast/images/animated-image-different-dest-size.html 30 fast/images/async-image-background-image.html 31 fast/images/async-image-canvas-draw-image.html 32 33 * WebCore.xcodeproj/project.pbxproj: 34 * platform/graphics/BitmapImage.cpp: 35 (WebCore::BitmapImage::frameImageAtIndexCacheIfNeeded): Gets the frame image, cache it synchronously if 36 the current one is invalid. frameImageAtIndex() returns whatever stored in the cache. 37 (WebCore::BitmapImage::nativeImage): Call frameImageAtIndexCacheIfNeeded() instead of frameImageAtIndex(). 38 (WebCore::BitmapImage::nativeImageForCurrentFrame): Ditto. 39 (WebCore::BitmapImage::nativeImageOfSize): Ditto. 40 (WebCore::BitmapImage::framesNativeImages): Ditto. 41 (WebCore::BitmapImage::draw): Change the logic to do the following: 42 -- The animated image has to be decoded with its full size. 43 -- The animated image expects the current frame to be ready for drawing. 44 -- The large image decoding does not need to call internalStartAnimation(). 45 -- The large image has to request async image decoding but draw the current one if it exists. 46 (WebCore::BitmapImage::drawPattern): Draw the pattern synchronously. 47 (WebCore::BitmapImage::shouldUseAsyncDecodingForLargeImages): Delete the call to shouldUseAsyncDecodingForTesting() 48 since it is only applied for animated images. 49 (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImages): Call shouldUseAsyncDecodingForAnimatedImageForTesting(). 50 (WebCore::BitmapImage::internalStartAnimation): Request decoding with the full size. 51 (WebCore::BitmapImage::advanceAnimation): Call shouldUseAsyncDecodingForAnimatedImageForTesting(). 52 (WebCore::BitmapImage::internalAdvanceAnimation): Assert the current frame is not being decoding asynchronously for any size. 53 (WebCore::BitmapImage::frameImageAtIndex): Deleted. Moved to the header file but with a new purpose: return 54 the current frame from the frame cache as is; do not cache a new one. 55 (WebCore::BitmapImage::shouldUseAsyncDecodingForLargeImage): Deleted. Function was renamed to shouldUseAsyncDecodingForLargeImages. 56 (WebCore::BitmapImage::shouldUseAsyncDecodingForAnimatedImage): Deleted. Function was renamed to shouldUseAsyncDecodingForAnimatedImages. 57 * platform/graphics/BitmapImage.h: 58 * platform/graphics/CrossfadeGeneratedImage.cpp: 59 (WebCore::CrossfadeGeneratedImage::draw): Add a new argument of type DecodingMode. 60 * platform/graphics/CrossfadeGeneratedImage.h: 61 * platform/graphics/DecodingOptions.h: Added. 62 (WebCore::DecodingOptions::DecodingOptions): Default constructor: Synchronous mode. 63 (WebCore::DecodingOptions::operator==): Compares two DecodingOptions for equality. 64 (WebCore::DecodingOptions::isSynchronous): Is the frame decoded synchronously? 65 (WebCore::DecodingOptions::isAsynchronous): Is the frame decoded asynchronously? 66 (WebCore::DecodingOptions::isAsynchronousCompatibleWith): Is this DecodingOptions compatible with another one? 67 (WebCore::DecodingOptions::hasFullSize): Is the decoding mode asynchronous but for the image full size? 68 (WebCore::DecodingOptions::hasSizeForDrawing): Is this decoding mode asynchronous but for a sizeForDrawing? 69 (WebCore::DecodingOptions::sizeForDrawing): Returns the sizeForDrawing. m_decodingModeOrSize has to hold an IntSize. 70 (WebCore::DecodingOptions::maxDimension): Moved form ImageFrame.cpp. 71 (WebCore::DecodingOptions::has): A helper function. 72 (WebCore::DecodingOptions::hasDecodingMode): Does m_decodingModeOrSize a DecodingMode? 73 (WebCore::DecodingOptions::hasSize): Does m_decodingModeOrSize an IntSize? 74 * platform/graphics/GeneratedImage.h: Add a new argument of type DecodingMode. 75 * platform/graphics/GradientImage.cpp: 76 (WebCore::GradientImage::draw): Ditto. 77 * platform/graphics/GradientImage.h: Ditto. 78 * platform/graphics/GraphicsContext.cpp: 79 (WebCore::GraphicsContext::drawImage): Pass the ImagePaintingOptions::m_DecodingMode to Image::draw(). 80 * platform/graphics/GraphicsContext.h: 81 (WebCore::ImagePaintingOptions::ImagePaintingOptions): Add a new member of type DecodingMode to ImagePaintingOptions. 82 * platform/graphics/Image.cpp: 83 (WebCore::Image::drawTiled): Pass DecodingMode::Synchronous to Image::draw(). 84 * platform/graphics/Image.h: Add a new argument of type DecodingMode to Image::draw(). 85 * platform/graphics/ImageFrame.cpp: 86 (WebCore::ImageFrame::operator=): Replace m_sizeForDrawing by m_decodingOptions. 87 (WebCore::ImageFrame::hasNativeImage): Check if m_nativeImage is valid and the subsamplingLevels match. 88 (WebCore::ImageFrame::hasFullSizeNativeImage): Checks hasNativeImage() and whether the image frame was 89 decoded for the image full size. 90 (WebCore::ImageFrame::hasDecodedNativeImageCompatibleWithOptions): Checks hasNativeImage() and the DecodingOptions match. 91 (WebCore::maxDimension): Deleted. Moved to DecodingOptions.h. 92 (WebCore::ImageFrame::isBeingDecoded): Deleted. The check for having an ImageFrame being decoded is 93 moved to ImageFrameCache. 94 (WebCore::ImageFrame::hasValidNativeImage): Deleted. No need to this function. 95 * platform/graphics/ImageFrame.h: 96 (WebCore::ImageFrame::hasNativeImage): Add an std::optional<SubsamplingLevel> argument. 97 (WebCore::ImageFrame::hasFullSizeNativeImage): Checks whether the ImageFrame was decoded for the image full size. 98 (WebCore::ImageFrame::enqueueSizeForDecoding): Deleted. 99 (WebCore::ImageFrame::dequeueSizeForDecoding): Deleted. 100 (WebCore::ImageFrame::clearSizeForDecoding): Deleted. 101 (WebCore::ImageFrame::isBeingDecoded): Deleted. 102 (WebCore::ImageFrame::sizeForDrawing): Deleted. 103 (WebCore::ImageFrame::hasDecodedNativeImage): Deleted. 104 The logic of knowing whether an ImageFrame is being decoded is moved to ImageFrameCache. 105 * platform/graphics/ImageFrameCache.cpp: 106 (WebCore::ImageFrameCache::cacheFrameMetadataAtIndex): Caches the metadata of an ImageFrame. If the NativeImage 107 was decoded for a sizeForDrawing, the size of the ImageFrame will be the nativeImageSize(). Otherwise, the 108 frameSizeAtIndex() will be called. 109 (WebCore::ImageFrameCache::cacheFrameNativeImageAtIndex): Cache a new NativeImage which involves caching new 110 metadata and updating the memory cache. No need to check if the existing native image is valid or not for the 111 DecodingOptions. Actually it would be a bug if it happens. This is why cacheNativeImageForFrameRequest() asserts 112 !frame.hasAsyncNativeImage() before calling cacheFrameNativeImageAtIndex(). 113 (WebCore::ImageFrameCache::cacheAsyncFrameNativeImageAtIndex): Cache new NativeImage which was decoded asynchronously. 114 (WebCore::ImageFrameCache::startAsyncDecodingQueue): Call cacheAsyncFrameNativeImageAtIndex() instead of 115 cacheNativeImageForFrameRequest() for clarity. 116 (WebCore::ImageFrameCache::requestFrameAsyncDecodingAtIndex): Call hasAsyncNativeImage() instead of hasValidNativeImage() 117 Call frameIsDecodingCompatibleWithOptionsAtIndex() instead of frame.isBeingDecoded(). Replace the call to enqueueSizeForDecoding() 118 by appending the same ImageFrameRequest to m_frameCommitQueue. 119 (WebCore::ImageFrameCache::isAsyncDecodingQueueIdle): Use m_frameCommitQueue to answer the question whether the decodingQueue is idle. 120 (WebCore::ImageFrameCache::stopAsyncDecodingQueue): Use m_frameCommitQueue to loop through all the ImageFrames which are currently being decoded. 121 (WebCore::ImageFrameCache::frameAtIndexCacheIfNeeded): For getting the metadata, this function needs a valid frame. If it is requested 122 to decode the nativeImage, it has to do it synchronously. 123 (WebCore::ImageFrameCache::singlePixelSolidColor): Don't cache the frame if it is an animated image or the size is not a single pixel. 124 (WebCore::ImageFrameCache::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex): Use m_frameCommitQueue to answer the question whether an ImageFrame 125 is being decoded and is compatible with DecodingOptions. 126 (WebCore::ImageFrameCache::frameHasFullSizeNativeImageAtIndex): Calls ImageFrame::hasFullNativeImage() for a frame. 127 (WebCore::ImageFrameCache::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex): Calls ImageFrame::hasDecodedNativeImageCompatibleWithOptions() for a frame. 128 (WebCore::ImageFrameCache::frameImageAtIndex): Returns the current NativeImage without caching. 129 (WebCore::ImageFrameCache::frameImageAtIndexCacheIfNeeded): Returns the current NativeImage but cache it synchronously if needed. 130 (WebCore::ImageFrameCache::setFrameNativeImageAtIndex): Deleted. 131 (WebCore::ImageFrameCache::setFrameMetadataAtIndex): Deleted. 132 (WebCore::ImageFrameCache::replaceFrameNativeImageAtIndex): Deleted. 133 (WebCore::ImageFrameCache::frameIsBeingDecodedAtIndex): Deleted. 134 (WebCore::ImageFrameCache::frameHasImageAtIndex): Deleted. 135 (WebCore::ImageFrameCache::frameHasValidNativeImageAtIndex): Deleted. 136 (WebCore::ImageFrameCache::frameHasDecodedNativeImage): Deleted. 137 * platform/graphics/ImageFrameCache.h: Two ImageFrameRequest queues will be used. 138 -- The existing one m_frameRequestQueue which is shared between the main thread and decoding thread. The requests will be 139 dequeued from it before starting the decoding. The decoded NativeImage will be cached only on the main thread. The decoding 140 thread is not blocked by the callOnMainThread(). This means there might be multiple ImageFrameRequests which were dequeued 141 while their NativeImages have not been cached yet. 142 -- A new one m_frameCommitQueue which is track all the ImageFrameRequests whose NativeImages have not been cached yet. 143 (WebCore::ImageFrameCache::frameAtIndexCacheIfNeeded): Be explicit about caching the image frame. frameImageAtIndex() 144 returns the current image frame without caching. frameAtIndexCacheIfNeeded(). returns the current image frame but cache 145 it if needed. 146 (WebCore::ImageFrameCache::ImageFrameRequest::operator==): Compares two ImageFrameRequests for equality. 147 * platform/graphics/ImageSource.cpp: 148 (WebCore::ImageSource::frameImageAtIndexCacheIfNeeded): 149 (WebCore::ImageSource::frameImageAtIndex): Deleted. 150 * platform/graphics/ImageSource.h: 151 (WebCore::ImageSource::requestFrameAsyncDecodingAtIndex): Change the type of the argument from IntSize to be const std::optional<IntSize>. 152 (WebCore::ImageSource::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex): Rename of frameIsBeingDecodedAtIndex(). Replace the argument of type 153 std::optional<IntSize> by an argument of type DecodingOptions. 154 (WebCore::ImageSource::frameHasFullSizeNativeImageAtIndex): A wrapper around the ImageFrameCache function. 155 (WebCore::ImageSource::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex): Ditto. 156 (WebCore::ImageSource::frameImageAtIndex): Ditto. 157 (WebCore::ImageSource::frameIsBeingDecodedAtIndex): Deleted. 158 (WebCore::ImageSource::frameHasValidNativeImageAtIndex): Deleted. 159 (WebCore::ImageSource::frameHasDecodedNativeImage): Deleted. 160 * platform/graphics/NamedImageGeneratedImage.cpp: 161 (WebCore::NamedImageGeneratedImage::draw): Add a new argument of type DecodingMode. 162 * platform/graphics/NamedImageGeneratedImage.h: Ditto. 163 * platform/graphics/cairo/ImageBufferCairo.cpp: 164 (WebCore::ImageBuffer::draw): Add a new argument of type DecodingMode. 165 * platform/graphics/cg/ImageDecoderCG.cpp: 166 (WebCore::ImageDecoder::createFrameImageAtIndex): Replace the sizeForDrawing argument by a DecodingMode argument. Add a new handling 167 for decoding asynchronously for the image full size. 168 * platform/graphics/cg/ImageDecoderCG.h: Change the prototype of the function. 169 * platform/graphics/cg/PDFDocumentImage.cpp: 170 (WebCore::PDFDocumentImage::draw): Add a new argument of type DecodingMode. 171 * platform/graphics/cg/PDFDocumentImage.h: 172 * platform/graphics/win/ImageCGWin.cpp: 173 (WebCore::BitmapImage::getHBITMAPOfSize): Pass DecodingMode::Synchronous to Image::draw(). 174 (WebCore::BitmapImage::drawFrameMatchingSourceSize): Ditto. 175 * platform/graphics/win/ImageDecoderDirect2D.cpp: 176 (WebCore::ImageDecoder::createFrameImageAtIndex): Replace the sizeForDrawing argument by a DecodingMode argument. 177 * platform/graphics/win/ImageDecoderDirect2D.h: Change the prototype of the function. 178 * platform/image-decoders/ImageDecoder.cpp: 179 (WebCore::ImageDecoder::createFrameImageAtIndex): Replace the sizeForDrawing argument by a DecodingMode argument. 180 * platform/image-decoders/ImageDecoder.h: Change the prototype of the function. 181 * rendering/RenderBoxModelObject.cpp: 182 (WebCore::RenderBoxModelObject::paintFillLayerExtended): Draw the background image asynchronously if the image size is large. 183 * rendering/RenderImage.cpp: 184 (WebCore::RenderImage::paintIntoRect): Draw the background image element asynchronously if the image size is large. 185 * svg/graphics/SVGImage.cpp: 186 (WebCore::SVGImage::drawForContainer): Pass DecodingMode::Synchronous to draw(). 187 (WebCore::SVGImage::nativeImageForCurrentFrame): Ditto. 188 (WebCore::SVGImage::nativeImage): Ditto. 189 (WebCore::SVGImage::draw): Add a new argument of type DecodingMode. 190 * svg/graphics/SVGImage.h: Change the prototype of the function. 191 * svg/graphics/SVGImageForContainer.cpp: 192 (WebCore::SVGImageForContainer::draw): Add a new argument of type DecodingMode. 193 * svg/graphics/SVGImageForContainer.h: Change the prototype of the function. 194 1 195 2017-03-27 Youenn Fablet <youenn@apple.com> 2 196 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r214420 r214450 2490 2490 550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; }; 2491 2491 550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2492 555130011E7CCCCB00A69E38 /* DecodingOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 555130001E7CCCCA00A69E38 /* DecodingOptions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2492 2493 555B87EC1CAAF0AB00349425 /* ImageDecoderCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */; }; 2493 2494 555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */; }; … … 10162 10163 550A0BC7085F6039007353D6 /* QualifiedName.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifiedName.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; 10163 10164 550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; 10165 555130001E7CCCCA00A69E38 /* DecodingOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecodingOptions.h; sourceTree = "<group>"; }; 10164 10166 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = "<group>"; }; 10165 10167 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = "<group>"; }; … … 22875 22877 2D2FC0551460CD6F00263633 /* CrossfadeGeneratedImage.h */, 22876 22878 A8CB41020E85B8A50032C4F0 /* DashArray.h */, 22879 555130001E7CCCCA00A69E38 /* DecodingOptions.h */, 22877 22880 49FC7A4F1444AF5F00A5D864 /* DisplayRefreshMonitor.cpp */, 22878 22881 49AF2D6814435D050016A784 /* DisplayRefreshMonitor.h */, … … 28174 28177 141DC054164834B900371E5A /* LayoutSize.h in Headers */, 28175 28178 2D9066070BE141D400956998 /* LayoutState.h in Headers */, 28179 555130011E7CCCCB00A69E38 /* DecodingOptions.h in Headers */, 28176 28180 141DC0481648348F00371E5A /* LayoutUnit.h in Headers */, 28177 28181 CDE8B5ED1A69777300B4B66A /* LegacyCDMPrivateClearKey.h in Headers */, -
trunk/Source/WebCore/platform/graphics/BitmapImage.cpp
r214241 r214450 103 103 } 104 104 105 NativeImagePtr BitmapImage::frameImageAtIndex (size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing, const GraphicsContext* targetContext)106 { 107 if (!frameHas ValidNativeImageAtIndex(index, subsamplingLevel, sizeForDrawing)) {105 NativeImagePtr BitmapImage::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext) 106 { 107 if (!frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel)) { 108 108 LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel was %d, resampling]", __FUNCTION__, this, sourceURL().utf8().data(), static_cast<int>(frameSubsamplingLevelAtIndex(index))); 109 109 invalidatePlatformData(); 110 110 } 111 111 112 return m_source.frameImageAtIndex (index, subsamplingLevel, sizeForDrawing, targetContext);112 return m_source.frameImageAtIndexCacheIfNeeded(index, subsamplingLevel, targetContext); 113 113 } 114 114 115 115 NativeImagePtr BitmapImage::nativeImage(const GraphicsContext* targetContext) 116 116 { 117 return frameImageAtIndex (0, SubsamplingLevel::Default, { }, targetContext);117 return frameImageAtIndexCacheIfNeeded(0, SubsamplingLevel::Default, targetContext); 118 118 } 119 119 120 120 NativeImagePtr BitmapImage::nativeImageForCurrentFrame(const GraphicsContext* targetContext) 121 121 { 122 return frameImageAtIndex (m_currentFrame, SubsamplingLevel::Default, { }, targetContext);122 return frameImageAtIndexCacheIfNeeded(m_currentFrame, SubsamplingLevel::Default, targetContext); 123 123 } 124 124 … … 129 129 130 130 for (size_t i = 0; i < count; ++i) { 131 auto image = frameImageAtIndex (i, SubsamplingLevel::Default, { }, targetContext);131 auto image = frameImageAtIndexCacheIfNeeded(i, SubsamplingLevel::Default, targetContext); 132 132 if (image && nativeImageSize(image) == size) 133 133 return image; … … 135 135 136 136 // Fallback to the first frame image if we can't find the right size 137 return frameImageAtIndex (0, SubsamplingLevel::Default, { }, targetContext);137 return frameImageAtIndexCacheIfNeeded(0, SubsamplingLevel::Default, targetContext); 138 138 } 139 139 … … 144 144 145 145 for (size_t i = 0; i < count; ++i) { 146 if (auto image = frameImageAtIndex (i))146 if (auto image = frameImageAtIndexCacheIfNeeded(i)) 147 147 images.append(image); 148 148 } … … 159 159 #endif 160 160 161 void BitmapImage::draw(GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode mode, ImageOrientationDescription description)161 void BitmapImage::draw(GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode mode, DecodingMode decodingMode, ImageOrientationDescription description) 162 162 { 163 163 if (destRect.isEmpty() || srcRect.isEmpty()) … … 166 166 float scale = subsamplingScale(context, destRect, srcRect); 167 167 m_currentSubsamplingLevel = allowSubsampling() ? m_source.subsamplingLevelForScale(scale) : SubsamplingLevel::Default; 168 m_sizeForDrawing = enclosingIntRect(context.getCTM().mapRect(destRect)).size();168 IntSize sizeForDrawing = enclosingIntRect(context.getCTM().mapRect(destRect)).size(); 169 169 170 170 LOG(Images, "BitmapImage::%s - %p - url: %s [subsamplingLevel = %d scale = %.4f]", __FUNCTION__, this, sourceURL().utf8().data(), static_cast<int>(m_currentSubsamplingLevel), scale); 171 171 172 StartAnimationResult result = internalStartAnimation();173 if (result == StartAnimationResult::DecodingActive && showDebugBackground()) {174 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op);175 return;176 }177 178 ASSERT_IMPLIES(result == StartAnimationResult::DecodingActive, m_source.frameHasValidNativeImageAtIndex(m_currentFrame, m_currentSubsamplingLevel, m_sizeForDrawing));179 180 172 NativeImagePtr image; 181 if (shouldUseAsyncDecodingForLargeImage()) { 182 if (m_source.frameHasValidNativeImageAtIndex(m_currentFrame, m_currentSubsamplingLevel, m_sizeForDrawing)) 183 image = frameImageAtIndex(m_currentFrame, m_currentSubsamplingLevel, m_sizeForDrawing, &context); 184 else { 185 ASSERT(!canAnimate() && !m_currentFrame); 186 if (!frameIsBeingDecodedAtIndex(m_currentFrame, m_sizeForDrawing)) { 187 m_source.requestFrameAsyncDecodingAtIndex(0, m_currentSubsamplingLevel, m_sizeForDrawing); 188 LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().utf8().data()); 173 if (decodingMode == DecodingMode::Asynchronous && shouldUseAsyncDecodingForLargeImages()) { 174 ASSERT(!canAnimate() && !m_currentFrame); 175 176 if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingOptions(sizeForDrawing)) 177 && !frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingOptions(sizeForDrawing))) { 178 m_source.requestFrameAsyncDecodingAtIndex(0, m_currentSubsamplingLevel, sizeForDrawing); 179 LOG(Images, "BitmapImage::%s - %p - url: %s [requesting large async decoding]", __FUNCTION__, this, sourceURL().utf8().data()); 180 } 181 182 if (!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(m_currentFrame, m_currentSubsamplingLevel, DecodingMode::Asynchronous)) { 183 if (showDebugBackground()) 184 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op); 185 return; 186 } 187 188 image = frameImageAtIndex(m_currentFrame); 189 } else { 190 StartAnimationStatus status = internalStartAnimation(); 191 ASSERT_IMPLIES(status == StartAnimationStatus::DecodingActive, frameHasFullSizeNativeImageAtIndex(m_currentFrame, m_currentSubsamplingLevel)); 192 193 if (status == StartAnimationStatus::DecodingActive && showDebugBackground()) { 194 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op); 195 return; 196 } 197 198 if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingMode::Asynchronous)) { 199 // FIXME: instead of showing the yellow rectangle and returning we need to wait for this the frame to finish decoding. 200 if (showDebugBackground()) { 201 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op); 202 LOG(Images, "BitmapImage::%s - %p - url: %s [waiting for async decoding to finish]", __FUNCTION__, this, sourceURL().utf8().data()); 189 203 } 190 191 if (!frameHasDecodedNativeImage(m_currentFrame)) { 192 if (showDebugBackground()) 193 fillWithSolidColor(context, destRect, Color(Color::yellow).colorWithAlpha(0.5), op); 194 return; 195 } 196 197 image = frameImageAtIndex(m_currentFrame); 198 } 199 } else { 200 ASSERT(!frameIsBeingDecodedAtIndex(m_currentFrame, m_sizeForDrawing)); 201 if (shouldUseAsyncDecodingForAnimatedImage()) 202 image = frameImageAtIndex(m_currentFrame); 203 else 204 image = frameImageAtIndex(m_currentFrame, m_currentSubsamplingLevel, { }, &context); 205 } 206 207 if (!image) // If it's too early we won't have an image yet. 208 return; 209 204 return; 205 } 206 207 image = frameImageAtIndexCacheIfNeeded(m_currentFrame, m_currentSubsamplingLevel, &context); 208 if (!image) // If it's too early we won't have an image yet. 209 return; 210 } 211 212 ASSERT(image); 210 213 Color color = singlePixelSolidColor(); 211 214 if (color.isValid()) { … … 244 247 setImageObserver(nullptr); 245 248 246 draw(buffer->context(), tileRect, tileRect, op, blendMode, ImageOrientationDescription());249 draw(buffer->context(), tileRect, tileRect, op, blendMode, DecodingMode::Synchronous, ImageOrientationDescription()); 247 250 248 251 setImageObserver(observer); … … 268 271 } 269 272 270 bool BitmapImage::shouldUseAsyncDecodingForLargeImage ()271 { 272 return !canAnimate() && allowLargeImageAsyncDecoding() && (shouldUseAsyncDecodingForTesting() || m_source.shouldUseAsyncDecoding());273 } 274 275 bool BitmapImage::shouldUseAsyncDecodingForAnimatedImage ()276 { 277 return canAnimate() && allowAnimatedImageAsyncDecoding() && (shouldUseAsyncDecodingFor Testing() || m_source.shouldUseAsyncDecoding());273 bool BitmapImage::shouldUseAsyncDecodingForLargeImages() 274 { 275 return !canAnimate() && allowLargeImageAsyncDecoding() && m_source.shouldUseAsyncDecoding(); 276 } 277 278 bool BitmapImage::shouldUseAsyncDecodingForAnimatedImages() 279 { 280 return canAnimate() && allowAnimatedImageAsyncDecoding() && (shouldUseAsyncDecodingForAnimatedImagesForTesting() || m_source.shouldUseAsyncDecoding()); 278 281 } 279 282 … … 290 293 } 291 294 292 BitmapImage::StartAnimation ResultBitmapImage::internalStartAnimation()295 BitmapImage::StartAnimationStatus BitmapImage::internalStartAnimation() 293 296 { 294 297 if (!canAnimate()) 295 return StartAnimation Result::CannotStart;298 return StartAnimationStatus::CannotStart; 296 299 297 300 if (m_frameTimer) 298 return StartAnimation Result::TimerActive;301 return StartAnimationStatus::TimerActive; 299 302 300 303 // Don't start a new animation until we draw the frame that is currently being decoded. 301 304 size_t nextFrame = (m_currentFrame + 1) % frameCount(); 302 if (frameIsBeingDecodedA tIndex(nextFrame, m_sizeForDrawing)) {305 if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(nextFrame, DecodingMode::Asynchronous)) { 303 306 LOG(Images, "BitmapImage::%s - %p - url: %s [nextFrame = %ld is being decoded]", __FUNCTION__, this, sourceURL().utf8().data(), nextFrame); 304 return StartAnimation Result::DecodingActive;307 return StartAnimationStatus::DecodingActive; 305 308 } 306 309 … … 311 314 // wait on it. 312 315 if (!m_source.isAllDataReceived() && repetitionCount() == RepetitionCountOnce) 313 return StartAnimation Result::IncompleteData;316 return StartAnimationStatus::IncompleteData; 314 317 315 318 ++m_repetitionsComplete; … … 319 322 m_animationFinished = true; 320 323 destroyDecodedDataIfNecessary(false); 321 return StartAnimation Result::CannotStart;324 return StartAnimationStatus::CannotStart; 322 325 } 323 326 … … 327 330 // Don't advance the animation to an incomplete frame. 328 331 if (!m_source.isAllDataReceived() && !frameIsCompleteAtIndex(nextFrame)) 329 return StartAnimation Result::IncompleteData;332 return StartAnimationStatus::IncompleteData; 330 333 331 334 double time = monotonicallyIncreasingTime(); … … 342 345 // through the callback newFrameNativeImageAvailableAtIndex(). Otherwise, advanceAnimation() will be called 343 346 // when the timer fires and m_currentFrame will be advanced to nextFrame since it is not being decoded. 344 if (shouldUseAsyncDecodingForAnimatedImage ()) {345 bool isAsyncDecode = m_source.requestFrameAsyncDecodingAtIndex(nextFrame, m_currentSubsamplingLevel , m_sizeForDrawing);347 if (shouldUseAsyncDecodingForAnimatedImages()) { 348 bool isAsyncDecode = m_source.requestFrameAsyncDecodingAtIndex(nextFrame, m_currentSubsamplingLevel); 346 349 347 350 #if !LOG_DISABLED … … 361 364 ASSERT(!m_frameTimer); 362 365 startTimer(m_desiredFrameStartTime - time); 363 return StartAnimation Result::Started;366 return StartAnimationStatus::Started; 364 367 } 365 368 … … 370 373 // Pretend as if decoding nextFrame has taken m_frameDecodingDurationForTesting from 371 374 // the time this decoding was requested. 372 if (shouldUseAsyncDecodingFor Testing()) {375 if (shouldUseAsyncDecodingForAnimatedImagesForTesting()) { 373 376 double time = monotonicallyIncreasingTime(); 374 377 // Start a timer with the remaining time from now till the m_desiredFrameDecodeTime. … … 381 384 // Don't advance to nextFrame unless its decoding has finished or was not required. 382 385 size_t nextFrame = (m_currentFrame + 1) % frameCount(); 383 if (!frameIsBeingDecodedA tIndex(nextFrame, m_sizeForDrawing))386 if (!frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(nextFrame, DecodingMode::Asynchronous)) 384 387 internalAdvanceAnimation(); 385 388 else { … … 394 397 { 395 398 m_currentFrame = (m_currentFrame + 1) % frameCount(); 396 ASSERT(!frameIsBeingDecodedA tIndex(m_currentFrame, m_sizeForDrawing));399 ASSERT(!frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(m_currentFrame, DecodingMode::Asynchronous)); 397 400 398 401 destroyDecodedDataIfNecessary(false); -
trunk/Source/WebCore/platform/graphics/BitmapImage.h
r214103 r214450 82 82 IntSize sizeRespectingOrientation() const { return m_source.sizeRespectingOrientation(); } 83 83 Color singlePixelSolidColor() const override { return m_source.singlePixelSolidColor(); } 84 85 bool frameIsBeingDecodedAtIndex(size_t index, const std::optional<IntSize>& sizeForDrawing) const { return m_source.frameIsBeingDecodedAtIndex(index, sizeForDrawing); } 86 bool frameHasDecodedNativeImage(size_t index) const { return m_source.frameHasDecodedNativeImage(index); } 84 bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) const { return m_source.frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); } 87 85 bool frameIsCompleteAtIndex(size_t index) const { return m_source.frameIsCompleteAtIndex(index); } 88 86 bool frameHasAlphaAtIndex(size_t index) const { return m_source.frameHasAlphaAtIndex(index); } 89 bool frameHasValidNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) const { return m_source.frameHasValidNativeImageAtIndex(index, subsamplingLevel, sizeForDrawing); } 87 88 bool frameHasFullSizeNativeImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) { return m_source.frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); } 89 bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_source.frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); } 90 90 91 SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) const { return m_source.frameSubsamplingLevelAtIndex(index); } 91 92 … … 97 98 ImageOrientation orientationForCurrentFrame() const override { return frameOrientationAtIndex(currentFrame()); } 98 99 99 bool shouldUseAsyncDecodingFor Testing() const { return m_frameDecodingDurationForTesting > 0; }100 bool shouldUseAsyncDecodingForAnimatedImagesForTesting() const { return m_frameDecodingDurationForTesting > 0; } 100 101 void setFrameDecodingDurationForTesting(float duration) { m_frameDecodingDurationForTesting = duration; } 101 bool shouldUseAsyncDecodingForLargeImage ();102 bool shouldUseAsyncDecodingForAnimatedImage ();102 bool shouldUseAsyncDecodingForLargeImages(); 103 bool shouldUseAsyncDecodingForAnimatedImages(); 103 104 void setClearDecoderAfterAsyncFrameRequestForTesting(bool value) { m_clearDecoderAfterAsyncFrameRequestForTesting = value; } 104 105 … … 133 134 WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr); 134 135 135 NativeImagePtr frameImageAtIndex(size_t, const std::optional<SubsamplingLevel>& = { }, const std::optional<IntSize>& sizeForDrawing = { }, const GraphicsContext* = nullptr); 136 NativeImagePtr frameImageAtIndex(size_t index) { return m_source.frameImageAtIndex(index); } 137 NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr); 136 138 137 139 String sourceURL() const { return imageObserver() ? imageObserver()->sourceUrl().string() : emptyString(); } … … 153 155 void destroyDecodedDataIfNecessary(bool destroyAll = true); 154 156 155 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override;157 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) override; 156 158 void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode = BlendModeNormal) override; 157 159 #if PLATFORM(WIN) … … 160 162 161 163 // Animation. 162 enum class StartAnimation Result{ CannotStart, IncompleteData, TimerActive, DecodingActive, Started };164 enum class StartAnimationStatus { CannotStart, IncompleteData, TimerActive, DecodingActive, Started }; 163 165 bool isAnimated() const override { return m_source.frameCount() > 1; } 164 166 bool shouldAnimate(); 165 167 bool canAnimate(); 166 168 void startAnimation() override { internalStartAnimation(); } 167 StartAnimation ResultinternalStartAnimation();169 StartAnimationStatus internalStartAnimation(); 168 170 void advanceAnimation(); 169 171 void internalAdvanceAnimation(); … … 204 206 size_t m_currentFrame { 0 }; // The index of the current frame of animation. 205 207 SubsamplingLevel m_currentSubsamplingLevel { SubsamplingLevel::Default }; 206 IntSize m_sizeForDrawing;207 208 std::unique_ptr<Timer> m_frameTimer; 208 209 RepetitionCount m_repetitionsComplete { RepetitionCountNone }; // How many repetitions we've finished. -
trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp
r206631 r214450 87 87 } 88 88 89 void CrossfadeGeneratedImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)89 void CrossfadeGeneratedImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, DecodingMode, ImageOrientationDescription) 90 90 { 91 91 GraphicsContextStateSaver stateSaver(context); -
trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.h
r206631 r214450 50 50 51 51 protected: 52 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override;52 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) override; 53 53 void drawPattern(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode) override; 54 54 -
trunk/Source/WebCore/platform/graphics/GeneratedImage.h
r206631 r214450 48 48 49 49 protected: 50 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override = 0;50 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) override = 0; 51 51 void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, 52 52 const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode) override = 0; -
trunk/Source/WebCore/platform/graphics/GradientImage.cpp
r210215 r214450 42 42 } 43 43 44 void GradientImage::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)44 void GradientImage::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, DecodingMode, ImageOrientationDescription) 45 45 { 46 46 GraphicsContextStateSaver stateSaver(destContext); -
trunk/Source/WebCore/platform/graphics/GradientImage.h
r210215 r214450 45 45 GradientImage(Gradient&, const FloatSize&); 46 46 47 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) final;47 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) final; 48 48 void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode) final; 49 49 bool isGradientImage() const final { return true; } -
trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp
r208985 r214450 729 729 730 730 InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_interpolationQuality); 731 image.draw(*this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode, imagePaintingOptions.m_ orientationDescription);731 image.draw(*this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode, imagePaintingOptions.m_decodingMode, imagePaintingOptions.m_orientationDescription); 732 732 } 733 733 -
trunk/Source/WebCore/platform/graphics/GraphicsContext.h
r208985 r214450 189 189 190 190 struct ImagePaintingOptions { 191 ImagePaintingOptions(CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), InterpolationQuality interpolationQuality = InterpolationDefault)191 ImagePaintingOptions(CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, DecodingMode decodingMode = DecodingMode::Synchronous, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), InterpolationQuality interpolationQuality = InterpolationDefault) 192 192 : m_compositeOperator(compositeOperator) 193 193 , m_blendMode(blendMode) 194 , m_decodingMode(decodingMode) 194 195 , m_orientationDescription(orientationDescription) 195 196 , m_interpolationQuality(interpolationQuality) … … 197 198 } 198 199 199 ImagePaintingOptions(ImageOrientationDescription orientationDescription, InterpolationQuality interpolationQuality = InterpolationDefault, CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal )200 ImagePaintingOptions(ImageOrientationDescription orientationDescription, InterpolationQuality interpolationQuality = InterpolationDefault, CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, DecodingMode decodingMode = DecodingMode::Synchronous) 200 201 : m_compositeOperator(compositeOperator) 201 202 , m_blendMode(blendMode) 203 , m_decodingMode(decodingMode) 202 204 , m_orientationDescription(orientationDescription) 203 205 , m_interpolationQuality(interpolationQuality) … … 205 207 } 206 208 207 ImagePaintingOptions(InterpolationQuality interpolationQuality, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal )209 ImagePaintingOptions(InterpolationQuality interpolationQuality, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, DecodingMode decodingMode = DecodingMode::Synchronous) 208 210 : m_compositeOperator(compositeOperator) 209 211 , m_blendMode(blendMode) 212 , m_decodingMode(decodingMode) 210 213 , m_orientationDescription(orientationDescription) 211 214 , m_interpolationQuality(interpolationQuality) … … 217 220 CompositeOperator m_compositeOperator; 218 221 BlendMode m_blendMode; 222 DecodingMode m_decodingMode; 219 223 ImageOrientationDescription m_orientationDescription; 220 224 InterpolationQuality m_interpolationQuality; -
trunk/Source/WebCore/platform/graphics/Image.cpp
r210828 r214450 127 127 visibleSrcRect.setWidth(destRect.width() / scale.width()); 128 128 visibleSrcRect.setHeight(destRect.height() / scale.height()); 129 draw(ctxt, destRect, visibleSrcRect, op, blendMode, ImageOrientationDescription());129 draw(ctxt, destRect, visibleSrcRect, op, blendMode, DecodingMode::Synchronous, ImageOrientationDescription()); 130 130 return; 131 131 } … … 140 140 visibleSrcRect.setWidth(1); 141 141 visibleSrcRect.setHeight(destRect.height() / scale.height()); 142 draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, ImageOrientationDescription());142 draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 143 143 return; 144 144 } … … 149 149 visibleSrcRect.setWidth(destRect.width() / scale.width()); 150 150 visibleSrcRect.setHeight(1); 151 draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, ImageOrientationDescription());151 draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 152 152 return; 153 153 } … … 181 181 fromRect.scale(1 / scale.width(), 1 / scale.height()); 182 182 183 draw(ctxt, toRect, fromRect, op, BlendModeNormal, ImageOrientationDescription());183 draw(ctxt, toRect, fromRect, op, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 184 184 toX += currentTileRect.width(); 185 185 currentTileRect.shiftXEdgeTo(oneTileRect.x()); -
trunk/Source/WebCore/platform/graphics/Image.h
r213715 r214450 29 29 30 30 #include "Color.h" 31 #include "DecodingOptions.h" 31 32 #include "FloatRect.h" 32 33 #include "FloatSize.h" … … 185 186 virtual void drawFrameMatchingSourceSize(GraphicsContext&, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator) { } 186 187 #endif 187 virtual void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) = 0;188 virtual void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) = 0; 188 189 void drawTiled(GraphicsContext&, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, const FloatSize& spacing, CompositeOperator, BlendMode); 189 190 void drawTiled(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, const FloatSize& tileScaleFactor, TileRule hRule, TileRule vRule, CompositeOperator); -
trunk/Source/WebCore/platform/graphics/ImageFrame.cpp
r213563 r214450 64 64 m_nativeImage = other.m_nativeImage; 65 65 m_subsamplingLevel = other.m_subsamplingLevel; 66 m_ sizeForDrawing = other.m_sizeForDrawing;66 m_decodingOptions = other.m_decodingOptions; 67 67 68 68 m_orientation = other.m_orientation; … … 86 86 clearNativeImageSubimages(m_nativeImage); 87 87 m_nativeImage = nullptr; 88 m_decodingOptions = { }; 88 89 89 90 return frameBytes; … … 126 127 } 127 128 128 static int maxDimension(const IntSize& size) 129 bool ImageFrame::hasNativeImage(const std::optional<SubsamplingLevel>& subsamplingLevel) const 129 130 { 130 return std::max(size.width(), size.height());131 return m_nativeImage && (!subsamplingLevel || *subsamplingLevel >= m_subsamplingLevel); 131 132 } 132 133 133 bool ImageFrame:: isBeingDecoded(const std::optional<IntSize>& sizeForDrawing) const134 bool ImageFrame::hasFullSizeNativeImage(const std::optional<SubsamplingLevel>& subsamplingLevel) const 134 135 { 135 if (!m_sizeForDecoding.size()) 136 return false; 137 138 if (!sizeForDrawing) 139 return true; 136 return hasNativeImage(subsamplingLevel) && (m_decodingOptions.isSynchronous() || m_decodingOptions.hasFullSize()); 137 } 140 138 141 // Return true if the ImageFrame will be decoded eventually with a suitable sizeForDecoding. 142 return maxDimension(m_sizeForDecoding.last()) >= maxDimension(*sizeForDrawing); 143 } 144 145 bool ImageFrame::hasValidNativeImage(const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) const 139 bool ImageFrame::hasDecodedNativeImageCompatibleWithOptions(const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) const 146 140 { 147 ASSERT_IMPLIES(!subsamplingLevel, !sizeForDrawing); 148 149 if (!hasNativeImage()) 150 return false; 151 152 // The caller does not care about subsamplingLevel or sizeForDrawing. The current NativeImage is fine. 153 if (!subsamplingLevel) 154 return true; 155 156 if (*subsamplingLevel < m_subsamplingLevel) 157 return false; 158 159 // The NativeImage was decoded with the native size. So it is valid for any size. 160 if (!m_sizeForDrawing) 161 return true; 162 163 // The NativeImage was decoded for a specific size. The two sizeForDrawings have to match. 164 return sizeForDrawing && maxDimension(*m_sizeForDrawing) >= maxDimension(*sizeForDrawing); 141 return hasNativeImage(subsamplingLevel) && m_decodingOptions.isAsynchronousCompatibleWith(decodingOptions); 165 142 } 166 143 -
trunk/Source/WebCore/platform/graphics/ImageFrame.h
r213563 r214450 27 27 28 28 #include "Color.h" 29 #include "DecodingOptions.h" 29 30 #include "ImageBackingStore.h" 30 31 #include "ImageOrientation.h" … … 99 100 void setDecoding(Decoding decoding) { m_decoding = decoding; } 100 101 Decoding decoding() const { return m_decoding; } 101 void enqueueSizeForDecoding(const IntSize& sizeForDecoding) { m_sizeForDecoding.append(sizeForDecoding); }102 void dequeueSizeForDecoding() { m_sizeForDecoding.removeFirst(); }103 void clearSizeForDecoding() { m_sizeForDecoding.clear(); }104 102 105 103 bool isEmpty() const { return m_decoding == Decoding::None; } 106 bool isBeingDecoded(const std::optional<IntSize>& sizeForDrawing = { }) const;107 104 bool isPartial() const { return m_decoding == Decoding::Partial; } 108 105 bool isComplete() const { return m_decoding == Decoding::Complete; } … … 112 109 unsigned frameBytes() const { return hasNativeImage() ? (size().area() * sizeof(RGBA32)).unsafeGet() : 0; } 113 110 SubsamplingLevel subsamplingLevel() const { return m_subsamplingLevel; } 114 std::optional<IntSize> sizeForDrawing() const { return m_sizeForDrawing; }115 111 116 112 #if !USE(CG) … … 131 127 bool hasAlpha() const { return !hasMetadata() || m_hasAlpha; } 132 128 133 bool hasNativeImage( ) const { return m_nativeImage; }134 bool has ValidNativeImage(const std::optional<SubsamplingLevel>&, const std::optional<IntSize>& sizeForDrawing) const;135 bool hasDecodedNativeImage () const { return hasNativeImage() && sizeForDrawing(); }129 bool hasNativeImage(const std::optional<SubsamplingLevel>& = { }) const; 130 bool hasFullSizeNativeImage(const std::optional<SubsamplingLevel>& = { }) const; 131 bool hasDecodedNativeImageCompatibleWithOptions(const std::optional<SubsamplingLevel>&, const DecodingOptions&) const; 136 132 bool hasMetadata() const { return !size().isEmpty(); } 137 133 … … 154 150 NativeImagePtr m_nativeImage; 155 151 SubsamplingLevel m_subsamplingLevel { SubsamplingLevel::Default }; 156 std::optional<IntSize> m_sizeForDrawing; 157 Deque<IntSize, 4> m_sizeForDecoding; 152 DecodingOptions m_decodingOptions; 158 153 159 154 ImageOrientation m_orientation { DefaultImageOrientation }; -
trunk/Source/WebCore/platform/graphics/ImageFrameCache.cpp
r214084 r214450 193 193 } 194 194 195 void ImageFrameCache::setFrameNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) 196 { 197 ASSERT(index < m_frames.size()); 198 ImageFrame& frame = m_frames[index]; 199 200 ASSERT(isDecoderAvailable()); 201 202 frame.m_nativeImage = WTFMove(nativeImage); 203 setFrameMetadataAtIndex(index, subsamplingLevel, sizeForDrawing); 204 } 205 206 void ImageFrameCache::setFrameMetadataAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) 195 void ImageFrameCache::cacheFrameMetadataAtIndex(size_t index, SubsamplingLevel subsamplingLevel) 207 196 { 208 197 ASSERT(index < m_frames.size()); … … 216 205 frame.m_subsamplingLevel = subsamplingLevel; 217 206 218 if (!sizeForDrawing) { 219 frame.m_size = m_decoder->frameSizeAtIndex(index, frame.m_subsamplingLevel); 220 frame.m_sizeForDrawing = { }; 221 } else { 222 ASSERT(frame.nativeImage()); 207 if (frame.m_decodingOptions.hasSizeForDrawing()) { 208 ASSERT(frame.hasNativeImage()); 223 209 frame.m_size = nativeImageSize(frame.nativeImage()); 224 frame.m_sizeForDrawing = sizeForDrawing;225 }210 } else 211 frame.m_size = m_decoder->frameSizeAtIndex(index, subsamplingLevel); 226 212 227 213 frame.m_orientation = m_decoder->frameOrientationAtIndex(index); … … 232 218 } 233 219 234 void ImageFrameCache:: replaceFrameNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing)220 void ImageFrameCache::cacheFrameNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions) 235 221 { 236 222 ASSERT(index < m_frames.size()); 237 223 ImageFrame& frame = m_frames[index]; 238 224 239 if (!frame.hasValidNativeImage(subsamplingLevel, sizeForDrawing)) { 240 // Clear the current image frame and update the observer with this clearance. 241 unsigned decodedSize = frame.clear(); 242 decodedSizeDecreased(decodedSize); 243 } 225 // Clear the current image frame and update the observer with this clearance. 226 decodedSizeDecreased(frame.clear()); 244 227 245 228 // Do not cache the NativeImage if adding its frameByes to the MemoryCache will cause numerical overflow. … … 248 231 return; 249 232 250 // Copy the new image to the cache. 251 setFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, sizeForDrawing); 233 // Move the new image to the cache. 234 frame.m_nativeImage = WTFMove(nativeImage); 235 frame.m_decodingOptions = decodingOptions; 236 cacheFrameMetadataAtIndex(index, subsamplingLevel); 252 237 253 238 // Update the observer with the new image frame bytes. … … 255 240 } 256 241 257 void ImageFrameCache::cache FrameNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const IntSize& sizeForDrawing)242 void ImageFrameCache::cacheAsyncFrameNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions) 258 243 { 259 244 if (!isDecoderAvailable()) … … 261 246 262 247 ASSERT(index < m_frames.size()); 263 ASSERT( m_frames[index].isBeingDecoded(sizeForDrawing));248 ASSERT(!frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions)); 264 249 265 250 // Clean the old native image and set a new one 266 replaceFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, sizeForDrawing); 267 m_frames[index].dequeueSizeForDecoding(); 251 cacheFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel, decodingOptions); 268 252 269 253 // Notify the image with the readiness of the new frame NativeImage. … … 299 283 300 284 // Get the frame NativeImage on the decoding thread. 301 NativeImagePtr nativeImage = protectedDecoder->createFrameImageAtIndex(frameRequest.index, frameRequest.subsamplingLevel, frameRequest. sizeForDrawing);285 NativeImagePtr nativeImage = protectedDecoder->createFrameImageAtIndex(frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions); 302 286 303 287 // Update the cached frames on the main thread to avoid updating the MemoryCache from a different thread. 304 288 callOnMainThread([this, protectedQueue = protectedQueue.copyRef(), nativeImage, frameRequest] () mutable { 305 289 // The queue may be closed if after we got the frame NativeImage, stopAsyncDecodingQueue() was called 306 if (protectedQueue.ptr() == m_decodingQueue) 307 cacheFrameNativeImageAtIndex(WTFMove(nativeImage), frameRequest.index, frameRequest.subsamplingLevel, frameRequest.sizeForDrawing); 290 if (protectedQueue.ptr() == m_decodingQueue) { 291 ASSERT(m_frameCommitQueue.first() == frameRequest); 292 m_frameCommitQueue.removeFirst(); 293 cacheAsyncFrameNativeImageAtIndex(WTFMove(nativeImage), frameRequest.index, frameRequest.subsamplingLevel, frameRequest.decodingOptions); 294 } 308 295 }); 309 296 } … … 311 298 } 312 299 313 bool ImageFrameCache::requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const IntSize& sizeForDrawing)300 bool ImageFrameCache::requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) 314 301 { 315 302 if (!isDecoderAvailable()) … … 317 304 318 305 ASSERT(index < m_frames.size()); 319 ImageFrame& frame = m_frames[index];320 306 321 307 // We need to coalesce multiple requests for decoding the same ImageFrame while it 322 308 // is still being decoded. This may happen if the image rectangle is repainted 323 309 // multiple times while the ImageFrame has not finished decoding. 324 if (frame .isBeingDecoded(sizeForDrawing))310 if (frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, sizeForDrawing)) 325 311 return true; 326 312 327 if (frame .hasValidNativeImage(subsamplingLevel, sizeForDrawing))313 if (frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, sizeForDrawing)) 328 314 return false; 329 315 330 316 if (!hasAsyncDecodingQueue()) 331 317 startAsyncDecodingQueue(); 332 333 frame.enqueueSizeForDecoding(sizeForDrawing); 318 334 319 m_frameRequestQueue.enqueue({ index, subsamplingLevel, sizeForDrawing }); 320 m_frameCommitQueue.append({ index, subsamplingLevel, sizeForDrawing }); 335 321 return true; 336 322 } … … 338 324 bool ImageFrameCache::isAsyncDecodingQueueIdle() const 339 325 { 340 for (const ImageFrame& frame : m_frames) { 341 if (frame.isBeingDecoded()) 342 return false; 343 } 344 return true; 326 return m_frameCommitQueue.isEmpty(); 345 327 } 346 328 … … 350 332 return; 351 333 334 std::for_each(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [this](const ImageFrameRequest& frameRequest) { 335 ImageFrame& frame = m_frames[frameRequest.index]; 336 if (!frame.isEmpty()) 337 frame.clear(); 338 }); 339 352 340 m_frameRequestQueue.close(); 341 m_frameCommitQueue.clear(); 353 342 m_decodingQueue = nullptr; 354 355 for (ImageFrame& frame : m_frames) { 356 if (frame.isBeingDecoded()) { 357 frame.clearSizeForDecoding(); 358 frame.clear(); 359 } 360 } 361 } 362 363 const ImageFrame& ImageFrameCache::frameAtIndexCacheIfNeeded(size_t index, ImageFrame::Caching caching, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) 343 } 344 345 const ImageFrame& ImageFrameCache::frameAtIndexCacheIfNeeded(size_t index, ImageFrame::Caching caching, const std::optional<SubsamplingLevel>& subsamplingLevel) 364 346 { 365 347 ASSERT(index < m_frames.size()); 366 348 ImageFrame& frame = m_frames[index]; 367 if (!isDecoderAvailable() || frame .isBeingDecoded(sizeForDrawing))349 if (!isDecoderAvailable() || frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, DecodingMode::Asynchronous)) 368 350 return frame; 369 351 … … 375 357 if (frame.isComplete()) 376 358 break; 377 setFrameMetadataAtIndex(index, subsamplingLevelValue, frame.sizeForDrawing());359 cacheFrameMetadataAtIndex(index, subsamplingLevelValue); 378 360 break; 379 361 380 362 case ImageFrame::Caching::MetadataAndImage: 381 363 // Cache the image and retrieve the metadata from ImageDecoder only if there was not valid image stored. 382 if (frame.has ValidNativeImage(subsamplingLevel, sizeForDrawing))364 if (frame.hasFullSizeNativeImage(subsamplingLevel)) 383 365 break; 384 // We have to perform synchronous image decoding in this code path regardless of the sizeForDrawing value. 385 // So pass an empty sizeForDrawing to create an ImageFrame with the native size. 386 replaceFrameNativeImageAtIndex(m_decoder->createFrameImageAtIndex(index, subsamplingLevelValue, { }), index, subsamplingLevelValue, { }); 366 // We have to perform synchronous image decoding in this code. 367 NativeImagePtr nativeImage = m_decoder->createFrameImageAtIndex(index, subsamplingLevelValue); 368 // Clean the old native image and set a new one. 369 cacheFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevelValue, DecodingMode::Synchronous); 387 370 break; 388 371 } … … 482 465 Color ImageFrameCache::singlePixelSolidColor() 483 466 { 484 return frameCount() == 1 ? frameMetadataAtIndexCacheIfNeeded<Color>(0, (&ImageFrame::singlePixelSolidColor), &m_singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage) : Color(); 485 } 486 487 bool ImageFrameCache::frameIsBeingDecodedAtIndex(size_t index, const std::optional<IntSize>& sizeForDrawing) 488 { 489 return frameMetadataAtIndex<bool>(index, (&ImageFrame::isBeingDecoded), sizeForDrawing); 467 if (!m_singlePixelSolidColor && (size() != IntSize(1, 1) || frameCount() != 1)) 468 m_singlePixelSolidColor = Color(); 469 470 if (m_singlePixelSolidColor) 471 return m_singlePixelSolidColor.value(); 472 473 return frameMetadataAtIndexCacheIfNeeded<Color>(0, (&ImageFrame::singlePixelSolidColor), &m_singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage); 474 } 475 476 bool ImageFrameCache::frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) 477 { 478 auto it = std::find_if(m_frameCommitQueue.begin(), m_frameCommitQueue.end(), [index, &decodingOptions](const ImageFrameRequest& frameRequest) { 479 return frameRequest.index == index && frameRequest.decodingOptions.isAsynchronousCompatibleWith(decodingOptions); 480 }); 481 return it != m_frameCommitQueue.end(); 490 482 } 491 483 … … 500 492 } 501 493 502 bool ImageFrameCache::frameHasImageAtIndex(size_t index) 503 { 504 return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasNativeImage)); 505 } 506 507 bool ImageFrameCache::frameHasValidNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) 508 { 509 return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasValidNativeImage), subsamplingLevel, sizeForDrawing); 510 } 511 512 bool ImageFrameCache::frameHasDecodedNativeImage(size_t index) 513 { 514 return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasDecodedNativeImage)); 515 } 516 494 bool ImageFrameCache::frameHasFullSizeNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel) 495 { 496 return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasFullSizeNativeImage), subsamplingLevel); 497 } 498 499 bool ImageFrameCache::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) 500 { 501 return frameMetadataAtIndex<bool>(index, (&ImageFrame::hasDecodedNativeImageCompatibleWithOptions), subsamplingLevel, decodingOptions); 502 } 503 517 504 SubsamplingLevel ImageFrameCache::frameSubsamplingLevelAtIndex(size_t index) 518 505 { … … 540 527 } 541 528 542 NativeImagePtr ImageFrameCache::frameImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) 543 { 544 return frameMetadataAtIndexCacheIfNeeded<NativeImagePtr>(index, (&ImageFrame::nativeImage), nullptr, ImageFrame::Caching::MetadataAndImage, subsamplingLevel, sizeForDrawing); 545 } 546 547 } 529 NativeImagePtr ImageFrameCache::frameImageAtIndex(size_t index) 530 { 531 return frameMetadataAtIndex<NativeImagePtr>(index, (&ImageFrame::nativeImage)); 532 } 533 534 NativeImagePtr ImageFrameCache::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel) 535 { 536 return frameMetadataAtIndexCacheIfNeeded<NativeImagePtr>(index, (&ImageFrame::nativeImage), nullptr, ImageFrame::Caching::MetadataAndImage, subsamplingLevel); 537 } 538 539 } -
trunk/Source/WebCore/platform/graphics/ImageFrameCache.h
r213833 r214450 70 70 // Asynchronous image decoding 71 71 void startAsyncDecodingQueue(); 72 bool requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const IntSize&);72 bool requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>&); 73 73 void stopAsyncDecodingQueue(); 74 74 bool hasAsyncDecodingQueue() const { return m_decodingQueue; } … … 90 90 91 91 // ImageFrame metadata which does not require caching the ImageFrame. 92 bool frameIsBeingDecodedA tIndex(size_t, const std::optional<IntSize>& sizeForDrawing);92 bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t, const DecodingOptions&); 93 93 bool frameIsCompleteAtIndex(size_t); 94 94 bool frameHasAlphaAtIndex(size_t); 95 95 bool frameHasImageAtIndex(size_t); 96 bool frameHas ValidNativeImageAtIndex(size_t, const std::optional<SubsamplingLevel>&, const std::optional<IntSize>& sizeForDrawing);97 bool frameHasDecodedNativeImage (size_t);96 bool frameHasFullSizeNativeImageAtIndex(size_t, const std::optional<SubsamplingLevel>&); 97 bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t, const std::optional<SubsamplingLevel>&, const DecodingOptions&); 98 98 SubsamplingLevel frameSubsamplingLevelAtIndex(size_t); 99 99 … … 103 103 float frameDurationAtIndex(size_t); 104 104 ImageOrientation frameOrientationAtIndex(size_t); 105 NativeImagePtr frameImageAtIndex(size_t, const std::optional<SubsamplingLevel>&, const std::optional<IntSize>& sizeForDrawing); 105 106 NativeImagePtr frameImageAtIndex(size_t); 107 NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel); 106 108 107 109 private: … … 127 129 128 130 void setNativeImage(NativeImagePtr&&); 129 void setFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const std::optional<IntSize>& sizeForDrawing); 130 void setFrameMetadataAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>& sizeForDrawing); 131 void replaceFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const std::optional<IntSize>& sizeForDrawing); 132 void cacheFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const IntSize& sizeForDrawing); 131 void cacheFrameMetadataAtIndex(size_t, SubsamplingLevel); 132 void cacheFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&); 133 void cacheAsyncFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&); 133 134 134 135 Ref<WorkQueue> decodingQueue(); 135 136 136 const ImageFrame& frameAtIndexCacheIfNeeded(size_t, ImageFrame::Caching, const std::optional<SubsamplingLevel>& = { } , const std::optional<IntSize>& sizeForDrawing = { });137 const ImageFrame& frameAtIndexCacheIfNeeded(size_t, ImageFrame::Caching, const std::optional<SubsamplingLevel>& = { }); 137 138 138 139 Image* m_image { nullptr }; … … 147 148 size_t index; 148 149 SubsamplingLevel subsamplingLevel; 149 IntSize sizeForDrawing; 150 DecodingOptions decodingOptions; 151 bool operator==(const ImageFrameRequest& other) const 152 { 153 return index == other.index && subsamplingLevel == other.subsamplingLevel && decodingOptions == other.decodingOptions; 154 } 150 155 }; 151 156 static const int BufferSize = 8; 152 157 using FrameRequestQueue = SynchronizedFixedQueue<ImageFrameRequest, BufferSize>; 158 using FrameCommitQueue = Deque<ImageFrameRequest, BufferSize>; 153 159 FrameRequestQueue m_frameRequestQueue; 160 FrameCommitQueue m_frameCommitQueue; 154 161 RefPtr<WorkQueue> m_decodingQueue; 155 162 -
trunk/Source/WebCore/platform/graphics/ImageSource.cpp
r213764 r214450 192 192 } 193 193 194 NativeImagePtr ImageSource::frameImageAtIndex (size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing, const GraphicsContext* targetContext)194 NativeImagePtr ImageSource::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel, const GraphicsContext* targetContext) 195 195 { 196 196 setDecoderTargetContext(targetContext); 197 return m_frameCache->frameImageAtIndex (index, subsamplingLevel, sizeForDrawing);197 return m_frameCache->frameImageAtIndexCacheIfNeeded(index, subsamplingLevel); 198 198 } 199 199 -
trunk/Source/WebCore/platform/graphics/ImageSource.h
r213833 r214450 70 70 71 71 bool shouldUseAsyncDecoding(); 72 bool requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const IntSize& sizeForDrawing) { return m_frameCache->requestFrameAsyncDecodingAtIndex(index, subsamplingLevel, sizeForDrawing); }72 bool requestFrameAsyncDecodingAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing = { }) { return m_frameCache->requestFrameAsyncDecodingAtIndex(index, subsamplingLevel, sizeForDrawing); } 73 73 bool hasAsyncDecodingQueue() const { return m_frameCache->hasAsyncDecodingQueue(); } 74 74 bool isAsyncDecodingQueueIdle() const { return m_frameCache->isAsyncDecodingQueueIdle(); } … … 88 88 89 89 // ImageFrame metadata which does not require caching the ImageFrame. 90 bool frameIsBeingDecodedA tIndex(size_t index, const std::optional<IntSize>& sizeForDrawing) { return m_frameCache->frameIsBeingDecodedAtIndex(index, sizeForDrawing); }90 bool frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(size_t index, const DecodingOptions& decodingOptions) { return m_frameCache->frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, decodingOptions); } 91 91 bool frameIsCompleteAtIndex(size_t index) { return m_frameCache->frameIsCompleteAtIndex(index); } 92 92 bool frameHasAlphaAtIndex(size_t index) { return m_frameCache->frameHasAlphaAtIndex(index); } 93 93 bool frameHasImageAtIndex(size_t index) { return m_frameCache->frameHasImageAtIndex(index); } 94 bool frameHas ValidNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) { return m_frameCache->frameHasValidNativeImageAtIndex(index, subsamplingLevel, sizeForDrawing); }95 bool frameHasDecodedNativeImage (size_t index) { return m_frameCache->frameHasDecodedNativeImage(index); }94 bool frameHasFullSizeNativeImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel) { return m_frameCache->frameHasFullSizeNativeImageAtIndex(index, subsamplingLevel); } 95 bool frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const std::optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) { return m_frameCache->frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(index, subsamplingLevel, decodingOptions); } 96 96 SubsamplingLevel frameSubsamplingLevelAtIndex(size_t index) { return m_frameCache->frameSubsamplingLevelAtIndex(index); } 97 97 … … 101 101 float frameDurationAtIndex(size_t index) { return m_frameCache->frameDurationAtIndex(index); } 102 102 ImageOrientation frameOrientationAtIndex(size_t index) { return m_frameCache->frameOrientationAtIndex(index); } 103 NativeImagePtr frameImageAtIndex(size_t index, const std::optional<SubsamplingLevel>& = { }, const std::optional<IntSize>& sizeForDrawing = { }, const GraphicsContext* targetContext = nullptr); 103 104 NativeImagePtr frameImageAtIndex(size_t index) { return m_frameCache->frameImageAtIndex(index); } 105 NativeImagePtr frameImageAtIndexCacheIfNeeded(size_t, SubsamplingLevel = SubsamplingLevel::Default, const GraphicsContext* = nullptr); 104 106 105 107 SubsamplingLevel maximumSubsamplingLevel(); -
trunk/Source/WebCore/platform/graphics/NamedImageGeneratedImage.cpp
r206631 r214450 41 41 } 42 42 43 void NamedImageGeneratedImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)43 void NamedImageGeneratedImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, DecodingMode, ImageOrientationDescription) 44 44 { 45 45 #if USE(NEW_THEME) || PLATFORM(IOS) -
trunk/Source/WebCore/platform/graphics/NamedImageGeneratedImage.h
r206631 r214450 41 41 42 42 protected: 43 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override;43 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) override; 44 44 void drawPattern(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, BlendMode) override; 45 45 -
trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
r213491 r214450 284 284 BackingStoreCopy copyMode = &destinationContext == &context() ? CopyBackingStore : DontCopyBackingStore; 285 285 RefPtr<Image> image = copyImage(copyMode); 286 destinationContext.drawImage(*image, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription()));286 destinationContext.drawImage(*image, destRect, srcRect, ImagePaintingOptions(op, blendMode, DecodingMode::Synchronous, ImageOrientationDescription())); 287 287 } 288 288 -
trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp
r213764 r214450 367 367 } 368 368 369 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>& sizeForDrawing) const369 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions& decodingOptions) const 370 370 { 371 371 LOG(Images, "ImageDecoder %p createFrameImageAtIndex %lu", this, index); … … 373 373 RetainPtr<CGImageRef> image; 374 374 375 if (!sizeForDrawing) { 375 if (!decodingOptions.isSynchronous()) { 376 if (decodingOptions.hasSizeForDrawing()) { 377 // CGImageSourceCreateThumbnailAtIndex() returns a CGImage with the image native size 378 // regardless of the subsamplingLevel unless kCGImageSourceSubsampleFactor is passed. 379 // Here we are trying to see which size is smaller: the image native size or the 380 // sizeForDrawing. If we want a CGImage with the image native size, sizeForDrawing will 381 // not passed. So we need to get the image native size with the default subsampling and 382 // then compare it with sizeForDrawing. 383 IntSize size = frameSizeAtIndex(index, SubsamplingLevel::Default); 384 std::optional<IntSize> sizeForDrawing = decodingOptions.sizeForDrawing(); 385 386 if (size.unclampedArea() < sizeForDrawing.value().unclampedArea()) { 387 // Decode an image asynchronously for its native size. 388 options = imageSourceAsyncOptions(subsamplingLevel); 389 } else { 390 // Decode an image asynchronously for sizeForDrawing since it is smaller than the image native size. 391 options = imageSourceAsyncOptions(subsamplingLevel, sizeForDrawing); 392 } 393 } else 394 options = imageSourceAsyncOptions(subsamplingLevel); 395 396 image = adoptCF(CGImageSourceCreateThumbnailAtIndex(m_nativeDecoder.get(), index, options.get())); 397 } else { 376 398 // Decode an image synchronously for its native size. 377 399 options = imageSourceOptions(subsamplingLevel); 378 400 image = adoptCF(CGImageSourceCreateImageAtIndex(m_nativeDecoder.get(), index, options.get())); 379 } else {380 // CGImageSourceCreateThumbnailAtIndex() returns a CGImage with the image native size381 // regardless of the subsamplingLevel unless kCGImageSourceSubsampleFactor is passed.382 // Here we are trying to see which size is smaller: the image native size or the383 // sizeForDrawing. If we want a CGImage with the image native size, sizeForDrawing will384 // not passed. So we need to get the image native size with the default subsampling and385 // then compare it with sizeForDrawing.386 IntSize size = frameSizeAtIndex(index, SubsamplingLevel::Default);387 388 if (size.unclampedArea() < sizeForDrawing.value().unclampedArea()) {389 // Decode an image asynchronously for its native size.390 options = imageSourceAsyncOptions(subsamplingLevel);391 } else {392 // Decode an image asynchronously for sizeForDrawing since it is smaller than the image native size.393 options = imageSourceAsyncOptions(subsamplingLevel, sizeForDrawing);394 }395 396 image = adoptCF(CGImageSourceCreateThumbnailAtIndex(m_nativeDecoder.get(), index, options.get()));397 401 } 398 402 -
trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h
r213833 r214450 63 63 unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const; 64 64 65 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const std::optional<IntSize>& sizeForDrawing = { }) const;65 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const DecodingOptions& = DecodingMode::Synchronous) const; 66 66 67 67 void setData(SharedBuffer&, bool allDataReceived); -
trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
r209397 r214450 264 264 } 265 265 266 void PDFDocumentImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op, BlendMode, ImageOrientationDescription)266 void PDFDocumentImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op, BlendMode, DecodingMode, ImageOrientationDescription) 267 267 { 268 268 if (!m_document || !m_hasPage) -
trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h
r206481 r214450 73 73 FloatSize size() const override; 74 74 75 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientationDescription) override;75 void draw(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) override; 76 76 77 77 // FIXME: Implement this to be less conservative. -
trunk/Source/WebCore/platform/graphics/win/ImageCGWin.cpp
r206742 r214450 81 81 drawFrameMatchingSourceSize(gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), *size, CompositeCopy); 82 82 else 83 draw(gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), CompositeCopy, BlendModeNormal, ImageOrientationDescription());83 draw(gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), CompositeCopy, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 84 84 85 85 // Do cleanup … … 97 97 size_t currentFrame = m_currentFrame; 98 98 m_currentFrame = i; 99 draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, srcSize.width(), srcSize.height()), compositeOp, BlendModeNormal, ImageOrientationDescription());99 draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, srcSize.width(), srcSize.height()), compositeOp, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 100 100 m_currentFrame = currentFrame; 101 101 return; … … 105 105 // No image of the correct size was found, fallback to drawing the current frame 106 106 FloatSize imageSize = BitmapImage::size(); 107 draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), compositeOp, BlendModeNormal, ImageOrientationDescription());107 draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), compositeOp, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 108 108 } 109 109 -
trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.cpp
r213563 r214450 181 181 } 182 182 183 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const std::optional<IntSize>&) const183 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel, const DecodingOptions&) const 184 184 { 185 185 if (!m_nativeDecoder || !m_renderTarget) -
trunk/Source/WebCore/platform/graphics/win/ImageDecoderDirect2D.h
r213833 r214450 68 68 unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const; 69 69 70 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const std::optional<IntSize>& sizeForDraw = { }) const;70 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const DecodingOptions& = DecodingMode::Synchronous) const; 71 71 72 72 void setData(SharedBuffer&, bool allDataReceived); -
trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
r213833 r214450 208 208 } 209 209 210 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel, const std::optional<IntSize>&)210 NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel, const DecodingOptions&) 211 211 { 212 212 // Zero-height images can cause problems for some ports. If we have an empty image dimension, just bail. -
trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h
r213833 r214450 137 137 float frameDurationAtIndex(size_t); 138 138 139 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const std::optional<IntSize>& sizeForDraw = { });139 NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const DecodingOptions& = DecodingMode::Synchronous); 140 140 141 141 void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; } -
trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp
r214173 r214450 879 879 880 880 auto interpolation = chooseInterpolationQuality(context, *image, &bgLayer, geometry.tileSize()); 881 context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer.blendMode(), ImageOrientationDescription(), interpolation));881 context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer.blendMode(), DecodingMode::Asynchronous, ImageOrientationDescription(), interpolation)); 882 882 } 883 883 } -
trunk/Source/WebCore/rendering/RenderImage.cpp
r214173 r214450 582 582 583 583 ImageOrientationDescription orientationDescription(shouldRespectImageOrientation(), style().imageOrientation()); 584 context.drawImage(*img, rect, ImagePaintingOptions(compositeOperator, BlendModeNormal, orientationDescription, interpolation));584 context.drawImage(*img, rect, ImagePaintingOptions(compositeOperator, BlendModeNormal, DecodingMode::Asynchronous, orientationDescription, interpolation)); 585 585 } 586 586 -
trunk/Source/WebCore/svg/graphics/SVGImage.cpp
r213446 r214450 189 189 scaledSrc.setSize(adjustedSrcSize); 190 190 191 draw(context, dstRect, scaledSrc, compositeOp, blendMode, ImageOrientationDescription());191 draw(context, dstRect, scaledSrc, compositeOp, blendMode, DecodingMode::Synchronous, ImageOrientationDescription()); 192 192 193 193 setImageObserver(observer); … … 207 207 return nullptr; 208 208 209 draw(buffer->context(), rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription());209 draw(buffer->context(), rect(), rect(), CompositeSourceOver, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 210 210 211 211 // FIXME: WK(Bug 113657): We should use DontCopyBackingStore here. … … 231 231 GraphicsContext localContext(nativeImageTarget.get()); 232 232 233 draw(localContext, rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription());233 draw(localContext, rect(), rect(), CompositeSourceOver, BlendModeNormal, DecodingMode::Synchronous, ImageOrientationDescription()); 234 234 235 235 COMPtr<ID2D1Bitmap> nativeImage; … … 277 277 } 278 278 279 void SVGImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)279 void SVGImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, DecodingMode, ImageOrientationDescription) 280 280 { 281 281 if (!m_page) -
trunk/Source/WebCore/svg/graphics/SVGImage.h
r208668 r214450 97 97 98 98 SVGImage(ImageObserver&, const URL&); 99 void draw(GraphicsContext&, const FloatRect& fromRect, const FloatRect& toRect, CompositeOperator, BlendMode, ImageOrientationDescription) final;99 void draw(GraphicsContext&, const FloatRect& fromRect, const FloatRect& toRect, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) final; 100 100 void drawForContainer(GraphicsContext&, const FloatSize, float, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode); 101 101 void drawPatternForContainer(GraphicsContext&, const FloatSize& containerSize, float zoom, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, -
trunk/Source/WebCore/svg/graphics/SVGImageForContainer.cpp
r207357 r214450 36 36 37 37 void SVGImageForContainer::draw(GraphicsContext& context, const FloatRect& dstRect, 38 const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription)38 const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, DecodingMode, ImageOrientationDescription) 39 39 { 40 40 m_image->drawForContainer(context, m_containerSize, m_zoom, dstRect, srcRect, compositeOp, blendMode); -
trunk/Source/WebCore/svg/graphics/SVGImageForContainer.h
r208668 r214450 56 56 } 57 57 58 void draw(GraphicsContext&, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientationDescription) final;58 void draw(GraphicsContext&, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, DecodingMode, ImageOrientationDescription) final; 59 59 60 60 void drawPattern(GraphicsContext&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, const FloatSize&, CompositeOperator, BlendMode) final;
Note:
See TracChangeset
for help on using the changeset viewer.