1 // Copyright 2013 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.
8 #include "cc/resources/picture_pile.h"
9 #include "cc/test/fake_content_layer_client.h"
10 #include "cc/test/fake_picture_pile.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gfx/geometry/rect_conversions.h"
13 #include "ui/gfx/geometry/size_conversions.h"
18 class PicturePileTestBase
{
22 pile_(min_scale_
, gfx::Size(1000, 1000)),
25 void InitializeData() {
26 pile_
.SetTileGridSize(gfx::Size(1000, 1000));
27 pile_
.SetMinContentsScale(min_scale_
);
28 client_
= FakeContentLayerClient();
29 SetTilingSize(pile_
.tiling().max_texture_size());
32 void SetTilingSize(const gfx::Size
& tiling_size
) {
34 gfx::Rect
viewport_rect(tiling_size
);
35 UpdateAndExpandInvalidation(&invalidation
, tiling_size
, viewport_rect
);
38 gfx::Size
tiling_size() const { return pile_
.GetSize(); }
39 gfx::Rect
tiling_rect() const { return gfx::Rect(pile_
.GetSize()); }
41 bool UpdateAndExpandInvalidation(Region
* invalidation
,
42 const gfx::Size
& layer_size
,
43 const gfx::Rect
& visible_layer_rect
) {
45 return pile_
.UpdateAndExpandInvalidation(&client_
, invalidation
, layer_size
,
46 visible_layer_rect
, frame_number_
,
47 RecordingSource::RECORD_NORMALLY
);
50 bool UpdateWholePile() {
51 Region invalidation
= tiling_rect();
52 bool result
= UpdateAndExpandInvalidation(&invalidation
, tiling_size(),
54 EXPECT_EQ(tiling_rect().ToString(), invalidation
.ToString());
58 FakeContentLayerClient client_
;
60 FakePicturePile pile_
;
64 class PicturePileTest
: public PicturePileTestBase
, public testing::Test
{
66 void SetUp() override
{ InitializeData(); }
69 TEST_F(PicturePileTest
, InvalidationOnTileBorderOutsideInterestRect
) {
70 // Don't expand the interest rect past what we invalidate.
71 pile_
.SetPixelRecordDistance(0);
73 gfx::Size
tile_size(100, 100);
74 pile_
.tiling().SetMaxTextureSize(tile_size
);
76 gfx::Size
pile_size(400, 400);
77 SetTilingSize(pile_size
);
79 // We have multiple tiles.
80 EXPECT_GT(pile_
.tiling().num_tiles_x(), 2);
81 EXPECT_GT(pile_
.tiling().num_tiles_y(), 2);
84 Region
invalidation(tiling_rect());
85 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
87 // +----------+-----------------+-----------+
91 // | ...|.................|... |
92 // | ...|.................|... |
93 // +----------+-----------------+-----------+
99 // +----------+-----------------+-----------+
100 // | ...|.................|... |
101 // | ...|.................|... |
102 // +----------+-----------------+-----------+
104 // .. = border pixels for tile 1,1
105 // VV = interest rect (what we will record)
107 // The first invalidation is inside VV, so it does not touch border pixels of
110 // The second invalidation goes below VV into the .. border pixels of 1,1.
112 // This is the VV interest rect which will be entirely inside 1,0 and not
113 // touch the border of 1,1.
114 gfx::Rect
interest_rect(
115 pile_
.tiling().TilePositionX(1) + pile_
.tiling().border_texels(),
118 pile_
.tiling().TileSizeY(0) - pile_
.tiling().border_texels());
120 // Invalidate tile 1,0 only. This is a rect that avoids the borders of any
122 gfx::Rect invalidate_tile
= interest_rect
;
123 // This should cause the tile 1,0 to be invalidated and re-recorded. The
124 // invalidation did not need to be expanded.
125 invalidation
= invalidate_tile
;
126 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), interest_rect
);
127 EXPECT_EQ(invalidate_tile
, invalidation
);
129 // Invalidate tile 1,0 and 1,1 by invalidating something that only touches the
130 // border of 1,1 (and is inside the tile bounds of 1,0). This is a 10px wide
131 // strip from the top of the tiling onto the border pixels of tile 1,1 that
132 // avoids border pixels of any other tiles.
133 gfx::Rect invalidate_border
= interest_rect
;
134 invalidate_border
.Inset(0, 0, 0, -1);
135 // This should cause the tile 1,0 and 1,1 to be invalidated. The 1,1 tile will
136 // not be re-recorded since it does not touch the interest rect, so the
137 // invalidation should be expanded to cover all of 1,1.
138 invalidation
= invalidate_border
;
139 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), interest_rect
);
140 Region expected_invalidation
= invalidate_border
;
141 expected_invalidation
.Union(pile_
.tiling().TileBounds(1, 1));
142 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
145 TEST_F(PicturePileTest
, SmallInvalidateInflated
) {
146 // Invalidate something inside a tile.
147 Region
invalidate_rect(gfx::Rect(50, 50, 1, 1));
148 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
149 EXPECT_EQ(gfx::Rect(50, 50, 1, 1).ToString(), invalidate_rect
.ToString());
151 EXPECT_EQ(1, pile_
.tiling().num_tiles_x());
152 EXPECT_EQ(1, pile_
.tiling().num_tiles_y());
154 PicturePile::PictureMapKey key
= FakePicturePile::PictureMapKey(0, 0);
155 PicturePile::PictureMap::iterator it
= pile_
.picture_map().find(key
);
156 EXPECT_TRUE(it
!= pile_
.picture_map().end());
157 const Picture
* picture
= it
->second
.get();
158 EXPECT_TRUE(picture
);
160 gfx::Rect picture_rect
=
161 gfx::ScaleToEnclosedRect(picture
->LayerRect(), min_scale_
);
163 // The the picture should be large enough that scaling it never makes a rect
164 // smaller than 1 px wide or tall.
165 EXPECT_FALSE(picture_rect
.IsEmpty()) << "Picture rect "
166 << picture_rect
.ToString();
169 TEST_F(PicturePileTest
, LargeInvalidateInflated
) {
170 // Invalidate something inside a tile.
171 Region
invalidate_rect(gfx::Rect(50, 50, 100, 100));
172 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
173 EXPECT_EQ(gfx::Rect(50, 50, 100, 100).ToString(), invalidate_rect
.ToString());
175 EXPECT_EQ(1, pile_
.tiling().num_tiles_x());
176 EXPECT_EQ(1, pile_
.tiling().num_tiles_y());
178 PicturePile::PictureMapKey key
= FakePicturePile::PictureMapKey(0, 0);
179 PicturePile::PictureMap::iterator it
= pile_
.picture_map().find(key
);
180 EXPECT_TRUE(it
!= pile_
.picture_map().end());
181 const Picture
* picture
= it
->second
.get();
182 EXPECT_TRUE(picture
);
184 int expected_inflation
= pile_
.buffer_pixels();
186 gfx::Rect
base_picture_rect(tiling_size());
187 base_picture_rect
.Inset(-expected_inflation
, -expected_inflation
);
188 EXPECT_EQ(base_picture_rect
.ToString(), picture
->LayerRect().ToString());
191 TEST_F(PicturePileTest
, ClearingInvalidatesRecordedRect
) {
192 gfx::Rect
rect(0, 0, 5, 5);
193 EXPECT_TRUE(pile_
.CanRasterLayerRect(rect
));
194 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(rect
));
198 // Make sure both the cache-aware check (using recorded region) and the normal
199 // check are both false after clearing.
200 EXPECT_FALSE(pile_
.CanRasterLayerRect(rect
));
201 EXPECT_FALSE(pile_
.CanRasterSlowTileCheck(rect
));
204 TEST_F(PicturePileTest
, NoInvalidationValidViewport
) {
205 // This test validates that the recorded_viewport cache of full tiles
206 // is still valid for some use cases. If it's not, it's a performance
207 // issue because CanRaster checks will go down the slow path.
208 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
210 // No invalidation, same viewport.
212 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
213 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
214 EXPECT_EQ(Region().ToString(), invalidation
.ToString());
216 // Partial invalidation, same viewport.
217 invalidation
= gfx::Rect(0, 0, 1, 1);
218 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
219 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
220 EXPECT_EQ(gfx::Rect(0, 0, 1, 1).ToString(), invalidation
.ToString());
222 // No invalidation, changing viewport.
223 invalidation
= Region();
224 UpdateAndExpandInvalidation(&invalidation
, tiling_size(),
225 gfx::Rect(5, 5, 5, 5));
226 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
227 EXPECT_EQ(Region().ToString(), invalidation
.ToString());
230 TEST_F(PicturePileTest
, BigFullLayerInvalidation
) {
231 gfx::Size
huge_layer_size(100000000, 100000000);
232 gfx::Rect
viewport(300000, 400000, 5000, 6000);
236 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
238 // Invalidating a huge layer should be fast.
239 base::TimeTicks start
= base::TimeTicks::Now();
240 invalidation
= gfx::Rect(huge_layer_size
);
241 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
242 base::TimeTicks end
= base::TimeTicks::Now();
243 base::TimeDelta length
= end
- start
;
244 // This is verrrry generous to avoid flake.
245 EXPECT_LT(length
.InSeconds(), 5);
248 TEST_F(PicturePileTest
, BigFullLayerInvalidationWithResizeGrow
) {
249 gfx::Size
huge_layer_size(100000000, 100000000);
250 gfx::Rect
viewport(300000, 400000, 5000, 6000);
254 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
256 // Resize the pile even larger, while invalidating everything in the old size.
257 // Invalidating the whole thing should be fast.
258 base::TimeTicks start
= base::TimeTicks::Now();
259 gfx::Size
bigger_layer_size(huge_layer_size
.width() * 2,
260 huge_layer_size
.height() * 2);
261 invalidation
= gfx::Rect(huge_layer_size
);
262 UpdateAndExpandInvalidation(&invalidation
, bigger_layer_size
, viewport
);
263 base::TimeTicks end
= base::TimeTicks::Now();
264 base::TimeDelta length
= end
- start
;
265 // This is verrrry generous to avoid flake.
266 EXPECT_LT(length
.InSeconds(), 5);
269 TEST_F(PicturePileTest
, BigFullLayerInvalidationWithResizeShrink
) {
270 gfx::Size
huge_layer_size(100000000, 100000000);
271 gfx::Rect
viewport(300000, 400000, 5000, 6000);
275 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
277 // Resize the pile smaller, while invalidating everything in the new size.
278 // Invalidating the whole thing should be fast.
279 base::TimeTicks start
= base::TimeTicks::Now();
280 gfx::Size
smaller_layer_size(huge_layer_size
.width() - 1000,
281 huge_layer_size
.height() - 1000);
282 invalidation
= gfx::Rect(smaller_layer_size
);
283 UpdateAndExpandInvalidation(&invalidation
, smaller_layer_size
, viewport
);
284 base::TimeTicks end
= base::TimeTicks::Now();
285 base::TimeDelta length
= end
- start
;
286 // This is verrrry generous to avoid flake.
287 EXPECT_LT(length
.InSeconds(), 5);
290 TEST_F(PicturePileTest
, InvalidationOutsideRecordingRect
) {
291 gfx::Size
huge_layer_size(10000000, 20000000);
292 gfx::Rect
viewport(300000, 400000, 5000, 6000);
294 // Resize the pile and set up the interest rect.
296 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
298 // Invalidation inside the recording rect does not need to be expanded.
299 invalidation
= viewport
;
300 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
301 EXPECT_EQ(viewport
.ToString(), invalidation
.ToString());
303 // Invalidation outside the recording rect should expand to the tiles it
305 gfx::Rect recorded_over_tiles
=
306 pile_
.tiling().ExpandRectToTileBounds(pile_
.recorded_viewport());
307 gfx::Rect
invalidation_outside(
308 recorded_over_tiles
.right(), recorded_over_tiles
.y(), 30, 30);
309 invalidation
= invalidation_outside
;
310 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
311 gfx::Rect expanded_recorded_viewport
=
312 pile_
.tiling().ExpandRectToTileBounds(pile_
.recorded_viewport());
313 Region expected_invalidation
=
314 pile_
.tiling().ExpandRectToTileBounds(invalidation_outside
);
315 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
325 class PicturePileResizeCornerTest
: public PicturePileTestBase
,
326 public testing::TestWithParam
<Corner
> {
328 void SetUp() override
{ InitializeData(); }
330 static gfx::Rect
CornerSinglePixelRect(Corner corner
, const gfx::Size
& s
) {
333 return gfx::Rect(0, 0, 1, 1);
335 return gfx::Rect(s
.width() - 1, 0, 1, 1);
337 return gfx::Rect(0, s
.height() - 1, 1, 1);
339 return gfx::Rect(s
.width() - 1, s
.height() - 1, 1, 1);
346 TEST_P(PicturePileResizeCornerTest
, ResizePileOutsideInterestRect
) {
347 Corner corner
= GetParam();
349 // This size chosen to be larger than the interest rect size, which is
350 // at least kPixelDistanceToRecord * 2 in each dimension.
351 int tile_size
= 100000;
352 // The small number subtracted keeps the last tile in each axis larger than
353 // the interest rect also.
355 gfx::Size
base_tiling_size(6 * tile_size
+ offset
, 6 * tile_size
+ offset
);
356 gfx::Size
grow_down_tiling_size(6 * tile_size
+ offset
,
357 8 * tile_size
+ offset
);
358 gfx::Size
grow_right_tiling_size(8 * tile_size
+ offset
,
359 6 * tile_size
+ offset
);
360 gfx::Size
grow_both_tiling_size(8 * tile_size
+ offset
,
361 8 * tile_size
+ offset
);
364 Region expected_invalidation
;
366 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
367 SetTilingSize(base_tiling_size
);
369 // We should have a recording for every tile.
370 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
371 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
372 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
373 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
374 FakePicturePile::PictureMapKey
key(i
, j
);
375 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
376 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
377 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
381 UpdateAndExpandInvalidation(
383 grow_down_tiling_size
,
384 CornerSinglePixelRect(corner
, grow_down_tiling_size
));
386 // We should have lost all of the recordings in the bottom row as none of them
387 // are in the current interest rect (which is either the above or below it).
388 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
389 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
390 for (int i
= 0; i
< 6; ++i
) {
391 for (int j
= 0; j
< 6; ++j
) {
392 FakePicturePile::PictureMapKey
key(i
, j
);
393 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
394 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
395 EXPECT_EQ(j
< 5, it
!= map
.end() && it
->second
.get());
399 // We invalidated all new pixels in the recording.
400 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
401 gfx::Rect(base_tiling_size
));
402 // But the new pixels don't cover the whole bottom row.
403 gfx::Rect bottom_row
= gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
404 pile_
.tiling().TileBounds(5, 5));
405 EXPECT_FALSE(expected_invalidation
.Contains(bottom_row
));
406 // We invalidated the entire old bottom row.
407 expected_invalidation
.Union(bottom_row
);
408 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
409 invalidation
.Clear();
412 UpdateAndExpandInvalidation(&invalidation
,
414 CornerSinglePixelRect(corner
, base_tiling_size
));
416 // When shrinking, we should have lost all the recordings in the bottom row
417 // not touching the interest rect.
418 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
419 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
420 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
421 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
422 FakePicturePile::PictureMapKey
key(i
, j
);
423 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
424 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
432 // The interest rect in the bottom left tile means we'll record it.
433 expect_tile
= j
< 5 || (j
== 5 && i
== 0);
436 // The interest rect in the bottom right tile means we'll record it.
437 expect_tile
= j
< 5 || (j
== 5 && i
== 5);
440 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.get());
444 // When shrinking, the previously exposed region is invalidated.
445 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
446 gfx::Rect(base_tiling_size
));
447 // The whole bottom row of tiles (except any with the interest rect) are
449 gfx::Rect bottom_row_minus_existing_corner
= gfx::UnionRects(
450 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(5, 5));
454 // No tiles are kept in the changed region because it doesn't
455 // intersect with the interest rect.
458 bottom_row_minus_existing_corner
.Subtract(
459 pile_
.tiling().TileBounds(0, 5));
462 bottom_row_minus_existing_corner
.Subtract(
463 pile_
.tiling().TileBounds(5, 5));
467 expected_invalidation
.Union(bottom_row_minus_existing_corner
);
468 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
469 invalidation
.Clear();
472 UpdateAndExpandInvalidation(
474 grow_right_tiling_size
,
475 CornerSinglePixelRect(corner
, grow_right_tiling_size
));
477 // We should have lost all of the recordings in the right column as none of
478 // them are in the current interest rect (which is either entirely left or
480 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
481 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
482 for (int i
= 0; i
< 6; ++i
) {
483 for (int j
= 0; j
< 6; ++j
) {
484 FakePicturePile::PictureMapKey
key(i
, j
);
485 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
486 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
487 EXPECT_EQ(i
< 5, it
!= map
.end() && it
->second
.get());
491 // We invalidated all new pixels in the recording.
492 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
493 gfx::Rect(base_tiling_size
));
494 // But the new pixels don't cover the whole right_column.
495 gfx::Rect right_column
= gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
496 pile_
.tiling().TileBounds(5, 5));
497 EXPECT_FALSE(expected_invalidation
.Contains(right_column
));
498 // We invalidated the entire old right column.
499 expected_invalidation
.Union(right_column
);
500 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
501 invalidation
.Clear();
504 UpdateAndExpandInvalidation(&invalidation
,
506 CornerSinglePixelRect(corner
, base_tiling_size
));
508 // When shrinking, we should have lost all the recordings in the right column
509 // not touching the interest rect.
510 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
511 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
512 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
513 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
514 FakePicturePile::PictureMapKey
key(i
, j
);
515 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
516 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
521 // No tiles are kept in the changed region because it doesn't
522 // intersect with the interest rect.
526 // The interest rect in the top right tile means we'll record it.
527 expect_tile
= i
< 5 || (j
== 0 && i
== 5);
530 // The interest rect in the bottom right tile means we'll record it.
531 expect_tile
= i
< 5 || (j
== 5 && i
== 5);
534 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.get());
538 // When shrinking, the previously exposed region is invalidated.
539 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
540 gfx::Rect(base_tiling_size
));
541 // The whole right column of tiles (except for ones with the interest rect)
543 gfx::Rect right_column_minus_existing_corner
= gfx::UnionRects(
544 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
550 right_column_minus_existing_corner
.Subtract(
551 pile_
.tiling().TileBounds(5, 0));
554 right_column_minus_existing_corner
.Subtract(
555 pile_
.tiling().TileBounds(5, 5));
558 expected_invalidation
.Union(right_column_minus_existing_corner
);
559 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
560 invalidation
.Clear();
563 UpdateAndExpandInvalidation(
565 grow_both_tiling_size
,
566 CornerSinglePixelRect(corner
, grow_both_tiling_size
));
568 // We should have lost the recordings in the right column and bottom row.
569 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
570 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
571 for (int i
= 0; i
< 6; ++i
) {
572 for (int j
= 0; j
< 6; ++j
) {
573 FakePicturePile::PictureMapKey
key(i
, j
);
574 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
575 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
576 EXPECT_EQ(i
< 5 && j
< 5, it
!= map
.end() && it
->second
.get());
580 // We invalidated all new pixels in the recording.
581 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
582 gfx::Rect(base_tiling_size
));
583 // But the new pixels don't cover the whole right column or bottom row.
584 Region right_column_and_bottom_row
=
585 UnionRegions(gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
586 pile_
.tiling().TileBounds(5, 5)),
587 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
588 pile_
.tiling().TileBounds(5, 5)));
589 EXPECT_FALSE(expected_invalidation
.Contains(right_column_and_bottom_row
));
590 // We invalidated the entire old right column and the old bottom row.
591 expected_invalidation
.Union(right_column_and_bottom_row
);
592 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
593 invalidation
.Clear();
596 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
,
597 CornerSinglePixelRect(corner
, base_tiling_size
));
599 // We should have lost the recordings in the right column and bottom row,
600 // except where it intersects the interest rect.
601 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
602 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
603 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
604 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
605 FakePicturePile::PictureMapKey
key(i
, j
);
606 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
607 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
611 expect_tile
= i
< 5 && j
< 5;
614 // The interest rect in the top right tile means we'll record it.
615 expect_tile
= (i
< 5 && j
< 5) || (j
== 0 && i
== 5);
618 // The interest rect in the bottom left tile means we'll record it.
619 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 0);
622 // The interest rect in the bottom right tile means we'll record it.
623 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 5);
626 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.get()) << i
<< ","
631 // We invalidated all previous pixels in the recording.
632 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
633 gfx::Rect(base_tiling_size
));
634 // The whole right column and bottom row of tiles (except for ones with the
635 // interest rect) are dropped.
636 Region right_column_and_bottom_row_minus_existing_corner
=
637 right_column_and_bottom_row
;
642 right_column_and_bottom_row_minus_existing_corner
.Subtract(
643 pile_
.tiling().TileBounds(0, 5));
646 right_column_and_bottom_row_minus_existing_corner
.Subtract(
647 pile_
.tiling().TileBounds(5, 0));
650 right_column_and_bottom_row_minus_existing_corner
.Subtract(
651 pile_
.tiling().TileBounds(5, 5));
654 expected_invalidation
.Union(
655 right_column_and_bottom_row_minus_existing_corner
);
656 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
657 invalidation
.Clear();
660 TEST_P(PicturePileResizeCornerTest
, SmallResizePileOutsideInterestRect
) {
661 Corner corner
= GetParam();
663 // This size chosen to be larger than the interest rect size, which is
664 // at least kPixelDistanceToRecord * 2 in each dimension.
665 int tile_size
= 100000;
666 // The small number subtracted keeps the last tile in each axis larger than
667 // the interest rect also.
669 gfx::Size
base_tiling_size(6 * tile_size
+ offset
, 6 * tile_size
+ offset
);
670 gfx::Size
grow_down_tiling_size(6 * tile_size
+ offset
,
671 6 * tile_size
+ offset
+ 5);
672 gfx::Size
grow_right_tiling_size(6 * tile_size
+ offset
+ 5,
673 6 * tile_size
+ offset
);
674 gfx::Size
grow_both_tiling_size(6 * tile_size
+ offset
+ 5,
675 6 * tile_size
+ offset
+ 5);
678 Region expected_invalidation
;
680 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
681 SetTilingSize(base_tiling_size
);
683 // We should have a recording for every tile.
684 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
685 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
686 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
687 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
688 FakePicturePile::PictureMapKey
key(i
, j
);
689 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
690 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
691 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
695 // In this test (unlike the large resize test), as all growing and shrinking
696 // happens within tiles, the resulting invalidation is symmetrical, so use
697 // this enum to repeat the test both ways.
698 enum ChangeDirection
{ GROW
, SHRINK
, LAST_DIRECTION
= SHRINK
};
701 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
702 gfx::Size new_tiling_size
=
703 dir
== GROW
? grow_down_tiling_size
: base_tiling_size
;
705 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
706 CornerSinglePixelRect(corner
, new_tiling_size
));
708 // We should have lost the recordings in the bottom row that do not
709 // intersect the interest rect.
710 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
711 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
712 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
713 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
714 FakePicturePile::PictureMapKey
key(i
, j
);
715 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
716 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
724 // The interest rect in the bottom left tile means we'll record it.
725 expect_tile
= j
< 5 || (j
== 5 && i
== 0);
728 // The interest rect in the bottom right tile means we'll record it.
729 expect_tile
= j
< 5 || (j
== 5 && i
== 5);
732 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.get());
736 // We invalidated the bottom row outside the new interest rect. The tile
737 // that insects the interest rect in invalidated only on its newly
738 // exposed or previously exposed pixels.
740 // Only calculate the expected invalidation while growing, as the tile
741 // bounds post-growing is the newly exposed / previously exposed sizes.
742 // Post-shrinking, the tile bounds are smaller, so can't be used.
746 expected_invalidation
= gfx::UnionRects(
747 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(5, 5));
750 expected_invalidation
= gfx::UnionRects(
751 pile_
.tiling().TileBounds(1, 5), pile_
.tiling().TileBounds(5, 5));
752 expected_invalidation
.Union(SubtractRects(
753 pile_
.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size
)));
756 expected_invalidation
= gfx::UnionRects(
757 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(4, 5));
758 expected_invalidation
.Union(SubtractRects(
759 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
763 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
764 invalidation
.Clear();
768 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
769 gfx::Size new_tiling_size
=
770 dir
== GROW
? grow_right_tiling_size
: base_tiling_size
;
772 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
773 CornerSinglePixelRect(corner
, new_tiling_size
));
775 // We should have lost the recordings in the right column.
776 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
777 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
778 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
779 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
780 FakePicturePile::PictureMapKey
key(i
, j
);
781 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
782 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
790 // The interest rect in the top right tile means we'll record it.
791 expect_tile
= i
< 5 || (j
== 0 && i
== 5);
794 // The interest rect in the bottom right tile means we'll record it.
795 expect_tile
= i
< 5 || (j
== 5 && i
== 5);
798 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.get());
802 // We invalidated the right column outside the new interest rect. The tile
803 // that insects the interest rect in invalidated only on its new or
804 // previously exposed pixels.
806 // Calculate the expected invalidation the first time through the loop.
810 expected_invalidation
= gfx::UnionRects(
811 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
814 expected_invalidation
= gfx::UnionRects(
815 pile_
.tiling().TileBounds(5, 1), pile_
.tiling().TileBounds(5, 5));
816 expected_invalidation
.Union(SubtractRects(
817 pile_
.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size
)));
820 expected_invalidation
= gfx::UnionRects(
821 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 4));
822 expected_invalidation
.Union(SubtractRects(
823 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
827 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
828 invalidation
.Clear();
832 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
833 gfx::Size new_tiling_size
=
834 dir
== GROW
? grow_both_tiling_size
: base_tiling_size
;
836 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
837 CornerSinglePixelRect(corner
, new_tiling_size
));
839 // We should have lost the recordings in the right column and bottom row.
840 // The tile that insects the interest rect in invalidated only on its new
841 // or previously exposed pixels.
842 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
843 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
844 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
845 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
846 FakePicturePile::PictureMapKey
key(i
, j
);
847 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
848 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
852 expect_tile
= i
< 5 && j
< 5;
855 // The interest rect in the top right tile means we'll record it.
856 expect_tile
= (i
< 5 && j
< 5) || (j
== 0 && i
== 5);
859 // The interest rect in the bottom left tile means we'll record it.
860 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 0);
863 // The interest rect in the bottom right tile means we'll record it.
864 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 5);
867 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.get()) << i
<< ","
872 // We invalidated the right column and the bottom row outside the new
873 // interest rect. The tile that insects the interest rect in invalidated
874 // only on its new or previous exposed pixels.
876 // Calculate the expected invalidation the first time through the loop.
879 expected_invalidation
= gfx::UnionRects(
880 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
881 expected_invalidation
.Union(
882 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
883 pile_
.tiling().TileBounds(5, 5)));
886 expected_invalidation
= gfx::UnionRects(
887 pile_
.tiling().TileBounds(5, 1), pile_
.tiling().TileBounds(5, 5));
888 expected_invalidation
.Union(
889 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
890 pile_
.tiling().TileBounds(5, 5)));
891 expected_invalidation
.Union(SubtractRects(
892 pile_
.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size
)));
895 expected_invalidation
= gfx::UnionRects(
896 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
897 expected_invalidation
.Union(
898 gfx::UnionRects(pile_
.tiling().TileBounds(1, 5),
899 pile_
.tiling().TileBounds(5, 5)));
900 expected_invalidation
.Union(SubtractRects(
901 pile_
.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size
)));
904 expected_invalidation
= gfx::UnionRects(
905 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 4));
906 expected_invalidation
.Union(
907 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
908 pile_
.tiling().TileBounds(4, 5)));
909 expected_invalidation
.Union(SubtractRegions(
910 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
914 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
915 invalidation
.Clear();
919 INSTANTIATE_TEST_CASE_P(
920 PicturePileResizeCornerTests
,
921 PicturePileResizeCornerTest
,
922 ::testing::Values(TOP_LEFT
, TOP_RIGHT
, BOTTOM_LEFT
, BOTTOM_RIGHT
));
924 TEST_F(PicturePileTest
, ResizePileInsideInterestRect
) {
925 // This size chosen to be small enough that all the rects below fit inside the
926 // the interest rect, so they are smaller than kPixelDistanceToRecord in each
929 gfx::Size
base_tiling_size(5 * tile_size
, 5 * tile_size
);
930 gfx::Size
grow_down_tiling_size(5 * tile_size
, 7 * tile_size
);
931 gfx::Size
grow_right_tiling_size(7 * tile_size
, 5 * tile_size
);
932 gfx::Size
grow_both_tiling_size(7 * tile_size
, 7 * tile_size
);
935 Region expected_invalidation
;
937 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
938 SetTilingSize(base_tiling_size
);
940 // We should have a recording for every tile.
941 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
942 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
943 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
944 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
945 FakePicturePile::PictureMapKey
key(i
, j
);
946 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
947 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
948 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
952 UpdateAndExpandInvalidation(
953 &invalidation
, grow_down_tiling_size
, gfx::Rect(1, 1));
955 // We should have a recording for every tile.
956 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
957 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
958 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
959 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
960 FakePicturePile::PictureMapKey
key(i
, j
);
961 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
962 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
963 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
967 // We invalidated the newly exposed pixels on the bottom row of tiles.
968 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
969 gfx::Rect(base_tiling_size
));
970 Region bottom_row_new_pixels
=
971 SubtractRegions(gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
972 pile_
.tiling().TileBounds(5, 5)),
973 gfx::Rect(base_tiling_size
));
974 EXPECT_TRUE(expected_invalidation
.Contains(bottom_row_new_pixels
));
975 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
976 invalidation
.Clear();
979 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
981 // We should have a recording for every tile.
982 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
983 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
984 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
985 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
986 FakePicturePile::PictureMapKey
key(i
, j
);
987 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
988 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
989 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
993 // We invalidated the previously exposed pixels on the bottom row of tiles.
994 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
995 gfx::Rect(base_tiling_size
));
996 EXPECT_TRUE(expected_invalidation
.Contains(bottom_row_new_pixels
));
997 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
998 invalidation
.Clear();
1001 UpdateAndExpandInvalidation(
1002 &invalidation
, grow_right_tiling_size
, gfx::Rect(1, 1));
1004 // We should have a recording for every tile.
1005 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
1006 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1007 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1008 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1009 FakePicturePile::PictureMapKey
key(i
, j
);
1010 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1011 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1012 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1016 // We invalidated the newly exposed pixels on the right column of tiles.
1017 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1018 gfx::Rect(base_tiling_size
));
1019 Region right_column_new_pixels
=
1020 SubtractRegions(gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
1021 pile_
.tiling().TileBounds(5, 5)),
1022 gfx::Rect(base_tiling_size
));
1023 EXPECT_TRUE(expected_invalidation
.Contains(right_column_new_pixels
));
1024 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1025 invalidation
.Clear();
1028 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1030 // We should have lost the recordings that are now outside the tiling only.
1031 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1032 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1033 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1034 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1035 FakePicturePile::PictureMapKey
key(i
, j
);
1036 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1037 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1038 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1042 // We invalidated the previously exposed pixels on the right column of tiles.
1043 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1044 gfx::Rect(base_tiling_size
));
1045 EXPECT_TRUE(expected_invalidation
.Contains(right_column_new_pixels
));
1046 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1047 invalidation
.Clear();
1050 UpdateAndExpandInvalidation(
1051 &invalidation
, grow_both_tiling_size
, gfx::Rect(1, 1));
1053 // We should have a recording for every tile.
1054 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
1055 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
1056 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1057 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1058 FakePicturePile::PictureMapKey
key(i
, j
);
1059 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1060 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1061 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1065 // We invalidated the newly exposed pixels on the bottom row and right column
1067 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1068 gfx::Rect(base_tiling_size
));
1069 Region bottom_row_and_right_column_new_pixels
= SubtractRegions(
1070 UnionRegions(gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1071 pile_
.tiling().TileBounds(5, 5)),
1072 gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
1073 pile_
.tiling().TileBounds(5, 5))),
1074 gfx::Rect(base_tiling_size
));
1076 expected_invalidation
.Contains(bottom_row_and_right_column_new_pixels
));
1077 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1078 invalidation
.Clear();
1081 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect());
1083 // We should have lost the recordings that are now outside the tiling only.
1084 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1085 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1086 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1087 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1088 FakePicturePile::PictureMapKey
key(i
, j
);
1089 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1090 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1091 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1095 // We invalidated the previously exposed pixels on the bottom row and right
1097 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1098 gfx::Rect(base_tiling_size
));
1100 expected_invalidation
.Contains(bottom_row_and_right_column_new_pixels
));
1101 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1102 invalidation
.Clear();
1105 TEST_F(PicturePileTest
, SmallResizePileInsideInterestRect
) {
1106 // This size chosen to be small enough that all the rects below fit inside the
1107 // the interest rect, so they are smaller than kPixelDistanceToRecord in each
1109 int tile_size
= 100;
1110 gfx::Size
base_tiling_size(5 * tile_size
, 5 * tile_size
);
1111 gfx::Size
grow_down_tiling_size(5 * tile_size
, 5 * tile_size
+ 5);
1112 gfx::Size
grow_right_tiling_size(5 * tile_size
+ 5, 5 * tile_size
);
1113 gfx::Size
grow_both_tiling_size(5 * tile_size
+ 5, 5 * tile_size
+ 5);
1115 Region invalidation
;
1116 Region expected_invalidation
;
1118 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
1119 SetTilingSize(base_tiling_size
);
1121 // We should have a recording for every tile.
1122 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1123 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1124 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1125 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1126 FakePicturePile::PictureMapKey
key(i
, j
);
1127 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1128 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1129 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1133 UpdateAndExpandInvalidation(
1134 &invalidation
, grow_down_tiling_size
, gfx::Rect(1, 1));
1136 // We should have a recording for every tile.
1137 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1138 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1139 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1140 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1141 FakePicturePile::PictureMapKey
key(i
, j
);
1142 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1143 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1144 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1148 // We invalidated the newly exposed pixels.
1149 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1150 gfx::Rect(base_tiling_size
));
1151 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1152 invalidation
.Clear();
1155 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1157 // We should have a recording for every tile.
1158 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1159 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1160 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1161 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1162 FakePicturePile::PictureMapKey
key(i
, j
);
1163 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1164 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1165 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1169 // We invalidated the previously exposed pixels.
1170 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1171 gfx::Rect(base_tiling_size
));
1172 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1173 invalidation
.Clear();
1176 UpdateAndExpandInvalidation(
1177 &invalidation
, grow_right_tiling_size
, gfx::Rect(1, 1));
1179 // We should have a recording for every tile.
1180 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1181 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1182 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1183 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1184 FakePicturePile::PictureMapKey
key(i
, j
);
1185 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1186 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1187 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1191 // We invalidated the newly exposed pixels.
1192 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1193 gfx::Rect(base_tiling_size
));
1194 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1195 invalidation
.Clear();
1198 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1200 // We should have lost the recordings that are now outside the tiling only.
1201 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1202 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1203 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1204 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1205 FakePicturePile::PictureMapKey
key(i
, j
);
1206 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1207 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1208 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1212 // We invalidated the previously exposed pixels.
1213 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1214 gfx::Rect(base_tiling_size
));
1215 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1216 invalidation
.Clear();
1219 UpdateAndExpandInvalidation(
1220 &invalidation
, grow_both_tiling_size
, gfx::Rect(1, 1));
1222 // We should have a recording for every tile.
1223 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1224 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1225 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1226 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1227 FakePicturePile::PictureMapKey
key(i
, j
);
1228 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1229 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1230 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1234 // We invalidated the newly exposed pixels.
1235 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1236 gfx::Rect(base_tiling_size
));
1237 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1238 invalidation
.Clear();
1241 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect());
1243 // We should have lost the recordings that are now outside the tiling only.
1244 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1245 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1246 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1247 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1248 FakePicturePile::PictureMapKey
key(i
, j
);
1249 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1250 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1251 EXPECT_TRUE(it
!= map
.end() && it
->second
.get());
1255 // We invalidated the previously exposed pixels.
1256 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1257 gfx::Rect(base_tiling_size
));
1258 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1259 invalidation
.Clear();
1262 TEST_F(PicturePileTest
, SolidRectangleIsSolid
) {
1263 // If the client has no contents, the solid state will be true.
1264 Region
invalidation1(tiling_rect());
1265 UpdateAndExpandInvalidation(&invalidation1
, tiling_size(), tiling_rect());
1266 EXPECT_TRUE(pile_
.is_solid_color());
1267 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), pile_
.solid_color());
1269 // If there is a single rect that covers the view, the solid
1270 // state will be true.
1272 paint
.setColor(SK_ColorCYAN
);
1273 client_
.add_draw_rect(tiling_rect(), paint
);
1274 Region
invalidation2(tiling_rect());
1275 UpdateAndExpandInvalidation(&invalidation2
, tiling_size(), tiling_rect());
1276 EXPECT_TRUE(pile_
.is_solid_color());
1277 EXPECT_EQ(SK_ColorCYAN
, pile_
.solid_color());
1279 // If a second smaller rect is draw that doesn't cover the viewport
1280 // completely, the solid state will be false.
1281 gfx::Rect smallRect
= tiling_rect();
1282 smallRect
.Inset(10, 10, 10, 10);
1283 client_
.add_draw_rect(smallRect
, paint
);
1284 Region
invalidation3(tiling_rect());
1285 UpdateAndExpandInvalidation(&invalidation3
, tiling_size(), tiling_rect());
1286 EXPECT_FALSE(pile_
.is_solid_color());
1288 // If a third rect is drawn over everything, we should be solid again.
1289 paint
.setColor(SK_ColorRED
);
1290 client_
.add_draw_rect(tiling_rect(), paint
);
1291 Region
invalidation4(tiling_rect());
1292 UpdateAndExpandInvalidation(&invalidation4
, tiling_size(), tiling_rect());
1293 EXPECT_TRUE(pile_
.is_solid_color());
1294 EXPECT_EQ(SK_ColorRED
, pile_
.solid_color());
1296 // If we draw too many, we don't bother doing the analysis and we should no
1297 // longer be in a solid state. There are 8 rects, two clips and a translate.
1298 client_
.add_draw_rect(tiling_rect(), paint
);
1299 client_
.add_draw_rect(tiling_rect(), paint
);
1300 client_
.add_draw_rect(tiling_rect(), paint
);
1301 client_
.add_draw_rect(tiling_rect(), paint
);
1302 client_
.add_draw_rect(tiling_rect(), paint
);
1303 Region
invalidation5(tiling_rect());
1304 UpdateAndExpandInvalidation(&invalidation5
, tiling_size(), tiling_rect());
1305 EXPECT_FALSE(pile_
.is_solid_color());
1308 TEST_F(PicturePileTest
, NonSolidRectangleOnOffsettedLayerIsNonSolid
) {
1309 gfx::Rect
visible_rect(tiling_rect());
1310 visible_rect
.Offset(gfx::Vector2d(1000, 1000));
1311 // The picture pile requires that the tiling completely encompass the viewport
1312 // to make this test work correctly since the recorded viewport is an
1313 // intersection of the tile size and viewport rect. This is possibly a flaw
1314 // in |PicturePile|.
1315 gfx::Size
tiling_size(visible_rect
.right(), visible_rect
.bottom());
1316 // |Setup()| will create pictures here that mess with the test, clear it!
1320 paint
.setColor(SK_ColorCYAN
);
1322 // Add a rect that doesn't cover the viewport completely, the solid state
1324 gfx::Rect smallRect
= visible_rect
;
1325 smallRect
.Inset(10, 10, 10, 10);
1326 client_
.add_draw_rect(smallRect
, paint
);
1327 Region
invalidation(visible_rect
);
1328 UpdateAndExpandInvalidation(&invalidation
, tiling_size
, visible_rect
);
1329 EXPECT_FALSE(pile_
.is_solid_color());
1332 TEST_F(PicturePileTest
, SetEmptyBounds
) {
1333 EXPECT_TRUE(pile_
.is_solid_color());
1334 EXPECT_FALSE(pile_
.GetSize().IsEmpty());
1335 EXPECT_FALSE(pile_
.picture_map().empty());
1336 EXPECT_TRUE(pile_
.HasRecordings());
1337 pile_
.SetEmptyBounds();
1338 EXPECT_FALSE(pile_
.is_solid_color());
1339 EXPECT_TRUE(pile_
.GetSize().IsEmpty());
1340 EXPECT_TRUE(pile_
.picture_map().empty());
1341 EXPECT_FALSE(pile_
.HasRecordings());