Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / ImageDecodingStoreTest.cpp
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 blink;
37
38 namespace {
39
40 class ImageDecodingStoreTest : public ::testing::Test, public MockImageDecoderClient {
41 public:
42     virtual void SetUp()
43     {
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;
49     }
50
51     virtual void TearDown()
52     {
53         ImageDecodingStore::instance()->clear();
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.setInfo(SkImageInfo::MakeN32Premul(size));
81         if (!discardable) {
82             bitmap.allocPixels();
83         } else {
84             MockDiscardablePixelRef::Allocator mockDiscardableAllocator;
85             bitmap.allocPixels(&mockDiscardableAllocator, 0);
86         }
87         return ScaledImageFragment::createComplete(size, index, bitmap);
88     }
89
90     PassOwnPtr<ScaledImageFragment> createIncompleteImage(const SkISize& size, bool discardable = false, size_t generation = 0)
91     {
92         SkBitmap bitmap;
93         bitmap.setInfo(SkImageInfo::MakeN32Premul(size));
94         if (!discardable) {
95             bitmap.allocPixels();
96         } else {
97             MockDiscardablePixelRef::Allocator mockDiscardableAllocator;
98             bitmap.allocPixels(&mockDiscardableAllocator, 0);
99         }
100         return ScaledImageFragment::createPartial(size, 0, generation, bitmap);
101     }
102
103     void insertCache(const SkISize& size)
104     {
105         const ScaledImageFragment* image = ImageDecodingStore::instance()->insertAndLockCache(
106             m_generator.get(), createCompleteImage(size));
107         unlockCache(image);
108     }
109
110     const ScaledImageFragment* lockCache(const SkISize& size, size_t index = 0)
111     {
112         const ScaledImageFragment* cachedImage = 0;
113         if (ImageDecodingStore::instance()->lockCache(m_generator.get(), size, index, &cachedImage))
114             return cachedImage;
115         return 0;
116     }
117
118     void unlockCache(const ScaledImageFragment* cachedImage)
119     {
120         ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedImage);
121     }
122
123     void evictOneCache()
124     {
125         size_t memoryUsageInBytes = ImageDecodingStore::instance()->memoryUsageInBytes();
126         if (memoryUsageInBytes)
127             ImageDecodingStore::instance()->setCacheLimitInBytes(memoryUsageInBytes - 1);
128         else
129             ImageDecodingStore::instance()->setCacheLimitInBytes(0);
130     }
131
132     bool isCacheAlive(const SkISize& size)
133     {
134         const ScaledImageFragment* cachedImage = lockCache(size);
135         if (!cachedImage)
136             return false;
137         ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedImage);
138         return true;
139     }
140
141     RefPtr<SharedBuffer> m_data;
142     RefPtr<ImageFrameGenerator> m_generator;
143     int m_decodersDestroyed;
144 };
145
146 TEST_F(ImageDecodingStoreTest, evictOneCache)
147 {
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());
152
153     evictOneCache();
154     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
155
156     evictOneCache();
157     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
158 }
159
160 TEST_F(ImageDecodingStoreTest, pruneOrderIsLeastRecentlyUsed)
161 {
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());
168
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)));
175
176     // Evict 3.
177     evictOneCache();
178     EXPECT_FALSE(isCacheAlive(SkISize::Make(3, 3)));
179     EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
180
181     // Evict 2.
182     evictOneCache();
183     EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
184     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
185
186     // Evict 4.
187     evictOneCache();
188     EXPECT_FALSE(isCacheAlive(SkISize::Make(4, 4)));
189     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
190
191     // Evict 1.
192     evictOneCache();
193     EXPECT_FALSE(isCacheAlive(SkISize::Make(1, 1)));
194     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
195
196     // Evict 5.
197     evictOneCache();
198     EXPECT_FALSE(isCacheAlive(SkISize::Make(5, 5)));
199     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
200 }
201
202 TEST_F(ImageDecodingStoreTest, pruneCausedByInsertion)
203 {
204     ImageDecodingStore::instance()->setCacheLimitInBytes(100);
205
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());
212
213     for (int i = 4; i <= 100; ++i)
214         insertCache(SkISize::Make(i, i));
215
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)));
220 }
221
222 TEST_F(ImageDecodingStoreTest, cacheInUseNotEvicted)
223 {
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());
228
229     const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
230     ASSERT_TRUE(cachedImage);
231
232     // Cache 2 is evicted because cache 1 is in use.
233     evictOneCache();
234     EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
235     EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
236     EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
237
238     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
239     unlockCache(cachedImage);
240 }
241
242 TEST_F(ImageDecodingStoreTest, destroyImageFrameGenerator)
243 {
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());
251
252     m_generator.clear();
253     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
254 }
255
256 TEST_F(ImageDecodingStoreTest, insertDecoder)
257 {
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());
265
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());
272 }
273
274 TEST_F(ImageDecodingStoreTest, evictDecoder)
275 {
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());
287
288     evictOneCache();
289     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
290     EXPECT_EQ(52u, ImageDecodingStore::instance()->memoryUsageInBytes());
291
292     evictOneCache();
293     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
294     EXPECT_EQ(36u, ImageDecodingStore::instance()->memoryUsageInBytes());
295
296     evictOneCache();
297     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
298     EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
299 }
300
301 TEST_F(ImageDecodingStoreTest, decoderInUseNotEvicted)
302 {
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());
313
314     ImageDecoder* testDecoder;
315     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), SkISize::Make(2, 2), &testDecoder));
316
317     evictOneCache();
318     evictOneCache();
319     evictOneCache();
320     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
321     EXPECT_EQ(16u, ImageDecodingStore::instance()->memoryUsageInBytes());
322
323     ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder);
324     evictOneCache();
325     EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
326     EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
327 }
328
329 TEST_F(ImageDecodingStoreTest, removeDecoder)
330 {
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());
338
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());
345
346     EXPECT_FALSE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
347 }
348
349 TEST_F(ImageDecodingStoreTest, multipleIndex)
350 {
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());
360
361     EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), size, 1, &refImage));
362     EXPECT_EQ(refImage, testImage);
363     unlockCache(refImage);
364 }
365
366 TEST_F(ImageDecodingStoreTest, finalAndPartialImage)
367 {
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());
377
378     EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), size, 0, &refImage));
379     EXPECT_NE(refImage, testImage);
380     unlockCache(refImage);
381 }
382
383 TEST_F(ImageDecodingStoreTest, insertNoGenerationCollision)
384 {
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());
394 }
395
396 TEST_F(ImageDecodingStoreTest, insertGenerationCollision)
397 {
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());
407 }
408
409 TEST_F(ImageDecodingStoreTest, insertGenerationCollisionAfterMemoryDiscarded)
410 {
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());
416     pixelRef->discard();
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());
422 }
423
424 TEST_F(ImageDecodingStoreTest, lockCacheFailedAfterMemoryDiscarded)
425 {
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());
430     pixelRef->discard();
431     EXPECT_EQ(0, lockCache(SkISize::Make(1, 1)));
432     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
433 }
434
435 TEST_F(ImageDecodingStoreTest, clear)
436 {
437     insertCache(SkISize::Make(1, 1));
438     insertCache(SkISize::Make(2, 2));
439     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
440
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());
445
446     ImageDecodingStore::instance()->clear();
447     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
448 }
449
450 TEST_F(ImageDecodingStoreTest, clearInUse)
451 {
452     insertCache(SkISize::Make(1, 1));
453     insertCache(SkISize::Make(2, 2));
454     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
455
456     const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
457     ASSERT_TRUE(cachedImage);
458     ImageDecodingStore::instance()->clear();
459     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
460
461     unlockCache(cachedImage);
462     EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
463 }
464
465 TEST_F(ImageDecodingStoreTest, disableImageCaching)
466 {
467     ImageDecodingStore::instance()->setImageCachingEnabled(false);
468     insertCache(SkISize::Make(1, 1));
469     insertCache(SkISize::Make(2, 2));
470     EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
471
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());
477 }
478
479 } // namespace