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

Changeset 126892 in webkit


Ignore:
Timestamp:
Aug 28, 2012, 10:48:38 AM (14 years ago)
Author:
hclam@chromium.org
Message:

Report frame bytes by platform ImageDecoder
https://bugs.webkit.org/show_bug.cgi?id=94241

Reviewed by James Robinson.

Decoded frame bytes should be reported by the platform ImageSource and
ImageDecoder. BitmapImage used to guess system memory used by a frame
but this is no longer true if a frame is backed by an accelerated
surface or defer-decoded.

Adds ImageSource::frameBytesAtIndex and ImageDecoder::frameBytesAtIndex
such that platform can report memory usage correctly.

No new tests. Refactoring without change of behavior.
Tested on Chromium port with pixel tests without any crash or failure.

  • platform/graphics/BitmapImage.cpp:

(WebCore::BitmapImage::destroyDecodedData):
(WebCore::BitmapImage::destroyDecodedDataIfNecessary):
(WebCore::BitmapImage::destroyMetadataAndNotify):
(WebCore::BitmapImage::cacheFrame):
(WebCore::BitmapImage::dataChanged):

  • platform/graphics/BitmapImage.h:

(WebCore::FrameData::FrameData):
(FrameData):
(BitmapImage):

  • platform/graphics/ImageSource.cpp:

(WebCore::ImageSource::frameBytesAtIndex):
(WebCore):

  • platform/graphics/ImageSource.h:
  • platform/graphics/cg/ImageSourceCG.cpp:

(WebCore::ImageSource::frameBytesAtIndex):
(WebCore):

  • platform/image-decoders/ImageDecoder.cpp:

(WebCore::ImageDecoder::frameBytesAtIndex):
(WebCore):

  • platform/image-decoders/ImageDecoder.h:

