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

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

Powered by Google App Engine
This is Rietveld 408576698