2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #include "platform/graphics/ImageDecodingStore.h"
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>
36 using namespace blink;
40 class ImageDecodingStoreTest : public ::testing::Test, public MockImageDecoderClient {
44 ImageDecodingStore::instance()->setCacheLimitInBytes(1024 * 1024);
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;
51 virtual void TearDown()
53 ImageDecodingStore::instance()->clear();
56 virtual void decoderBeingDestroyed()
58 ++m_decodersDestroyed;
61 virtual void frameBufferRequested()
63 // Decoder is never used by ImageDecodingStore.
67 virtual ImageFrame::Status status()
69 return ImageFrame::FramePartial;
72 virtual size_t frameCount() { return 1; }
73 virtual int repetitionCount() const { return cAnimationNone; }
74 virtual float frameDuration() const { return 0; }
77 PassOwnPtr<ScaledImageFragment> createCompleteImage(const SkISize& size, bool discardable = false, size_t index = 0)
80 bitmap.setInfo(SkImageInfo::MakeN32Premul(size));
84 MockDiscardablePixelRef::Allocator mockDiscardableAllocator;
85 bitmap.allocPixels(&mockDiscardableAllocator, 0);
87 return ScaledImageFragment::createComplete(size, index, bitmap);
90 PassOwnPtr<ScaledImageFragment> createIncompleteImage(const SkISize& size, bool discardable = false, size_t generation = 0)
93 bitmap.setInfo(SkImageInfo::MakeN32Premul(size));
97 MockDiscardablePixelRef::Allocator mockDiscardableAllocator;
98 bitmap.allocPixels(&mockDiscardableAllocator, 0);
100 return ScaledImageFragment::createPartial(size, 0, generation, bitmap);
103 void insertCache(const SkISize& size)
105 const ScaledImageFragment* image = ImageDecodingStore::instance()->insertAndLockCache(
106 m_generator.get(), createCompleteImage(size));
110 const ScaledImageFragment* lockCache(const SkISize& size, size_t index = 0)
112 const ScaledImageFragment* cachedImage = 0;
113 if (ImageDecodingStore::instance()->lockCache(m_generator.get(), size, index, &cachedImage))
118 void unlockCache(const ScaledImageFragment* cachedImage)
120 ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedImage);
125 size_t memoryUsageInBytes = ImageDecodingStore::instance()->memoryUsageInBytes();
126 if (memoryUsageInBytes)
127 ImageDecodingStore::instance()->setCacheLimitInBytes(memoryUsageInBytes - 1);
129 ImageDecodingStore::instance()->setCacheLimitInBytes(0);
132 bool isCacheAlive(const SkISize& size)
134 const ScaledImageFragment* cachedImage = lockCache(size);
137 ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedImage);
141 RefPtr<SharedBuffer> m_data;
142 RefPtr<ImageFrameGenerator> m_generator;
143 int m_decodersDestroyed;
146 TEST_F(ImageDecodingStoreTest, evictOneCache)
148 insertCache(SkISize::Make(1, 1));
149 insertCache(SkISize::Make(2, 2));
150 insertCache(SkISize::Make(3, 3));
151 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
154 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
157 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
160 TEST_F(ImageDecodingStoreTest, pruneOrderIsLeastRecentlyUsed)
162 insertCache(SkISize::Make(1, 1));
163 insertCache(SkISize::Make(2, 2));
164 insertCache(SkISize::Make(3, 3));
165 insertCache(SkISize::Make(4, 4));
166 insertCache(SkISize::Make(5, 5));
167 EXPECT_EQ(5, ImageDecodingStore::instance()->cacheEntries());
169 // Use cache in the order 3, 2, 4, 1, 5.
170 EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
171 EXPECT_TRUE(isCacheAlive(SkISize::Make(2, 2)));
172 EXPECT_TRUE(isCacheAlive(SkISize::Make(4, 4)));
173 EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
174 EXPECT_TRUE(isCacheAlive(SkISize::Make(5, 5)));
178 EXPECT_FALSE(isCacheAlive(SkISize::Make(3, 3)));
179 EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
183 EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
184 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
188 EXPECT_FALSE(isCacheAlive(SkISize::Make(4, 4)));
189 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
193 EXPECT_FALSE(isCacheAlive(SkISize::Make(1, 1)));
194 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
198 EXPECT_FALSE(isCacheAlive(SkISize::Make(5, 5)));
199 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
202 TEST_F(ImageDecodingStoreTest, pruneCausedByInsertion)
204 ImageDecodingStore::instance()->setCacheLimitInBytes(100);
206 // Insert 100 entries.
207 // Cache entries stored should increase and eventually decrease to 1.
208 insertCache(SkISize::Make(1, 1));
209 insertCache(SkISize::Make(2, 2));
210 insertCache(SkISize::Make(3, 3));
211 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
213 for (int i = 4; i <= 100; ++i)
214 insertCache(SkISize::Make(i, i));
216 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
217 for (int i = 1; i <= 99; ++i)
218 EXPECT_FALSE(isCacheAlive(SkISize::Make(i, i)));
219 EXPECT_TRUE(isCacheAlive(SkISize::Make(100, 100)));
222 TEST_F(ImageDecodingStoreTest, cacheInUseNotEvicted)
224 insertCache(SkISize::Make(1, 1));
225 insertCache(SkISize::Make(2, 2));
226 insertCache(SkISize::Make(3, 3));
227 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
229 const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
230 ASSERT_TRUE(cachedImage);
232 // Cache 2 is evicted because cache 1 is in use.
234 EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
235 EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
236 EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
238 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
239 unlockCache(cachedImage);
242 TEST_F(ImageDecodingStoreTest, destroyImageFrameGenerator)
244 insertCache(SkISize::Make(1, 1));
245 insertCache(SkISize::Make(2, 2));
246 insertCache(SkISize::Make(3, 3));
247 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
248 decoder->setSize(1, 1);
249 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
250 EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
253 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
256 TEST_F(ImageDecodingStoreTest, insertDecoder)
258 const SkISize size = SkISize::Make(1, 1);
259 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
260 decoder->setSize(1, 1);
261 const ImageDecoder* refDecoder = decoder.get();
262 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
263 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
264 EXPECT_EQ(4u, ImageDecodingStore::instance()->memoryUsageInBytes());
266 ImageDecoder* testDecoder;
267 EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
268 EXPECT_TRUE(testDecoder);
269 EXPECT_EQ(refDecoder, testDecoder);
270 ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder);
271 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
274 TEST_F(ImageDecodingStoreTest, evictDecoder)
276 OwnPtr<ImageDecoder> decoder1 = MockImageDecoder::create(this);
277 OwnPtr<ImageDecoder> decoder2 = MockImageDecoder::create(this);
278 OwnPtr<ImageDecoder> decoder3 = MockImageDecoder::create(this);
279 decoder1->setSize(1, 1);
280 decoder2->setSize(2, 2);
281 decoder3->setSize(3, 3);
282 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder1.release(), false);
283 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder2.release(), false);
284 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder3.release(), false);
285 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
286 EXPECT_EQ(56u, ImageDecodingStore::instance()->memoryUsageInBytes());
289 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
290 EXPECT_EQ(52u, ImageDecodingStore::instance()->memoryUsageInBytes());
293 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
294 EXPECT_EQ(36u, ImageDecodingStore::instance()->memoryUsageInBytes());
297 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
298 EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
301 TEST_F(ImageDecodingStoreTest, decoderInUseNotEvicted)
303 OwnPtr<ImageDecoder> decoder1 = MockImageDecoder::create(this);
304 OwnPtr<ImageDecoder> decoder2 = MockImageDecoder::create(this);
305 OwnPtr<ImageDecoder> decoder3 = MockImageDecoder::create(this);
306 decoder1->setSize(1, 1);
307 decoder2->setSize(2, 2);
308 decoder3->setSize(3, 3);
309 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder1.release(), false);
310 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder2.release(), false);
311 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder3.release(), false);
312 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
314 ImageDecoder* testDecoder;
315 EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), SkISize::Make(2, 2), &testDecoder));
320 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
321 EXPECT_EQ(16u, ImageDecodingStore::instance()->memoryUsageInBytes());
323 ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder);
325 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
326 EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
329 TEST_F(ImageDecodingStoreTest, removeDecoder)
331 const SkISize size = SkISize::Make(1, 1);
332 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
333 decoder->setSize(1, 1);
334 const ImageDecoder* refDecoder = decoder.get();
335 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
336 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
337 EXPECT_EQ(4u, ImageDecodingStore::instance()->memoryUsageInBytes());
339 ImageDecoder* testDecoder;
340 EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
341 EXPECT_TRUE(testDecoder);
342 EXPECT_EQ(refDecoder, testDecoder);
343 ImageDecodingStore::instance()->removeDecoder(m_generator.get(), testDecoder);
344 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
346 EXPECT_FALSE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
349 TEST_F(ImageDecodingStoreTest, multipleIndex)
351 const SkISize size = SkISize::Make(1, 1);
352 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
353 m_generator.get(), createCompleteImage(size, false, 0));
354 unlockCache(refImage);
355 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
356 m_generator.get(), createCompleteImage(size, false, 1));
357 unlockCache(testImage);
358 EXPECT_NE(refImage, testImage);
359 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
361 EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), size, 1, &refImage));
362 EXPECT_EQ(refImage, testImage);
363 unlockCache(refImage);
366 TEST_F(ImageDecodingStoreTest, finalAndPartialImage)
368 const SkISize size = SkISize::Make(1, 1);
369 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
370 m_generator.get(), createCompleteImage(size, false, 0));
371 unlockCache(refImage);
372 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
373 m_generator.get(), createIncompleteImage(size, false, 1));
374 unlockCache(testImage);
375 EXPECT_NE(refImage, testImage);
376 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
378 EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), size, 0, &refImage));
379 EXPECT_NE(refImage, testImage);
380 unlockCache(refImage);
383 TEST_F(ImageDecodingStoreTest, insertNoGenerationCollision)
385 const SkISize size = SkISize::Make(1, 1);
386 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
387 m_generator.get(), createIncompleteImage(size, false, 1));
388 unlockCache(refImage);
389 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
390 m_generator.get(), createIncompleteImage(size, false, 2));
391 unlockCache(testImage);
392 EXPECT_NE(refImage, testImage);
393 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
396 TEST_F(ImageDecodingStoreTest, insertGenerationCollision)
398 const SkISize size = SkISize::Make(1, 1);
399 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
400 m_generator.get(), createIncompleteImage(size, false, 1));
401 unlockCache(refImage);
402 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
403 m_generator.get(), createIncompleteImage(size, false, 1));
404 unlockCache(testImage);
405 EXPECT_EQ(refImage, testImage);
406 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
409 TEST_F(ImageDecodingStoreTest, insertGenerationCollisionAfterMemoryDiscarded)
411 const SkISize size = SkISize::Make(1, 1);
412 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insertAndLockCache(
413 m_generator.get(), createIncompleteImage(size, true, 1));
414 unlockCache(refImage);
415 MockDiscardablePixelRef* pixelRef = static_cast<MockDiscardablePixelRef*>(refImage->bitmap().pixelRef());
417 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->insertAndLockCache(
418 m_generator.get(), createIncompleteImage(size, false, 1));
419 unlockCache(testImage);
420 EXPECT_NE(refImage, testImage);
421 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
424 TEST_F(ImageDecodingStoreTest, lockCacheFailedAfterMemoryDiscarded)
426 const ScaledImageFragment* cachedImage = ImageDecodingStore::instance()->insertAndLockCache(
427 m_generator.get(), createCompleteImage(SkISize::Make(1, 1), true));
428 unlockCache(cachedImage);
429 MockDiscardablePixelRef* pixelRef = static_cast<MockDiscardablePixelRef*>(cachedImage->bitmap().pixelRef());
431 EXPECT_EQ(0, lockCache(SkISize::Make(1, 1)));
432 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
435 TEST_F(ImageDecodingStoreTest, clear)
437 insertCache(SkISize::Make(1, 1));
438 insertCache(SkISize::Make(2, 2));
439 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
441 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
442 decoder->setSize(1, 1);
443 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.release(), false);
444 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
446 ImageDecodingStore::instance()->clear();
447 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
450 TEST_F(ImageDecodingStoreTest, clearInUse)
452 insertCache(SkISize::Make(1, 1));
453 insertCache(SkISize::Make(2, 2));
454 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
456 const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
457 ASSERT_TRUE(cachedImage);
458 ImageDecodingStore::instance()->clear();
459 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
461 unlockCache(cachedImage);
462 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
465 TEST_F(ImageDecodingStoreTest, disableImageCaching)
467 ImageDecodingStore::instance()->setImageCachingEnabled(false);
468 insertCache(SkISize::Make(1, 1));
469 insertCache(SkISize::Make(2, 2));
470 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
472 const ScaledImageFragment* cachedImage = ImageDecodingStore::instance()->insertAndLockCache(
473 m_generator.get(), createCompleteImage(SkISize::Make(3, 3), true));
474 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
475 unlockCache(cachedImage);
476 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());