Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #include "platform/graphics/ImageDecodingStore.h"
     29 
     30 #include "platform/SharedBuffer.h"
     31 #include "platform/graphics/ImageFrameGenerator.h"
     32 #include "platform/graphics/test/MockDiscardablePixelRef.h"
     33 #include "platform/graphics/test/MockImageDecoder.h"
     34 #include <gtest/gtest.h>
     35 
     36 using namespace WebCore;
     37 
     38 namespace {
     39 
     40 class ImageDecodingStoreTest : public ::testing::Test, public MockImageDecoderClient {
     41 public:
     42     virtual void SetUp()
     43     {
     44         ImageDecodingStore::initializeOnce();
     45         ImageDecodingStore::instance()->setImageCachingEnabled(true);
     46         m_data = SharedBuffer::create();
     47         m_generator = ImageFrameGenerator::create(SkISize::Make(100, 100), m_data, true);
     48         m_decodersDestroyed = 0;
     49     }
     50 
     51     virtual void TearDown()
     52     {
     53         ImageDecodingStore::shutdown();
     54     }
     55 
     56     virtual void decoderBeingDestroyed()
     57     {
     58         ++m_decodersDestroyed;
     59     }
     60 
     61     virtual void frameBufferRequested()
     62     {
     63         // Decoder is never used by ImageDecodingStore.
     64         ASSERT_TRUE(false);
     65     }
     66 
     67     virtual ImageFrame::Status status()
     68     {
     69         return ImageFrame::FramePartial;
     70     }
     71 
     72     virtual size_t frameCount() { return 1; }
     73     virtual int repetitionCount() const { return cAnimationNone; }
     74     virtual float frameDuration() const { return 0; }
     75 
     76 protected:
     77     PassOwnPtr<ScaledImageFragment> createCompleteImage(const SkISize& size, bool discardable = false, size_t index = 0)
     78     {
     79         SkBitmap bitmap;
     80         bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
     81         if (!discardable)
     82             bitmap.allocPixels();
     83         else
     84             bitmap.setPixelRef(new MockDiscardablePixelRef())->unref();
     85         return ScaledImageFragment::createComplete(size, index, bitmap);
     86     }
     87 
     88     PassOwnPtr<ScaledImageFragment> createIncompleteImage(const SkISize& size, bool discardable = false, size_t generation = 0)
     89     {
     90         SkBitmap bitmap;
     91         bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
     92         if (!discardable)
     93             bitmap.allocPixels();
     94         else
     95             bitmap.setPixelRef(new MockDiscardablePixelRef())->unref();
     96         return ScaledImageFragment::createPartial(size, 0, generation, bitmap);
     97     }
     98 
     99     void insertCache(const SkISize& size)
    100     {
    101         const ScaledImageFragment* image = ImageDecodingStore::instance()->insertAndLockCache(
    102             m_generator.get(), createCompleteImage(size));
    103         unlockCache(image);
    104     }
    105 
    106     const ScaledImageFragment* lockCache(const SkISize& size, size_t index = 0)
    107     {
    108         const ScaledImageFragment* cachedImage = 0;
    109         if (ImageDecodingStore::instance()->lockCache(m_generator.get(), size, index, &cachedImage))
    110             return cachedImage;
    111         return 0;
    112     }
    113 
    114     void unlockCache(const ScaledImageFragment* cachedImage)
    115     {
    116         ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedImage);
    117     }
    118 
    119     void evictOneCache()
    120     {
    121         size_t memoryUsageInBytes = ImageDecodingStore::instance()->memoryUsageInBytes();
    122         if (memoryUsageInBytes)
    123             ImageDecodingStore::instance()->setCacheLimitInBytes(memoryUsageInBytes - 1);
    124         else
    125             ImageDecodingStore::instance()->setCacheLimitInBytes(0);
    126     }
    127 
    128     bool isCacheAlive(const SkISize& size)
    129     {
    130         const ScaledImageFragment* cachedImage = lockCache(size);
    131         if (!cachedImage)
    132             return false;
    133         ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedImage);
    134         return true;
    135     }
    136 
    137     RefPtr<SharedBuffer> m_data;
    138     RefPtr<ImageFrameGenerator> m_generator;
    139     int m_decodersDestroyed;
    140 };
    141 
    142 TEST_F(ImageDecodingStoreTest, evictOneCache)
    143 {
    144     insertCache(SkISize::Make(1, 1));
    145     insertCache(SkISize::Make(2, 2));
    146     insertCache(SkISize::Make(3, 3));
    147     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    148 
    149     evictOneCache();
    150     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    151 
    152     evictOneCache();
    153     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    154 }
    155 
    156 TEST_F(ImageDecodingStoreTest, pruneOrderIsLeastRecentlyUsed)
    157 {
    158     insertCache(SkISize::Make(1, 1));
    159     insertCache(SkISize::Make(2, 2));
    160     insertCache(SkISize::Make(3, 3));
    161     insertCache(SkISize::Make(4, 4));
    162     insertCache(SkISize::Make(5, 5));
    163     EXPECT_EQ(5, ImageDecodingStore::instance()->cacheEntries());
    164 
    165     // Use cache in the order 3, 2, 4, 1, 5.
    166     EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
    167     EXPECT_TRUE(isCacheAlive(SkISize::Make(2, 2)));
    168     EXPECT_TRUE(isCacheAlive(SkISize::Make(4, 4)));
    169     EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
    170     EXPECT_TRUE(isCacheAlive(SkISize::Make(5, 5)));
    171 
    172     // Evict 3.
    173     evictOneCache();
    174     EXPECT_FALSE(isCacheAlive(SkISize::Make(3, 3)));
    175     EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
    176 
    177     // Evict 2.
    178     evictOneCache();
    179     EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
    180     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    181 
    182     // Evict 4.
    183     evictOneCache();
    184     EXPECT_FALSE(isCacheAlive(SkISize::Make(4, 4)));
    185     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    186 
    187     // Evict 1.
    188     evictOneCache();
    189     EXPECT_FALSE(isCacheAlive(SkISize::Make(1, 1)));
    190     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    191 
    192     // Evict 5.
    193     evictOneCache();
    194     EXPECT_FALSE(isCacheAlive(SkISize::Make(5, 5)));
    195     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
    196 }
    197 
    198 TEST_F(ImageDecodingStoreTest, pruneCausedByInsertion)
    199 {
    200     ImageDecodingStore::instance()->setCacheLimitInBytes(100);
    201 
    202     // Insert 100 entries.
    203     // Cache entries stored should increase and eventually decrease to 1.
    204     insertCache(SkISize::Make(1, 1));
    205     insertCache(SkISize::Make(2, 2));
    206     insertCache(SkISize::Make(3, 3));
    207     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    208 
    209     for (int i = 4; i <= 100; ++i)
    210         insertCache(SkISize::Make(i, i));
    211 
    212     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    213     for (int i = 1; i <= 99; ++i)
    214         EXPECT_FALSE(isCacheAlive(SkISize::Make(i, i)));
    215     EXPECT_TRUE(isCacheAlive(SkISize::Make(100, 100)));
    216 }
    217 
    218 TEST_F(ImageDecodingStoreTest, cacheInUseNotEvicted)
    219 {
    220     insertCache(SkISize::Make(1, 1));
    221     insertCache(SkISize::Make(2, 2));
    222     insertCache(SkISize::Make(3, 3));
    223     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    224 
    225     const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
    226     ASSERT_TRUE(cachedImage);
    227 
    228     // Cache 2 is evicted because cache 1 is in use.
    229     evictOneCache();
    230     EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
    231     EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
    232     EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
    233 
    234     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    235     unlockCache(cachedImage);
    236 }
    237 
    238 TEST_F(ImageDecodingStoreTest, destroyImageFrameGenerator)
    239 {
    240     insertCache(SkISize::Make(1, 1));
    241     insertCache(SkISize::Make(2, 2));
    242     insertCache(SkISize::Make(3, 3));
    243     OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
    244     decoder->setSize(1, 1);
    245     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
    246     EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
    247 
    248     m_generator.clear();
    249     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
    250 }
    251 
    252 TEST_F(ImageDecodingStoreTest, insertDecoder)
    253 {
    254     const SkISize size = SkISize::Make(1, 1);
    255     OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
    256     decoder->setSize(1, 1);
    257     const ImageDecoder* refDecoder = decoder.get();
    258     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
    259     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    260     EXPECT_EQ(4u, ImageDecodingStore::instance()->memoryUsageInBytes());
    261 
    262     ImageDecoder* testDecoder;
    263     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
    264     EXPECT_TRUE(testDecoder);
    265     EXPECT_EQ(refDecoder, testDecoder);
    266     ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder);
    267     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    268 }
    269 
    270 TEST_F(ImageDecodingStoreTest, evictDecoder)
    271 {
    272     OwnPtr<ImageDecoder> decoder1 = MockImageDecoder::create(this);
    273     OwnPtr<ImageDecoder> decoder2 = MockImageDecoder::create(this);
    274     OwnPtr<ImageDecoder> decoder3 = MockImageDecoder::create(this);
    275     decoder1->setSize(1, 1);
    276     decoder2->setSize(2, 2);
    277     decoder3->setSize(3, 3);
    278     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder1.release(), false);
    279     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder2.release(), false);
    280     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder3.release(), false);
    281     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    282     EXPECT_EQ(56u, ImageDecodingStore::instance()->memoryUsageInBytes());
    283 
    284     evictOneCache();
    285     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    286     EXPECT_EQ(52u, ImageDecodingStore::instance()->memoryUsageInBytes());
    287 
    288     evictOneCache();
    289     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    290     EXPECT_EQ(36u, ImageDecodingStore::instance()->memoryUsageInBytes());
    291 
    292     evictOneCache();
    293     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
    294     EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
    295 }
    296 
    297 TEST_F(ImageDecodingStoreTest, decoderInUseNotEvicted)
    298 {
    299     OwnPtr<ImageDecoder> decoder1 = MockImageDecoder::create(this);
    300     OwnPtr<ImageDecoder> decoder2 = MockImageDecoder::create(this);
    301     OwnPtr<ImageDecoder> decoder3 = MockImageDecoder::create(this);
    302     decoder1->setSize(1, 1);
    303     decoder2->setSize(2, 2);
    304     decoder3->setSize(3, 3);
    305     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder1.release(), false);
    306     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder2.release(), false);
    307     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder3.release(), false);
    308     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    309 
    310     ImageDecoder* testDecoder;
    311     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), SkISize::Make(2, 2), &testDecoder));
    312 
    313     evictOneCache();
    314     evictOneCache();
    315     evictOneCache();
    316     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    317     EXPECT_EQ(16u, ImageDecodingStore::instance()->memoryUsageInBytes());
    318 
    319     ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder);
    320     evictOneCache();
    321     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
    322     EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
    323 }
    324 
    325 TEST_F(ImageDecodingStoreTest, removeDecoder)
    326 {
    327     const SkISize size = SkISize::Make(1, 1);
    328     OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
    329     decoder->setSize(1, 1);
    330     const ImageDecoder* refDecoder = decoder.get();
    331     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
    332     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    333     EXPECT_EQ(4u, ImageDecodingStore::instance()->memoryUsageInBytes());
    334 
    335     ImageDecoder* testDecoder;
    336     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
    337     EXPECT_TRUE(testDecoder);
    338     EXPECT_EQ(refDecoder, testDecoder);
    339     ImageDecodingStore::instance()->removeDecoder(m_generator.get(), testDecoder);
    340     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
    341 
    342     EXPECT_FALSE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
    343 }
    344 
    345 TEST_F(ImageDecodingStoreTest, multipleIndex)
    346 {
    347     const SkISize size = SkISize::Make(1, 1);
    348     const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
    349         m_generator.get(), createCompleteImage(size, false, 0));
    350     unlockCache(refImage);
    351     const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
    352         m_generator.get(), createCompleteImage(size, false, 1));
    353     unlockCache(testImage);
    354     EXPECT_NE(refImage, testImage);
    355     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    356 
    357     EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), size, 1, &refImage));
    358     EXPECT_EQ(refImage, testImage);
    359     unlockCache(refImage);
    360 }
    361 
    362 TEST_F(ImageDecodingStoreTest, finalAndPartialImage)
    363 {
    364     const SkISize size = SkISize::Make(1, 1);
    365     const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
    366         m_generator.get(), createCompleteImage(size, false, 0));
    367     unlockCache(refImage);
    368     const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
    369         m_generator.get(), createIncompleteImage(size, false, 1));
    370     unlockCache(testImage);
    371     EXPECT_NE(refImage, testImage);
    372     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    373 
    374     EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), size, 0, &refImage));
    375     EXPECT_NE(refImage, testImage);
    376     unlockCache(refImage);
    377 }
    378 
    379 TEST_F(ImageDecodingStoreTest, insertNoGenerationCollision)
    380 {
    381     const SkISize size = SkISize::Make(1, 1);
    382     const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
    383         m_generator.get(), createIncompleteImage(size, false, 1));
    384     unlockCache(refImage);
    385     const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
    386         m_generator.get(), createIncompleteImage(size, false, 2));
    387     unlockCache(testImage);
    388     EXPECT_NE(refImage, testImage);
    389     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    390 }
    391 
    392 TEST_F(ImageDecodingStoreTest, insertGenerationCollision)
    393 {
    394     const SkISize size = SkISize::Make(1, 1);
    395     const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
    396         m_generator.get(), createIncompleteImage(size, false, 1));
    397     unlockCache(refImage);
    398     const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
    399         m_generator.get(), createIncompleteImage(size, false, 1));
    400     unlockCache(testImage);
    401     EXPECT_EQ(refImage, testImage);
    402     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    403 }
    404 
    405 TEST_F(ImageDecodingStoreTest, insertGenerationCollisionAfterMemoryDiscarded)
    406 {
    407     const SkISize size = SkISize::Make(1, 1);
    408     const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
    409         m_generator.get(), createIncompleteImage(size, true, 1));
    410     unlockCache(refImage);
    411     MockDiscardablePixelRef* pixelRef = static_cast<MockDiscardablePixelRef*>(refImage->bitmap().pixelRef());
    412     pixelRef->discard();
    413     const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
    414         m_generator.get(), createIncompleteImage(size, false, 1));
    415     unlockCache(testImage);
    416     EXPECT_NE(refImage, testImage);
    417     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    418 }
    419 
    420 TEST_F(ImageDecodingStoreTest, lockCacheFailedAfterMemoryDiscarded)
    421 {
    422     const ScaledImageFragment* cachedImage = ImageDecodingStore::instance()->insertAndLockCache(
    423         m_generator.get(), createCompleteImage(SkISize::Make(1, 1), true));
    424     unlockCache(cachedImage);
    425     MockDiscardablePixelRef* pixelRef = static_cast<MockDiscardablePixelRef*>(cachedImage->bitmap().pixelRef());
    426     pixelRef->discard();
    427     EXPECT_EQ(0, lockCache(SkISize::Make(1, 1)));
    428     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
    429 }
    430 
    431 TEST_F(ImageDecodingStoreTest, clear)
    432 {
    433     insertCache(SkISize::Make(1, 1));
    434     insertCache(SkISize::Make(2, 2));
    435     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    436 
    437     OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
    438     decoder->setSize(1, 1);
    439     ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
    440     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
    441 
    442     ImageDecodingStore::instance()->clear();
    443     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
    444 }
    445 
    446 TEST_F(ImageDecodingStoreTest, clearInUse)
    447 {
    448     insertCache(SkISize::Make(1, 1));
    449     insertCache(SkISize::Make(2, 2));
    450     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
    451 
    452     const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
    453     ASSERT_TRUE(cachedImage);
    454     ImageDecodingStore::instance()->clear();
    455     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    456 
    457     unlockCache(cachedImage);
    458     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    459 }
    460 
    461 TEST_F(ImageDecodingStoreTest, disableImageCaching)
    462 {
    463     ImageDecodingStore::instance()->setImageCachingEnabled(false);
    464     insertCache(SkISize::Make(1, 1));
    465     insertCache(SkISize::Make(2, 2));
    466     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
    467 
    468     const ScaledImageFragment* cachedImage = ImageDecodingStore::instance()->insertAndLockCache(
    469         m_generator.get(), createCompleteImage(SkISize::Make(3, 3), true));
    470     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
    471     unlockCache(cachedImage);
    472     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
    473 }
    474 
    475 } // namespace
    476