Changeset 78652 in webkit


Ignore:
Timestamp:
Feb 15, 2011 5:15:20 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-02-15 Ian Henderson <ianh@apple.com>

Reviewed by Darin Adler.

To determine image properties, CG allocates memory which isn't included in CachedImage's decoded size
https://bugs.webkit.org/show_bug.cgi?id=53281

When determining properties of an image (such as its size), CG ends up
decoding part of the image. This patch adds accounting for this extra
decoded size so a cache prune can clean up the allocations.

  • platform/graphics/BitmapImage.cpp: (WebCore::BitmapImage::BitmapImage): (WebCore::BitmapImage::destroyMetadataAndNotify): Clearing the source destroys the extra decoded data. Report this change in decoded size to the image observer. (WebCore::BitmapImage::cacheFrame): The first decoded frame subsumes the data decoded when determining image properties, so we subtract it out here. (WebCore::BitmapImage::didDecodeProperties): Reports the extra decoded size to the image's observer. (WebCore::BitmapImage::size): (WebCore::BitmapImage::currentFrameSize): (WebCore::BitmapImage::getHotSpot): (WebCore::BitmapImage::frameCount): (WebCore::BitmapImage::isSizeAvailable): (WebCore::BitmapImage::repetitionCount):
  • platform/graphics/BitmapImage.h:
  • platform/graphics/ImageSource.cpp: (WebCore::ImageSource::bytesDecodedToDetermineProperties): The default value is 0 to match the current behavior on other platforms.
  • platform/graphics/ImageSource.h:
  • platform/graphics/cg/ImageSourceCG.cpp: (WebCore::ImageSource::bytesDecodedToDetermineProperties): Add a constant value for bytesDecodedToDetermineProperties(), measured by tracing malloc/calloc calls while asking an image source for its properties.
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r78648 r78652  
     12011-02-15  Ian Henderson  <ianh@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        To determine image properties, CG allocates memory which isn't included in CachedImage's decoded size
     6        https://bugs.webkit.org/show_bug.cgi?id=53281
     7
     8        When determining properties of an image (such as its size), CG ends up
     9        decoding part of the image.  This patch adds accounting for this extra
     10        decoded size so a cache prune can clean up the allocations.
     11
     12        * platform/graphics/BitmapImage.cpp:
     13        (WebCore::BitmapImage::BitmapImage):
     14        (WebCore::BitmapImage::destroyMetadataAndNotify):
     15        Clearing the source destroys the extra decoded data.  Report this
     16        change in decoded size to the image observer.
     17        (WebCore::BitmapImage::cacheFrame):
     18        The first decoded frame subsumes the data decoded when determining
     19        image properties, so we subtract it out here.
     20        (WebCore::BitmapImage::didDecodeProperties):
     21        Reports the extra decoded size to the image's observer.
     22        (WebCore::BitmapImage::size):
     23        (WebCore::BitmapImage::currentFrameSize):
     24        (WebCore::BitmapImage::getHotSpot):
     25        (WebCore::BitmapImage::frameCount):
     26        (WebCore::BitmapImage::isSizeAvailable):
     27        (WebCore::BitmapImage::repetitionCount):
     28        * platform/graphics/BitmapImage.h:
     29        * platform/graphics/ImageSource.cpp:
     30        (WebCore::ImageSource::bytesDecodedToDetermineProperties):
     31        The default value is 0 to match the current behavior on other
     32        platforms.
     33        * platform/graphics/ImageSource.h:
     34        * platform/graphics/cg/ImageSourceCG.cpp:
     35        (WebCore::ImageSource::bytesDecodedToDetermineProperties):
     36        Add a constant value for bytesDecodedToDetermineProperties(), measured
     37        by tracing malloc/calloc calls while asking an image source for its
     38        properties.
     39
    1402011-02-15  James Robinson  <jamesr@chromium.org>
    241
  • trunk/Source/WebCore/platform/graphics/BitmapImage.cpp

    r60849 r78652  
    6161    , m_hasUniformFrameSize(true)
    6262    , m_decodedSize(0)
     63    , m_decodedPropertiesSize(0)
    6364    , m_haveFrameCount(false)
    6465    , m_frameCount(0)
     
    105106    invalidatePlatformData();
    106107
    107     const int deltaBytes = framesCleared * -frameBytes(m_size);
     108    int deltaBytes = framesCleared * -frameBytes(m_size);
    108109    m_decodedSize += deltaBytes;
     110    if (framesCleared > 0) {
     111        deltaBytes -= m_decodedPropertiesSize;
     112        m_decodedPropertiesSize = 0;
     113    }
    109114    if (deltaBytes && imageObserver())
    110115        imageObserver()->decodedSizeChanged(this, deltaBytes);
     
    133138        m_hasUniformFrameSize = false;
    134139    if (m_frames[index].m_frame) {
    135         const int deltaBytes = frameBytes(frameSize);
     140        int deltaBytes = frameBytes(frameSize);
    136141        m_decodedSize += deltaBytes;
     142        // The fully-decoded frame will subsume the partially decoded data used
     143        // to determine image properties.
     144        deltaBytes -= m_decodedPropertiesSize;
     145        m_decodedPropertiesSize = 0;
    137146        if (imageObserver())
    138147            imageObserver()->decodedSizeChanged(this, deltaBytes);
    139148    }
     149}
     150
     151void BitmapImage::didDecodeProperties() const
     152{
     153    if (m_decodedSize)
     154        return;
     155    size_t updatedSize = m_source.bytesDecodedToDetermineProperties();
     156    if (m_decodedPropertiesSize == updatedSize)
     157        return;
     158    int deltaBytes = updatedSize - m_decodedPropertiesSize;
     159#ifndef NDEBUG
     160    bool overflow = updatedSize > m_decodedPropertiesSize && deltaBytes < 0;
     161    bool underflow = updatedSize < m_decodedPropertiesSize && deltaBytes > 0;
     162    ASSERT(!overflow && !underflow);
     163#endif
     164    m_decodedPropertiesSize = updatedSize;
     165    if (imageObserver())
     166        imageObserver()->decodedSizeChanged(this, deltaBytes);
    140167}
    141168
     
    145172        m_size = m_source.size();
    146173        m_haveSize = true;
     174        didDecodeProperties();
    147175    }
    148176    return m_size;
     
    153181    if (!m_currentFrame || m_hasUniformFrameSize)
    154182        return size();
    155     return m_source.frameSizeAtIndex(m_currentFrame);
     183    IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame);
     184    didDecodeProperties();
     185    return frameSize;
    156186}
    157187
    158188bool BitmapImage::getHotSpot(IntPoint& hotSpot) const
    159189{
    160     return m_source.getHotSpot(hotSpot);
     190    bool result = m_source.getHotSpot(hotSpot);
     191    didDecodeProperties();
     192    return result;
    161193}
    162194
     
    191223        m_haveFrameCount = true;
    192224        m_frameCount = m_source.frameCount();
     225        didDecodeProperties();
    193226    }
    194227    return m_frameCount;
     
    201234
    202235    m_sizeAvailable = m_source.isSizeAvailable();
     236    didDecodeProperties();
    203237
    204238    return m_sizeAvailable;
     
    257291        // the count again once the whole image is decoded.
    258292        m_repetitionCount = m_source.repetitionCount();
     293        didDecodeProperties();
    259294        m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == cAnimationNone) ? Certain : Uncertain;
    260295    }
  • trunk/Source/WebCore/platform/graphics/BitmapImage.h

    r76248 r78652  
    212212    bool isSizeAvailable();
    213213
     214    // Called after asking the source for any information that may require
     215    // decoding part of the image (e.g., the image size).  We need to report
     216    // the partially decoded data to our observer so it has an accurate
     217    // account of the BitmapImage's memory usage.
     218    void didDecodeProperties() const;
     219
    214220    // Animation.
    215221    int repetitionCount(bool imageKnownToBeComplete);  // |imageKnownToBeComplete| should be set if the caller knows the entire image has been decoded.
     
    278284
    279285    unsigned m_decodedSize; // The current size of all decoded frames.
     286    mutable unsigned m_decodedPropertiesSize; // The size of data decoded by the source to determine image properties (e.g. size, frame count, etc).
    280287
    281288    mutable bool m_haveFrameCount;
  • trunk/Source/WebCore/platform/graphics/ImageSource.cpp

    r75748 r78652  
    116116}
    117117
     118size_t ImageSource::bytesDecodedToDetermineProperties() const
     119{
     120    return 0;
     121}
     122
    118123int ImageSource::repetitionCount()
    119124{
  • trunk/Source/WebCore/platform/graphics/ImageSource.h

    r76248 r78652  
    170170    bool getHotSpot(IntPoint&) const;
    171171
     172    size_t bytesDecodedToDetermineProperties() const;
     173
    172174    int repetitionCount();
    173175
  • trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp

    r73819 r78652  
    223223}
    224224
     225size_t ImageSource::bytesDecodedToDetermineProperties() const
     226{
     227    // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64.
     228    // A non-zero value ensures cached images with no decoded frames still enter
     229    // the live decoded resources list when the CGImageSource decodes image
     230    // properties, allowing the cache to prune the partially decoded image.
     231    // This value is likely to be inaccurate on other platforms, but the overall
     232    // behavior is unchanged.
     233    return 13088;
     234}
     235   
    225236int ImageSource::repetitionCount()
    226237{
Note: See TracChangeset for help on using the changeset viewer.