[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / tiles / software_image_decode_cache_unittest.cc
1 // Copyright 2015 The Chromium Authors
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 "cc/paint/draw_image.h"
8 #include "cc/paint/paint_image_builder.h"
9 #include "cc/test/fake_paint_image_generator.h"
10 #include "cc/test/skia_common.h"
11 #include "cc/test/test_tile_task_runner.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/skia/include/core/SkRefCnt.h"
14
15 namespace cc {
16 namespace {
17
18 TargetColorParams DefaultTargetColorParams() {
19   return TargetColorParams();
20 }
21
22 sk_sp<SkColorSpace> DefaultSkColorSpace() {
23   return DefaultTargetColorParams().color_space.ToSkColorSpace();
24 }
25
26 size_t kLockedMemoryLimitBytes = 128 * 1024 * 1024;
27 class TestSoftwareImageDecodeCache : public SoftwareImageDecodeCache {
28  public:
29   TestSoftwareImageDecodeCache()
30       : SoftwareImageDecodeCache(kN32_SkColorType, kLockedMemoryLimitBytes) {}
31 };
32
33 SkM44 CreateMatrix(const SkSize& scale, bool is_decomposable) {
34   SkM44 matrix = SkM44::Scale(scale.width(), scale.height());
35
36   if (!is_decomposable) {
37     // Perspective is not decomposable, add it.
38     matrix.setRC(3, 0, 0.1f);
39   }
40
41   return matrix;
42 }
43
44 PaintImage CreatePaintImage(int width, int height) {
45   return CreateDiscardablePaintImage(gfx::Size(width, height),
46                                      DefaultSkColorSpace());
47 }
48
49 PaintImage CreatePaintImage(int width,
50                             int height,
51                             const TargetColorParams& target_color_params) {
52   return CreateDiscardablePaintImage(
53       gfx::Size(width, height),
54       target_color_params.color_space.ToSkColorSpace());
55 }
56
57 TEST(SoftwareImageDecodeCacheTest, ImageKeyNoneQuality) {
58   PaintImage paint_image = CreatePaintImage(100, 100);
59   bool is_decomposable = true;
60   DrawImage draw_image(
61       paint_image, false,
62       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
63       PaintFlags::FilterQuality::kNone,
64       CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
65       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
66
67   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
68       draw_image, kN32_SkColorType);
69   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
70   EXPECT_TRUE(key.is_nearest_neighbor());
71   EXPECT_EQ(100, key.target_size().width());
72   EXPECT_EQ(100, key.target_size().height());
73   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
74   // Since the original decode will be used, the locked_bytes is that of the
75   // original image.
76   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
77 }
78
79 TEST(SoftwareImageDecodeCacheTest,
80      ImageKeyLowQualityIncreasedToMediumIfDownscale) {
81   PaintImage paint_image = CreatePaintImage(100, 100);
82   bool is_decomposable = true;
83   DrawImage draw_image(
84       paint_image, false,
85       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
86       PaintFlags::FilterQuality::kLow,
87       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
88       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
89
90   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
91       draw_image, kN32_SkColorType);
92   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
93   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
94   EXPECT_EQ(50, key.target_size().width());
95   EXPECT_EQ(50, key.target_size().height());
96   EXPECT_EQ(50u * 50u * 4u, key.locked_bytes());
97 }
98
99 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropsToLowIfMipLevel0) {
100   PaintImage paint_image = CreatePaintImage(100, 100);
101   bool is_decomposable = true;
102   DrawImage draw_image(
103       paint_image, false,
104       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
105       PaintFlags::FilterQuality::kMedium,
106       CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
107       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
108
109   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
110       draw_image, kN32_SkColorType);
111   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
112   EXPECT_FALSE(key.is_nearest_neighbor());
113   EXPECT_EQ(100, key.target_size().width());
114   EXPECT_EQ(100, key.target_size().height());
115   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
116   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
117 }
118
119 TEST(SoftwareImageDecodeCacheTest, LowUnscalableFormatStaysLow) {
120   PaintImage paint_image = CreatePaintImage(100, 100);
121   bool is_decomposable = true;
122   DrawImage draw_image(
123       paint_image, false,
124       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
125       PaintFlags::FilterQuality::kLow,
126       CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
127       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
128
129   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
130       draw_image, kARGB_4444_SkColorType);
131   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
132   EXPECT_FALSE(key.is_nearest_neighbor());
133   EXPECT_EQ(100, key.target_size().width());
134   EXPECT_EQ(100, key.target_size().height());
135   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
136   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
137 }
138
139 TEST(SoftwareImageDecodeCacheTest, HighUnscalableFormatBecomesLow) {
140   PaintImage paint_image = CreatePaintImage(100, 100);
141   bool is_decomposable = true;
142   DrawImage draw_image(
143       paint_image, false,
144       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
145       PaintFlags::FilterQuality::kHigh,
146       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
147       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
148
149   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
150       draw_image, kARGB_4444_SkColorType);
151   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
152   EXPECT_FALSE(key.is_nearest_neighbor());
153   EXPECT_EQ(100, key.target_size().width());
154   EXPECT_EQ(100, key.target_size().height());
155   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
156   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
157 }
158
159 TEST(SoftwareImageDecodeCacheTest, ImageKeyLowQualityKeptLowIfUpscale) {
160   PaintImage paint_image = CreatePaintImage(100, 100);
161   bool is_decomposable = true;
162   DrawImage draw_image(
163       paint_image, false,
164       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
165       PaintFlags::FilterQuality::kLow,
166       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
167       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
168
169   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
170       draw_image, kN32_SkColorType);
171   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
172   EXPECT_FALSE(key.is_nearest_neighbor());
173   EXPECT_EQ(100, key.target_size().width());
174   EXPECT_EQ(100, key.target_size().height());
175   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
176   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
177 }
178
179 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQuality) {
180   PaintImage paint_image = CreatePaintImage(100, 100);
181   bool is_decomposable = true;
182   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
183
184   DrawImage draw_image(
185       paint_image, false,
186       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
187       CreateMatrix(SkSize::Make(0.5f, 0.4f), is_decomposable),
188       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
189
190   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
191       draw_image, kN32_SkColorType);
192   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
193   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
194   EXPECT_EQ(50, key.target_size().width());
195   EXPECT_EQ(50, key.target_size().height());
196   EXPECT_EQ(50u * 50u * 4u, key.locked_bytes());
197 }
198
199 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropToLowIfEnlarging) {
200   PaintImage paint_image = CreatePaintImage(100, 100);
201   bool is_decomposable = true;
202   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
203
204   DrawImage draw_image(
205       paint_image, false,
206       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
207       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
208       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
209
210   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
211       draw_image, kN32_SkColorType);
212   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
213   EXPECT_FALSE(key.is_nearest_neighbor());
214   EXPECT_EQ(100, key.target_size().width());
215   EXPECT_EQ(100, key.target_size().height());
216   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
217   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
218 }
219
220 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityDropToLowIfIdentity) {
221   PaintImage paint_image = CreatePaintImage(100, 100);
222   bool is_decomposable = true;
223   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
224
225   DrawImage draw_image(
226       paint_image, false,
227       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
228       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
229       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
230
231   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
232       draw_image, kN32_SkColorType);
233   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
234   EXPECT_FALSE(key.is_nearest_neighbor());
235   EXPECT_EQ(100, key.target_size().width());
236   EXPECT_EQ(100, key.target_size().height());
237   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
238   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
239 }
240
241 TEST(SoftwareImageDecodeCacheTest,
242      ImageKeyMediumQualityDropToLowIfNearlyIdentity) {
243   PaintImage paint_image = CreatePaintImage(100, 100);
244   bool is_decomposable = true;
245   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
246
247   DrawImage draw_image(
248       paint_image, false,
249       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
250       CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
251       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
252
253   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
254       draw_image, kN32_SkColorType);
255   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
256   EXPECT_FALSE(key.is_nearest_neighbor());
257   EXPECT_EQ(100, key.target_size().width());
258   EXPECT_EQ(100, key.target_size().height());
259   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
260   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
261 }
262
263 TEST(SoftwareImageDecodeCacheTest,
264      ImageKeyMediumQualityDropToLowIfNearlyIdentity2) {
265   PaintImage paint_image = CreatePaintImage(100, 100);
266   bool is_decomposable = true;
267   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
268
269   DrawImage draw_image(
270       paint_image, false,
271       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
272       CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
273       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
274
275   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
276       draw_image, kN32_SkColorType);
277   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
278   EXPECT_FALSE(key.is_nearest_neighbor());
279   EXPECT_EQ(100, key.target_size().width());
280   EXPECT_EQ(100, key.target_size().height());
281   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
282   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
283 }
284
285 TEST(SoftwareImageDecodeCacheTest,
286      ImageKeyMediumQualityDropToLowIfNotDecomposable) {
287   PaintImage paint_image = CreatePaintImage(100, 100);
288   bool is_decomposable = false;
289   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
290
291   DrawImage draw_image(
292       paint_image, false,
293       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
294       CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
295       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
296
297   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
298       draw_image, kN32_SkColorType);
299   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
300
301   EXPECT_FALSE(key.is_nearest_neighbor());
302   EXPECT_EQ(100, key.target_size().width());
303   EXPECT_EQ(100, key.target_size().height());
304   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
305   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
306 }
307
308 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt1_5Scale) {
309   PaintImage paint_image = CreatePaintImage(500, 200);
310   bool is_decomposable = true;
311   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
312
313   DrawImage draw_image(
314       paint_image, false,
315       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
316       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
317       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
318
319   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
320       draw_image, kN32_SkColorType);
321   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
322   EXPECT_FALSE(key.is_nearest_neighbor());
323   EXPECT_EQ(500, key.target_size().width());
324   EXPECT_EQ(200, key.target_size().height());
325   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
326   EXPECT_EQ(500u * 200u * 4u, key.locked_bytes());
327 }
328
329 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt1_0cale) {
330   PaintImage paint_image = CreatePaintImage(500, 200);
331   bool is_decomposable = true;
332   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
333
334   DrawImage draw_image(
335       paint_image, false,
336       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
337       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
338       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
339
340   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
341       draw_image, kN32_SkColorType);
342   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
343   EXPECT_FALSE(key.is_nearest_neighbor());
344   EXPECT_EQ(500, key.target_size().width());
345   EXPECT_EQ(200, key.target_size().height());
346   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
347   EXPECT_EQ(500u * 200u * 4u, key.locked_bytes());
348 }
349
350 TEST(SoftwareImageDecodeCacheTest, ImageKeyLowQualityAt0_75Scale) {
351   PaintImage paint_image = CreatePaintImage(500, 200);
352   bool is_decomposable = true;
353   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
354
355   DrawImage draw_image(
356       paint_image, false,
357       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
358       CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
359       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
360
361   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
362       draw_image, kN32_SkColorType);
363   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
364   EXPECT_FALSE(key.is_nearest_neighbor());
365   EXPECT_EQ(500, key.target_size().width());
366   EXPECT_EQ(200, key.target_size().height());
367   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
368   EXPECT_EQ(500u * 200u * 4u, key.locked_bytes());
369 }
370
371 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_5Scale) {
372   PaintImage paint_image = CreatePaintImage(500, 200);
373   bool is_decomposable = true;
374   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
375
376   DrawImage draw_image(
377       paint_image, false,
378       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
379       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
380       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
381
382   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
383       draw_image, kN32_SkColorType);
384   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
385   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
386   EXPECT_EQ(250, key.target_size().width());
387   EXPECT_EQ(100, key.target_size().height());
388   EXPECT_EQ(250u * 100u * 4u, key.locked_bytes());
389 }
390
391 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_49Scale) {
392   PaintImage paint_image = CreatePaintImage(500, 200);
393   bool is_decomposable = true;
394   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
395
396   DrawImage draw_image(
397       paint_image, false,
398       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
399       CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
400       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
401
402   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
403       draw_image, kN32_SkColorType);
404   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
405   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
406   EXPECT_EQ(250, key.target_size().width());
407   EXPECT_EQ(100, key.target_size().height());
408   EXPECT_EQ(250u * 100u * 4u, key.locked_bytes());
409 }
410
411 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_1Scale) {
412   PaintImage paint_image = CreatePaintImage(500, 200);
413   bool is_decomposable = true;
414   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
415
416   DrawImage draw_image(
417       paint_image, false,
418       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
419       CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
420       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
421
422   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
423       draw_image, kN32_SkColorType);
424   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
425   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
426   EXPECT_EQ(63, key.target_size().width());
427   EXPECT_EQ(25, key.target_size().height());
428   EXPECT_EQ(63u * 25u * 4u, key.locked_bytes());
429 }
430
431 TEST(SoftwareImageDecodeCacheTest, ImageKeyMediumQualityAt0_01Scale) {
432   PaintImage paint_image = CreatePaintImage(500, 200);
433   bool is_decomposable = true;
434   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
435
436   DrawImage draw_image(
437       paint_image, false,
438       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
439       CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
440       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
441
442   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
443       draw_image, kN32_SkColorType);
444   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
445   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
446   EXPECT_EQ(8, key.target_size().width());
447   EXPECT_EQ(4, key.target_size().height());
448   EXPECT_EQ(8u * 4u * 4u, key.locked_bytes());
449 }
450
451 TEST(SoftwareImageDecodeCacheTest,
452      ImageKeyFullDowscalesDropsHighQualityToMedium) {
453   PaintImage paint_image = CreatePaintImage(100, 100);
454   bool is_decomposable = true;
455   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
456
457   DrawImage draw_image(
458       paint_image, false,
459       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
460       CreateMatrix(SkSize::Make(0.5f, 0.2f), is_decomposable),
461       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
462
463   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
464       draw_image, kN32_SkColorType);
465   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
466   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
467   EXPECT_EQ(50, key.target_size().width());
468   EXPECT_EQ(50, key.target_size().height());
469   EXPECT_EQ(50u * 50u * 4u, key.locked_bytes());
470 }
471
472 TEST(SoftwareImageDecodeCacheTest, ImageKeyUpscaleIsLowQuality) {
473   PaintImage paint_image = CreatePaintImage(100, 100);
474   bool is_decomposable = true;
475   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
476
477   DrawImage draw_image(
478       paint_image, false,
479       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
480       CreateMatrix(SkSize::Make(2.5f, 1.5f), is_decomposable),
481       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
482
483   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
484       draw_image, kN32_SkColorType);
485   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
486   EXPECT_FALSE(key.is_nearest_neighbor());
487   EXPECT_EQ(100, key.target_size().width());
488   EXPECT_EQ(100, key.target_size().height());
489   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
490   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
491 }
492
493 TEST(SoftwareImageDecodeCacheTest, ImageKeyHighQualityDropToMediumIfTooLarge) {
494   // Just over 64MB when scaled.
495   PaintImage paint_image = CreatePaintImage(4555, 2048);
496   bool is_decomposable = true;
497   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
498
499   // At least one dimension should scale down, so that medium quality doesn't
500   // become low.
501   DrawImage draw_image(
502       paint_image, false,
503       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
504       CreateMatrix(SkSize::Make(0.45f, 0.45f), is_decomposable),
505       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
506
507   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
508       draw_image, kN32_SkColorType);
509   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
510   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
511   EXPECT_EQ(2278, key.target_size().width());
512   EXPECT_EQ(1024, key.target_size().height());
513   EXPECT_EQ(2278u * 1024u * 4u, key.locked_bytes());
514 }
515
516 TEST(SoftwareImageDecodeCacheTest,
517      ImageKeyHighQualityDropToLowIfNotDecomposable) {
518   PaintImage paint_image = CreatePaintImage(100, 100);
519   bool is_decomposable = false;
520   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
521
522   DrawImage draw_image(
523       paint_image, false,
524       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
525       CreateMatrix(SkSize::Make(0.5f, 1.5f), is_decomposable),
526       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
527
528   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
529       draw_image, kN32_SkColorType);
530   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
531   EXPECT_FALSE(key.is_nearest_neighbor());
532   EXPECT_EQ(100, key.target_size().width());
533   EXPECT_EQ(100, key.target_size().height());
534   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
535   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
536 }
537
538 TEST(SoftwareImageDecodeCacheTest, ImageKeyHighQualityDropToLowIfIdentity) {
539   PaintImage paint_image = CreatePaintImage(100, 100);
540   bool is_decomposable = true;
541   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
542
543   DrawImage draw_image(
544       paint_image, false,
545       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
546       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
547       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
548
549   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
550       draw_image, kN32_SkColorType);
551   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
552   EXPECT_FALSE(key.is_nearest_neighbor());
553   EXPECT_EQ(100, key.target_size().width());
554   EXPECT_EQ(100, key.target_size().height());
555   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
556   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
557 }
558
559 TEST(SoftwareImageDecodeCacheTest,
560      ImageKeyHighQualityDropToLowIfNearlyIdentity) {
561   PaintImage paint_image = CreatePaintImage(100, 100);
562   bool is_decomposable = true;
563   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
564
565   DrawImage draw_image(
566       paint_image, false,
567       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
568       CreateMatrix(SkSize::Make(1.001f, 1.001f), is_decomposable),
569       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
570
571   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
572       draw_image, kN32_SkColorType);
573   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
574   EXPECT_FALSE(key.is_nearest_neighbor());
575   EXPECT_EQ(100, key.target_size().width());
576   EXPECT_EQ(100, key.target_size().height());
577   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
578   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
579 }
580
581 TEST(SoftwareImageDecodeCacheTest,
582      ImageKeyHighQualityDropToLowIfNearlyIdentity2) {
583   PaintImage paint_image = CreatePaintImage(100, 100);
584   bool is_decomposable = true;
585   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
586
587   DrawImage draw_image(
588       paint_image, false,
589       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
590       CreateMatrix(SkSize::Make(0.999f, 0.999f), is_decomposable),
591       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
592
593   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
594       draw_image, kN32_SkColorType);
595   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
596   EXPECT_FALSE(key.is_nearest_neighbor());
597   EXPECT_EQ(100, key.target_size().width());
598   EXPECT_EQ(100, key.target_size().height());
599   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
600   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
601 }
602
603 TEST(SoftwareImageDecodeCacheTest, ImageKeyDownscaleMipLevelWithRounding) {
604   // Tests that, when using a non-zero mip level, the final target size (which
605   // is the size of the chosen mip level) is as expected if rounding is
606   // required.
607   //
608   // The 97x61 dimensions and the (0.2f, 0.2f) scaling were chosen specifically
609   // so that:
610   //
611   // - The starting target size is 19x12 which means that 2 is the chosen mip
612   //   level.
613   //
614   // - Attempting to get the final target size by simply multiplying the
615   //   dimensions of the |src_rect| (97x61) times
616   //   MipMapUtil::GetScaleAdjustmentForLevel() yields 24x15 if we attempt to
617   //   store the result as integers. This is inconsistent with the rounding
618   //   behavior introduced in https://crrev.com/c/1107049 and was the cause of
619   //   https://crbug.com/891316.
620   PaintImage paint_image = CreatePaintImage(97, 61);
621   bool is_decomposable = true;
622   DrawImage draw_image(
623       paint_image, false,
624       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
625       PaintFlags::FilterQuality::kMedium,
626       CreateMatrix(SkSize::Make(0.2f, 0.2f), is_decomposable),
627       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
628
629   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
630       draw_image, kN32_SkColorType);
631   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
632   EXPECT_FALSE(key.is_nearest_neighbor());
633   EXPECT_EQ(25, key.target_size().width());
634   EXPECT_EQ(16, key.target_size().height());
635   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
636   EXPECT_EQ(25u * 16u * 4u, key.locked_bytes());
637 }
638
639 TEST(SoftwareImageDecodeCacheTest, OriginalDecodesAreEqual) {
640   PaintImage paint_image = CreatePaintImage(100, 100);
641   bool is_decomposable = true;
642   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kNone;
643
644   DrawImage draw_image(
645       paint_image, false,
646       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
647       CreateMatrix(SkSize::Make(0.5f, 0.5), is_decomposable),
648       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
649
650   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
651       draw_image, kN32_SkColorType);
652   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
653   EXPECT_TRUE(key.is_nearest_neighbor());
654   EXPECT_EQ(100, key.target_size().width());
655   EXPECT_EQ(100, key.target_size().height());
656   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
657   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
658
659   DrawImage another_draw_image(
660       paint_image, false,
661       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
662       CreateMatrix(SkSize::Make(1.5f, 1.5), is_decomposable),
663       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
664
665   auto another_key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
666       another_draw_image, kN32_SkColorType);
667   EXPECT_EQ(another_draw_image.frame_key(), another_key.frame_key());
668   EXPECT_TRUE(another_key.is_nearest_neighbor());
669   EXPECT_EQ(100, another_key.target_size().width());
670   EXPECT_EQ(100, another_key.target_size().height());
671   EXPECT_EQ(another_key.type(), SoftwareImageDecodeCache::CacheKey::kOriginal);
672   EXPECT_EQ(100u * 100u * 4u, another_key.locked_bytes());
673
674   EXPECT_TRUE(key == another_key);
675 }
676
677 TEST(SoftwareImageDecodeCacheTest, ImageRectDoesNotContainSrcRect) {
678   PaintImage paint_image = CreatePaintImage(100, 100);
679   bool is_decomposable = true;
680   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
681
682   DrawImage draw_image(
683       paint_image, false,
684       SkIRect::MakeXYWH(25, 35, paint_image.width(), paint_image.height()),
685       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
686       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
687
688   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
689       draw_image, kN32_SkColorType);
690   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
691   EXPECT_FALSE(key.is_nearest_neighbor());
692   EXPECT_EQ(100, key.target_size().width());
693   EXPECT_EQ(100, key.target_size().height());
694   EXPECT_EQ(gfx::Rect(25, 35, 75, 65), key.src_rect());
695   EXPECT_EQ(100u * 100u * 4u, key.locked_bytes());
696 }
697
698 TEST(SoftwareImageDecodeCacheTest, ImageRectDoesNotContainSrcRectWithScale) {
699   PaintImage paint_image = CreatePaintImage(100, 100);
700   bool is_decomposable = true;
701   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
702
703   DrawImage draw_image(
704       paint_image, false,
705       SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
706       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
707       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
708
709   auto key = SoftwareImageDecodeCache::CacheKey::FromDrawImage(
710       draw_image, kN32_SkColorType);
711   EXPECT_EQ(draw_image.frame_key(), key.frame_key());
712   EXPECT_EQ(key.type(), SoftwareImageDecodeCache::CacheKey::kSubrectAndScale);
713   EXPECT_EQ(40, key.target_size().width());
714   EXPECT_EQ(35, key.target_size().height());
715   EXPECT_EQ(gfx::Rect(20, 30, 80, 70), key.src_rect());
716   EXPECT_EQ(40u * 35u * 4u, key.locked_bytes());
717 }
718
719 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImage) {
720   TestSoftwareImageDecodeCache cache;
721   PaintImage paint_image = CreatePaintImage(100, 100);
722   bool is_decomposable = true;
723   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
724
725   DrawImage draw_image(
726       paint_image, false,
727       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
728       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
729       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
730   ImageDecodeCache::TaskResult result =
731       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
732   EXPECT_TRUE(result.need_unref);
733   EXPECT_TRUE(result.task);
734
735   DrawImage another_draw_image(
736       paint_image, false,
737       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
738       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
739       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
740   ImageDecodeCache::TaskResult another_result = cache.GetTaskForImageAndRef(
741       another_draw_image, ImageDecodeCache::TracingInfo());
742   EXPECT_TRUE(another_result.need_unref);
743   EXPECT_TRUE(result.task.get() == another_result.task.get());
744
745   TestTileTaskRunner::ProcessTask(result.task.get());
746
747   cache.UnrefImage(draw_image);
748   cache.UnrefImage(draw_image);
749 }
750
751 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageProcessUnrefCancel) {
752   TestSoftwareImageDecodeCache cache;
753   PaintImage paint_image = CreatePaintImage(100, 100);
754   bool is_decomposable = true;
755   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
756
757   DrawImage draw_image(
758       paint_image, false,
759       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
760       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
761       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
762   ImageDecodeCache::TaskResult result =
763       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
764   EXPECT_TRUE(result.need_unref);
765   EXPECT_TRUE(result.task);
766
767   TestTileTaskRunner::ProcessTask(result.task.get());
768   cache.UnrefImage(draw_image);
769
770   result =
771       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
772   EXPECT_TRUE(result.need_unref);
773   EXPECT_TRUE(result.task);
774
775   TestTileTaskRunner::CancelTask(result.task.get());
776   TestTileTaskRunner::CompleteTask(result.task.get());
777   // This is expected to pass instead of DCHECKing since we're reducing the ref
778   // for an image which isn't locked to begin with.
779   cache.UnrefImage(draw_image);
780 }
781
782 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentQuality) {
783   TestSoftwareImageDecodeCache cache;
784   PaintImage paint_image = CreatePaintImage(100, 100);
785   bool is_decomposable = true;
786
787   DrawImage high_quality_draw_image(
788       paint_image, false,
789       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
790       PaintFlags::FilterQuality::kHigh,
791       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
792       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
793   ImageDecodeCache::TaskResult high_quality_result =
794       cache.GetTaskForImageAndRef(high_quality_draw_image,
795                                   ImageDecodeCache::TracingInfo());
796   EXPECT_TRUE(high_quality_result.need_unref);
797   EXPECT_TRUE(high_quality_result.task);
798
799   DrawImage none_quality_draw_image(
800       paint_image, false,
801       SkIRect::MakeWH(paint_image.width(), paint_image.height()),
802       PaintFlags::FilterQuality::kNone,
803       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
804       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
805   ImageDecodeCache::TaskResult none_quality_result =
806       cache.GetTaskForImageAndRef(none_quality_draw_image,
807                                   ImageDecodeCache::TracingInfo());
808   EXPECT_TRUE(none_quality_result.need_unref);
809   EXPECT_TRUE(none_quality_result.task);
810   EXPECT_TRUE(high_quality_result.task.get() != none_quality_result.task.get());
811
812   TestTileTaskRunner::ProcessTask(high_quality_result.task.get());
813   TestTileTaskRunner::ProcessTask(none_quality_result.task.get());
814
815   cache.UnrefImage(high_quality_draw_image);
816   cache.UnrefImage(none_quality_draw_image);
817 }
818
819 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageSameImageDifferentSize) {
820   TestSoftwareImageDecodeCache cache;
821   PaintImage paint_image = CreatePaintImage(100, 100);
822   bool is_decomposable = true;
823   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
824
825   DrawImage half_size_draw_image(
826       paint_image, false,
827       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
828       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
829       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
830   ImageDecodeCache::TaskResult half_size_result = cache.GetTaskForImageAndRef(
831       half_size_draw_image, ImageDecodeCache::TracingInfo());
832   EXPECT_TRUE(half_size_result.need_unref);
833   EXPECT_TRUE(half_size_result.task);
834
835   DrawImage quarter_size_draw_image(
836       paint_image, false,
837       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
838       CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
839       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
840   ImageDecodeCache::TaskResult quarter_size_result =
841       cache.GetTaskForImageAndRef(quarter_size_draw_image,
842                                   ImageDecodeCache::TracingInfo());
843   EXPECT_TRUE(quarter_size_result.need_unref);
844   EXPECT_TRUE(quarter_size_result.task);
845   EXPECT_TRUE(half_size_result.task.get() != quarter_size_result.task.get());
846
847   TestTileTaskRunner::ProcessTask(half_size_result.task.get());
848   TestTileTaskRunner::ProcessTask(quarter_size_result.task.get());
849
850   cache.UnrefImage(half_size_draw_image);
851   cache.UnrefImage(quarter_size_draw_image);
852 }
853
854 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageDifferentImage) {
855   TestSoftwareImageDecodeCache cache;
856   bool is_decomposable = true;
857   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
858
859   PaintImage first_paint_image = CreatePaintImage(100, 100);
860   DrawImage first_draw_image(
861       first_paint_image, false,
862       SkIRect::MakeWH(first_paint_image.width(), first_paint_image.height()),
863       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
864       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
865   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
866       first_draw_image, ImageDecodeCache::TracingInfo());
867   EXPECT_TRUE(first_result.need_unref);
868   EXPECT_TRUE(first_result.task);
869
870   PaintImage second_paint_image = CreatePaintImage(100, 100);
871   DrawImage second_draw_image(
872       second_paint_image, false,
873       SkIRect::MakeWH(second_paint_image.width(), second_paint_image.height()),
874       quality, CreateMatrix(SkSize::Make(0.25f, 0.25f), is_decomposable),
875       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
876   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
877       second_draw_image, ImageDecodeCache::TracingInfo());
878   EXPECT_TRUE(second_result.need_unref);
879   EXPECT_TRUE(second_result.task);
880   EXPECT_TRUE(first_result.task.get() != second_result.task.get());
881
882   TestTileTaskRunner::ProcessTask(first_result.task.get());
883   TestTileTaskRunner::ProcessTask(second_result.task.get());
884
885   cache.UnrefImage(first_draw_image);
886   cache.UnrefImage(second_draw_image);
887 }
888
889 // crbug.com/709341
890 #if defined(MEMORY_SANITIZER)
891 #define MAYBE_GetTaskForImageDifferentColorSpace \
892   DISABLED_GetTaskForImageDifferentColorSpace
893 #else
894 #define MAYBE_GetTaskForImageDifferentColorSpace \
895   GetTaskForImageDifferentColorSpace
896 #endif
897 TEST(SoftwareImageDecodeCacheTest, MAYBE_GetTaskForImageDifferentColorSpace) {
898   TestSoftwareImageDecodeCache cache;
899   bool is_decomposable = true;
900   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
901
902   TargetColorParams target_color_params_a(gfx::ColorSpace(
903       gfx::ColorSpace::PrimaryID::XYZ_D50, gfx::ColorSpace::TransferID::SRGB));
904
905   TargetColorParams target_color_params_b(
906       gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M,
907                       gfx::ColorSpace::TransferID::SRGB));
908
909   TargetColorParams target_color_params_c(gfx::ColorSpace::CreateSRGB());
910
911   PaintImage paint_image = CreatePaintImage(100, 100, target_color_params_a);
912   DrawImage first_draw_image(
913       paint_image, false,
914       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
915       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
916       PaintImage::kDefaultFrameIndex, target_color_params_b);
917   ImageDecodeCache::TaskResult first_result = cache.GetTaskForImageAndRef(
918       first_draw_image, ImageDecodeCache::TracingInfo());
919   EXPECT_TRUE(first_result.need_unref);
920   EXPECT_TRUE(first_result.task);
921
922   DrawImage second_draw_image(
923       paint_image, false,
924       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
925       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
926       PaintImage::kDefaultFrameIndex, target_color_params_c);
927   ImageDecodeCache::TaskResult second_result = cache.GetTaskForImageAndRef(
928       second_draw_image, ImageDecodeCache::TracingInfo());
929   EXPECT_TRUE(second_result.need_unref);
930   EXPECT_TRUE(second_result.task);
931   EXPECT_TRUE(first_result.task.get() != second_result.task.get());
932
933   DrawImage third_draw_image(
934       paint_image, false,
935       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
936       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
937       PaintImage::kDefaultFrameIndex, target_color_params_b);
938   ImageDecodeCache::TaskResult third_result = cache.GetTaskForImageAndRef(
939       third_draw_image, ImageDecodeCache::TracingInfo());
940   EXPECT_TRUE(third_result.need_unref);
941   EXPECT_TRUE(third_result.task);
942   EXPECT_TRUE(first_result.task.get() == third_result.task.get());
943
944   TestTileTaskRunner::ProcessTask(first_result.task.get());
945   TestTileTaskRunner::ProcessTask(second_result.task.get());
946
947   cache.UnrefImage(first_draw_image);
948   cache.UnrefImage(second_draw_image);
949   cache.UnrefImage(third_draw_image);
950 }
951
952 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyDecoded) {
953   TestSoftwareImageDecodeCache cache;
954   bool is_decomposable = true;
955   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
956
957   PaintImage paint_image = CreatePaintImage(100, 100);
958   DrawImage draw_image(
959       paint_image, false,
960       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
961       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
962       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
963   ImageDecodeCache::TaskResult result =
964       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
965   EXPECT_TRUE(result.need_unref);
966   EXPECT_TRUE(result.task);
967
968   TestTileTaskRunner::ScheduleTask(result.task.get());
969   TestTileTaskRunner::RunTask(result.task.get());
970
971   ImageDecodeCache::TaskResult another_result =
972       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
973   EXPECT_TRUE(another_result.need_unref);
974   EXPECT_FALSE(another_result.task);
975
976   TestTileTaskRunner::CompleteTask(result.task.get());
977
978   cache.UnrefImage(draw_image);
979   cache.UnrefImage(draw_image);
980 }
981
982 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageAlreadyPrerolled) {
983   TestSoftwareImageDecodeCache cache;
984   bool is_decomposable = true;
985   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kLow;
986
987   PaintImage paint_image = CreatePaintImage(100, 100);
988   DrawImage draw_image(
989       paint_image, false,
990       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
991       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
992       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
993   ImageDecodeCache::TaskResult result =
994       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
995   EXPECT_TRUE(result.need_unref);
996   EXPECT_TRUE(result.task);
997
998   TestTileTaskRunner::ScheduleTask(result.task.get());
999   TestTileTaskRunner::RunTask(result.task.get());
1000
1001   ImageDecodeCache::TaskResult another_result =
1002       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1003   EXPECT_TRUE(another_result.need_unref);
1004   EXPECT_FALSE(another_result.task);
1005
1006   TestTileTaskRunner::CompleteTask(result.task.get());
1007
1008   ImageDecodeCache::TaskResult third_result =
1009       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1010   EXPECT_TRUE(third_result.need_unref);
1011   EXPECT_FALSE(third_result.task);
1012
1013   cache.UnrefImage(draw_image);
1014   cache.UnrefImage(draw_image);
1015   cache.UnrefImage(draw_image);
1016 }
1017
1018 TEST(SoftwareImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {
1019   TestSoftwareImageDecodeCache cache;
1020   bool is_decomposable = true;
1021   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1022
1023   PaintImage paint_image = CreatePaintImage(100, 100);
1024   DrawImage draw_image(
1025       paint_image, false,
1026       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1027       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1028       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1029   ImageDecodeCache::TaskResult result =
1030       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1031   EXPECT_TRUE(result.need_unref);
1032   EXPECT_TRUE(result.task);
1033
1034   ImageDecodeCache::TaskResult another_result =
1035       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1036   EXPECT_TRUE(another_result.need_unref);
1037   EXPECT_TRUE(another_result.task.get() == result.task.get());
1038
1039   // Didn't run the task, complete it (it was canceled).
1040   TestTileTaskRunner::CancelTask(result.task.get());
1041   TestTileTaskRunner::CompleteTask(result.task.get());
1042
1043   // Fully cancel everything (so the raster would unref things).
1044   cache.UnrefImage(draw_image);
1045   cache.UnrefImage(draw_image);
1046
1047   // Here a new task is created.
1048   ImageDecodeCache::TaskResult third_result =
1049       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1050   EXPECT_TRUE(third_result.need_unref);
1051   EXPECT_TRUE(third_result.task);
1052   EXPECT_FALSE(third_result.task.get() == result.task.get());
1053
1054   TestTileTaskRunner::ProcessTask(third_result.task.get());
1055
1056   cache.UnrefImage(draw_image);
1057 }
1058
1059 TEST(SoftwareImageDecodeCacheTest,
1060      GetTaskForImageCanceledWhileReffedGetsNewTask) {
1061   TestSoftwareImageDecodeCache cache;
1062   bool is_decomposable = true;
1063   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1064
1065   PaintImage paint_image = CreatePaintImage(100, 100);
1066   DrawImage draw_image(
1067       paint_image, false,
1068       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1069       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1070       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1071   ImageDecodeCache::TaskResult result =
1072       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1073   EXPECT_TRUE(result.need_unref);
1074   EXPECT_TRUE(result.task);
1075
1076   ImageDecodeCache::TaskResult another_result =
1077       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1078   EXPECT_TRUE(another_result.need_unref);
1079   EXPECT_TRUE(another_result.task.get() == result.task.get());
1080
1081   // Didn't run the task, complete it (it was canceled).
1082   TestTileTaskRunner::CancelTask(result.task.get());
1083   TestTileTaskRunner::CompleteTask(result.task.get());
1084
1085   // Note that here, everything is reffed, but a new task is created. This is
1086   // possible with repeated schedule/cancel operations.
1087   ImageDecodeCache::TaskResult third_result =
1088       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1089   EXPECT_TRUE(third_result.need_unref);
1090   EXPECT_TRUE(third_result.task);
1091   EXPECT_FALSE(third_result.task.get() == result.task.get());
1092
1093   TestTileTaskRunner::ProcessTask(third_result.task.get());
1094
1095   // 3 Unrefs!!!
1096   cache.UnrefImage(draw_image);
1097   cache.UnrefImage(draw_image);
1098   cache.UnrefImage(draw_image);
1099 }
1100
1101 TEST(SoftwareImageDecodeCacheTest, GetDecodedImageForDraw) {
1102   TestSoftwareImageDecodeCache cache;
1103   bool is_decomposable = true;
1104   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1105
1106   PaintImage paint_image = CreatePaintImage(100, 100);
1107   DrawImage draw_image(
1108       paint_image, false,
1109       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1110       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1111       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1112   ImageDecodeCache::TaskResult result =
1113       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1114   EXPECT_TRUE(result.need_unref);
1115   EXPECT_TRUE(result.task);
1116
1117   TestTileTaskRunner::ProcessTask(result.task.get());
1118
1119   DecodedDrawImage decoded_draw_image =
1120       cache.GetDecodedImageForDraw(draw_image);
1121   EXPECT_TRUE(decoded_draw_image.image());
1122   EXPECT_EQ(50, decoded_draw_image.image()->width());
1123   EXPECT_EQ(50, decoded_draw_image.image()->height());
1124   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
1125   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
1126   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1127             decoded_draw_image.filter_quality());
1128   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
1129
1130   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1131   cache.UnrefImage(draw_image);
1132 }
1133
1134 TEST(SoftwareImageDecodeCacheTest,
1135      GetDecodedImageForDrawWithNonContainedSrcRect) {
1136   TestSoftwareImageDecodeCache cache;
1137   bool is_decomposable = true;
1138   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1139
1140   PaintImage paint_image = CreatePaintImage(100, 100);
1141   DrawImage draw_image(
1142       paint_image, false,
1143       SkIRect::MakeXYWH(20, 30, paint_image.width(), paint_image.height()),
1144       quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1145       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1146   ImageDecodeCache::TaskResult result =
1147       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1148   EXPECT_TRUE(result.need_unref);
1149   EXPECT_TRUE(result.task);
1150
1151   TestTileTaskRunner::ProcessTask(result.task.get());
1152
1153   DecodedDrawImage decoded_draw_image =
1154       cache.GetDecodedImageForDraw(draw_image);
1155   EXPECT_TRUE(decoded_draw_image.image());
1156   EXPECT_EQ(40, decoded_draw_image.image()->width());
1157   EXPECT_EQ(35, decoded_draw_image.image()->height());
1158   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
1159   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
1160   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1161             decoded_draw_image.filter_quality());
1162   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
1163
1164   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1165   cache.UnrefImage(draw_image);
1166 }
1167
1168 TEST(SoftwareImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {
1169   TestSoftwareImageDecodeCache cache;
1170   bool is_decomposable = true;
1171   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1172
1173   PaintImage paint_image = CreatePaintImage(100, 100);
1174   DrawImage draw_image(
1175       paint_image, false,
1176       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1177       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1178       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1179
1180   DecodedDrawImage decoded_draw_image =
1181       cache.GetDecodedImageForDraw(draw_image);
1182   EXPECT_TRUE(decoded_draw_image.image());
1183   EXPECT_EQ(50, decoded_draw_image.image()->width());
1184   EXPECT_EQ(50, decoded_draw_image.image()->height());
1185   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
1186   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
1187   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1188             decoded_draw_image.filter_quality());
1189   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
1190
1191   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1192 }
1193
1194 TEST(SoftwareImageDecodeCacheTest,
1195      GetDecodedImageForDrawAtRasterDecodeMultipleTimes) {
1196   TestSoftwareImageDecodeCache cache;
1197   bool is_decomposable = true;
1198   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1199
1200   PaintImage paint_image = CreatePaintImage(100, 100);
1201   DrawImage draw_image(
1202       paint_image, false,
1203       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1204       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1205       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1206
1207   DecodedDrawImage decoded_draw_image =
1208       cache.GetDecodedImageForDraw(draw_image);
1209   ASSERT_TRUE(decoded_draw_image.image());
1210   EXPECT_EQ(50, decoded_draw_image.image()->width());
1211   EXPECT_EQ(50, decoded_draw_image.image()->height());
1212   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
1213   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
1214   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1215             decoded_draw_image.filter_quality());
1216   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
1217
1218   DecodedDrawImage another_decoded_draw_image =
1219       cache.GetDecodedImageForDraw(draw_image);
1220   EXPECT_EQ(decoded_draw_image.image()->uniqueID(),
1221             another_decoded_draw_image.image()->uniqueID());
1222
1223   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1224   cache.DrawWithImageFinished(draw_image, another_decoded_draw_image);
1225 }
1226
1227 TEST(SoftwareImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {
1228   TestSoftwareImageDecodeCache cache;
1229   bool is_decomposable = true;
1230   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1231
1232   PaintImage paint_image = CreatePaintImage(100, 100);
1233   DrawImage draw_image(
1234       paint_image, false,
1235       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1236       CreateMatrix(SkSize::Make(0.f, 0.f), is_decomposable),
1237       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1238
1239   ImageDecodeCache::TaskResult result =
1240       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1241   EXPECT_FALSE(result.task);
1242   EXPECT_FALSE(result.need_unref);
1243
1244   DecodedDrawImage decoded_draw_image =
1245       cache.GetDecodedImageForDraw(draw_image);
1246   EXPECT_FALSE(decoded_draw_image.image());
1247
1248   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1249 }
1250
1251 TEST(SoftwareImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {
1252   TestSoftwareImageDecodeCache cache;
1253   bool is_decomposable = true;
1254   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1255
1256   PaintImage paint_image = CreatePaintImage(100, 100);
1257   DrawImage draw_image(
1258       paint_image, false,
1259       SkIRect::MakeXYWH(150, 150, paint_image.width(), paint_image.height()),
1260       quality, CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1261       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1262
1263   ImageDecodeCache::TaskResult result =
1264       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1265   EXPECT_FALSE(result.task);
1266   EXPECT_FALSE(result.need_unref);
1267
1268   DecodedDrawImage decoded_draw_image =
1269       cache.GetDecodedImageForDraw(draw_image);
1270   EXPECT_FALSE(decoded_draw_image.image());
1271
1272   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1273 }
1274
1275 TEST(SoftwareImageDecodeCacheTest, LowQualityFilterIsHandled) {
1276   TestSoftwareImageDecodeCache cache;
1277   bool is_decomposable = true;
1278   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kLow;
1279
1280   PaintImage paint_image = CreatePaintImage(100, 100);
1281   DrawImage draw_image(
1282       paint_image, false,
1283       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1284       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1285       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1286
1287   ImageDecodeCache::TaskResult result =
1288       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1289   EXPECT_TRUE(result.task);
1290   EXPECT_TRUE(result.need_unref);
1291
1292   TestTileTaskRunner::ProcessTask(result.task.get());
1293
1294   DecodedDrawImage decoded_draw_image =
1295       cache.GetDecodedImageForDraw(draw_image);
1296   EXPECT_TRUE(decoded_draw_image.image());
1297   // If we decoded the image and cached it, it would be stored in a different
1298   // SkImage object.
1299   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1300
1301   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1302   cache.UnrefImage(draw_image);
1303 }
1304
1305 TEST(SoftwareImageDecodeCacheTest, LowQualityScaledSubrectIsHandled) {
1306   TestSoftwareImageDecodeCache cache;
1307   bool is_decomposable = true;
1308   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kLow;
1309
1310   PaintImage paint_image = CreatePaintImage(100, 100);
1311   DrawImage draw_image(
1312       paint_image, false, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
1313       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1314       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1315
1316   ImageDecodeCache::TaskResult result =
1317       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1318   EXPECT_TRUE(result.task);
1319   EXPECT_TRUE(result.need_unref);
1320
1321   TestTileTaskRunner::ProcessTask(result.task.get());
1322
1323   DecodedDrawImage decoded_draw_image =
1324       cache.GetDecodedImageForDraw(draw_image);
1325   EXPECT_TRUE(decoded_draw_image.image());
1326   // If we decoded the image and cached it, it would be stored in a different
1327   // SkImage object.
1328   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1329   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1330             decoded_draw_image.filter_quality());
1331   // Low quality will be upgraded to medium and mip-mapped.
1332   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
1333   EXPECT_EQ(0.5f, decoded_draw_image.scale_adjustment().width());
1334   EXPECT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
1335
1336   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1337   cache.UnrefImage(draw_image);
1338 }
1339
1340 TEST(SoftwareImageDecodeCacheTest, NoneQualityScaledSubrectIsHandled) {
1341   TestSoftwareImageDecodeCache cache;
1342   bool is_decomposable = true;
1343   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kNone;
1344
1345   PaintImage paint_image = CreatePaintImage(100, 100);
1346   DrawImage draw_image(
1347       paint_image, false, SkIRect::MakeXYWH(10, 10, 80, 80), quality,
1348       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1349       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1350
1351   ImageDecodeCache::TaskResult result =
1352       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1353   EXPECT_TRUE(result.task);
1354   EXPECT_TRUE(result.need_unref);
1355
1356   TestTileTaskRunner::ProcessTask(result.task.get());
1357
1358   DecodedDrawImage decoded_draw_image =
1359       cache.GetDecodedImageForDraw(draw_image);
1360   EXPECT_TRUE(decoded_draw_image.image());
1361   // If we decoded the image and cached it, it would be stored in a different
1362   // SkImage object.
1363   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1364   EXPECT_EQ(PaintFlags::FilterQuality::kNone,
1365             decoded_draw_image.filter_quality());
1366   EXPECT_TRUE(decoded_draw_image.is_scale_adjustment_identity());
1367
1368   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1369   cache.UnrefImage(draw_image);
1370 }
1371
1372 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt01_5ScaleIsHandled) {
1373   TestSoftwareImageDecodeCache cache;
1374   bool is_decomposable = true;
1375   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1376
1377   PaintImage paint_image = CreatePaintImage(500, 200);
1378   DrawImage draw_image(
1379       paint_image, false,
1380       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1381       CreateMatrix(SkSize::Make(1.5f, 1.5f), is_decomposable),
1382       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1383
1384   ImageDecodeCache::TaskResult result =
1385       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1386   EXPECT_TRUE(result.task);
1387   EXPECT_TRUE(result.need_unref);
1388
1389   TestTileTaskRunner::ProcessTask(result.task.get());
1390
1391   DecodedDrawImage decoded_draw_image =
1392       cache.GetDecodedImageForDraw(draw_image);
1393   EXPECT_TRUE(decoded_draw_image.image());
1394   // Decoded image should not be lazy generated.
1395   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1396   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1397             decoded_draw_image.filter_quality());
1398   EXPECT_EQ(500, decoded_draw_image.image()->width());
1399   EXPECT_EQ(200, decoded_draw_image.image()->height());
1400
1401   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1402   cache.UnrefImage(draw_image);
1403 }
1404
1405 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt1_0ScaleIsHandled) {
1406   TestSoftwareImageDecodeCache cache;
1407   bool is_decomposable = true;
1408   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1409
1410   PaintImage paint_image = CreatePaintImage(500, 200);
1411   DrawImage draw_image(
1412       paint_image, false,
1413       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1414       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1415       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1416
1417   ImageDecodeCache::TaskResult result =
1418       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1419   EXPECT_TRUE(result.task);
1420   EXPECT_TRUE(result.need_unref);
1421
1422   TestTileTaskRunner::ProcessTask(result.task.get());
1423
1424   DecodedDrawImage decoded_draw_image =
1425       cache.GetDecodedImageForDraw(draw_image);
1426   EXPECT_TRUE(decoded_draw_image.image());
1427   // Decoded image should not be lazy generated.
1428   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1429   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1430             decoded_draw_image.filter_quality());
1431   EXPECT_EQ(500, decoded_draw_image.image()->width());
1432   EXPECT_EQ(200, decoded_draw_image.image()->height());
1433
1434   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1435   cache.UnrefImage(draw_image);
1436 }
1437
1438 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_75ScaleIsHandled) {
1439   TestSoftwareImageDecodeCache cache;
1440   bool is_decomposable = true;
1441   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1442
1443   PaintImage paint_image = CreatePaintImage(500, 200);
1444   DrawImage draw_image(
1445       paint_image, false,
1446       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1447       CreateMatrix(SkSize::Make(0.75f, 0.75f), is_decomposable),
1448       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1449
1450   ImageDecodeCache::TaskResult result =
1451       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1452   EXPECT_TRUE(result.task);
1453   EXPECT_TRUE(result.need_unref);
1454
1455   TestTileTaskRunner::ProcessTask(result.task.get());
1456
1457   DecodedDrawImage decoded_draw_image =
1458       cache.GetDecodedImageForDraw(draw_image);
1459   EXPECT_TRUE(decoded_draw_image.image());
1460   // Decoded image should not be lazy generated.
1461   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1462   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1463             decoded_draw_image.filter_quality());
1464   EXPECT_EQ(500, decoded_draw_image.image()->width());
1465   EXPECT_EQ(200, decoded_draw_image.image()->height());
1466
1467   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1468   cache.UnrefImage(draw_image);
1469 }
1470
1471 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_5ScaleIsHandled) {
1472   TestSoftwareImageDecodeCache cache;
1473   bool is_decomposable = true;
1474   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1475
1476   PaintImage paint_image = CreatePaintImage(500, 200);
1477   DrawImage draw_image(
1478       paint_image, false,
1479       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1480       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1481       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1482
1483   ImageDecodeCache::TaskResult result =
1484       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1485   EXPECT_TRUE(result.task);
1486   EXPECT_TRUE(result.need_unref);
1487
1488   TestTileTaskRunner::ProcessTask(result.task.get());
1489
1490   DecodedDrawImage decoded_draw_image =
1491       cache.GetDecodedImageForDraw(draw_image);
1492   EXPECT_TRUE(decoded_draw_image.image());
1493   // Decoded image should not be lazy generated.
1494   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1495   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1496             decoded_draw_image.filter_quality());
1497   EXPECT_EQ(250, decoded_draw_image.image()->width());
1498   EXPECT_EQ(100, decoded_draw_image.image()->height());
1499
1500   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1501   cache.UnrefImage(draw_image);
1502 }
1503
1504 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_49ScaleIsHandled) {
1505   TestSoftwareImageDecodeCache cache;
1506   bool is_decomposable = true;
1507   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1508
1509   PaintImage paint_image = CreatePaintImage(500, 200);
1510   DrawImage draw_image(
1511       paint_image, false,
1512       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1513       CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
1514       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1515
1516   ImageDecodeCache::TaskResult result =
1517       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1518   EXPECT_TRUE(result.task);
1519   EXPECT_TRUE(result.need_unref);
1520
1521   TestTileTaskRunner::ProcessTask(result.task.get());
1522
1523   DecodedDrawImage decoded_draw_image =
1524       cache.GetDecodedImageForDraw(draw_image);
1525   EXPECT_TRUE(decoded_draw_image.image());
1526   // Decoded image should not be lazy generated.
1527   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1528   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1529             decoded_draw_image.filter_quality());
1530   EXPECT_EQ(250, decoded_draw_image.image()->width());
1531   EXPECT_EQ(100, decoded_draw_image.image()->height());
1532
1533   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1534   cache.UnrefImage(draw_image);
1535 }
1536
1537 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_1ScaleIsHandled) {
1538   TestSoftwareImageDecodeCache cache;
1539   bool is_decomposable = true;
1540   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1541
1542   PaintImage paint_image = CreatePaintImage(500, 200);
1543   DrawImage draw_image(
1544       paint_image, false,
1545       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1546       CreateMatrix(SkSize::Make(0.1f, 0.1f), is_decomposable),
1547       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1548
1549   ImageDecodeCache::TaskResult result =
1550       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1551   EXPECT_TRUE(result.task);
1552   EXPECT_TRUE(result.need_unref);
1553
1554   TestTileTaskRunner::ProcessTask(result.task.get());
1555
1556   DecodedDrawImage decoded_draw_image =
1557       cache.GetDecodedImageForDraw(draw_image);
1558   EXPECT_TRUE(decoded_draw_image.image());
1559   // Decoded image should not be lazy generated.
1560   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1561   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1562             decoded_draw_image.filter_quality());
1563   EXPECT_EQ(63, decoded_draw_image.image()->width());
1564   EXPECT_EQ(25, decoded_draw_image.image()->height());
1565
1566   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1567   cache.UnrefImage(draw_image);
1568 }
1569
1570 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_01ScaleIsHandled) {
1571   TestSoftwareImageDecodeCache cache;
1572   bool is_decomposable = true;
1573   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1574
1575   PaintImage paint_image = CreatePaintImage(500, 200);
1576   DrawImage draw_image(
1577       paint_image, false,
1578       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1579       CreateMatrix(SkSize::Make(0.01f, 0.01f), is_decomposable),
1580       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1581
1582   ImageDecodeCache::TaskResult result =
1583       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1584   EXPECT_TRUE(result.task);
1585   EXPECT_TRUE(result.need_unref);
1586
1587   TestTileTaskRunner::ProcessTask(result.task.get());
1588
1589   DecodedDrawImage decoded_draw_image =
1590       cache.GetDecodedImageForDraw(draw_image);
1591   EXPECT_TRUE(decoded_draw_image.image());
1592   // Decoded image should not be lazy generated.
1593   EXPECT_FALSE(decoded_draw_image.image()->isLazyGenerated());
1594   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1595             decoded_draw_image.filter_quality());
1596   EXPECT_EQ(8, decoded_draw_image.image()->width());
1597   EXPECT_EQ(4, decoded_draw_image.image()->height());
1598
1599   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1600   cache.UnrefImage(draw_image);
1601 }
1602
1603 TEST(SoftwareImageDecodeCacheTest, MediumQualityAt0_001ScaleIsHandled) {
1604   TestSoftwareImageDecodeCache cache;
1605   bool is_decomposable = true;
1606   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1607
1608   PaintImage paint_image = CreatePaintImage(500, 200);
1609   DrawImage draw_image(
1610       paint_image, false,
1611       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1612       CreateMatrix(SkSize::Make(0.001f, 0.001f), is_decomposable),
1613       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1614
1615   ImageDecodeCache::TaskResult result =
1616       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1617   EXPECT_FALSE(result.task);
1618   EXPECT_FALSE(result.need_unref);
1619
1620   DecodedDrawImage decoded_draw_image =
1621       cache.GetDecodedImageForDraw(draw_image);
1622   EXPECT_FALSE(decoded_draw_image.image());
1623
1624   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1625 }
1626
1627 TEST(SoftwareImageDecodeCacheTest,
1628      MediumQualityImagesAreTheSameAt0_5And0_49Scale) {
1629   TestSoftwareImageDecodeCache cache;
1630   bool is_decomposable = true;
1631   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1632
1633   PaintImage paint_image = CreatePaintImage(500, 200);
1634   DrawImage draw_image_50(
1635       paint_image, false,
1636       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1637       CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable),
1638       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1639   DrawImage draw_image_49(
1640       paint_image, false,
1641       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1642       CreateMatrix(SkSize::Make(0.49f, 0.49f), is_decomposable),
1643       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1644
1645   ImageDecodeCache::TaskResult result_50 = cache.GetTaskForImageAndRef(
1646       draw_image_50, ImageDecodeCache::TracingInfo());
1647   EXPECT_TRUE(result_50.task);
1648   EXPECT_TRUE(result_50.need_unref);
1649   ImageDecodeCache::TaskResult result_49 = cache.GetTaskForImageAndRef(
1650       draw_image_49, ImageDecodeCache::TracingInfo());
1651   EXPECT_TRUE(result_49.task);
1652   EXPECT_TRUE(result_49.need_unref);
1653
1654   TestTileTaskRunner::ProcessTask(result_49.task.get());
1655
1656   DecodedDrawImage decoded_draw_image_50 =
1657       cache.GetDecodedImageForDraw(draw_image_50);
1658   EXPECT_TRUE(decoded_draw_image_50.image());
1659   DecodedDrawImage decoded_draw_image_49 =
1660       cache.GetDecodedImageForDraw(draw_image_49);
1661   EXPECT_TRUE(decoded_draw_image_49.image());
1662   // Decoded image should not be lazy generated.
1663   EXPECT_FALSE(decoded_draw_image_50.image()->isLazyGenerated());
1664   EXPECT_FALSE(decoded_draw_image_49.image()->isLazyGenerated());
1665   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1666             decoded_draw_image_50.filter_quality());
1667   EXPECT_EQ(PaintFlags::FilterQuality::kLow,
1668             decoded_draw_image_49.filter_quality());
1669   EXPECT_EQ(250, decoded_draw_image_50.image()->width());
1670   EXPECT_EQ(250, decoded_draw_image_49.image()->width());
1671   EXPECT_EQ(100, decoded_draw_image_50.image()->height());
1672   EXPECT_EQ(100, decoded_draw_image_49.image()->height());
1673
1674   EXPECT_EQ(decoded_draw_image_50.image(), decoded_draw_image_49.image());
1675
1676   cache.DrawWithImageFinished(draw_image_50, decoded_draw_image_50);
1677   cache.UnrefImage(draw_image_50);
1678   cache.DrawWithImageFinished(draw_image_49, decoded_draw_image_49);
1679   cache.UnrefImage(draw_image_49);
1680 }
1681
1682 TEST(SoftwareImageDecodeCacheTest, ClearCache) {
1683   TestSoftwareImageDecodeCache cache;
1684   bool is_decomposable = true;
1685   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1686
1687   for (int i = 0; i < 10; ++i) {
1688     PaintImage paint_image = CreatePaintImage(100, 100);
1689     DrawImage draw_image(
1690         paint_image, false,
1691         SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1692         CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
1693         PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1694     ImageDecodeCache::TaskResult result = cache.GetTaskForImageAndRef(
1695         draw_image, ImageDecodeCache::TracingInfo());
1696     EXPECT_TRUE(result.need_unref);
1697     EXPECT_TRUE(result.task);
1698     TestTileTaskRunner::ProcessTask(result.task.get());
1699     cache.UnrefImage(draw_image);
1700   }
1701
1702   EXPECT_EQ(10u, cache.GetNumCacheEntriesForTesting());
1703
1704   // Tell our cache to clear resources.
1705   cache.ClearCache();
1706
1707   EXPECT_EQ(0u, cache.GetNumCacheEntriesForTesting());
1708 }
1709
1710 TEST(SoftwareImageDecodeCacheTest, CacheDecodesExpectedFrames) {
1711   TestSoftwareImageDecodeCache cache;
1712   std::vector<FrameMetadata> frames = {
1713       FrameMetadata(true, base::Milliseconds(2)),
1714       FrameMetadata(true, base::Milliseconds(3)),
1715       FrameMetadata(true, base::Milliseconds(4)),
1716       FrameMetadata(true, base::Milliseconds(5)),
1717   };
1718   sk_sp<FakePaintImageGenerator> generator =
1719       sk_make_sp<FakePaintImageGenerator>(
1720           SkImageInfo::MakeN32Premul(10, 10, SkColorSpace::MakeSRGB()), frames);
1721   PaintImage image = PaintImageBuilder::WithDefault()
1722                          .set_id(PaintImage::GetNextId())
1723                          .set_paint_image_generator(generator)
1724                          .TakePaintImage();
1725
1726   bool is_decomposable = true;
1727   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1728   DrawImage draw_image(image, false,
1729                        SkIRect::MakeWH(image.width(), image.height()), quality,
1730                        CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable),
1731                        1u, DefaultTargetColorParams());
1732   auto decoded_image = cache.GetDecodedImageForDraw(draw_image);
1733   ASSERT_TRUE(decoded_image.image());
1734   ASSERT_EQ(generator->frames_decoded().size(), 1u);
1735   EXPECT_EQ(generator->frames_decoded().count(1u), 1u);
1736   generator->reset_frames_decoded();
1737   cache.DrawWithImageFinished(draw_image, decoded_image);
1738
1739   // Scaled.
1740   DrawImage scaled_draw_image(draw_image, 0.5f, 2u,
1741                               draw_image.target_color_params());
1742   decoded_image = cache.GetDecodedImageForDraw(scaled_draw_image);
1743   ASSERT_TRUE(decoded_image.image());
1744   ASSERT_EQ(generator->frames_decoded().size(), 1u);
1745   EXPECT_EQ(generator->frames_decoded().count(2u), 1u);
1746   generator->reset_frames_decoded();
1747   cache.DrawWithImageFinished(scaled_draw_image, decoded_image);
1748
1749   // Subset.
1750   DrawImage subset_draw_image(
1751       image, false, SkIRect::MakeWH(5, 5), quality,
1752       CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), 3u,
1753       DefaultTargetColorParams());
1754   decoded_image = cache.GetDecodedImageForDraw(subset_draw_image);
1755   ASSERT_TRUE(decoded_image.image());
1756   ASSERT_EQ(generator->frames_decoded().size(), 1u);
1757   EXPECT_EQ(generator->frames_decoded().count(3u), 1u);
1758   generator->reset_frames_decoded();
1759   cache.DrawWithImageFinished(subset_draw_image, decoded_image);
1760 }
1761
1762 TEST(SoftwareImageDecodeCacheTest, SizeSubrectingIsHandled) {
1763   const int min_dimension = 4 * 1024 + 2;
1764   TestSoftwareImageDecodeCache cache;
1765   bool is_decomposable = true;
1766   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kLow;
1767
1768   auto paint_image = CreateDiscardablePaintImage(
1769       gfx::Size(min_dimension, min_dimension), DefaultSkColorSpace(), false);
1770   DrawImage draw_image(
1771       paint_image, false, SkIRect::MakeXYWH(0, 0, 10, 10), quality,
1772       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1773       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1774
1775   ImageDecodeCache::TaskResult result =
1776       cache.GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
1777   EXPECT_TRUE(result.task);
1778   EXPECT_TRUE(result.need_unref);
1779
1780   TestTileTaskRunner::ProcessTask(result.task.get());
1781
1782   DecodedDrawImage decoded_draw_image =
1783       cache.GetDecodedImageForDraw(draw_image);
1784   // Since we didn't allocate any backing for the memory, we expect this to be
1785   // false. This test is here to ensure that we at least got to the point where
1786   // we tried to decode something instead of recursing infinitely.
1787   EXPECT_FALSE(decoded_draw_image.image());
1788   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1789   cache.UnrefImage(draw_image);
1790 }
1791
1792 TEST(SoftwareImageDecodeCacheTest, EmptyTargetSizeDecode) {
1793   // Tests that requesting an empty sized decode followed by an original sized
1794   // decode returns no decoded images. This is a regression test. See
1795   // crbug.com/802976.
1796
1797   TestSoftwareImageDecodeCache cache;
1798   bool is_decomposable = true;
1799   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kLow;
1800
1801   // Populate the cache with an original sized decode.
1802   auto paint_image =
1803       CreateDiscardablePaintImage(gfx::Size(100, 100), DefaultSkColorSpace());
1804   DrawImage draw_image(paint_image, false, SkIRect::MakeWH(100, 100), quality,
1805                        CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1806                        PaintImage::kDefaultFrameIndex,
1807                        DefaultTargetColorParams());
1808   DecodedDrawImage decoded_draw_image =
1809       cache.GetDecodedImageForDraw(draw_image);
1810   EXPECT_TRUE(decoded_draw_image.image());
1811   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1812
1813   // Ask for another decode, this time with an empty subrect.
1814   DrawImage empty_draw_image(
1815       paint_image, false, SkIRect::MakeEmpty(), quality,
1816       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1817       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1818   DecodedDrawImage empty_decoded_draw_image =
1819       cache.GetDecodedImageForDraw(empty_draw_image);
1820   EXPECT_FALSE(empty_decoded_draw_image.image());
1821   cache.DrawWithImageFinished(empty_draw_image, empty_decoded_draw_image);
1822 }
1823
1824 TEST(SoftwareImageDecodeCacheTest, BitmapImageColorConverted) {
1825   TestSoftwareImageDecodeCache cache;
1826   bool is_decomposable = true;
1827   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1828   const TargetColorParams target_color_params(
1829       gfx::ColorSpace::CreateDisplayP3D65());
1830
1831   PaintImage paint_image = CreateBitmapImage(gfx::Size(100, 100));
1832   DrawImage draw_image(
1833       paint_image, false,
1834       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1835       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1836       PaintImage::kDefaultFrameIndex, target_color_params);
1837
1838   DecodedDrawImage decoded_draw_image =
1839       cache.GetDecodedImageForDraw(draw_image);
1840   EXPECT_TRUE(decoded_draw_image.image());
1841   // Expect that we allocated a new image.
1842   EXPECT_NE(decoded_draw_image.image().get(), paint_image.GetSwSkImage().get());
1843   // Expect that the image color space match the target color space.
1844   EXPECT_TRUE(decoded_draw_image.image()->colorSpace());
1845   EXPECT_TRUE(SkColorSpace::Equals(
1846       decoded_draw_image.image()->colorSpace(),
1847       target_color_params.color_space.ToSkColorSpace().get()));
1848
1849   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1850 }
1851
1852 TEST(SoftwareImageDecodeCacheTest, BitmapImageNotColorConverted) {
1853   TestSoftwareImageDecodeCache cache;
1854   bool is_decomposable = true;
1855   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1856
1857   PaintImage paint_image = CreateBitmapImage(gfx::Size(100, 100));
1858   DrawImage draw_image(
1859       paint_image, false,
1860       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1861       CreateMatrix(SkSize::Make(1.f, 1.f), is_decomposable),
1862       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1863
1864   // The cache should not support this image.
1865   EXPECT_FALSE(cache.UseCacheForDrawImage(draw_image));
1866 }
1867
1868 // TODO(ccameron): Re-enable this when the root cause of crashes is discovered.
1869 // https://crbug.com/791828
1870 TEST(SoftwareImageDecodeCacheTest, DISABLED_ContentIdCaching) {
1871   TestSoftwareImageDecodeCache cache;
1872   bool is_decomposable = true;
1873   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kHigh;
1874   PaintImage::Id stable_id = 1001;
1875
1876   for (int i = 0; i < 10; ++i) {
1877     // Create several images with the same stable id, but new content ids.
1878     PaintImage paint_image = CreateDiscardablePaintImage(
1879         gfx::Size(100, 100), nullptr, true, stable_id);
1880
1881     // Cache two entries of different scales.
1882     for (int j = 0; j < 2; ++j) {
1883       float scale = j == 0 ? 1.f : 0.5f;
1884       DrawImage draw_image(
1885           paint_image, false,
1886           SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1887           CreateMatrix(SkSize::Make(scale, scale), is_decomposable),
1888           PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1889       DecodedDrawImage decoded_draw_image =
1890           cache.GetDecodedImageForDraw(draw_image);
1891       EXPECT_TRUE(decoded_draw_image.image());
1892       cache.DrawWithImageFinished(draw_image, decoded_draw_image);
1893     }
1894
1895     // After the first two entries come in, we start evicting old content ids.
1896     if (i == 0)
1897       EXPECT_LE(cache.GetNumCacheEntriesForTesting(), 2u);
1898     else
1899       EXPECT_LE(cache.GetNumCacheEntriesForTesting(), 4u);
1900   }
1901 }
1902
1903 TEST(SoftwareImageDecodeCacheTest, DecodeToScale) {
1904   TestSoftwareImageDecodeCache cache;
1905   bool is_decomposable = true;
1906   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1907
1908   SkISize full_size = SkISize::Make(100, 100);
1909   std::vector<SkISize> supported_sizes = {SkISize::Make(25, 25),
1910                                           SkISize::Make(50, 50)};
1911   std::vector<FrameMetadata> frames = {FrameMetadata()};
1912   sk_sp<FakePaintImageGenerator> generator =
1913       sk_make_sp<FakePaintImageGenerator>(
1914           SkImageInfo::MakeN32Premul(full_size.width(), full_size.height(),
1915                                      DefaultSkColorSpace()),
1916           frames, true, supported_sizes);
1917   PaintImage paint_image = PaintImageBuilder::WithDefault()
1918                                .set_id(PaintImage::GetNextId())
1919                                .set_paint_image_generator(generator)
1920                                .TakePaintImage();
1921
1922   // Scale to mip level 1, there should be a single entry in the cache from
1923   // the direct decode.
1924   DrawImage draw_image1(
1925       paint_image, false,
1926       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1927       CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
1928       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1929   DecodedDrawImage decoded_image1 = cache.GetDecodedImageForDraw(draw_image1);
1930   ASSERT_TRUE(decoded_image1.image());
1931   EXPECT_EQ(decoded_image1.image()->width(), 50);
1932   EXPECT_EQ(decoded_image1.image()->height(), 50);
1933   EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 1u);
1934
1935   // We should have requested a scaled decode from the generator.
1936   ASSERT_EQ(generator->decode_infos().size(), 1u);
1937   EXPECT_EQ(generator->decode_infos().at(0).width(), 50);
1938   EXPECT_EQ(generator->decode_infos().at(0).height(), 50);
1939
1940   // Scale to mip level 2, we should be using the existing entry instead of
1941   // re-decoding.
1942   DrawImage draw_image2(
1943       paint_image, false,
1944       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
1945       CreateMatrix(SkSize::Make(0.25, 0.25), is_decomposable),
1946       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
1947   DecodedDrawImage decoded_image2 = cache.GetDecodedImageForDraw(draw_image2);
1948   ASSERT_TRUE(decoded_image2.image());
1949   EXPECT_EQ(decoded_image2.image()->width(), 25);
1950   EXPECT_EQ(decoded_image2.image()->height(), 25);
1951   EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 2u);
1952
1953   // Since we scaled from the existing entry, no new decodes should be
1954   // requested from the generator.
1955   ASSERT_EQ(generator->decode_infos().size(), 1u);
1956   EXPECT_EQ(generator->decode_infos().at(0).width(), 50);
1957   EXPECT_EQ(generator->decode_infos().at(0).height(), 50);
1958
1959   cache.DrawWithImageFinished(draw_image1, decoded_image1);
1960   cache.DrawWithImageFinished(draw_image2, decoded_image2);
1961 }
1962
1963 TEST(SoftwareImageDecodeCacheTest, DecodeToScaleSubrect) {
1964   TestSoftwareImageDecodeCache cache;
1965   bool is_decomposable = true;
1966   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kMedium;
1967
1968   SkISize full_size = SkISize::Make(100, 100);
1969   std::vector<SkISize> supported_sizes = {SkISize::Make(25, 25),
1970                                           SkISize::Make(50, 50)};
1971   std::vector<FrameMetadata> frames = {FrameMetadata()};
1972   sk_sp<FakePaintImageGenerator> generator =
1973       sk_make_sp<FakePaintImageGenerator>(
1974           SkImageInfo::MakeN32Premul(full_size.width(), full_size.height(),
1975                                      DefaultSkColorSpace()),
1976           frames, true, supported_sizes);
1977   PaintImage paint_image = PaintImageBuilder::WithDefault()
1978                                .set_id(PaintImage::GetNextId())
1979                                .set_paint_image_generator(generator)
1980                                .TakePaintImage();
1981
1982   // Scale to mip level 1, there should be 2 entries in the cache, since the
1983   // subrect vetoes decode to scale.
1984   DrawImage draw_image(paint_image, false, SkIRect::MakeWH(50, 50), quality,
1985                        CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
1986                        PaintImage::kDefaultFrameIndex,
1987                        DefaultTargetColorParams());
1988   DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
1989   ASSERT_TRUE(decoded_image.image());
1990   EXPECT_EQ(decoded_image.image()->width(), 25);
1991   EXPECT_EQ(decoded_image.image()->height(), 25);
1992   EXPECT_EQ(cache.GetNumCacheEntriesForTesting(), 2u);
1993
1994   // We should have requested the original decode from the generator.
1995   ASSERT_EQ(generator->decode_infos().size(), 1u);
1996   EXPECT_EQ(generator->decode_infos().at(0).width(), 100);
1997   EXPECT_EQ(generator->decode_infos().at(0).height(), 100);
1998   cache.DrawWithImageFinished(draw_image, decoded_image);
1999 }
2000
2001 TEST(SoftwareImageDecodeCacheTest, DecodeToScaleNoneQuality) {
2002   TestSoftwareImageDecodeCache cache;
2003   bool is_decomposable = true;
2004   PaintFlags::FilterQuality quality = PaintFlags::FilterQuality::kNone;
2005
2006   SkISize full_size = SkISize::Make(100, 100);
2007   std::vector<SkISize> supported_sizes = {SkISize::Make(25, 25),
2008                                           SkISize::Make(50, 50)};
2009   std::vector<FrameMetadata> frames = {FrameMetadata()};
2010   sk_sp<FakePaintImageGenerator> generator =
2011       sk_make_sp<FakePaintImageGenerator>(
2012           SkImageInfo::MakeN32Premul(full_size.width(), full_size.height(),
2013                                      DefaultSkColorSpace()),
2014           frames, true, supported_sizes);
2015   PaintImage paint_image = PaintImageBuilder::WithDefault()
2016                                .set_id(PaintImage::GetNextId())
2017                                .set_paint_image_generator(generator)
2018                                .TakePaintImage();
2019
2020   DrawImage draw_image(
2021       paint_image, false,
2022       SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality,
2023       CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable),
2024       PaintImage::kDefaultFrameIndex, DefaultTargetColorParams());
2025   DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
2026   ASSERT_TRUE(decoded_image.image());
2027   EXPECT_EQ(decoded_image.image()->width(), 100);
2028   EXPECT_EQ(decoded_image.image()->height(), 100);
2029
2030   // We should have requested the original decode from the generator.
2031   ASSERT_EQ(generator->decode_infos().size(), 1u);
2032   EXPECT_EQ(generator->decode_infos().at(0).width(), 100);
2033   EXPECT_EQ(generator->decode_infos().at(0).height(), 100);
2034   cache.DrawWithImageFinished(draw_image, decoded_image);
2035 }
2036
2037 TEST(SoftwareImageDecodeCacheTest, HdrDecodeToHdr) {
2038   TestSoftwareImageDecodeCache cache;
2039
2040   const TargetColorParams target_color_params(gfx::ColorSpace::CreateHDR10());
2041   auto size = SkISize::Make(100, 100);
2042   auto info = SkImageInfo::Make(
2043       size.width(), size.height(), kRGBA_F16_SkColorType, kPremul_SkAlphaType,
2044       target_color_params.color_space.ToSkColorSpace());
2045   SkBitmap bitmap;
2046   bitmap.allocPixels(info);
2047   PaintImage image = PaintImageBuilder::WithDefault()
2048                          .set_id(PaintImage::kInvalidId)
2049                          .set_is_high_bit_depth(true)
2050                          .set_image(SkImage::MakeFromBitmap(bitmap),
2051                                     PaintImage::GetNextContentId())
2052                          .TakePaintImage();
2053
2054   DrawImage draw_image(image, false,
2055                        SkIRect::MakeWH(image.width(), image.height()),
2056                        PaintFlags::FilterQuality::kMedium,
2057                        CreateMatrix(SkSize::Make(0.5, 0.5), true),
2058                        PaintImage::kDefaultFrameIndex, target_color_params);
2059
2060   DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
2061   EXPECT_EQ(decoded_image.image()->colorType(), kRGBA_F16_SkColorType);
2062   cache.DrawWithImageFinished(draw_image, decoded_image);
2063 }
2064
2065 TEST(SoftwareImageDecodeCacheTest, HdrDecodeToSdr) {
2066   TestSoftwareImageDecodeCache cache;
2067
2068   auto image_color_space = gfx::ColorSpace::CreateHDR10();
2069   auto size = SkISize::Make(100, 100);
2070   auto info = SkImageInfo::Make(size.width(), size.height(),
2071                                 kRGBA_F16_SkColorType, kPremul_SkAlphaType,
2072                                 image_color_space.ToSkColorSpace());
2073   SkBitmap bitmap;
2074   bitmap.allocPixels(info);
2075   PaintImage image = PaintImageBuilder::WithDefault()
2076                          .set_id(PaintImage::kInvalidId)
2077                          .set_is_high_bit_depth(true)
2078                          .set_image(SkImage::MakeFromBitmap(bitmap),
2079                                     PaintImage::GetNextContentId())
2080                          .TakePaintImage();
2081
2082   // Note: We use P3 here since software cache shouldn't be used when conversion
2083   // to SRGB is needed.
2084   auto raster_color_space = gfx::ColorSpace::CreateDisplayP3D65();
2085   DrawImage draw_image(
2086       image, false, SkIRect::MakeWH(image.width(), image.height()),
2087       PaintFlags::FilterQuality::kMedium,
2088       CreateMatrix(SkSize::Make(0.5, 0.5), true),
2089       PaintImage::kDefaultFrameIndex, TargetColorParams(raster_color_space));
2090
2091   DecodedDrawImage decoded_image = cache.GetDecodedImageForDraw(draw_image);
2092   EXPECT_NE(decoded_image.image()->colorType(), kRGBA_F16_SkColorType);
2093   cache.DrawWithImageFinished(draw_image, decoded_image);
2094 }
2095
2096 }  // namespace
2097 }  // namespace cc