⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294731 in webkit


Ignore:
Timestamp:
May 23, 2022, 10:26:28 PM (4 years ago)
Author:
Alan Coon
Message:

Cherry-pick r294280. rdar://problem/87980543

This reverts r294684.

Location:
branches/safari-7613.3.1.1-branch/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-7613.3.1.1-branch/Source/WebCore/ChangeLog

    r294684 r294731  
    8484            (WebCore::AccessibilityObject::accessibilityIsIgnored const):
    8585            Don't call ignoredFromModalPresence if we're in the midst of computing the current modal.
     86
     872022-05-23  Alan Coon  <alancoon@apple.com>
     88
     89        Cherry-pick r294280. rdar://problem/87980543
     90
     91    REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded
     92    https://bugs.webkit.org/show_bug.cgi?id=239113
     93    rdar://87980543
     94   
     95    Reviewed by Simon Fraser.
     96   
     97    Source/WebCore:
     98   
     99    CanvasRenderingContext2DBase::drawImage() needs to ensure the first frame
     100    of the animated image can be decoded correctly before creating the temporary
     101    static image. If the first frame can't be decoded, this function should return
     102    immediately. This matches the behavior of this function before r249162.
     103   
     104    The animated image decodes its frames asynchronously in a work queue. But
     105    the first frame has to be decoded synchronously in the main run loop. So
     106    to avoid running the image decoder in two different threads we are going
     107    to keep the first and the current frame cached when we receive a memory
     108    pressure warning. This should not increase the memory allocation of the
     109    animated image because the numbers of cached frames increases quickly and
     110    we keep all of them till a memory warning is received. But the memory
     111    pressure warning will be received a little bit more often. This depends
     112    on the memory size of the first frame.
     113   
     114    To make the code more robust, make ImageSource take a Ref<NativeImage>
     115    instead of taking a RefPtr<NativeImage>.
     116   
     117    * html/canvas/CanvasRenderingContext2DBase.cpp:
     118    (WebCore::CanvasRenderingContext2DBase::drawImage):
     119    * platform/graphics/BitmapImage.cpp:
     120    (WebCore::BitmapImage::BitmapImage):
     121    (WebCore::BitmapImage::destroyDecodedData):
     122    * platform/graphics/BitmapImage.h:
     123    * platform/graphics/ImageSource.cpp:
     124    (WebCore::ImageSource::ImageSource):
     125    (WebCore::ImageSource::destroyDecodedData):
     126    (WebCore::ImageSource::setNativeImage):
     127    * platform/graphics/ImageSource.h:
     128    (WebCore::ImageSource::create):
     129    (WebCore::ImageSource::isDecoderAvailable const):
     130    (WebCore::ImageSource::destroyAllDecodedData): Deleted.
     131    (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame): Deleted.
     132    (WebCore::ImageSource::destroyDecodedDataBeforeFrame): Deleted.
     133   
     134    Source/WebKit:
     135   
     136    * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
     137    (WebKit::RemoteDisplayListRecorder::drawSystemImage):
     138   
     139    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294280 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     140
     141    2022-05-16  Said Abou-Hallawa  <said@apple.com>
     142
     143            REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded
     144            https://bugs.webkit.org/show_bug.cgi?id=239113
     145            rdar://87980543
     146
     147            Reviewed by Simon Fraser.
     148
     149            CanvasRenderingContext2DBase::drawImage() needs to ensure the first frame
     150            of the animated image can be decoded correctly before creating the temporary
     151            static image. If the first frame can't be decoded, this function should return
     152            immediately. This matches the behavior of this function before r249162.
     153
     154            The animated image decodes its frames asynchronously in a work queue. But
     155            the first frame has to be decoded synchronously in the main run loop. So
     156            to avoid running the image decoder in two different threads we are going
     157            to keep the first and the current frame cached when we receive a memory
     158            pressure warning. This should not increase the memory allocation of the
     159            animated image because the numbers of cached frames increases quickly and
     160            we keep all of them till a memory warning is received. But the memory
     161            pressure warning will be received a little bit more often. This depends
     162            on the memory size of the first frame.
     163
     164            To make the code more robust, make ImageSource take a Ref<NativeImage>
     165            instead of taking a RefPtr<NativeImage>.
     166
     167            * html/canvas/CanvasRenderingContext2DBase.cpp:
     168            (WebCore::CanvasRenderingContext2DBase::drawImage):
     169            * platform/graphics/BitmapImage.cpp:
     170            (WebCore::BitmapImage::BitmapImage):
     171            (WebCore::BitmapImage::destroyDecodedData):
     172            * platform/graphics/BitmapImage.h:
     173            * platform/graphics/ImageSource.cpp:
     174            (WebCore::ImageSource::ImageSource):
     175            (WebCore::ImageSource::destroyDecodedData):
     176            (WebCore::ImageSource::setNativeImage):
     177            * platform/graphics/ImageSource.h:
     178            (WebCore::ImageSource::create):
     179            (WebCore::ImageSource::isDecoderAvailable const):
     180            (WebCore::ImageSource::destroyAllDecodedData): Deleted.
     181            (WebCore::ImageSource::destroyAllDecodedDataExcludeFrame): Deleted.
     182            (WebCore::ImageSource::destroyDecodedDataBeforeFrame): Deleted.
    86183
    871842022-05-23  Alan Coon  <alancoon@apple.com>
  • branches/safari-7613.3.1.1-branch/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp

    r294684 r294731  
    15461546    if (image->isBitmapImage()) {
    15471547        // 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()) {
    15491549            image = BitmapImage::create(image->nativeImage());
     1550            if (!image)
     1551                return { };
     1552        }
    15501553        downcast<BitmapImage>(*image).updateFromSettings(document.settings());
    15511554    }
  • branches/safari-7613.3.1.1-branch/Source/WebCore/platform/graphics/BitmapImage.cpp

    r294684 r294731  
    5353}
    5454
    55 BitmapImage::BitmapImage(RefPtr<NativeImage>&& image, ImageObserver* observer)
    56     : Image(observer)
    57     , m_source(ImageSource::create(WTFMove(image)))
     55BitmapImage::BitmapImage(Ref<NativeImage>&& image)
     56    : m_source(ImageSource::create(WTFMove(image)))
    5857{
    5958}
     
    7877    LOG(Images, "BitmapImage::%s - %p - url: %s", __FUNCTION__, this, sourceURL().string().utf8().data());
    7978
    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());
    8688        m_currentFrameDecodingStatus = DecodingStatus::Invalid;
    8789    }
     
    229231        return ImageDrawResult::DidNothing;
    230232
    231    
    232233    auto srcRect = requestedSrcRect;
    233234    auto preferredSize = size();
  • branches/safari-7613.3.1.1-branch/Source/WebCore/platform/graphics/BitmapImage.h

    r294684 r294731  
    5454class BitmapImage final : public Image {
    5555public:
    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)));
    6369    }
    6470    static Ref<BitmapImage> create(ImageObserver* observer = nullptr)
     
    155161
    156162private:
    157     WEBCORE_EXPORT BitmapImage(RefPtr<NativeImage>&&, ImageObserver* = nullptr);
     163    WEBCORE_EXPORT BitmapImage(Ref<NativeImage>&&);
    158164    WEBCORE_EXPORT BitmapImage(ImageObserver* = nullptr);
    159165
  • branches/safari-7613.3.1.1-branch/Source/WebCore/platform/graphics/ImageSource.cpp

    r294684 r294731  
    4545}
    4646
    47 ImageSource::ImageSource(RefPtr<NativeImage>&& nativeImage)
     47ImageSource::ImageSource(Ref<NativeImage>&& nativeImage)
    4848    : m_runLoop(RunLoop::current())
    4949{
     
    121121}
    122122
    123 void ImageSource::destroyDecodedData(size_t frameCount, size_t excludeFrame)
    124 {
     123void ImageSource::destroyDecodedData(size_t begin, size_t end)
     124{
     125    if (begin >= end)
     126        return;
     127
     128    ASSERT(end <= m_frames.size());
     129
    125130    unsigned decodedSize = 0;
    126131
    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)
    132133        decodedSize += m_frames[index].clearImage();
    133     }
    134134
    135135    decodedSizeReset(decodedSize);
     
    233233}
    234234
    235 void ImageSource::setNativeImage(RefPtr<NativeImage>&& nativeImage)
     235void ImageSource::setNativeImage(Ref<NativeImage>&& nativeImage)
    236236{
    237237    ASSERT(m_frames.size() == 1);
  • branches/safari-7613.3.1.1-branch/Source/WebCore/platform/graphics/ImageSource.h

    r294684 r294731  
    5252    }
    5353
    54     static Ref<ImageSource> create(RefPtr<NativeImage>&& nativeImage)
     54    static Ref<ImageSource> create(Ref<NativeImage>&& nativeImage)
    5555    {
    5656        return adoptRef(*new ImageSource(WTFMove(nativeImage)));
     
    6363
    6464    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);
    6866    void destroyIncompleteDecodedData();
    6967    void clearFrameBufferCache(size_t beforeFrame);
     
    129127private:
    130128    ImageSource(BitmapImage*, AlphaOption = AlphaOption::Premultiplied, GammaAndColorProfileOption = GammaAndColorProfileOption::Applied);
    131     ImageSource(RefPtr<NativeImage>&&);
     129    ImageSource(Ref<NativeImage>&&);
    132130
    133131    enum class MetadataType {
     
    154152    bool ensureDecoderAvailable(FragmentedSharedBuffer* data);
    155153    bool isDecoderAvailable() const { return m_decoder; }
    156     void destroyDecodedData(size_t frameCount, size_t excludeFrame);
    157154    void decodedSizeChanged(long long decodedSize);
    158155    void didDecodeProperties(unsigned decodedPropertiesSize);
     
    162159    void encodedDataStatusChanged(EncodedDataStatus);
    163160
    164     void setNativeImage(RefPtr<NativeImage>&&);
     161    void setNativeImage(Ref<NativeImage>&&);
    165162    void cacheMetadataAtIndex(size_t, SubsamplingLevel, DecodingStatus = DecodingStatus::Invalid);
    166163    void cachePlatformImageAtIndex(PlatformImagePtr&&, size_t, SubsamplingLevel, const DecodingOptions&, DecodingStatus = DecodingStatus::Invalid);
  • branches/safari-7613.3.1.1-branch/Source/WebKit/ChangeLog

    r294684 r294731  
     12022-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    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294280 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     54
     55    2022-05-16  Said Abou-Hallawa  <said@apple.com>
     56
     57            REGRESSION(r249162): CanvasRenderingContext2DBase::drawImage() crashes if the image is animated and the first frame cannot be decoded
     58            https://bugs.webkit.org/show_bug.cgi?id=239113
     59            rdar://87980543
     60
     61            Reviewed by Simon Fraser.
     62
     63            * GPUProcess/graphics/RemoteDisplayListRecorder.cpp:
     64            (WebKit::RemoteDisplayListRecorder::drawSystemImage):
     65
    1662022-05-02  Alan Coon  <alancoon@apple.com>
    267
Note: See TracChangeset for help on using the changeset viewer.