Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: Source/core/platform/graphics/ImageDecodingStoreTest.cpp

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "core/platform/graphics/ImageDecodingStore.h"
29
30 #include "platform/SharedBuffer.h"
31 #include "core/platform/graphics/ImageFrameGenerator.h"
32 #include "core/platform/graphics/test/MockDiscardablePixelRef.h"
33 #include "core/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 MockImageDecoderCl ient {
41 public:
42 virtual void SetUp()
43 {
44 ImageDecodingStore::initializeOnce();
45 m_data = SharedBuffer::create();
46 m_generator = ImageFrameGenerator::create(SkISize::Make(100, 100), m_dat a, true);
47 m_decodersDestroyed = 0;
48 }
49
50 virtual void TearDown()
51 {
52 ImageDecodingStore::shutdown();
53 }
54
55 virtual void decoderBeingDestroyed()
56 {
57 ++m_decodersDestroyed;
58 }
59
60 virtual void frameBufferRequested()
61 {
62 // Decoder is never used by ImageDecodingStore.
63 ASSERT_TRUE(false);
64 }
65
66 virtual ImageFrame::Status status()
67 {
68 return ImageFrame::FramePartial;
69 }
70
71 virtual size_t frameCount() { return 1; }
72 virtual int repetitionCount() const { return cAnimationNone; }
73 virtual float frameDuration() const { return 0; }
74
75 protected:
76 PassOwnPtr<ScaledImageFragment> createCompleteImage(const SkISize& size, boo l discardable = false, size_t index = 0)
77 {
78 SkBitmap bitmap;
79 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height( ));
80 if (!discardable)
81 bitmap.allocPixels();
82 else
83 bitmap.setPixelRef(new MockDiscardablePixelRef())->unref();
84 return ScaledImageFragment::createComplete(size, index, bitmap);
85 }
86
87 PassOwnPtr<ScaledImageFragment> createIncompleteImage(const SkISize& size, b ool discardable = false, size_t generation = 0)
88 {
89 SkBitmap bitmap;
90 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height( ));
91 if (!discardable)
92 bitmap.allocPixels();
93 else
94 bitmap.setPixelRef(new MockDiscardablePixelRef())->unref();
95 return ScaledImageFragment::createPartial(size, 0, generation, bitmap);
96 }
97
98 void insertCache(const SkISize& size)
99 {
100 const ScaledImageFragment* image = ImageDecodingStore::instance()->inser tAndLockCache(
101 m_generator.get(), createCompleteImage(size));
102 unlockCache(image);
103 }
104
105 const ScaledImageFragment* lockCache(const SkISize& size, size_t index = 0)
106 {
107 const ScaledImageFragment* cachedImage = 0;
108 if (ImageDecodingStore::instance()->lockCache(m_generator.get(), size, i ndex, &cachedImage))
109 return cachedImage;
110 return 0;
111 }
112
113 void unlockCache(const ScaledImageFragment* cachedImage)
114 {
115 ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedIma ge);
116 }
117
118 void evictOneCache()
119 {
120 size_t memoryUsageInBytes = ImageDecodingStore::instance()->memoryUsageI nBytes();
121 if (memoryUsageInBytes)
122 ImageDecodingStore::instance()->setCacheLimitInBytes(memoryUsageInBy tes - 1);
123 else
124 ImageDecodingStore::instance()->setCacheLimitInBytes(0);
125 }
126
127 bool isCacheAlive(const SkISize& size)
128 {
129 const ScaledImageFragment* cachedImage = lockCache(size);
130 if (!cachedImage)
131 return false;
132 ImageDecodingStore::instance()->unlockCache(m_generator.get(), cachedIma ge);
133 return true;
134 }
135
136 RefPtr<SharedBuffer> m_data;
137 RefPtr<ImageFrameGenerator> m_generator;
138 int m_decodersDestroyed;
139 };
140
141 TEST_F(ImageDecodingStoreTest, evictOneCache)
142 {
143 insertCache(SkISize::Make(1, 1));
144 insertCache(SkISize::Make(2, 2));
145 insertCache(SkISize::Make(3, 3));
146 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
147
148 evictOneCache();
149 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
150
151 evictOneCache();
152 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
153 }
154
155 TEST_F(ImageDecodingStoreTest, pruneOrderIsLeastRecentlyUsed)
156 {
157 insertCache(SkISize::Make(1, 1));
158 insertCache(SkISize::Make(2, 2));
159 insertCache(SkISize::Make(3, 3));
160 insertCache(SkISize::Make(4, 4));
161 insertCache(SkISize::Make(5, 5));
162 EXPECT_EQ(5, ImageDecodingStore::instance()->cacheEntries());
163
164 // Use cache in the order 3, 2, 4, 1, 5.
165 EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
166 EXPECT_TRUE(isCacheAlive(SkISize::Make(2, 2)));
167 EXPECT_TRUE(isCacheAlive(SkISize::Make(4, 4)));
168 EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
169 EXPECT_TRUE(isCacheAlive(SkISize::Make(5, 5)));
170
171 // Evict 3.
172 evictOneCache();
173 EXPECT_FALSE(isCacheAlive(SkISize::Make(3, 3)));
174 EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
175
176 // Evict 2.
177 evictOneCache();
178 EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
179 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
180
181 // Evict 4.
182 evictOneCache();
183 EXPECT_FALSE(isCacheAlive(SkISize::Make(4, 4)));
184 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
185
186 // Evict 1.
187 evictOneCache();
188 EXPECT_FALSE(isCacheAlive(SkISize::Make(1, 1)));
189 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
190
191 // Evict 5.
192 evictOneCache();
193 EXPECT_FALSE(isCacheAlive(SkISize::Make(5, 5)));
194 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
195 }
196
197 TEST_F(ImageDecodingStoreTest, pruneCausedByInsertion)
198 {
199 ImageDecodingStore::instance()->setCacheLimitInBytes(100);
200
201 // Insert 100 entries.
202 // Cache entries stored should increase and eventually decrease to 1.
203 insertCache(SkISize::Make(1, 1));
204 insertCache(SkISize::Make(2, 2));
205 insertCache(SkISize::Make(3, 3));
206 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
207
208 for (int i = 4; i <= 100; ++i)
209 insertCache(SkISize::Make(i, i));
210
211 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
212 for (int i = 1; i <= 99; ++i)
213 EXPECT_FALSE(isCacheAlive(SkISize::Make(i, i)));
214 EXPECT_TRUE(isCacheAlive(SkISize::Make(100, 100)));
215 }
216
217 TEST_F(ImageDecodingStoreTest, cacheInUseNotEvicted)
218 {
219 insertCache(SkISize::Make(1, 1));
220 insertCache(SkISize::Make(2, 2));
221 insertCache(SkISize::Make(3, 3));
222 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
223
224 const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
225 ASSERT_TRUE(cachedImage);
226
227 // Cache 2 is evicted because cache 1 is in use.
228 evictOneCache();
229 EXPECT_TRUE(isCacheAlive(SkISize::Make(1, 1)));
230 EXPECT_FALSE(isCacheAlive(SkISize::Make(2, 2)));
231 EXPECT_TRUE(isCacheAlive(SkISize::Make(3, 3)));
232
233 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
234 unlockCache(cachedImage);
235 }
236
237 TEST_F(ImageDecodingStoreTest, destroyImageFrameGenerator)
238 {
239 insertCache(SkISize::Make(1, 1));
240 insertCache(SkISize::Make(2, 2));
241 insertCache(SkISize::Make(3, 3));
242 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
243 decoder->setSize(1, 1);
244 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.rel ease(), false);
245 EXPECT_EQ(4, ImageDecodingStore::instance()->cacheEntries());
246
247 m_generator.clear();
248 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
249 }
250
251 TEST_F(ImageDecodingStoreTest, insertDecoder)
252 {
253 const SkISize size = SkISize::Make(1, 1);
254 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
255 decoder->setSize(1, 1);
256 const ImageDecoder* refDecoder = decoder.get();
257 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.rel ease(), false);
258 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
259 EXPECT_EQ(4u, ImageDecodingStore::instance()->memoryUsageInBytes());
260
261 ImageDecoder* testDecoder;
262 EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), s ize, &testDecoder));
263 EXPECT_TRUE(testDecoder);
264 EXPECT_EQ(refDecoder, testDecoder);
265 ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder );
266 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
267 }
268
269 TEST_F(ImageDecodingStoreTest, evictDecoder)
270 {
271 OwnPtr<ImageDecoder> decoder1 = MockImageDecoder::create(this);
272 OwnPtr<ImageDecoder> decoder2 = MockImageDecoder::create(this);
273 OwnPtr<ImageDecoder> decoder3 = MockImageDecoder::create(this);
274 decoder1->setSize(1, 1);
275 decoder2->setSize(2, 2);
276 decoder3->setSize(3, 3);
277 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder1.re lease(), false);
278 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder2.re lease(), false);
279 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder3.re lease(), false);
280 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
281 EXPECT_EQ(56u, ImageDecodingStore::instance()->memoryUsageInBytes());
282
283 evictOneCache();
284 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
285 EXPECT_EQ(52u, ImageDecodingStore::instance()->memoryUsageInBytes());
286
287 evictOneCache();
288 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
289 EXPECT_EQ(36u, ImageDecodingStore::instance()->memoryUsageInBytes());
290
291 evictOneCache();
292 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
293 EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
294 }
295
296 TEST_F(ImageDecodingStoreTest, decoderInUseNotEvicted)
297 {
298 OwnPtr<ImageDecoder> decoder1 = MockImageDecoder::create(this);
299 OwnPtr<ImageDecoder> decoder2 = MockImageDecoder::create(this);
300 OwnPtr<ImageDecoder> decoder3 = MockImageDecoder::create(this);
301 decoder1->setSize(1, 1);
302 decoder2->setSize(2, 2);
303 decoder3->setSize(3, 3);
304 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder1.re lease(), false);
305 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder2.re lease(), false);
306 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder3.re lease(), false);
307 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
308
309 ImageDecoder* testDecoder;
310 EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), S kISize::Make(2, 2), &testDecoder));
311
312 evictOneCache();
313 evictOneCache();
314 evictOneCache();
315 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
316 EXPECT_EQ(16u, ImageDecodingStore::instance()->memoryUsageInBytes());
317
318 ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), testDecoder );
319 evictOneCache();
320 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
321 EXPECT_FALSE(ImageDecodingStore::instance()->memoryUsageInBytes());
322 }
323
324 TEST_F(ImageDecodingStoreTest, removeDecoder)
325 {
326 const SkISize size = SkISize::Make(1, 1);
327 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
328 decoder->setSize(1, 1);
329 const ImageDecoder* refDecoder = decoder.get();
330 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.rel ease(), false);
331 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
332 EXPECT_EQ(4u, ImageDecodingStore::instance()->memoryUsageInBytes());
333
334 ImageDecoder* testDecoder;
335 EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), s ize, &testDecoder));
336 EXPECT_TRUE(testDecoder);
337 EXPECT_EQ(refDecoder, testDecoder);
338 ImageDecodingStore::instance()->removeDecoder(m_generator.get(), testDecoder );
339 EXPECT_FALSE(ImageDecodingStore::instance()->cacheEntries());
340
341 EXPECT_FALSE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), size, &testDecoder));
342 }
343
344 TEST_F(ImageDecodingStoreTest, multipleIndex)
345 {
346 const SkISize size = SkISize::Make(1, 1);
347 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insert AndLockCache(
348 m_generator.get(), createCompleteImage(size, false, 0));
349 unlockCache(refImage);
350 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->inser tAndLockCache(
351 m_generator.get(), createCompleteImage(size, false, 1));
352 unlockCache(testImage);
353 EXPECT_NE(refImage, testImage);
354 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
355
356 EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), siz e, 1, &refImage));
357 EXPECT_EQ(refImage, testImage);
358 unlockCache(refImage);
359 }
360
361 TEST_F(ImageDecodingStoreTest, finalAndPartialImage)
362 {
363 const SkISize size = SkISize::Make(1, 1);
364 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insert AndLockCache(
365 m_generator.get(), createCompleteImage(size, false, 0));
366 unlockCache(refImage);
367 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->inser tAndLockCache(
368 m_generator.get(), createIncompleteImage(size, false, 1));
369 unlockCache(testImage);
370 EXPECT_NE(refImage, testImage);
371 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
372
373 EXPECT_TRUE(ImageDecodingStore::instance()->lockCache(m_generator.get(), siz e, 0, &refImage));
374 EXPECT_NE(refImage, testImage);
375 unlockCache(refImage);
376 }
377
378 TEST_F(ImageDecodingStoreTest, insertNoGenerationCollision)
379 {
380 const SkISize size = SkISize::Make(1, 1);
381 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insert AndLockCache(
382 m_generator.get(), createIncompleteImage(size, false, 1));
383 unlockCache(refImage);
384 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->inser tAndLockCache(
385 m_generator.get(), createIncompleteImage(size, false, 2));
386 unlockCache(testImage);
387 EXPECT_NE(refImage, testImage);
388 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
389 }
390
391 TEST_F(ImageDecodingStoreTest, insertGenerationCollision)
392 {
393 const SkISize size = SkISize::Make(1, 1);
394 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insert AndLockCache(
395 m_generator.get(), createIncompleteImage(size, false, 1));
396 unlockCache(refImage);
397 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->inser tAndLockCache(
398 m_generator.get(), createIncompleteImage(size, false, 1));
399 unlockCache(testImage);
400 EXPECT_EQ(refImage, testImage);
401 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
402 }
403
404 TEST_F(ImageDecodingStoreTest, insertGenerationCollisionAfterMemoryDiscarded)
405 {
406 const SkISize size = SkISize::Make(1, 1);
407 const ScaledImageFragment* refImage = ImageDecodingStore::instance()->insert AndLockCache(
408 m_generator.get(), createIncompleteImage(size, true, 1));
409 unlockCache(refImage);
410 MockDiscardablePixelRef* pixelRef = static_cast<MockDiscardablePixelRef*>(re fImage->bitmap().pixelRef());
411 pixelRef->discard();
412 const ScaledImageFragment* testImage = ImageDecodingStore::instance()->inser tAndLockCache(
413 m_generator.get(), createIncompleteImage(size, false, 1));
414 unlockCache(testImage);
415 EXPECT_NE(refImage, testImage);
416 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
417 }
418
419 TEST_F(ImageDecodingStoreTest, lockCacheFailedAfterMemoryDiscarded)
420 {
421 const ScaledImageFragment* cachedImage = ImageDecodingStore::instance()->ins ertAndLockCache(
422 m_generator.get(), createCompleteImage(SkISize::Make(1, 1), true));
423 unlockCache(cachedImage);
424 MockDiscardablePixelRef* pixelRef = static_cast<MockDiscardablePixelRef*>(ca chedImage->bitmap().pixelRef());
425 pixelRef->discard();
426 EXPECT_EQ(0, lockCache(SkISize::Make(1, 1)));
427 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
428 }
429
430 TEST_F(ImageDecodingStoreTest, clear)
431 {
432 insertCache(SkISize::Make(1, 1));
433 insertCache(SkISize::Make(2, 2));
434 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
435
436 OwnPtr<ImageDecoder> decoder = MockImageDecoder::create(this);
437 decoder->setSize(1, 1);
438 ImageDecodingStore::instance()->insertDecoder(m_generator.get(), decoder.rel ease(), false);
439 EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
440
441 ImageDecodingStore::instance()->clear();
442 EXPECT_EQ(0, ImageDecodingStore::instance()->cacheEntries());
443 }
444
445 TEST_F(ImageDecodingStoreTest, clearInUse)
446 {
447 insertCache(SkISize::Make(1, 1));
448 insertCache(SkISize::Make(2, 2));
449 EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
450
451 const ScaledImageFragment* cachedImage = lockCache(SkISize::Make(1, 1));
452 ASSERT_TRUE(cachedImage);
453 ImageDecodingStore::instance()->clear();
454 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
455
456 unlockCache(cachedImage);
457 EXPECT_EQ(1, ImageDecodingStore::instance()->cacheEntries());
458 }
459
460 } // namespace
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/ImageDecodingStore.cpp ('k') | Source/core/platform/graphics/ImageFrameGenerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698