1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/playback/discardable_image_map.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/values.h"
10 #include "cc/playback/picture.h"
11 #include "cc/test/fake_content_layer_client.h"
12 #include "cc/test/skia_common.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/skia/include/core/SkGraphics.h"
15 #include "third_party/skia/include/core/SkImageGenerator.h"
16 #include "ui/gfx/geometry/rect.h"
17 #include "ui/gfx/skia_util.h"
22 class TestImageGenerator
: public SkImageGenerator
{
24 explicit TestImageGenerator(const SkImageInfo
& info
)
25 : SkImageGenerator(info
) {}
28 skia::RefPtr
<SkImage
> CreateDiscardableImage(const gfx::Size
& size
) {
29 const SkImageInfo info
=
30 SkImageInfo::MakeN32Premul(size
.width(), size
.height());
31 return skia::AdoptRef(
32 SkImage::NewFromGenerator(new TestImageGenerator(info
)));
35 TEST(DiscardableImageMapTest
, DiscardableImageMapIterator
) {
36 gfx::Rect
layer_rect(2048, 2048);
38 gfx::Size
tile_grid_size(512, 512);
40 FakeContentLayerClient content_layer_client
;
42 // Discardable pixel refs are found in the following grids:
52 skia::RefPtr
<SkImage
> discardable_image
[4][4];
53 for (int y
= 0; y
< 4; ++y
) {
54 for (int x
= 0; x
< 4; ++x
) {
56 discardable_image
[y
][x
] = CreateDiscardableImage(gfx::Size(500, 500));
58 content_layer_client
.add_draw_image(
59 discardable_image
[y
][x
].get(), gfx::Point(x
* 512 + 6, y
* 512 + 6),
65 scoped_refptr
<Picture
> picture
=
66 Picture::Create(layer_rect
, &content_layer_client
, tile_grid_size
, true,
67 RecordingSource::RECORD_NORMALLY
);
69 // Default iterator does not have any pixel refs.
71 DiscardableImageMap::Iterator iterator
;
72 EXPECT_FALSE(iterator
);
75 for (int y
= 0; y
< 4; ++y
) {
76 for (int x
= 0; x
< 4; ++x
) {
77 DiscardableImageMap::Iterator
iterator(
78 gfx::Rect(x
* 512, y
* 512, 500, 500), picture
.get());
80 EXPECT_TRUE(iterator
) << x
<< " " << y
;
81 EXPECT_TRUE(iterator
->image
== discardable_image
[y
][x
].get())
83 EXPECT_EQ(gfx::RectF(x
* 512 + 6, y
* 512 + 6, 500, 500).ToString(),
84 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
85 EXPECT_FALSE(++iterator
) << x
<< " " << y
;
87 EXPECT_FALSE(iterator
) << x
<< " " << y
;
92 // Capture 4 pixel refs.
94 DiscardableImageMap::Iterator
iterator(gfx::Rect(512, 512, 2048, 2048),
96 EXPECT_TRUE(iterator
);
97 EXPECT_TRUE(iterator
->image
== discardable_image
[1][2].get());
98 EXPECT_EQ(gfx::RectF(2 * 512 + 6, 512 + 6, 500, 500).ToString(),
99 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
100 EXPECT_TRUE(++iterator
);
101 EXPECT_TRUE(iterator
->image
== discardable_image
[2][1].get());
102 EXPECT_EQ(gfx::RectF(512 + 6, 2 * 512 + 6, 500, 500).ToString(),
103 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
104 EXPECT_TRUE(++iterator
);
105 EXPECT_TRUE(iterator
->image
== discardable_image
[2][3].get());
106 EXPECT_EQ(gfx::RectF(3 * 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
107 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
108 EXPECT_TRUE(++iterator
);
109 EXPECT_TRUE(iterator
->image
== discardable_image
[3][2].get());
110 EXPECT_EQ(gfx::RectF(2 * 512 + 6, 3 * 512 + 6, 500, 500).ToString(),
111 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
112 EXPECT_FALSE(++iterator
);
117 DiscardableImageMap::Iterator
iterator(gfx::Rect(512, 512, 2048, 2048),
119 EXPECT_TRUE(iterator
);
120 EXPECT_TRUE(iterator
->image
== discardable_image
[1][2].get());
121 EXPECT_EQ(gfx::RectF(2 * 512 + 6, 512 + 6, 500, 500).ToString(),
122 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
123 EXPECT_TRUE(++iterator
);
124 EXPECT_TRUE(iterator
->image
== discardable_image
[2][1].get());
125 EXPECT_EQ(gfx::RectF(512 + 6, 2 * 512 + 6, 500, 500).ToString(),
126 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
128 // copy now points to the same spot as iterator,
129 // but both can be incremented independently.
130 DiscardableImageMap::Iterator copy
= iterator
;
131 EXPECT_TRUE(++iterator
);
132 EXPECT_TRUE(iterator
->image
== discardable_image
[2][3].get());
133 EXPECT_EQ(gfx::RectF(3 * 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
134 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
135 EXPECT_TRUE(++iterator
);
136 EXPECT_TRUE(iterator
->image
== discardable_image
[3][2].get());
137 EXPECT_EQ(gfx::RectF(2 * 512 + 6, 3 * 512 + 6, 500, 500).ToString(),
138 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
139 EXPECT_FALSE(++iterator
);
142 EXPECT_TRUE(copy
->image
== discardable_image
[2][1].get());
143 EXPECT_EQ(gfx::RectF(512 + 6, 2 * 512 + 6, 500, 500).ToString(),
144 gfx::SkRectToRectF(copy
->image_rect
).ToString());
146 EXPECT_TRUE(copy
->image
== discardable_image
[2][3].get());
147 EXPECT_EQ(gfx::RectF(3 * 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
148 gfx::SkRectToRectF(copy
->image_rect
).ToString());
150 EXPECT_TRUE(copy
->image
== discardable_image
[3][2].get());
151 EXPECT_EQ(gfx::RectF(2 * 512 + 6, 3 * 512 + 6, 500, 500).ToString(),
152 gfx::SkRectToRectF(copy
->image_rect
).ToString());
153 EXPECT_FALSE(++copy
);
157 TEST(DiscardableImageMapTest
, DiscardableImageMapIteratorNonZeroLayer
) {
158 gfx::Rect
layer_rect(1024, 0, 2048, 2048);
160 gfx::Size
tile_grid_size(512, 512);
162 FakeContentLayerClient content_layer_client
;
164 // Discardable pixel refs are found in the following grids:
174 skia::RefPtr
<SkImage
> discardable_image
[4][4];
175 for (int y
= 0; y
< 4; ++y
) {
176 for (int x
= 0; x
< 4; ++x
) {
178 discardable_image
[y
][x
] = CreateDiscardableImage(gfx::Size(500, 500));
180 content_layer_client
.add_draw_image(
181 discardable_image
[y
][x
].get(),
182 gfx::Point(1024 + x
* 512 + 6, y
* 512 + 6), paint
);
187 scoped_refptr
<Picture
> picture
=
188 Picture::Create(layer_rect
, &content_layer_client
, tile_grid_size
, true,
189 RecordingSource::RECORD_NORMALLY
);
191 // Default iterator does not have any pixel refs.
193 DiscardableImageMap::Iterator iterator
;
194 EXPECT_FALSE(iterator
);
197 for (int y
= 0; y
< 4; ++y
) {
198 for (int x
= 0; x
< 4; ++x
) {
199 DiscardableImageMap::Iterator
iterator(
200 gfx::Rect(1024 + x
* 512, y
* 512, 500, 500), picture
.get());
202 EXPECT_TRUE(iterator
) << x
<< " " << y
;
203 EXPECT_TRUE(iterator
->image
== discardable_image
[y
][x
].get());
205 gfx::RectF(1024 + x
* 512 + 6, y
* 512 + 6, 500, 500).ToString(),
206 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
207 EXPECT_FALSE(++iterator
) << x
<< " " << y
;
209 EXPECT_FALSE(iterator
) << x
<< " " << y
;
213 // Capture 4 pixel refs.
215 DiscardableImageMap::Iterator
iterator(
216 gfx::Rect(1024 + 512, 512, 2048, 2048), picture
.get());
217 EXPECT_TRUE(iterator
);
218 EXPECT_TRUE(iterator
->image
== discardable_image
[1][2].get());
219 EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 512 + 6, 500, 500).ToString(),
220 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
221 EXPECT_TRUE(++iterator
);
222 EXPECT_TRUE(iterator
->image
== discardable_image
[2][1].get());
223 EXPECT_EQ(gfx::RectF(1024 + 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
224 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
225 EXPECT_TRUE(++iterator
);
226 EXPECT_TRUE(iterator
->image
== discardable_image
[2][3].get());
227 EXPECT_EQ(gfx::RectF(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
228 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
229 EXPECT_TRUE(++iterator
);
230 EXPECT_TRUE(iterator
->image
== discardable_image
[3][2].get());
231 EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500).ToString(),
232 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
233 EXPECT_FALSE(++iterator
);
238 DiscardableImageMap::Iterator
iterator(
239 gfx::Rect(1024 + 512, 512, 2048, 2048), picture
.get());
240 EXPECT_TRUE(iterator
);
241 EXPECT_TRUE(iterator
->image
== discardable_image
[1][2].get());
242 EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 512 + 6, 500, 500).ToString(),
243 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
244 EXPECT_TRUE(++iterator
);
245 EXPECT_TRUE(iterator
->image
== discardable_image
[2][1].get());
246 EXPECT_EQ(gfx::RectF(1024 + 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
247 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
249 // copy now points to the same spot as iterator,
250 // but both can be incremented independently.
251 DiscardableImageMap::Iterator copy
= iterator
;
252 EXPECT_TRUE(++iterator
);
253 EXPECT_TRUE(iterator
->image
== discardable_image
[2][3].get());
254 EXPECT_EQ(gfx::RectF(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
255 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
256 EXPECT_TRUE(++iterator
);
257 EXPECT_TRUE(iterator
->image
== discardable_image
[3][2].get());
258 EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500).ToString(),
259 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
260 EXPECT_FALSE(++iterator
);
263 EXPECT_TRUE(copy
->image
== discardable_image
[2][1].get());
264 EXPECT_EQ(gfx::RectF(1024 + 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
265 gfx::SkRectToRectF(copy
->image_rect
).ToString());
267 EXPECT_TRUE(copy
->image
== discardable_image
[2][3].get());
268 EXPECT_EQ(gfx::RectF(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500).ToString(),
269 gfx::SkRectToRectF(copy
->image_rect
).ToString());
271 EXPECT_TRUE(copy
->image
== discardable_image
[3][2].get());
272 EXPECT_EQ(gfx::RectF(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500).ToString(),
273 gfx::SkRectToRectF(copy
->image_rect
).ToString());
274 EXPECT_FALSE(++copy
);
277 // Non intersecting rects
279 DiscardableImageMap::Iterator
iterator(gfx::Rect(0, 0, 1000, 1000),
281 EXPECT_FALSE(iterator
);
284 DiscardableImageMap::Iterator
iterator(gfx::Rect(3500, 0, 1000, 1000),
286 EXPECT_FALSE(iterator
);
289 DiscardableImageMap::Iterator
iterator(gfx::Rect(0, 1100, 1000, 1000),
291 EXPECT_FALSE(iterator
);
294 DiscardableImageMap::Iterator
iterator(gfx::Rect(3500, 1100, 1000, 1000),
296 EXPECT_FALSE(iterator
);
300 TEST(DiscardableImageMapTest
, DiscardableImageMapIteratorOnePixelQuery
) {
301 gfx::Rect
layer_rect(2048, 2048);
303 gfx::Size
tile_grid_size(512, 512);
305 FakeContentLayerClient content_layer_client
;
307 // Discardable pixel refs are found in the following grids:
317 skia::RefPtr
<SkImage
> discardable_image
[4][4];
318 for (int y
= 0; y
< 4; ++y
) {
319 for (int x
= 0; x
< 4; ++x
) {
321 discardable_image
[y
][x
] = CreateDiscardableImage(gfx::Size(500, 500));
323 content_layer_client
.add_draw_image(
324 discardable_image
[y
][x
].get(), gfx::Point(x
* 512 + 6, y
* 512 + 6),
330 scoped_refptr
<Picture
> picture
=
331 Picture::Create(layer_rect
, &content_layer_client
, tile_grid_size
, true,
332 RecordingSource::RECORD_NORMALLY
);
334 // Default iterator does not have any pixel refs.
336 DiscardableImageMap::Iterator iterator
;
337 EXPECT_FALSE(iterator
);
340 for (int y
= 0; y
< 4; ++y
) {
341 for (int x
= 0; x
< 4; ++x
) {
342 DiscardableImageMap::Iterator
iterator(
343 gfx::Rect(x
* 512, y
* 512 + 256, 1, 1), picture
.get());
345 EXPECT_TRUE(iterator
) << x
<< " " << y
;
346 EXPECT_TRUE(iterator
->image
== discardable_image
[y
][x
].get());
347 EXPECT_EQ(gfx::RectF(x
* 512 + 6, y
* 512 + 6, 500, 500).ToString(),
348 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
349 EXPECT_FALSE(++iterator
) << x
<< " " << y
;
351 EXPECT_FALSE(iterator
) << x
<< " " << y
;
357 TEST(DiscardableImageMapTest
, DiscardableImageMapIteratorMassiveImage
) {
358 gfx::Rect
layer_rect(2048, 2048);
359 gfx::Size
tile_grid_size(512, 512);
360 FakeContentLayerClient content_layer_client
;
362 skia::RefPtr
<SkImage
> discardable_image
;
363 discardable_image
= CreateDiscardableImage(gfx::Size(1 << 25, 1 << 25));
365 content_layer_client
.add_draw_image(discardable_image
.get(), gfx::Point(0, 0),
368 scoped_refptr
<Picture
> picture
=
369 Picture::Create(layer_rect
, &content_layer_client
, tile_grid_size
, true,
370 RecordingSource::RECORD_NORMALLY
);
372 DiscardableImageMap::Iterator
iterator(gfx::Rect(0, 0, 1, 1), picture
.get());
373 EXPECT_TRUE(iterator
);
374 EXPECT_TRUE(iterator
->image
== discardable_image
.get());
375 EXPECT_EQ(gfx::RectF(0, 0, 1 << 25, 1 << 25).ToString(),
376 gfx::SkRectToRectF(iterator
->image_rect
).ToString());
377 EXPECT_FALSE(++iterator
);