Changeset 294280 in webkit
- Timestamp:
- May 16, 2022, 4:44:54 PM (4 years ago)
- Location:
- trunk/Source
- Files:
-
- 8 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (modified) (1 diff)
-
WebCore/platform/graphics/BitmapImage.cpp (modified) (3 diffs)
-
WebCore/platform/graphics/BitmapImage.h (modified) (2 diffs)
-
WebCore/platform/graphics/ImageSource.cpp (modified) (3 diffs)
-
WebCore/platform/graphics/ImageSource.h (modified) (5 diffs)
-
WebKit/ChangeLog (modified) (1 diff)
-
WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r294275 r294280 1 2022-05-16 Said Abou-Hallawa <said@apple.com> 2 3 REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded 4 https://bugs.webkit.org/show_bug.cgi?id=239113 5 rdar://87980543 6 7 Reviewed by Simon Fraser. 8 9 CanvasRenderingContext2DBase::drawImage() needs to ensure the first frame 10 of the animated image can be decoded correctly before creating the temporary 11 static image. If the first frame can't be decoded, this function should return 12 immediately. This matches the behavior of this function before r249162. 13 14 The animated image decodes its frames asynchronously in a work queue. But 15 the first frame has to be decoded synchronously in the main run loop. So 16 to avoid running the image decoder in two different threads we are going 17 to keep the first and the current frame cached when we receive a memory 18 pressure warning. This should not increase the memory allocation of the 19 animated image because the numbers of cached frames increases quickly and 20 we keep all of them till a memory warning is received. But the memory 21 pressure warning will be received a little bit more often. This depends 22 on the memory size of the first frame. 23 24 To make the code more robust, make ImageSource take a Ref<NativeImage> 25 instead of taking a RefPtr<NativeImage>. 26 27 * html/canvas/CanvasRenderingContext2DBase.cpp: 28 (WebCore::CanvasRenderingContext2DBase::drawImage): 29 * platform/graphics/BitmapImage.cpp: 30 (WebCore::BitmapImage::BitmapImage): 31 (WebCore::BitmapImage::destroyDecodedData): 32 * platform/graphics/BitmapImage.h: 33 * platform/graphics/ImageSource.cpp: 34 (WebCore::ImageSource::ImageSource): 35 (WebCore::ImageSource::destroyDecodedData): 36 (WebCore::ImageSource::setNativeImage): 37 * platform/graphics/ImageSource.h: 38 (WebCore::ImageSource::create): 39 (WebCore::ImageSource::isDecoderAvailable const): 40 (WebCore::ImageSource::destroyAllDecodedData): Deleted. 41 (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame): Deleted. 42 (WebCore::ImageSource::destroyDecodedDataBeforeFrame): Deleted. 43 1 44 2022-05-16 Oriol Brufau <obrufau@igalia.com> 2 45 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
r294057 r294280 1546 1546 if (image->isBitmapImage()) { 1547 1547 // Drawing an animated image to a canvas should draw the first frame (except for a few layout tests) 1548 if (image->isAnimated() && !document.settings().animatedImageDebugCanvasDrawingEnabled()) 1548 if (image->isAnimated() && !document.settings().animatedImageDebugCanvasDrawingEnabled()) { 1549 1549 image = BitmapImage::create(image->nativeImage()); 1550 if (!image) 1551 return { }; 1552 } 1550 1553 downcast<BitmapImage>(*image).updateFromSettings(document.settings()); 1551 1554 } -
trunk/Source/WebCore/platform/graphics/BitmapImage.cpp
r292469 r294280 53 53 } 54 54 55 BitmapImage::BitmapImage(RefPtr<NativeImage>&& image, ImageObserver* observer) 56 : Image(observer) 57 , m_source(ImageSource::create(WTFMove(image))) 55 BitmapImage::BitmapImage(Ref<NativeImage>&& image) 56 : m_source(ImageSource::create(WTFMove(image))) 58 57 { 59 58 } … … 78 77 LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().string().utf8().data()); 79 78 80 if (!destroyAll) 81 m_source->destroyDecodedDataBeforeFrame(m_currentFrame); 82 else if (!canDestroyDecodedData()) 83 m_source->destroyAllDecodedDataExcludeFrame(m_currentFrame); 84 else { 85 m_source->destroyAllDecodedData(); 79 if (!destroyAll) { 80 // Destroy all the frames between frame0 and m_currentFrame. 81 m_source->destroyDecodedData(1, m_currentFrame); 82 } else if (!canDestroyDecodedData()) { 83 // Destroy all the frames except frame0 and m_currentFrame. 84 m_source->destroyDecodedData(1, m_currentFrame); 85 m_source->destroyDecodedData(m_currentFrame + 1, frameCount()); 86 } else { 87 m_source->destroyDecodedData(0, frameCount()); 86 88 m_currentFrameDecodingStatus = DecodingStatus::Invalid; 87 89 } … … 230 232 return ImageDrawResult::DidNothing; 231 233 232 233 234 auto srcRect = requestedSrcRect; 234 235 auto preferredSize = size(); -
trunk/Source/WebCore/platform/graphics/BitmapImage.h
r289981 r294280 54 54 class BitmapImage final : public Image { 55 55 public: 56 static Ref<BitmapImage> create(PlatformImagePtr&& platformImage, ImageObserver* observer = nullptr) 57 { 58 return adoptRef(*new BitmapImage(NativeImage::create(WTFMove(platformImage)), observer)); 59 } 60 static Ref<BitmapImage> create(RefPtr<NativeImage>&& nativeImage, ImageObserver* observer = nullptr) 61 { 62 return adoptRef(*new BitmapImage(WTFMove(nativeImage), observer)); 56 static RefPtr<BitmapImage> create(PlatformImagePtr&& platformImage) 57 { 58 return create(NativeImage::create(WTFMove(platformImage))); 59 } 60 static RefPtr<BitmapImage> create(RefPtr<NativeImage>&& nativeImage) 61 { 62 if (!nativeImage) 63 return nullptr; 64 return create(nativeImage.releaseNonNull()); 65 } 66 static Ref<BitmapImage> create(Ref<NativeImage>&& nativeImage) 67 { 68 return adoptRef(*new BitmapImage(WTFMove(nativeImage))); 63 69 } 64 70 static Ref<BitmapImage> create(ImageObserver* observer = nullptr) … … 155 161 156 162 private: 157 WEBCORE_EXPORT BitmapImage(Ref Ptr<NativeImage>&&, ImageObserver* = nullptr);163 WEBCORE_EXPORT BitmapImage(Ref<NativeImage>&&); 158 164 WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr); 159 165 -
trunk/Source/WebCore/platform/graphics/ImageSource.cpp
r290901 r294280 45 45 } 46 46 47 ImageSource::ImageSource(Ref Ptr<NativeImage>&& nativeImage)47 ImageSource::ImageSource(Ref<NativeImage>&& nativeImage) 48 48 : m_runLoop(RunLoop::current()) 49 49 { … … 121 121 } 122 122 123 void ImageSource::destroyDecodedData(size_t frameCount, size_t excludeFrame) 124 { 123 void ImageSource::destroyDecodedData(size_t begin, size_t end) 124 { 125 if (begin >= end) 126 return; 127 128 ASSERT(end <= m_frames.size()); 129 125 130 unsigned decodedSize = 0; 126 131 127 ASSERT(frameCount <= m_frames.size()); 128 129 for (size_t index = 0; index < frameCount; ++index) { 130 if (index == excludeFrame) 131 continue; 132 for (size_t index = begin; index < end; ++index) 132 133 decodedSize += m_frames[index].clearImage(); 133 }134 134 135 135 decodedSizeReset(decodedSize); … … 233 233 } 234 234 235 void ImageSource::setNativeImage(Ref Ptr<NativeImage>&& nativeImage)235 void ImageSource::setNativeImage(Ref<NativeImage>&& nativeImage) 236 236 { 237 237 ASSERT(m_frames.size() == 1); -
trunk/Source/WebCore/platform/graphics/ImageSource.h
r287829 r294280 52 52 } 53 53 54 static Ref<ImageSource> create(Ref Ptr<NativeImage>&& nativeImage)54 static Ref<ImageSource> create(Ref<NativeImage>&& nativeImage) 55 55 { 56 56 return adoptRef(*new ImageSource(WTFMove(nativeImage))); … … 63 63 64 64 unsigned decodedSize() const { return m_decodedSize; } 65 void destroyAllDecodedData() { destroyDecodedData(frameCount(), frameCount()); } 66 void destroyAllDecodedDataExcludeFrame(size_t excludeFrame) { destroyDecodedData(frameCount(), excludeFrame); } 67 void destroyDecodedDataBeforeFrame(size_t beforeFrame) { destroyDecodedData(beforeFrame, beforeFrame); } 65 void destroyDecodedData(size_t begin, size_t end); 68 66 void destroyIncompleteDecodedData(); 69 67 void clearFrameBufferCache(size_t beforeFrame); … … 129 127 private: 130 128 ImageSource(BitmapImage*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied); 131 ImageSource(Ref Ptr<NativeImage>&&);129 ImageSource(Ref<NativeImage>&&); 132 130 133 131 enum class MetadataType { … … 154 152 bool ensureDecoderAvailable(FragmentedSharedBuffer* data); 155 153 bool isDecoderAvailable() const { return m_decoder; } 156 void destroyDecodedData(size_t frameCount, size_t excludeFrame);157 154 void decodedSizeChanged(long long decodedSize); 158 155 void didDecodeProperties(unsigned decodedPropertiesSize); … … 162 159 void encodedDataStatusChanged(EncodedDataStatus); 163 160 164 void setNativeImage(Ref Ptr<NativeImage>&&);161 void setNativeImage(Ref<NativeImage>&&); 165 162 void cacheMetadataAtIndex(size_t, SubsamplingLevel, DecodingStatus = DecodingStatus::Invalid); 166 163 void cachePlatformImageAtIndex(PlatformImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&, DecodingStatus = DecodingStatus::Invalid); -
trunk/Source/WebKit/ChangeLog
r294274 r294280 1 2022-05-16 Said Abou-Hallawa <said@apple.com> 2 3 REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded 4 https://bugs.webkit.org/show_bug.cgi?id=239113 5 rdar://87980543 6 7 Reviewed by Simon Fraser. 8 9 * GPUProcess/graphics/RemoteDisplayListRecorder.cpp: 10 (WebKit::RemoteDisplayListRecorder::drawSystemImage): 11 1 12 2022-05-16 Tim Horton <timothy_horton@apple.com> 2 13 -
trunk/Source/WebKit/GPUProcess/graphics/RemoteDisplayListRecorder.cpp
r292319 r294280 303 303 return; 304 304 } 305 badge.setImage(BitmapImage::create( WTFMove(nativeImage)));305 badge.setImage(BitmapImage::create(nativeImage.releaseNonNull())); 306 306 } 307 307 #endif
Note:
See TracChangeset
for help on using the changeset viewer.