(ImageDecoder):

Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r126891 r126892  
     12012-08-28  Alpha Lam  <hclam@chromium.org>
     2
     3        Report frame bytes by platform ImageDecoder
     4        https://bugs.webkit.org/show_bug.cgi?id=94241
     5
     6        Reviewed by James Robinson.
     7
     8        Decoded frame bytes should be reported by the platform ImageSource and
     9        ImageDecoder. BitmapImage used to guess system memory used by a frame
     10        but this is no longer true if a frame is backed by an accelerated
     11        surface or defer-decoded.
     12
     13        Adds ImageSource::frameBytesAtIndex and ImageDecoder::frameBytesAtIndex
     14        such that platform can report memory usage correctly.
     15
     16        No new tests. Refactoring without change of behavior.
     17        Tested on Chromium port with pixel tests without any crash or failure.
     18
     19        * platform/graphics/BitmapImage.cpp:
     20        (WebCore::BitmapImage::destroyDecodedData):
     21        (WebCore::BitmapImage::destroyDecodedDataIfNecessary):
     22        (WebCore::BitmapImage::destroyMetadataAndNotify):
     23        (WebCore::BitmapImage::cacheFrame):
     24        (WebCore::BitmapImage::dataChanged):
     25        * platform/graphics/BitmapImage.h:
     26        (WebCore::FrameData::FrameData):
     27        (FrameData):
     28        (BitmapImage):
     29        * platform/graphics/ImageSource.cpp:
     30        (WebCore::ImageSource::frameBytesAtIndex):
     31        (WebCore):
     32        * platform/graphics/ImageSource.h:
     33        * platform/graphics/cg/ImageSourceCG.cpp:
     34        (WebCore::ImageSource::frameBytesAtIndex):
     35        (WebCore):
     36        * platform/image-decoders/ImageDecoder.cpp:
     37        (WebCore::ImageDecoder::frameBytesAtIndex):
     38        (WebCore):
     39        * platform/image-decoders/ImageDecoder.h:
     40        (ImageDecoder):
     41
    1422012-08-28  Gustavo Noronha Silva  <gns@gnome.org>
    243
  • trunk/Source/WebCore/platform/graphics/BitmapImage.cpp

    r125154 r126892  
    3939namespace WebCore {
    4040
    41 static int frameBytes(const IntSize& frameSize)
    42 {
    43     return frameSize.width() * frameSize.height() * 4;
    44 }
    45 
    4641BitmapImage::BitmapImage(ImageObserver* observer)
    4742    : Image(observer)
     
    8681void BitmapImage::destroyDecodedData(bool destroyAll)
    8782{
    88     int framesCleared = 0;
     83    unsigned frameBytesCleared = 0;
    8984    const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFrame;
    9085    for (size_t i = 0; i < clearBeforeFrame; ++i) {
     
    9287        // save the memory for the framebuffer data), so we don't need to clear
    9388        // the metadata.
     89        unsigned frameBytes = m_frames[i].m_frameBytes;
    9490        if (m_frames[i].clear(false))
    95           ++framesCleared;
    96     }
    97 
    98     destroyMetadataAndNotify(framesCleared);
     91            frameBytesCleared += frameBytes;
     92    }
     93
     94    destroyMetadataAndNotify(frameBytesCleared);
    9995
    10096    m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived);
     
    107103    // to one frame at a time.
    108104    static const unsigned cLargeAnimationCutoff = 5242880;
    109     if (m_frames.size() * frameBytes(m_size) > cLargeAnimationCutoff)
     105    unsigned allFrameBytes = 0;
     106    for (size_t i = 0; i < m_frames.size(); ++i)
     107        allFrameBytes += m_frames[i].m_frameBytes;
     108
     109    if (allFrameBytes > cLargeAnimationCutoff)
    110110        destroyDecodedData(destroyAll);
    111111}
    112112
    113 void BitmapImage::destroyMetadataAndNotify(int framesCleared)
     113void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared)
    114114{
    115115    m_isSolidColor = false;
     
    117117    invalidatePlatformData();
    118118
    119     int deltaBytes = framesCleared * -frameBytes(m_size);
    120     m_decodedSize += deltaBytes;
    121     if (framesCleared > 0) {
    122         deltaBytes -= m_decodedPropertiesSize;
     119    ASSERT(m_decodedSize >= frameBytesCleared);
     120    m_decodedSize -= frameBytesCleared;
     121    if (frameBytesCleared > 0) {
     122        frameBytesCleared += m_decodedPropertiesSize;
    123123        m_decodedPropertiesSize = 0;
    124124    }
    125     if (deltaBytes && imageObserver())
    126         imageObserver()->decodedSizeChanged(this, deltaBytes);
     125    if (frameBytesCleared && imageObserver())
     126        imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared));
    127127}
    128128
     
    145145        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
    146146    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
     147    m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index);
    147148
    148149    const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size);
     
    150151        m_hasUniformFrameSize = false;
    151152    if (m_frames[index].m_frame) {
    152         int deltaBytes = frameBytes(frameSize);
     153        int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes);
    153154        m_decodedSize += deltaBytes;
    154155        // The fully-decoded frame will subsume the partially decoded data used
     
    237238    // frame affected by appending new data here. Thus we have to clear all the
    238239    // incomplete frames to be safe.
    239     int framesCleared = 0;
     240    unsigned frameBytesCleared = 0;
    240241    for (size_t i = 0; i < m_frames.size(); ++i) {
    241242        // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to
    242243        // decode any uncached (i.e. never-decoded or
    243244        // cleared-on-a-previous-pass) frames!
     245        unsigned frameBytes = m_frames[i].m_frameBytes;
    244246        if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete)
    245             framesCleared += (m_frames[i].clear(true) ? 1 : 0);
    246     }
    247     destroyMetadataAndNotify(framesCleared);
     247            frameBytesCleared += (m_frames[i].clear(true) ? frameBytes : 0);
     248    }
     249    destroyMetadataAndNotify(frameBytesCleared);
    248250   
    249251    // Feed all the data we've seen so far to the image decoder.
  • trunk/Source/WebCore/platform/graphics/BitmapImage.h

    r125374 r126892  
    7676        , m_isComplete(false)
    7777        , m_hasAlpha(true)
     78        , m_frameBytes(0)
    7879    {
    7980    }
     
    9495    bool m_isComplete : 1;
    9596    bool m_hasAlpha : 1;
     97    unsigned m_frameBytes;
    9698};
    9799
     
    235237    // Generally called by destroyDecodedData(), destroys whole-image metadata
    236238    // and notifies observers that the memory footprint has (hopefully)
    237     // decreased by |framesCleared| times the size (in bytes) of a frame.
    238     void destroyMetadataAndNotify(int framesCleared);
     239    // decreased by |frameBytesCleared|.
     240    void destroyMetadataAndNotify(unsigned frameBytesCleared);
    239241
    240242    // Whether or not size is available yet.   
  • trunk/Source/WebCore/platform/graphics/ImageSource.cpp

    r125154 r126892  
    199199}
    200200
    201 }
     201unsigned ImageSource::frameBytesAtIndex(size_t index) const
     202{
     203    if (!m_decoder)
     204        return 0;
     205    return m_decoder->frameBytesAtIndex(index);
     206}
     207
     208}
  • trunk/Source/WebCore/platform/graphics/ImageSource.h

    r126477 r126892  
    147147    ImageOrientation orientationAtIndex(size_t) const; // EXIF image orientation
    148148
     149    // Return the number of bytes in the decoded frame. If the frame is not yet
     150    // decoded then return 0.
     151    unsigned frameBytesAtIndex(size_t) const;
     152
    149153#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
    150154    static unsigned maxPixelsPerDecodedImage() { return s_maxPixelsPerDecodedImage; }
  • trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp

    r126477 r126892  
    385385}
    386386
     387unsigned ImageSource::frameBytesAtIndex(size_t index) const
     388{
     389    IntSize frameSize = frameSizeAtIndex(index, RespectImageOrientation);
     390    return frameSize.width() * frameSize.height() * 4;
     391}
     392
    387393}
    388394
  • trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp

    r125154 r126892  
    287287}
    288288
     289unsigned ImageDecoder::frameBytesAtIndex(size_t index) const
     290{
     291    if (m_frameBufferCache.size() <= index)
     292        return 0;
     293    // FIXME: Use the dimension of the requested frame.
     294    return m_size.area() * sizeof(ImageFrame::PixelData);
     295}
     296
    289297void ImageDecoder::prepareScaleDataIfNecessary()
    290298{
  • trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h

    r125154 r126892  
    280280        virtual bool frameHasAlphaAtIndex(size_t) const;
    281281
     282        // Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
     283        virtual unsigned frameBytesAtIndex(size_t) const;
     284
    282285        void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
    283286        bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
Note: See TracChangeset for help on using the changeset viewer.