Changeset 294669 in webkit
- Timestamp:
- May 23, 2022 12:44:15 PM (2 years ago)
- Location:
- branches/safari-7613.3.1.0-branch/Source
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/safari-7613.3.1.0-branch/Source/WebCore/ChangeLog
r294667 r294669 1 2022-05-23 Alan Coon <alancoon@apple.com> 2 3 Cherry-pick r294280. rdar://problem/87980543 4 5 REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded 6 https://bugs.webkit.org/show_bug.cgi?id=239113 7 rdar://87980543 8 9 Reviewed by Simon Fraser. 10 11 Source/WebCore: 12 13 CanvasRenderingContext2DBase::drawImage() needs to ensure the first frame 14 of the animated image can be decoded correctly before creating the temporary 15 static image. If the first frame can't be decoded, this function should return 16 immediately. This matches the behavior of this function before r249162. 17 18 The animated image decodes its frames asynchronously in a work queue. But 19 the first frame has to be decoded synchronously in the main run loop. So 20 to avoid running the image decoder in two different threads we are going 21 to keep the first and the current frame cached when we receive a memory 22 pressure warning. This should not increase the memory allocation of the 23 animated image because the numbers of cached frames increases quickly and 24 we keep all of them till a memory warning is received. But the memory 25 pressure warning will be received a little bit more often. This depends 26 on the memory size of the first frame. 27 28 To make the code more robust, make ImageSource take a Ref<NativeImage> 29 instead of taking a RefPtr<NativeImage>. 30 31 * html/canvas/CanvasRenderingContext2DBase.cpp: 32 (WebCore::CanvasRenderingContext2DBase::drawImage): 33 * platform/graphics/BitmapImage.cpp: 34 (WebCore::BitmapImage::BitmapImage): 35 (WebCore::BitmapImage::destroyDecodedData): 36 * platform/graphics/BitmapImage.h: 37 * platform/graphics/ImageSource.cpp: 38 (WebCore::ImageSource::ImageSource): 39 (WebCore::ImageSource::destroyDecodedData): 40 (WebCore::ImageSource::setNativeImage): 41 * platform/graphics/ImageSource.h: 42 (WebCore::ImageSource::create): 43 (WebCore::ImageSource::isDecoderAvailable const): 44 (WebCore::ImageSource::destroyAllDecodedData): Deleted. 45 (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame): Deleted. 46 (WebCore::ImageSource::destroyDecodedDataBeforeFrame): Deleted. 47 48 Source/WebKit: 49 50 * GPUProcess/graphics/RemoteDisplayListRecorder.cpp: 51 (WebKit::RemoteDisplayListRecorder::drawSystemImage): 52 53 Canonical link: https://commits.webkit.org/250624@main 54 git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294280 268f45cc-cd09-0410-ab3c-d52691b4dbfc 55 56 2022-05-16 Said Abou-Hallawa <said@apple.com> 57 58 REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded 59 https://bugs.webkit.org/show_bug.cgi?id=239113 60 rdar://87980543 61 62 Reviewed by Simon Fraser. 63 64 CanvasRenderingContext2DBase::drawImage() needs to ensure the first frame 65 of the animated image can be decoded correctly before creating the temporary 66 static image. If the first frame can't be decoded, this function should return 67 immediately. This matches the behavior of this function before r249162. 68 69 The animated image decodes its frames asynchronously in a work queue. But 70 the first frame has to be decoded synchronously in the main run loop. So 71 to avoid running the image decoder in two different threads we are going 72 to keep the first and the current frame cached when we receive a memory 73 pressure warning. This should not increase the memory allocation of the 74 animated image because the numbers of cached frames increases quickly and 75 we keep all of them till a memory warning is received. But the memory 76 pressure warning will be received a little bit more often. This depends 77 on the memory size of the first frame. 78 79 To make the code more robust, make ImageSource take a Ref<NativeImage> 80 instead of taking a RefPtr<NativeImage>. 81 82 * html/canvas/CanvasRenderingContext2DBase.cpp: 83 (WebCore::CanvasRenderingContext2DBase::drawImage): 84 * platform/graphics/BitmapImage.cpp: 85 (WebCore::BitmapImage::BitmapImage): 86 (WebCore::BitmapImage::destroyDecodedData): 87 * platform/graphics/BitmapImage.h: 88 * platform/graphics/ImageSource.cpp: 89 (WebCore::ImageSource::ImageSource): 90 (WebCore::ImageSource::destroyDecodedData): 91 (WebCore::ImageSource::setNativeImage): 92 * platform/graphics/ImageSource.h: 93 (WebCore::ImageSource::create): 94 (WebCore::ImageSource::isDecoderAvailable const): 95 (WebCore::ImageSource::destroyAllDecodedData): Deleted. 96 (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame): Deleted. 97 (WebCore::ImageSource::destroyDecodedDataBeforeFrame): Deleted. 98 1 99 2022-05-23 Alan Coon <alancoon@apple.com> 2 100 -
branches/safari-7613.3.1.0-branch/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
r287731 r294669 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 } -
branches/safari-7613.3.1.0-branch/Source/WebCore/platform/graphics/BitmapImage.cpp
r287829 r294669 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 } … … 229 231 return ImageDrawResult::DidNothing; 230 232 231 232 233 auto srcRect = requestedSrcRect; 233 234 auto preferredSize = size(); -
branches/safari-7613.3.1.0-branch/Source/WebCore/platform/graphics/BitmapImage.h
r287829 r294669 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 -
branches/safari-7613.3.1.0-branch/Source/WebCore/platform/graphics/ImageSource.cpp
r287829 r294669 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); -
branches/safari-7613.3.1.0-branch/Source/WebCore/platform/graphics/ImageSource.h
r287829 r294669 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); -
branches/safari-7613.3.1.0-branch/Source/WebKit/ChangeLog
r293866 r294669 1 2022-05-23 Alan Coon <alancoon@apple.com> 2 3 Cherry-pick r294280. rdar://problem/87980543 4 5 REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded 6 https://bugs.webkit.org/show_bug.cgi?id=239113 7 rdar://87980543 8 9 Reviewed by Simon Fraser. 10 11 Source/WebCore: 12 13 CanvasRenderingContext2DBase::drawImage() needs to ensure the first frame 14 of the animated image can be decoded correctly before creating the temporary 15 static image. If the first frame can't be decoded, this function should return 16 immediately. This matches the behavior of this function before r249162. 17 18 The animated image decodes its frames asynchronously in a work queue. But 19 the first frame has to be decoded synchronously in the main run loop. So 20 to avoid running the image decoder in two different threads we are going 21 to keep the first and the current frame cached when we receive a memory 22 pressure warning. This should not increase the memory allocation of the 23 animated image because the numbers of cached frames increases quickly and 24 we keep all of them till a memory warning is received. But the memory 25 pressure warning will be received a little bit more often. This depends 26 on the memory size of the first frame. 27 28 To make the code more robust, make ImageSource take a Ref<NativeImage> 29 instead of taking a RefPtr<NativeImage>. 30 31 * html/canvas/CanvasRenderingContext2DBase.cpp: 32 (WebCore::CanvasRenderingContext2DBase::drawImage): 33 * platform/graphics/BitmapImage.cpp: 34 (WebCore::BitmapImage::BitmapImage): 35 (WebCore::BitmapImage::destroyDecodedData): 36 * platform/graphics/BitmapImage.h: 37 * platform/graphics/ImageSource.cpp: 38 (WebCore::ImageSource::ImageSource): 39 (WebCore::ImageSource::destroyDecodedData): 40 (WebCore::ImageSource::setNativeImage): 41 * platform/graphics/ImageSource.h: 42 (WebCore::ImageSource::create): 43 (WebCore::ImageSource::isDecoderAvailable const): 44 (WebCore::ImageSource::destroyAllDecodedData): Deleted. 45 (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame): Deleted. 46 (WebCore::ImageSource::destroyDecodedDataBeforeFrame): Deleted. 47 48 Source/WebKit: 49 50 * GPUProcess/graphics/RemoteDisplayListRecorder.cpp: 51 (WebKit::RemoteDisplayListRecorder::drawSystemImage): 52 53 Canonical link: https://commits.webkit.org/250624@main 54 git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294280 268f45cc-cd09-0410-ab3c-d52691b4dbfc 55 56 2022-05-16 Said Abou-Hallawa <said@apple.com> 57 58 REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded 59 https://bugs.webkit.org/show_bug.cgi?id=239113 60 rdar://87980543 61 62 Reviewed by Simon Fraser. 63 64 * GPUProcess/graphics/RemoteDisplayListRecorder.cpp: 65 (WebKit::RemoteDisplayListRecorder::drawSystemImage): 66 1 67 2022-05-02 Alan Coon <alancoon@apple.com> 2 68
Note: See TracChangeset
for help on using the changeset viewer.