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

Side by Side Diff: cc/playback/discardable_image_map_unittest.cc

Issue 2748263002: Move cc::DisplayItemList and related classes into cc/paint/ (Closed)
Patch Set: none Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "cc/playback/discardable_image_map.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10
11 #include "base/memory/ref_counted.h"
12 #include "base/values.h"
13 #include "cc/base/region.h"
14 #include "cc/test/fake_content_layer_client.h"
15 #include "cc/test/fake_recording_source.h"
16 #include "cc/test/skia_common.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/core/SkCanvas.h"
19 #include "third_party/skia/include/core/SkGraphics.h"
20 #include "third_party/skia/include/core/SkImageGenerator.h"
21 #include "third_party/skia/include/core/SkRefCnt.h"
22 #include "ui/gfx/geometry/rect.h"
23 #include "ui/gfx/skia_util.h"
24
25 namespace cc {
26 namespace {
27
28 struct PositionScaleDrawImage {
29 PositionScaleDrawImage(sk_sp<const SkImage> image,
30 const gfx::Rect& image_rect,
31 const SkSize& scale)
32 : image(std::move(image)), image_rect(image_rect), scale(scale) {}
33 sk_sp<const SkImage> image;
34 gfx::Rect image_rect;
35 SkSize scale;
36 };
37
38 } // namespace
39
40 class DiscardableImageMapTest : public testing::Test {
41 public:
42 std::vector<PositionScaleDrawImage> GetDiscardableImagesInRect(
43 const DiscardableImageMap& image_map,
44 const gfx::Rect& rect) {
45 std::vector<DrawImage> draw_images;
46 image_map.GetDiscardableImagesInRect(rect, 1.f, &draw_images);
47
48 std::vector<size_t> indices;
49 image_map.images_rtree_.Search(rect, &indices);
50 std::vector<PositionScaleDrawImage> position_draw_images;
51 for (size_t index : indices) {
52 position_draw_images.push_back(
53 PositionScaleDrawImage(image_map.all_images_[index].first.image(),
54 image_map.all_images_[index].second,
55 image_map.all_images_[index].first.scale()));
56 }
57
58 EXPECT_EQ(draw_images.size(), position_draw_images.size());
59 for (size_t i = 0; i < draw_images.size(); ++i)
60 EXPECT_TRUE(draw_images[i].image() == position_draw_images[i].image);
61 return position_draw_images;
62 }
63 };
64
65 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectTest) {
66 gfx::Rect visible_rect(2048, 2048);
67 FakeContentLayerClient content_layer_client;
68 content_layer_client.set_bounds(visible_rect.size());
69
70 // Discardable pixel refs are found in the following grids:
71 // |---|---|---|---|
72 // | | x | | x |
73 // |---|---|---|---|
74 // | x | | x | |
75 // |---|---|---|---|
76 // | | x | | x |
77 // |---|---|---|---|
78 // | x | | x | |
79 // |---|---|---|---|
80 sk_sp<SkImage> discardable_image[4][4];
81 for (int y = 0; y < 4; ++y) {
82 for (int x = 0; x < 4; ++x) {
83 if ((x + y) & 1) {
84 discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500));
85 PaintFlags flags;
86 content_layer_client.add_draw_image(
87 discardable_image[y][x], gfx::Point(x * 512 + 6, y * 512 + 6),
88 flags);
89 }
90 }
91 }
92
93 scoped_refptr<DisplayItemList> display_list =
94 content_layer_client.PaintContentsToDisplayList(
95 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
96
97 DiscardableImageMap image_map;
98 {
99 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
100 visible_rect.size());
101 display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f);
102 }
103
104 for (int y = 0; y < 4; ++y) {
105 for (int x = 0; x < 4; ++x) {
106 std::vector<PositionScaleDrawImage> images = GetDiscardableImagesInRect(
107 image_map, gfx::Rect(x * 512, y * 512, 500, 500));
108 if ((x + y) & 1) {
109 EXPECT_EQ(1u, images.size()) << x << " " << y;
110 EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " "
111 << y;
112 EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500),
113 images[0].image_rect);
114 EXPECT_EQ(images[0].image_rect,
115 image_map.GetRectForImage(images[0].image->uniqueID()));
116 } else {
117 EXPECT_EQ(0u, images.size()) << x << " " << y;
118 }
119 }
120 }
121
122 // Capture 4 pixel refs.
123 std::vector<PositionScaleDrawImage> images =
124 GetDiscardableImagesInRect(image_map, gfx::Rect(512, 512, 2048, 2048));
125 EXPECT_EQ(4u, images.size());
126
127 EXPECT_TRUE(images[0].image == discardable_image[1][2]);
128 EXPECT_EQ(gfx::Rect(2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect);
129 EXPECT_EQ(images[0].image_rect,
130 image_map.GetRectForImage(images[0].image->uniqueID()));
131
132 EXPECT_TRUE(images[1].image == discardable_image[2][1]);
133 EXPECT_EQ(gfx::Rect(512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect);
134 EXPECT_EQ(images[1].image_rect,
135 image_map.GetRectForImage(images[1].image->uniqueID()));
136
137 EXPECT_TRUE(images[2].image == discardable_image[2][3]);
138 EXPECT_EQ(gfx::Rect(3 * 512 + 6, 2 * 512 + 6, 500, 500),
139 images[2].image_rect);
140 EXPECT_EQ(images[2].image_rect,
141 image_map.GetRectForImage(images[2].image->uniqueID()));
142
143 EXPECT_TRUE(images[3].image == discardable_image[3][2]);
144 EXPECT_EQ(gfx::Rect(2 * 512 + 6, 3 * 512 + 6, 500, 500),
145 images[3].image_rect);
146 EXPECT_EQ(images[3].image_rect,
147 image_map.GetRectForImage(images[3].image->uniqueID()));
148 }
149
150 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectNonZeroLayer) {
151 gfx::Rect visible_rect(1024, 0, 2048, 2048);
152 // Make sure visible rect fits into the layer size.
153 gfx::Size layer_size(visible_rect.right(), visible_rect.bottom());
154 FakeContentLayerClient content_layer_client;
155 content_layer_client.set_bounds(layer_size);
156
157 // Discardable pixel refs are found in the following grids:
158 // |---|---|---|---|
159 // | | x | | x |
160 // |---|---|---|---|
161 // | x | | x | |
162 // |---|---|---|---|
163 // | | x | | x |
164 // |---|---|---|---|
165 // | x | | x | |
166 // |---|---|---|---|
167 sk_sp<SkImage> discardable_image[4][4];
168 for (int y = 0; y < 4; ++y) {
169 for (int x = 0; x < 4; ++x) {
170 if ((x + y) & 1) {
171 discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500));
172 PaintFlags flags;
173 content_layer_client.add_draw_image(
174 discardable_image[y][x],
175 gfx::Point(1024 + x * 512 + 6, y * 512 + 6), flags);
176 }
177 }
178 }
179
180 scoped_refptr<DisplayItemList> display_list =
181 content_layer_client.PaintContentsToDisplayList(
182 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
183
184 DiscardableImageMap image_map;
185 {
186 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
187 layer_size);
188 display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f);
189 }
190
191 for (int y = 0; y < 4; ++y) {
192 for (int x = 0; x < 4; ++x) {
193 std::vector<PositionScaleDrawImage> images = GetDiscardableImagesInRect(
194 image_map, gfx::Rect(1024 + x * 512, y * 512, 500, 500));
195 if ((x + y) & 1) {
196 EXPECT_EQ(1u, images.size()) << x << " " << y;
197 EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " "
198 << y;
199 EXPECT_EQ(gfx::Rect(1024 + x * 512 + 6, y * 512 + 6, 500, 500),
200 images[0].image_rect);
201 EXPECT_EQ(images[0].image_rect,
202 image_map.GetRectForImage(images[0].image->uniqueID()));
203 } else {
204 EXPECT_EQ(0u, images.size()) << x << " " << y;
205 }
206 }
207 }
208 // Capture 4 pixel refs.
209 {
210 std::vector<PositionScaleDrawImage> images = GetDiscardableImagesInRect(
211 image_map, gfx::Rect(1024 + 512, 512, 2048, 2048));
212 EXPECT_EQ(4u, images.size());
213
214 EXPECT_TRUE(images[0].image == discardable_image[1][2]);
215 EXPECT_EQ(gfx::Rect(1024 + 2 * 512 + 6, 512 + 6, 500, 500),
216 images[0].image_rect);
217 EXPECT_EQ(images[0].image_rect,
218 image_map.GetRectForImage(images[0].image->uniqueID()));
219
220 EXPECT_TRUE(images[1].image == discardable_image[2][1]);
221 EXPECT_EQ(gfx::Rect(1024 + 512 + 6, 2 * 512 + 6, 500, 500),
222 images[1].image_rect);
223 EXPECT_EQ(images[1].image_rect,
224 image_map.GetRectForImage(images[1].image->uniqueID()));
225
226 EXPECT_TRUE(images[2].image == discardable_image[2][3]);
227 EXPECT_EQ(gfx::Rect(1024 + 3 * 512 + 6, 2 * 512 + 6, 500, 500),
228 images[2].image_rect);
229 EXPECT_EQ(images[2].image_rect,
230 image_map.GetRectForImage(images[2].image->uniqueID()));
231
232 EXPECT_TRUE(images[3].image == discardable_image[3][2]);
233 EXPECT_EQ(gfx::Rect(1024 + 2 * 512 + 6, 3 * 512 + 6, 500, 500),
234 images[3].image_rect);
235 EXPECT_EQ(images[3].image_rect,
236 image_map.GetRectForImage(images[3].image->uniqueID()));
237 }
238
239 // Non intersecting rects
240 {
241 std::vector<PositionScaleDrawImage> images =
242 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1000, 1000));
243 EXPECT_EQ(0u, images.size());
244 }
245 {
246 std::vector<PositionScaleDrawImage> images =
247 GetDiscardableImagesInRect(image_map, gfx::Rect(3500, 0, 1000, 1000));
248 EXPECT_EQ(0u, images.size());
249 }
250 {
251 std::vector<PositionScaleDrawImage> images =
252 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 1100, 1000, 1000));
253 EXPECT_EQ(0u, images.size());
254 }
255 {
256 std::vector<PositionScaleDrawImage> images = GetDiscardableImagesInRect(
257 image_map, gfx::Rect(3500, 1100, 1000, 1000));
258 EXPECT_EQ(0u, images.size());
259 }
260
261 // Image not present in the list.
262 {
263 sk_sp<SkImage> image = CreateDiscardableImage(gfx::Size(500, 500));
264 EXPECT_EQ(gfx::Rect(), image_map.GetRectForImage(image->uniqueID()));
265 }
266 }
267
268 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectOnePixelQuery) {
269 gfx::Rect visible_rect(2048, 2048);
270 FakeContentLayerClient content_layer_client;
271 content_layer_client.set_bounds(visible_rect.size());
272
273 // Discardable pixel refs are found in the following grids:
274 // |---|---|---|---|
275 // | | x | | x |
276 // |---|---|---|---|
277 // | x | | x | |
278 // |---|---|---|---|
279 // | | x | | x |
280 // |---|---|---|---|
281 // | x | | x | |
282 // |---|---|---|---|
283 sk_sp<SkImage> discardable_image[4][4];
284 for (int y = 0; y < 4; ++y) {
285 for (int x = 0; x < 4; ++x) {
286 if ((x + y) & 1) {
287 discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500));
288 PaintFlags flags;
289 content_layer_client.add_draw_image(
290 discardable_image[y][x], gfx::Point(x * 512 + 6, y * 512 + 6),
291 flags);
292 }
293 }
294 }
295
296 scoped_refptr<DisplayItemList> display_list =
297 content_layer_client.PaintContentsToDisplayList(
298 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
299
300 DiscardableImageMap image_map;
301 {
302 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
303 visible_rect.size());
304 display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f);
305 }
306
307 for (int y = 0; y < 4; ++y) {
308 for (int x = 0; x < 4; ++x) {
309 std::vector<PositionScaleDrawImage> images = GetDiscardableImagesInRect(
310 image_map, gfx::Rect(x * 512 + 256, y * 512 + 256, 1, 1));
311 if ((x + y) & 1) {
312 EXPECT_EQ(1u, images.size()) << x << " " << y;
313 EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " "
314 << y;
315 EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500),
316 images[0].image_rect);
317 EXPECT_EQ(images[0].image_rect,
318 image_map.GetRectForImage(images[0].image->uniqueID()));
319 } else {
320 EXPECT_EQ(0u, images.size()) << x << " " << y;
321 }
322 }
323 }
324 }
325
326 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectMassiveImage) {
327 gfx::Rect visible_rect(2048, 2048);
328 FakeContentLayerClient content_layer_client;
329 content_layer_client.set_bounds(visible_rect.size());
330
331 sk_sp<SkImage> discardable_image =
332 CreateDiscardableImage(gfx::Size(1 << 25, 1 << 25));
333 PaintFlags flags;
334 content_layer_client.add_draw_image(discardable_image, gfx::Point(0, 0),
335 flags);
336
337 scoped_refptr<DisplayItemList> display_list =
338 content_layer_client.PaintContentsToDisplayList(
339 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
340
341 DiscardableImageMap image_map;
342 {
343 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
344 visible_rect.size());
345 display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f);
346 }
347 std::vector<PositionScaleDrawImage> images =
348 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1));
349 EXPECT_EQ(1u, images.size());
350 EXPECT_TRUE(images[0].image == discardable_image);
351 EXPECT_EQ(gfx::Rect(0, 0, 2048, 2048), images[0].image_rect);
352 EXPECT_EQ(images[0].image_rect,
353 image_map.GetRectForImage(images[0].image->uniqueID()));
354 }
355
356 TEST_F(DiscardableImageMapTest, PaintDestroyedWhileImageIsDrawn) {
357 gfx::Rect visible_rect(2048, 2048);
358 FakeContentLayerClient content_layer_client;
359 content_layer_client.set_bounds(visible_rect.size());
360
361 sk_sp<SkImage> discardable_image = CreateDiscardableImage(gfx::Size(10, 10));
362
363 DiscardableImageMap image_map;
364 {
365 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
366 visible_rect.size());
367 {
368 std::unique_ptr<SkPaint> paint(new SkPaint());
369 generator.canvas()->saveLayer(gfx::RectToSkRect(visible_rect),
370 paint.get());
371 }
372 generator.canvas()->drawImage(discardable_image, 0, 0, nullptr);
373 generator.canvas()->restore();
374 }
375
376 std::vector<PositionScaleDrawImage> images =
377 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1));
378 EXPECT_EQ(1u, images.size());
379 EXPECT_TRUE(images[0].image == discardable_image);
380 }
381
382 TEST_F(DiscardableImageMapTest, NullPaintOnSaveLayer) {
383 gfx::Rect visible_rect(2048, 2048);
384 FakeContentLayerClient content_layer_client;
385 content_layer_client.set_bounds(visible_rect.size());
386
387 sk_sp<SkImage> discardable_image = CreateDiscardableImage(gfx::Size(10, 10));
388
389 DiscardableImageMap image_map;
390 {
391 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
392 visible_rect.size());
393 SkPaint* null_paint = nullptr;
394 generator.canvas()->saveLayer(gfx::RectToSkRect(visible_rect), null_paint);
395 generator.canvas()->drawImage(discardable_image, 0, 0, nullptr);
396 generator.canvas()->restore();
397 }
398
399 std::vector<PositionScaleDrawImage> images =
400 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1));
401 EXPECT_EQ(1u, images.size());
402 EXPECT_TRUE(images[0].image == discardable_image);
403 }
404
405 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectMaxImage) {
406 gfx::Rect visible_rect(2048, 2048);
407 FakeContentLayerClient content_layer_client;
408 content_layer_client.set_bounds(visible_rect.size());
409
410 int dimension = std::numeric_limits<int>::max();
411 sk_sp<SkImage> discardable_image =
412 CreateDiscardableImage(gfx::Size(dimension, dimension));
413 PaintFlags flags;
414 content_layer_client.add_draw_image(discardable_image, gfx::Point(42, 42),
415 flags);
416
417 scoped_refptr<DisplayItemList> display_list =
418 content_layer_client.PaintContentsToDisplayList(
419 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
420
421 DiscardableImageMap image_map;
422 {
423 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
424 visible_rect.size());
425 display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f);
426 }
427 std::vector<PositionScaleDrawImage> images =
428 GetDiscardableImagesInRect(image_map, gfx::Rect(42, 42, 1, 1));
429 EXPECT_EQ(1u, images.size());
430 EXPECT_TRUE(images[0].image == discardable_image);
431 EXPECT_EQ(gfx::Rect(42, 42, 2006, 2006), images[0].image_rect);
432 EXPECT_EQ(images[0].image_rect,
433 image_map.GetRectForImage(images[0].image->uniqueID()));
434 }
435
436 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInRectMaxImageMaxLayer) {
437 // At large values of integer x, x != static_cast<int>(static_cast<float>(x)).
438 // So, make sure the dimension can be converted back and forth for the
439 // purposes of the unittest. Also, at near max int values, Skia seems to skip
440 // some draw calls, so we subtract 64 since we only care about "really large"
441 // values, not necessarily max int values.
442 int dimension = static_cast<int>(
443 static_cast<float>(std::numeric_limits<int>::max() - 64));
444 gfx::Rect visible_rect(dimension, dimension);
445 FakeContentLayerClient content_layer_client;
446 content_layer_client.set_bounds(visible_rect.size());
447
448 sk_sp<SkImage> discardable_image =
449 CreateDiscardableImage(gfx::Size(dimension, dimension));
450 PaintFlags flags;
451 content_layer_client.add_draw_image(discardable_image, gfx::Point(0, 0),
452 flags);
453 content_layer_client.add_draw_image(discardable_image, gfx::Point(10000, 0),
454 flags);
455 content_layer_client.add_draw_image(discardable_image,
456 gfx::Point(-10000, 500), flags);
457
458 scoped_refptr<DisplayItemList> display_list =
459 content_layer_client.PaintContentsToDisplayList(
460 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
461
462 DiscardableImageMap image_map;
463 {
464 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
465 visible_rect.size());
466 display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f);
467 }
468 std::vector<PositionScaleDrawImage> images =
469 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1));
470 EXPECT_EQ(1u, images.size());
471 EXPECT_EQ(gfx::Rect(0, 0, dimension, dimension), images[0].image_rect);
472
473 images = GetDiscardableImagesInRect(image_map, gfx::Rect(10000, 0, 1, 1));
474 EXPECT_EQ(2u, images.size());
475 EXPECT_EQ(gfx::Rect(10000, 0, dimension - 10000, dimension),
476 images[1].image_rect);
477 EXPECT_EQ(gfx::Rect(0, 0, dimension, dimension), images[0].image_rect);
478
479 // Since we adjust negative offsets before using ToEnclosingRect, the expected
480 // width will be converted to float, which means that we lose some precision.
481 // The expected value is whatever the value is converted to float and then
482 // back to int.
483 int expected10k = static_cast<int>(static_cast<float>(dimension - 10000));
484 images = GetDiscardableImagesInRect(image_map, gfx::Rect(0, 500, 1, 1));
485 EXPECT_EQ(2u, images.size());
486 EXPECT_EQ(gfx::Rect(0, 500, expected10k, dimension - 500),
487 images[1].image_rect);
488 EXPECT_EQ(gfx::Rect(0, 0, dimension, dimension), images[0].image_rect);
489
490 EXPECT_EQ(gfx::Rect(0, 0, dimension, dimension),
491 image_map.GetRectForImage(discardable_image->uniqueID()));
492 }
493
494 TEST_F(DiscardableImageMapTest, GetDiscardableImagesRectInBounds) {
495 gfx::Rect visible_rect(1000, 1000);
496 FakeContentLayerClient content_layer_client;
497 content_layer_client.set_bounds(visible_rect.size());
498
499 sk_sp<SkImage> discardable_image =
500 CreateDiscardableImage(gfx::Size(100, 100));
501 sk_sp<SkImage> long_discardable_image =
502 CreateDiscardableImage(gfx::Size(10000, 100));
503
504 PaintFlags flags;
505 content_layer_client.add_draw_image(discardable_image, gfx::Point(-10, -11),
506 flags);
507 content_layer_client.add_draw_image(discardable_image, gfx::Point(950, 951),
508 flags);
509 content_layer_client.add_draw_image(long_discardable_image,
510 gfx::Point(-100, 500), flags);
511
512 scoped_refptr<DisplayItemList> display_list =
513 content_layer_client.PaintContentsToDisplayList(
514 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
515
516 DiscardableImageMap image_map;
517 {
518 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
519 visible_rect.size());
520 display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f);
521 }
522 std::vector<PositionScaleDrawImage> images =
523 GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1));
524 EXPECT_EQ(1u, images.size());
525 EXPECT_EQ(gfx::Rect(0, 0, 90, 89), images[0].image_rect);
526
527 images = GetDiscardableImagesInRect(image_map, gfx::Rect(999, 999, 1, 1));
528 EXPECT_EQ(1u, images.size());
529 EXPECT_EQ(gfx::Rect(950, 951, 50, 49), images[0].image_rect);
530
531 images = GetDiscardableImagesInRect(image_map, gfx::Rect(0, 500, 1, 1));
532 EXPECT_EQ(1u, images.size());
533 EXPECT_EQ(gfx::Rect(0, 500, 1000, 100), images[0].image_rect);
534
535 gfx::Rect discardable_image_rect;
536 discardable_image_rect.Union(gfx::Rect(0, 0, 90, 89));
537 discardable_image_rect.Union(gfx::Rect(950, 951, 50, 49));
538 EXPECT_EQ(discardable_image_rect,
539 image_map.GetRectForImage(discardable_image->uniqueID()));
540
541 EXPECT_EQ(gfx::Rect(0, 500, 1000, 100),
542 image_map.GetRectForImage(long_discardable_image->uniqueID()));
543 }
544
545 TEST_F(DiscardableImageMapTest, GetDiscardableImagesInShader) {
546 gfx::Rect visible_rect(2048, 2048);
547 FakeContentLayerClient content_layer_client;
548 content_layer_client.set_bounds(visible_rect.size());
549
550 // Discardable pixel refs are found in the following grids:
551 // |---|---|---|---|
552 // | | x | | x |
553 // |---|---|---|---|
554 // | x | | x | |
555 // |---|---|---|---|
556 // | | x | | x |
557 // |---|---|---|---|
558 // | x | | x | |
559 // |---|---|---|---|
560 sk_sp<SkImage> discardable_image[4][4];
561
562 // Skia doesn't allow shader instantiation with non-invertible local
563 // transforms, so we can't let the scale drop all the way to 0.
564 static constexpr float kMinScale = 0.1f;
565
566 for (int y = 0; y < 4; ++y) {
567 for (int x = 0; x < 4; ++x) {
568 if ((x + y) & 1) {
569 discardable_image[y][x] = CreateDiscardableImage(gfx::Size(500, 500));
570 SkMatrix scale = SkMatrix::MakeScale(std::max(x * 0.5f, kMinScale),
571 std::max(y * 0.5f, kMinScale));
572 PaintFlags flags;
573 flags.setShader(discardable_image[y][x]->makeShader(
574 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &scale));
575 content_layer_client.add_draw_rect(
576 gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), flags);
577 }
578 }
579 }
580
581 scoped_refptr<DisplayItemList> display_list =
582 content_layer_client.PaintContentsToDisplayList(
583 ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
584
585 DiscardableImageMap image_map;
586 {
587 DiscardableImageMap::ScopedMetadataGenerator generator(&image_map,
588 visible_rect.size());
589 display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f);
590 }
591
592 for (int y = 0; y < 4; ++y) {
593 for (int x = 0; x < 4; ++x) {
594 std::vector<PositionScaleDrawImage> images = GetDiscardableImagesInRect(
595 image_map, gfx::Rect(x * 512, y * 512, 500, 500));
596 if ((x + y) & 1) {
597 EXPECT_EQ(1u, images.size()) << x << " " << y;
598 EXPECT_TRUE(images[0].image == discardable_image[y][x]) << x << " "
599 << y;
600 EXPECT_EQ(gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500),
601 images[0].image_rect);
602 EXPECT_EQ(std::max(x * 0.5f, kMinScale), images[0].scale.fWidth);
603 EXPECT_EQ(std::max(y * 0.5f, kMinScale), images[0].scale.fHeight);
604 } else {
605 EXPECT_EQ(0u, images.size()) << x << " " << y;
606 }
607 }
608 }
609
610 // Capture 4 pixel refs.
611 std::vector<PositionScaleDrawImage> images =
612 GetDiscardableImagesInRect(image_map, gfx::Rect(512, 512, 2048, 2048));
613 EXPECT_EQ(4u, images.size());
614 EXPECT_TRUE(images[0].image == discardable_image[1][2]);
615 EXPECT_EQ(gfx::Rect(2 * 512 + 6, 512 + 6, 500, 500), images[0].image_rect);
616 EXPECT_TRUE(images[1].image == discardable_image[2][1]);
617 EXPECT_EQ(gfx::Rect(512 + 6, 2 * 512 + 6, 500, 500), images[1].image_rect);
618 EXPECT_TRUE(images[2].image == discardable_image[2][3]);
619 EXPECT_EQ(gfx::Rect(3 * 512 + 6, 2 * 512 + 6, 500, 500),
620 images[2].image_rect);
621 EXPECT_TRUE(images[3].image == discardable_image[3][2]);
622 EXPECT_EQ(gfx::Rect(2 * 512 + 6, 3 * 512 + 6, 500, 500),
623 images[3].image_rect);
624 }
625
626 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698