Пример #1
0
TEST_F(BitmapImageTest, destroyDecodedData) {
    loadImage("/LayoutTests/fast/images/resources/animated-10color.gif");
    size_t totalSize = decodedSize();
    EXPECT_GT(totalSize, 0u);
    destroyDecodedData();
    EXPECT_EQ(-static_cast<int>(totalSize), lastDecodedSizeChange());
    EXPECT_EQ(0u, decodedSize());
}
Пример #2
0
void CachedImage::decodedSizeChanged(const Image* image, long long delta)
{
    if (!image || image != m_image)
        return;

    ASSERT(delta >= 0 || decodedSize() + delta >= 0);
    setDecodedSize(static_cast<unsigned>(decodedSize() + delta));
}
Пример #3
0
TEST_F(BitmapImageTest, destroyAllDecodedData)
{
    loadImage("/tests/fast/images/resources/animated-10color.gif");
    size_t totalSize = decodedSize();
    EXPECT_GT(totalSize, 0u);
    destroyDecodedData(true);
    EXPECT_EQ(-static_cast<int>(totalSize), m_imageObserver.m_lastDecodedSizeChangedDelta);
    EXPECT_EQ(0u, decodedSize());
}
Пример #4
0
TEST_F(BitmapImageTest, webpHasColorProfile)
{
    loadImage("/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(2560000u, decodedSize());
    EXPECT_TRUE(m_image->hasColorProfile());

    destroyDecodedData(true);
    resetDecoder();

    loadImage("/LayoutTests/fast/images/resources/test.webp");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(65536u, decodedSize());
    EXPECT_FALSE(m_image->hasColorProfile());
}
Пример #5
0
TEST_F(BitmapImageTest, jpegHasColorProfile)
{
    loadImage("/tests/fast/images/resources/icc-v2-gbr.jpg");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(227700u, decodedSize());
    EXPECT_TRUE(m_image->hasColorProfile());

    resetDecoder();
    destroyDecodedData(true);

    loadImage("/tests/fast/images/resources/green.jpg");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(1024u, decodedSize());
    EXPECT_FALSE(m_image->hasColorProfile());
}
Пример #6
0
TEST_F(BitmapImageTest, pngHasColorProfile)
{
    loadImage("/tests/fast/images/resources/palatted-color-png-gamma-one-color-profile.png");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(65536u, decodedSize());
    EXPECT_TRUE(m_image->hasColorProfile());

    resetDecoder();
    destroyDecodedData(true);

    loadImage("/tests/fast/images/resources/green.jpg");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(1024u, decodedSize());
    EXPECT_FALSE(m_image->hasColorProfile());
}
Пример #7
0
void CachedImage::decodedSizeChanged(const Image* image, int delta)
{
    if (image != m_image)
        return;
    
    setDecodedSize(decodedSize() + delta);
}
Пример #8
0
void ImageResource::decodedSizeChanged(const blink::Image* image, int delta)
{
    if (!image || image != m_image)
        return;

    setDecodedSize(decodedSize() + delta);
}
Пример #9
0
TEST_F(BitmapImageTest, noColorProfile)
{
    loadImage("/LayoutTests/fast/images/resources/green.jpg");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(1024u, decodedSize());
    EXPECT_FALSE(m_image->hasColorProfile());
}
Пример #10
0
TEST_F(BitmapImageTest, jpegHasColorProfile)
{
    loadImage("/LayoutTests/fast/images/resources/icc-v2-gbr.jpg");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(227700u, decodedSize());
    EXPECT_TRUE(m_image->hasColorProfile());
}
Пример #11
0
TEST_F(BitmapImageTest, pngHasColorProfile)
{
    loadImage("/LayoutTests/fast/images/resources/palatted-color-png-gamma-one-color-profile.png");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(65536u, decodedSize());
    EXPECT_TRUE(m_image->hasColorProfile());
}
Пример #12
0
void ImageDecoder::updateAggressivePurging(size_t index) {
  if (m_purgeAggressively)
    return;

  // We don't want to cache so much that we cause a memory issue.
  //
  // If we used a LRU cache we would fill it and then on next animation loop
  // we would need to decode all the frames again -- the LRU would give no
  // benefit and would consume more memory.
  // So instead, simply purge unused frames if caching all of the frames of
  // the image would use more memory than the image decoder is allowed
  // (m_maxDecodedBytes) or would overflow 32 bits..
  //
  // As we decode we will learn the total number of frames, and thus total
  // possible image memory used.

  const uint64_t frameArea = decodedSize().area();
  const uint64_t frameMemoryUsage = frameArea * 4;  // 4 bytes per pixel
  if (frameMemoryUsage / 4 != frameArea) {          // overflow occurred
    m_purgeAggressively = true;
    return;
  }

  const uint64_t totalMemoryUsage = frameMemoryUsage * index;
  if (totalMemoryUsage / frameMemoryUsage != index) {  // overflow occurred
    m_purgeAggressively = true;
    return;
  }

  if (totalMemoryUsage > m_maxDecodedBytes) {
    m_purgeAggressively = true;
  }
}
Пример #13
0
TEST_F(BitmapImageTest, webpHasColorProfile)
{
    loadImage("/LayoutTests/fast/images/resources/webp-color-profile-lossy.webp");
    EXPECT_EQ(1u, decodedFramesCount());
    EXPECT_EQ(2560000u, decodedSize());
    EXPECT_TRUE(m_image->hasColorProfile());
}
Пример #14
0
void ImageResource::didDraw(const blink::Image* image)
{
    if (!image || image != m_image)
        return;
    // decodedSize() == 0 indicates that the image is decoded into DiscardableMemory,
    // not in MemoryCache. So we don't need to call Resource::didAccessDecodedData()
    // to update MemoryCache.
    if (decodedSize() != 0)
        Resource::didAccessDecodedData();
}
Пример #15
0
TEST_F(BitmapImageTest, destroyDecodedDataExceptCurrentFrame)
{
    loadImage("/tests/fast/images/resources/animated-10color.gif");
    size_t totalSize = decodedSize();
    size_t frame = frameCount() / 2;
    setCurrentFrame(frame);
    size_t size = frameDecodedSize(frame);
    destroyDecodedData(false);
    EXPECT_LT(m_imageObserver.m_lastDecodedSizeChangedDelta, 0);
    EXPECT_GE(m_imageObserver.m_lastDecodedSizeChangedDelta, -static_cast<int>(totalSize - size));
}
Пример #16
0
    void loadImage(const char* fileName)
    {
        RefPtr<SharedBuffer> imageData = readFile("/LayoutTests/fast/images/resources/animated-10color.gif");
        ASSERT_TRUE(imageData.get());

        m_image->setData(imageData, true);
        EXPECT_EQ(0u, decodedSize());

        size_t frameCount = m_image->frameCount();
        for (size_t i = 0; i < frameCount; ++i)
            m_image->frameAtIndex(i);
    }
Пример #17
0
    void loadImage(const char* fileName)
    {
        RefPtr<SharedBuffer> imageData = readFile(fileName);
        ASSERT_TRUE(imageData.get());

        m_image->setData(imageData, true);
        EXPECT_EQ(0u, decodedSize());

        size_t frameCount = m_image->frameCount();
        for (size_t i = 0; i < frameCount; ++i)
            m_image->frameAtIndex(i);
    }
Пример #18
0
void GIFImageDecoder::updateAggressivePurging(size_t index)
{
    if (m_purgeAggressively)
        return;

    // We don't want to cache so much that we cause a memory issue.
    //
    // If we used a LRU cache we would fill it and then on next animation loop
    // we would need to decode all the frames again -- the LRU would give no
    // benefit and would consume more memory.
    // So instead, simply purge unused frames if caching all of the frames of
    // the image would use more memory than the image decoder is allowed
    // (m_maxDecodedBytes) or would overflow 32 bits..
    //
    // As we decode we will learn the total number of frames, and thus total
    // possible image memory used.

    const uint64_t frameArea = decodedSize().area();
    // We are about to multiply by 4, which may require an extra bit of storage
    bool wouldOverflow = frameArea > (UINT64_C(1) << 62);
    if (wouldOverflow) {
        m_purgeAggressively = true;
        return;
    }

    const uint64_t frameMemoryUsage = frameArea * 4; // 4 bytes per pixel
    // We are about to multiply by a size_t, which does not have a fixed
    // size.
    // To simplify things, let's make sure our per-frame memory usage and
    // index can be stored in 32 bits and store the multiplicand in a 64-bit
    // number.
    wouldOverflow = (frameMemoryUsage > (UINT32_C(1) << 31))
        || (index > (UINT32_C(1) << 31));
    if (wouldOverflow) {
        m_purgeAggressively = true;
        return;
    }

    const uint64_t totalMemoryUsage = frameMemoryUsage * index;
    if (totalMemoryUsage > m_maxDecodedBytes) {
        m_purgeAggressively = true;
    }
}
Пример #19
0
void ImageFrameCache::replaceFrameNativeImageAtIndex(NativeImagePtr&& nativeImage, size_t index, SubsamplingLevel subsamplingLevel)
{
    ASSERT(index < m_frames.size());
    ImageFrame& frame = m_frames[index];

    if (!frame.hasValidNativeImage(subsamplingLevel)) {
        // Clear the current image frame and update the observer with this clearance.
        unsigned decodedSize = frame.clear();
        decodedSizeDecreased(decodedSize);
    }

    // Do not cache the NativeImage if adding its frameByes to the MemoryCache will cause numerical overflow.
    size_t frameBytes = size().unclampedArea() * sizeof(RGBA32);
    if (!WTF::isInBounds<unsigned>(frameBytes + decodedSize()))
        return;

    // Copy the new image to the cache.
    setFrameNativeImageAtIndex(WTFMove(nativeImage), index, subsamplingLevel);

    // Update the observer with the new image frame bytes.
    decodedSizeIncreased(frame.frameBytes());
}
Пример #20
0
void CachedScript::sourceProviderCacheSizeChanged(int delta)
{
    setDecodedSize(decodedSize() + delta);
}