1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/tiles/software_image_decode_cache.h"
6
7 #include "base/strings/stringprintf.h"
8 #include "cc/paint/draw_image.h"
9 #include "cc/paint/paint_image_builder.h"
10 #include "cc/test/fake_paint_image_generator.h"
11 #include "cc/test/skia_common.h"
12 #include "cc/test/test_tile_task_runner.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/skia/include/core/SkRefCnt.h"
15
16 namespace cc {
17 namespace {
18
19 size_t kLockedMemoryLimitBytes = 128 * 1024 * 1024;
CreateMatrix(const SkSize & scale,bool is_decomposable)20 SkMatrix CreateMatrix(const SkSize& scale, bool is_decomposable) {
21 SkMatrix matrix;
22 matrix.setScale(scale.width(), scale.height());
23
24 if (!is_decomposable) {
25 // Perspective is not decomposable, add it.
26 matrix[SkMatrix::kMPersp0] = 0.1f;
27 }
28
29 return matrix;
30 }
31
32 class BaseTest : public testing::Test {
33 public:
SetUp()34 void SetUp() override {
35 cache_ = CreateCache();
36 paint_image_ = CreatePaintImage(gfx::Size(512, 512));
37 }
38
TearDown()39 void TearDown() override {
40 paint_image_ = PaintImage();
41 cache_.reset();
42 }
43
CreateDrawImageForScale(float scale,const SkIRect src_rect=SkIRect::MakeEmpty ())44 DrawImage CreateDrawImageForScale(
45 float scale,
46 const SkIRect src_rect = SkIRect::MakeEmpty()) {
47 return DrawImage(
48 paint_image(),
49 src_rect.isEmpty()
50 ? SkIRect::MakeWH(paint_image().width(), paint_image().height())
51 : src_rect,
52 kMedium_SkFilterQuality, CreateMatrix(SkSize::Make(scale, scale), true),
53 PaintImage::kDefaultFrameIndex, GetColorSpace());
54 }
55
cache()56 SoftwareImageDecodeCache& cache() { return *cache_; }
paint_image()57 PaintImage& paint_image() { return paint_image_; }
58
59 protected:
60 struct CacheEntryResult {
61 bool has_task = false;
62 bool needs_unref = false;
63 };
64
65 virtual std::unique_ptr<SoftwareImageDecodeCache> CreateCache() = 0;
66 virtual CacheEntryResult GenerateCacheEntry(const DrawImage& image) = 0;
67 virtual PaintImage CreatePaintImage(const gfx::Size& size) = 0;
68 virtual gfx::ColorSpace GetColorSpace() = 0;
69 virtual void VerifyEntryExists(int line,
70 const DrawImage& draw_image,
71 const gfx::Size& expected_size) = 0;
72
73 private:
74 std::unique_ptr<SoftwareImageDecodeCache> cache_;
75 PaintImage paint_image_;
76 };
77
78 class N32Cache : public virtual BaseTest {
79 protected:
CreateCache()80 std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
81 return std::make_unique<SoftwareImageDecodeCache>(
82 kN32_SkColorType, kLockedMemoryLimitBytes,
83 PaintImage::kDefaultGeneratorClientId);
84 }
85 };
86
87 class RGBA4444Cache : public virtual BaseTest {
88 protected:
CreateCache()89 std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
90 return std::make_unique<SoftwareImageDecodeCache>(
91 kARGB_4444_SkColorType, kLockedMemoryLimitBytes,
92 PaintImage::kDefaultGeneratorClientId);
93 }
94 };
95
96 class RGBA_F16Cache : public virtual BaseTest {
97 protected:
CreateCache()98 std::unique_ptr<SoftwareImageDecodeCache> CreateCache() override {
99 return std::make_unique<SoftwareImageDecodeCache>(
100 kRGBA_F16_SkColorType, kLockedMemoryLimitBytes,
101 PaintImage::kDefaultGeneratorClientId);
102 }
103 };
104
105 class AtRaster : public virtual BaseTest {
106 protected:
GenerateCacheEntry(const DrawImage & image)107 CacheEntryResult GenerateCacheEntry(const DrawImage& image) override {
108 // At raster doesn't generate cache entries.
109 return {false, false};
110 }
VerifyEntryExists(int line,const DrawImage & draw_image,const gfx::Size & expected_size)111 void VerifyEntryExists(int line,
112 const DrawImage& draw_image,
113 const gfx::Size& expected_size) override {
114 auto decoded = cache().GetDecodedImageForDraw(draw_image);
115 SCOPED_TRACE(base::StringPrintf("Failure from line %d", line));
116 EXPECT_EQ(decoded.image()->width(), expected_size.width());
117 EXPECT_EQ(decoded.image()->height(), expected_size.height());
118 cache().DrawWithImageFinished(draw_image, decoded);
119 }
120 };
121
122 class Predecode : public virtual BaseTest {
123 protected:
GenerateCacheEntry(const DrawImage & image)124 CacheEntryResult GenerateCacheEntry(const DrawImage& image) override {
125 auto task_result =
126 cache().GetTaskForImageAndRef(image, ImageDecodeCache::TracingInfo());
127 CacheEntryResult result = {!!task_result.task, task_result.need_unref};
128
129 if (task_result.task)
130 TestTileTaskRunner::ProcessTask(task_result.task.get());
131 return result;
132 }
133
VerifyEntryExists(int line,const DrawImage & draw_image,const gfx::Size & expected_size)134 void VerifyEntryExists(int line,
135 const DrawImage& draw_image,
136 const gfx::Size& expected_size) override {
137 auto decoded = cache().GetDecodedImageForDraw(draw_image);
138 EXPECT_TRUE(SkColorSpace::Equals(
139 decoded.image()->colorSpace(),
140 draw_image.target_color_space().ToSkColorSpace().get()));
141 SCOPED_TRACE(base::StringPrintf("Failure from line %d", line));
142 EXPECT_EQ(decoded.image()->width(), expected_size.width());
143 EXPECT_EQ(decoded.image()->height(), expected_size.height());
144 cache().DrawWithImageFinished(draw_image, decoded);
145 }
146 };
147
148 class NoDecodeToScaleSupport : public virtual BaseTest {
149 protected:
CreatePaintImage(const gfx::Size & size)150 PaintImage CreatePaintImage(const gfx::Size& size) override {
151 return CreateDiscardablePaintImage(size, GetColorSpace().ToSkColorSpace());
152 }
153 };
154
155 class NoDecodeToScaleSupportF16 : public virtual BaseTest {
156 protected:
CreatePaintImage(const gfx::Size & size)157 PaintImage CreatePaintImage(const gfx::Size& size) override {
158 PaintImage paint_image = CreateDiscardablePaintImage(
159 size, GetColorSpace().ToSkColorSpace(),
160 true /*allocate_encoded_memory*/, PaintImage::kInvalidId,
161 kRGBA_F16_SkColorType);
162 return paint_image;
163 }
164 };
165
166 class DefaultColorSpace : public virtual BaseTest {
167 protected:
GetColorSpace()168 gfx::ColorSpace GetColorSpace() override {
169 return gfx::ColorSpace::CreateSRGB();
170 }
171 };
172
173 class ExoticColorSpace : public virtual BaseTest {
174 protected:
GetColorSpace()175 gfx::ColorSpace GetColorSpace() override {
176 return gfx::ColorSpace(gfx::ColorSpace::PrimaryID::XYZ_D50,
177 gfx::ColorSpace::TransferID::IEC61966_2_1);
178 }
179 };
180
181 class WideGamutCanvasColorSpace : public virtual BaseTest {
182 protected:
GetColorSpace()183 gfx::ColorSpace GetColorSpace() override {
184 return gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTEST432_1, // P3
185 gfx::ColorSpace::TransferID::LINEAR);
186 }
187 };
188 class SoftwareImageDecodeCacheTest_Typical : public N32Cache,
189 public Predecode,
190 public NoDecodeToScaleSupport,
191 public DefaultColorSpace {};
192
TEST_F(SoftwareImageDecodeCacheTest_Typical,UseClosestAvailableDecode)193 TEST_F(SoftwareImageDecodeCacheTest_Typical, UseClosestAvailableDecode) {
194 auto draw_image_50 = CreateDrawImageForScale(0.5f);
195 auto result = GenerateCacheEntry(draw_image_50);
196 EXPECT_TRUE(result.has_task);
197 EXPECT_TRUE(result.needs_unref);
198
199 // Clear the cache to eliminate the transient 1.f scale from the cache.
200 cache().ClearCache();
201 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
202 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
203
204 auto draw_image_125 = CreateDrawImageForScale(0.125f);
205 result = GenerateCacheEntry(draw_image_125);
206 EXPECT_TRUE(result.has_task);
207 EXPECT_TRUE(result.needs_unref);
208 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
209
210 // We didn't clear the cache the second time, and should only expect to find
211 // these entries: 0.5 scale and 0.125 scale.
212 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
213
214 cache().UnrefImage(draw_image_50);
215 cache().UnrefImage(draw_image_125);
216 }
217
TEST_F(SoftwareImageDecodeCacheTest_Typical,UseClosestAvailableDecodeNotSmaller)218 TEST_F(SoftwareImageDecodeCacheTest_Typical,
219 UseClosestAvailableDecodeNotSmaller) {
220 auto draw_image_25 = CreateDrawImageForScale(0.25f);
221 auto result = GenerateCacheEntry(draw_image_25);
222 EXPECT_TRUE(result.has_task);
223 EXPECT_TRUE(result.needs_unref);
224
225 // Clear the cache to eliminate the transient 1.f scale from the cache.
226 cache().ClearCache();
227 VerifyEntryExists(__LINE__, draw_image_25, gfx::Size(128, 128));
228 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
229
230 auto draw_image_50 = CreateDrawImageForScale(0.5f);
231 result = GenerateCacheEntry(draw_image_50);
232 EXPECT_TRUE(result.has_task);
233 EXPECT_TRUE(result.needs_unref);
234 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
235
236 // We didn't clear the cache the second time, and should only expect to find
237 // these entries: 1.0 scale, 0.5 scale and 0.25 scale.
238 EXPECT_EQ(3u, cache().GetNumCacheEntriesForTesting());
239
240 cache().UnrefImage(draw_image_50);
241 cache().UnrefImage(draw_image_25);
242 }
243
TEST_F(SoftwareImageDecodeCacheTest_Typical,UseClosestAvailableDecodeFirstImageSubrected)244 TEST_F(SoftwareImageDecodeCacheTest_Typical,
245 UseClosestAvailableDecodeFirstImageSubrected) {
246 auto draw_image_50 = CreateDrawImageForScale(0.5f, SkIRect::MakeWH(500, 500));
247 auto result = GenerateCacheEntry(draw_image_50);
248 EXPECT_TRUE(result.has_task);
249 EXPECT_TRUE(result.needs_unref);
250
251 // Clear the cache to eliminate the transient 1.f scale from the cache.
252 cache().ClearCache();
253 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(250, 250));
254 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
255
256 auto draw_image_125 = CreateDrawImageForScale(0.125f);
257 result = GenerateCacheEntry(draw_image_125);
258 EXPECT_TRUE(result.has_task);
259 EXPECT_TRUE(result.needs_unref);
260 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
261
262 // We didn't clear the cache the second time, and should only expect to find
263 // these entries: 1.0 scale, 0.5 scale subrected and 0.125 scale.
264 EXPECT_EQ(3u, cache().GetNumCacheEntriesForTesting());
265
266 cache().UnrefImage(draw_image_50);
267 cache().UnrefImage(draw_image_125);
268 }
269
TEST_F(SoftwareImageDecodeCacheTest_Typical,UseClosestAvailableDecodeSecondImageSubrected)270 TEST_F(SoftwareImageDecodeCacheTest_Typical,
271 UseClosestAvailableDecodeSecondImageSubrected) {
272 auto draw_image_50 = CreateDrawImageForScale(0.5f);
273 auto result = GenerateCacheEntry(draw_image_50);
274 EXPECT_TRUE(result.has_task);
275 EXPECT_TRUE(result.needs_unref);
276
277 // Clear the cache to eliminate the transient 1.f scale from the cache.
278 cache().ClearCache();
279 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
280 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
281
282 auto draw_image_125 =
283 CreateDrawImageForScale(0.125f, SkIRect::MakeWH(400, 400));
284 result = GenerateCacheEntry(draw_image_125);
285 EXPECT_TRUE(result.has_task);
286 EXPECT_TRUE(result.needs_unref);
287 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(50, 50));
288
289 // We didn't clear the cache the second time, and should only expect to find
290 // these entries: 1.0 scale, 0.5 scale and 0.125 scale subrected.
291 EXPECT_EQ(3u, cache().GetNumCacheEntriesForTesting());
292
293 cache().UnrefImage(draw_image_50);
294 cache().UnrefImage(draw_image_125);
295 }
296
TEST_F(SoftwareImageDecodeCacheTest_Typical,UseClosestAvailableDecodeBothSubrected)297 TEST_F(SoftwareImageDecodeCacheTest_Typical,
298 UseClosestAvailableDecodeBothSubrected) {
299 auto draw_image_50 = CreateDrawImageForScale(0.5f, SkIRect::MakeWH(400, 400));
300 auto result = GenerateCacheEntry(draw_image_50);
301 EXPECT_TRUE(result.has_task);
302 EXPECT_TRUE(result.needs_unref);
303
304 // Clear the cache to eliminate the transient 1.f scale from the cache.
305 cache().ClearCache();
306 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(200, 200));
307 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
308
309 auto draw_image_125 =
310 CreateDrawImageForScale(0.125f, SkIRect::MakeWH(400, 400));
311 result = GenerateCacheEntry(draw_image_125);
312 EXPECT_TRUE(result.has_task);
313 EXPECT_TRUE(result.needs_unref);
314 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(50, 50));
315
316 // We didn't clear the cache the second time, and should only expect to find
317 // these entries: 0.5 scale subrected and 0.125 scale subrected.
318 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
319
320 cache().UnrefImage(draw_image_50);
321 cache().UnrefImage(draw_image_125);
322 }
323
TEST_F(SoftwareImageDecodeCacheTest_Typical,UseClosestAvailableDecodeBothPastPostScaleSize)324 TEST_F(SoftwareImageDecodeCacheTest_Typical,
325 UseClosestAvailableDecodeBothPastPostScaleSize) {
326 auto draw_image_50 =
327 CreateDrawImageForScale(0.5f, SkIRect::MakeXYWH(300, 300, 52, 52));
328 auto result = GenerateCacheEntry(draw_image_50);
329 EXPECT_TRUE(result.has_task);
330 EXPECT_TRUE(result.needs_unref);
331
332 // Clear the cache to eliminate the transient 1.f scale from the cache.
333 cache().ClearCache();
334 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(26, 26));
335 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
336
337 auto draw_image_25 =
338 CreateDrawImageForScale(0.25, SkIRect::MakeXYWH(300, 300, 52, 52));
339 result = GenerateCacheEntry(draw_image_25);
340 EXPECT_TRUE(result.has_task);
341 EXPECT_TRUE(result.needs_unref);
342 VerifyEntryExists(__LINE__, draw_image_25, gfx::Size(13, 13));
343
344 // We didn't clear the cache the second time, and should only expect to find
345 // these entries: 0.5 scale subrected and 0.25 scale subrected.
346 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
347
348 cache().UnrefImage(draw_image_50);
349 cache().UnrefImage(draw_image_25);
350 }
351
352 class SoftwareImageDecodeCacheTest_AtRaster : public N32Cache,
353 public AtRaster,
354 public NoDecodeToScaleSupport,
355 public DefaultColorSpace {};
356
TEST_F(SoftwareImageDecodeCacheTest_AtRaster,UseClosestAvailableDecode)357 TEST_F(SoftwareImageDecodeCacheTest_AtRaster, UseClosestAvailableDecode) {
358 auto draw_image_50 = CreateDrawImageForScale(0.5f);
359 auto decoded = cache().GetDecodedImageForDraw(draw_image_50);
360 {
361 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
362 cache().ClearCache();
363 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
364
365 auto draw_image_125 = CreateDrawImageForScale(0.125f);
366 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
367 }
368 cache().DrawWithImageFinished(draw_image_50, decoded);
369
370 // We should only expect to find these entries: 0.5 scale and 0.125 scale.
371 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
372 }
373
TEST_F(SoftwareImageDecodeCacheTest_AtRaster,UseClosestAvailableDecodeSubrected)374 TEST_F(SoftwareImageDecodeCacheTest_AtRaster,
375 UseClosestAvailableDecodeSubrected) {
376 auto draw_image_50 = CreateDrawImageForScale(0.5f, SkIRect::MakeWH(500, 500));
377 auto decoded = cache().GetDecodedImageForDraw(draw_image_50);
378 {
379 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(250, 250));
380 cache().ClearCache();
381 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
382
383 auto draw_image_125 = CreateDrawImageForScale(0.125f);
384 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
385 }
386 cache().DrawWithImageFinished(draw_image_50, decoded);
387
388 // We should only expect to find these entries: 1.0 scale, 0.5 scale subrected
389 // and 0.125 scale.
390 EXPECT_EQ(3u, cache().GetNumCacheEntriesForTesting());
391 }
392
393 class SoftwareImageDecodeCacheTest_ExoticColorSpace
394 : public N32Cache,
395 public Predecode,
396 public NoDecodeToScaleSupport,
397 public ExoticColorSpace {};
398
TEST_F(SoftwareImageDecodeCacheTest_ExoticColorSpace,UseClosestAvailableDecode)399 TEST_F(SoftwareImageDecodeCacheTest_ExoticColorSpace,
400 UseClosestAvailableDecode) {
401 auto draw_image_50 = CreateDrawImageForScale(0.5f);
402 auto result = GenerateCacheEntry(draw_image_50);
403
404 EXPECT_TRUE(result.has_task);
405 EXPECT_TRUE(result.needs_unref);
406
407 // Clear the cache to eliminate the transient 1.f scale from the cache.
408 cache().ClearCache();
409 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
410 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
411
412 auto draw_image_125 = CreateDrawImageForScale(0.125f);
413 result = GenerateCacheEntry(draw_image_125);
414 EXPECT_TRUE(result.has_task);
415 EXPECT_TRUE(result.needs_unref);
416 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
417
418 // We didn't clear the cache the second time, and should only expect to find
419 // these entries: 0.5 scale and 0.125 scale.
420 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
421
422 cache().UnrefImage(draw_image_50);
423 cache().UnrefImage(draw_image_125);
424 }
425
426 class SoftwareImageDecodeCacheTest_F16_ExoticColorSpace
427 : public RGBA_F16Cache,
428 public Predecode,
429 public NoDecodeToScaleSupportF16,
430 public ExoticColorSpace {};
431
TEST_F(SoftwareImageDecodeCacheTest_F16_ExoticColorSpace,UseClosestAvailableDecode_F16_ExoticColorSpace)432 TEST_F(SoftwareImageDecodeCacheTest_F16_ExoticColorSpace,
433 UseClosestAvailableDecode_F16_ExoticColorSpace) {
434 auto draw_image_50 = CreateDrawImageForScale(0.5f);
435 auto result = GenerateCacheEntry(draw_image_50);
436 EXPECT_TRUE(result.has_task);
437 EXPECT_TRUE(result.needs_unref);
438
439 // Clear the cache to eliminate the transient 1.f scale from the cache.
440 cache().ClearCache();
441 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
442 EXPECT_EQ(kRGBA_F16_SkColorType, draw_image_50.paint_image().GetColorType());
443 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
444
445 auto draw_image_125 = CreateDrawImageForScale(0.125f);
446 result = GenerateCacheEntry(draw_image_125);
447 EXPECT_TRUE(result.has_task);
448 EXPECT_TRUE(result.needs_unref);
449 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
450 EXPECT_EQ(kRGBA_F16_SkColorType, draw_image_125.paint_image().GetColorType());
451
452 // We didn't clear the cache the second time, and should only expect to find
453 // these entries: 0.5 scale and 0.125 scale.
454 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
455
456 cache().UnrefImage(draw_image_50);
457 cache().UnrefImage(draw_image_125);
458 }
459
460 class SoftwareImageDecodeCacheTest_F16_WideGamutCanvasColorSpace
461 : public RGBA_F16Cache,
462 public Predecode,
463 public NoDecodeToScaleSupportF16,
464 public WideGamutCanvasColorSpace {};
465
TEST_F(SoftwareImageDecodeCacheTest_F16_WideGamutCanvasColorSpace,UseClosestAvailableDecode_F16_WideGamutCanvasColorSpace)466 TEST_F(SoftwareImageDecodeCacheTest_F16_WideGamutCanvasColorSpace,
467 UseClosestAvailableDecode_F16_WideGamutCanvasColorSpace) {
468 auto draw_image_50 = CreateDrawImageForScale(0.5f);
469 auto result = GenerateCacheEntry(draw_image_50);
470 EXPECT_TRUE(result.has_task);
471 EXPECT_TRUE(result.needs_unref);
472
473 // Clear the cache to eliminate the transient 1.f scale from the cache.
474 cache().ClearCache();
475 VerifyEntryExists(__LINE__, draw_image_50, gfx::Size(256, 256));
476 EXPECT_EQ(kRGBA_F16_SkColorType, draw_image_50.paint_image().GetColorType());
477 EXPECT_EQ(1u, cache().GetNumCacheEntriesForTesting());
478
479 auto draw_image_125 = CreateDrawImageForScale(0.125f);
480 result = GenerateCacheEntry(draw_image_125);
481 EXPECT_TRUE(result.has_task);
482 EXPECT_TRUE(result.needs_unref);
483 VerifyEntryExists(__LINE__, draw_image_125, gfx::Size(64, 64));
484 EXPECT_EQ(kRGBA_F16_SkColorType, draw_image_125.paint_image().GetColorType());
485
486 // We didn't clear the cache the second time, and should only expect to find
487 // these entries: 0.5 scale and 0.125 scale.
488 EXPECT_EQ(2u, cache().GetNumCacheEntriesForTesting());
489
490 cache().UnrefImage(draw_image_50);
491 cache().UnrefImage(draw_image_125);
492 }
493
494 } // namespace
495 } // namespace cc
496