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
{
20 PicturePileTestBase() : min_scale_(0.125), frame_number_(0) {}
22 void InitializeData() {
23 pile_
.SetTileGridSize(gfx::Size(1000, 1000));
24 pile_
.SetMinContentsScale(min_scale_
);
25 client_
= FakeContentLayerClient();
26 SetTilingSize(pile_
.tiling().max_texture_size());
29 void SetTilingSize(const gfx::Size
& tiling_size
) {
31 gfx::Rect
viewport_rect(tiling_size
);
32 UpdateAndExpandInvalidation(&invalidation
, tiling_size
, viewport_rect
);
35 gfx::Size
tiling_size() const { return pile_
.GetSize(); }
36 gfx::Rect
tiling_rect() const { return gfx::Rect(pile_
.GetSize()); }
38 bool UpdateAndExpandInvalidation(Region
* invalidation
,
39 const gfx::Size
& layer_size
,
40 const gfx::Rect
& visible_layer_rect
) {
42 return pile_
.UpdateAndExpandInvalidation(
43 &client_
, invalidation
, false, layer_size
, visible_layer_rect
,
44 frame_number_
, Picture::RECORD_NORMALLY
);
47 bool UpdateWholePile() {
48 Region invalidation
= tiling_rect();
49 bool result
= UpdateAndExpandInvalidation(&invalidation
, tiling_size(),
51 EXPECT_EQ(tiling_rect().ToString(), invalidation
.ToString());
55 FakeContentLayerClient client_
;
56 FakePicturePile pile_
;
61 class PicturePileTest
: public PicturePileTestBase
, public testing::Test
{
63 void SetUp() override
{ InitializeData(); }
66 TEST_F(PicturePileTest
, InvalidationOnTileBorderOutsideInterestRect
) {
67 // Don't expand the interest rect past what we invalidate.
68 pile_
.SetPixelRecordDistance(0);
70 gfx::Size
tile_size(100, 100);
71 pile_
.tiling().SetMaxTextureSize(tile_size
);
73 gfx::Size
pile_size(400, 400);
74 SetTilingSize(pile_size
);
76 // We have multiple tiles.
77 EXPECT_GT(pile_
.tiling().num_tiles_x(), 2);
78 EXPECT_GT(pile_
.tiling().num_tiles_y(), 2);
81 Region
invalidation(tiling_rect());
82 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
84 // +----------+-----------------+-----------+
88 // | ...|.................|... |
89 // | ...|.................|... |
90 // +----------+-----------------+-----------+
96 // +----------+-----------------+-----------+
97 // | ...|.................|... |
98 // | ...|.................|... |
99 // +----------+-----------------+-----------+
101 // .. = border pixels for tile 1,1
102 // VV = interest rect (what we will record)
104 // The first invalidation is inside VV, so it does not touch border pixels of
107 // The second invalidation goes below VV into the .. border pixels of 1,1.
109 // This is the VV interest rect which will be entirely inside 1,0 and not
110 // touch the border of 1,1.
111 gfx::Rect
interest_rect(
112 pile_
.tiling().TilePositionX(1) + pile_
.tiling().border_texels(),
115 pile_
.tiling().TileSizeY(0) - pile_
.tiling().border_texels());
117 // Invalidate tile 1,0 only. This is a rect that avoids the borders of any
119 gfx::Rect invalidate_tile
= interest_rect
;
120 // This should cause the tile 1,0 to be invalidated and re-recorded. The
121 // invalidation did not need to be expanded.
122 invalidation
= invalidate_tile
;
123 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), interest_rect
);
124 EXPECT_EQ(invalidate_tile
, invalidation
);
126 // Invalidate tile 1,0 and 1,1 by invalidating something that only touches the
127 // border of 1,1 (and is inside the tile bounds of 1,0). This is a 10px wide
128 // strip from the top of the tiling onto the border pixels of tile 1,1 that
129 // avoids border pixels of any other tiles.
130 gfx::Rect invalidate_border
= interest_rect
;
131 invalidate_border
.Inset(0, 0, 0, -1);
132 // This should cause the tile 1,0 and 1,1 to be invalidated. The 1,1 tile will
133 // not be re-recorded since it does not touch the interest rect, so the
134 // invalidation should be expanded to cover all of 1,1.
135 invalidation
= invalidate_border
;
136 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), interest_rect
);
137 Region expected_invalidation
= invalidate_border
;
138 expected_invalidation
.Union(pile_
.tiling().TileBounds(1, 1));
139 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
142 TEST_F(PicturePileTest
, SmallInvalidateInflated
) {
143 // Invalidate something inside a tile.
144 Region
invalidate_rect(gfx::Rect(50, 50, 1, 1));
145 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
146 EXPECT_EQ(gfx::Rect(50, 50, 1, 1).ToString(), invalidate_rect
.ToString());
148 EXPECT_EQ(1, pile_
.tiling().num_tiles_x());
149 EXPECT_EQ(1, pile_
.tiling().num_tiles_y());
151 FakePicturePile::PictureInfo
& picture_info
=
152 pile_
.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second
;
153 // We should have a picture.
154 EXPECT_TRUE(!!picture_info
.GetPicture());
155 gfx::Rect picture_rect
= gfx::ScaleToEnclosedRect(
156 picture_info
.GetPicture()->LayerRect(), min_scale_
);
158 // The the picture should be large enough that scaling it never makes a rect
159 // smaller than 1 px wide or tall.
160 EXPECT_FALSE(picture_rect
.IsEmpty()) << "Picture rect " <<
161 picture_rect
.ToString();
164 TEST_F(PicturePileTest
, LargeInvalidateInflated
) {
165 // Invalidate something inside a tile.
166 Region
invalidate_rect(gfx::Rect(50, 50, 100, 100));
167 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
168 EXPECT_EQ(gfx::Rect(50, 50, 100, 100).ToString(), invalidate_rect
.ToString());
170 EXPECT_EQ(1, pile_
.tiling().num_tiles_x());
171 EXPECT_EQ(1, pile_
.tiling().num_tiles_y());
173 FakePicturePile::PictureInfo
& picture_info
=
174 pile_
.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second
;
175 EXPECT_TRUE(!!picture_info
.GetPicture());
177 int expected_inflation
= pile_
.buffer_pixels();
179 const Picture
* base_picture
= picture_info
.GetPicture();
180 gfx::Rect
base_picture_rect(tiling_size());
181 base_picture_rect
.Inset(-expected_inflation
, -expected_inflation
);
182 EXPECT_EQ(base_picture_rect
.ToString(),
183 base_picture
->LayerRect().ToString());
186 TEST_F(PicturePileTest
, InvalidateOnTileBoundaryInflated
) {
187 gfx::Size new_tiling_size
=
188 gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 2.f
));
189 // This creates initial pictures.
190 SetTilingSize(new_tiling_size
);
192 // Due to border pixels, we should have 3 tiles.
193 EXPECT_EQ(3, pile_
.tiling().num_tiles_x());
194 EXPECT_EQ(3, pile_
.tiling().num_tiles_y());
196 // We should have 1/.125 - 1 = 7 border pixels.
197 EXPECT_EQ(7, pile_
.buffer_pixels());
198 EXPECT_EQ(7, pile_
.tiling().border_texels());
200 // Invalidate everything to have a non zero invalidation frequency.
203 // Invalidate something just over a tile boundary by a single pixel.
204 // This will invalidate the tile (1, 1), as well as 1 row of pixels in (1, 0).
205 Region
invalidate_rect(
206 gfx::Rect(pile_
.tiling().TileBoundsWithBorder(0, 0).right(),
207 pile_
.tiling().TileBoundsWithBorder(0, 0).bottom() - 1,
210 Region expected_invalidation
= invalidate_rect
;
211 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
212 EXPECT_EQ(expected_invalidation
.ToString(), invalidate_rect
.ToString());
214 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
215 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
216 FakePicturePile::PictureInfo
& picture_info
=
218 .find(FakePicturePile::PictureMapKey(i
, j
))
221 // Expect (1, 1) and (1, 0) to be invalidated once more
222 // than the rest of the tiles.
223 if (i
== 1 && (j
== 0 || j
== 1)) {
225 2.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
226 picture_info
.GetInvalidationFrequencyForTesting());
229 1.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
230 picture_info
.GetInvalidationFrequencyForTesting());
236 TEST_F(PicturePileTest
, InvalidateOnFullLayer
) {
239 // Everything was invalidated once so far.
240 for (auto& it
: pile_
.picture_map()) {
242 1.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
243 it
.second
.GetInvalidationFrequencyForTesting());
246 // Invalidate everything,
247 Region invalidation
= tiling_rect();
248 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
250 // Everything was invalidated again.
251 for (auto& it
: pile_
.picture_map()) {
253 2.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
254 it
.second
.GetInvalidationFrequencyForTesting());
258 TEST_F(PicturePileTest
, StopRecordingOffscreenInvalidations
) {
259 gfx::Size new_tiling_size
=
260 gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 4.f
));
261 SetTilingSize(new_tiling_size
);
263 gfx::Rect
viewport(tiling_size().width(), 1);
265 // Update the whole pile until the invalidation frequency is high.
266 for (int frame
= 0; frame
< 33; ++frame
) {
270 // Make sure we have a high invalidation frequency.
271 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
272 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
273 FakePicturePile::PictureInfo
& picture_info
=
275 .find(FakePicturePile::PictureMapKey(i
, j
))
277 EXPECT_FLOAT_EQ(1.0f
, picture_info
.GetInvalidationFrequencyForTesting())
278 << "i " << i
<< " j " << j
;
282 // Update once more with a small viewport.
283 Region
invalidation(tiling_rect());
284 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), viewport
);
285 EXPECT_EQ(tiling_rect().ToString(), invalidation
.ToString());
287 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
288 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
289 FakePicturePile::PictureInfo
& picture_info
=
291 .find(FakePicturePile::PictureMapKey(i
, j
))
293 EXPECT_FLOAT_EQ(1.0f
, picture_info
.GetInvalidationFrequencyForTesting());
295 // If the y far enough away we expect to find no picture (no re-recording
296 // happened). For close y, the picture should change.
298 EXPECT_FALSE(picture_info
.GetPicture()) << "i " << i
<< " j " << j
;
300 EXPECT_TRUE(picture_info
.GetPicture()) << "i " << i
<< " j " << j
;
304 // Update a partial tile that doesn't get recorded. We should expand the
305 // invalidation to the entire tiles that overlap it.
306 Region small_invalidation
=
307 gfx::Rect(pile_
.tiling().TileBounds(3, 4).x(),
308 pile_
.tiling().TileBounds(3, 4).y() + 10,
311 UpdateAndExpandInvalidation(&small_invalidation
, tiling_size(), viewport
);
312 EXPECT_TRUE(small_invalidation
.Contains(gfx::UnionRects(
313 pile_
.tiling().TileBounds(2, 4), pile_
.tiling().TileBounds(3, 4))))
314 << small_invalidation
.ToString();
316 // Now update with no invalidation and full viewport
317 Region empty_invalidation
;
318 UpdateAndExpandInvalidation(&empty_invalidation
, tiling_size(),
320 EXPECT_EQ(Region().ToString(), empty_invalidation
.ToString());
322 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
323 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
324 FakePicturePile::PictureInfo
& picture_info
=
326 .find(FakePicturePile::PictureMapKey(i
, j
))
328 // Expect the invalidation frequency to be less than 1, since we just
329 // updated with no invalidations.
330 EXPECT_LT(picture_info
.GetInvalidationFrequencyForTesting(), 1.f
);
332 // We expect that there are pictures everywhere now.
333 EXPECT_TRUE(picture_info
.GetPicture()) << "i " << i
<< " j " << j
;
338 TEST_F(PicturePileTest
, ClearingInvalidatesRecordedRect
) {
339 gfx::Rect
rect(0, 0, 5, 5);
340 EXPECT_TRUE(pile_
.CanRasterLayerRect(rect
));
341 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(rect
));
345 // Make sure both the cache-aware check (using recorded region) and the normal
346 // check are both false after clearing.
347 EXPECT_FALSE(pile_
.CanRasterLayerRect(rect
));
348 EXPECT_FALSE(pile_
.CanRasterSlowTileCheck(rect
));
351 TEST_F(PicturePileTest
, FrequentInvalidationCanRaster
) {
352 // This test makes sure that if part of the page is frequently invalidated
353 // and doesn't get re-recorded, then CanRaster is not true for any
354 // tiles touching it, but is true for adjacent tiles, even if it
355 // overlaps on borders (edge case).
356 gfx::Size new_tiling_size
=
357 gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 4.f
));
358 SetTilingSize(new_tiling_size
);
360 gfx::Rect tile01_borders
= pile_
.tiling().TileBoundsWithBorder(0, 1);
361 gfx::Rect tile02_borders
= pile_
.tiling().TileBoundsWithBorder(0, 2);
362 gfx::Rect tile01_noborders
= pile_
.tiling().TileBounds(0, 1);
363 gfx::Rect tile02_noborders
= pile_
.tiling().TileBounds(0, 2);
365 // Sanity check these two tiles are overlapping with borders, since this is
366 // what the test is trying to repro.
367 EXPECT_TRUE(tile01_borders
.Intersects(tile02_borders
));
368 EXPECT_FALSE(tile01_noborders
.Intersects(tile02_noborders
));
370 EXPECT_TRUE(pile_
.CanRasterLayerRect(tile01_noborders
));
371 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(tile01_noborders
));
372 EXPECT_TRUE(pile_
.CanRasterLayerRect(tile02_noborders
));
373 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(tile02_noborders
));
374 // Sanity check that an initial paint goes down the fast path of having
375 // a valid recorded viewport.
376 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
378 // Update the whole layer until the invalidation frequency is high.
379 for (int frame
= 0; frame
< 33; ++frame
) {
383 // Update once more with a small viewport.
384 gfx::Rect
viewport(tiling_size().width(), 1);
385 Region
invalidation(tiling_rect());
386 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), viewport
);
387 EXPECT_EQ(tiling_rect().ToString(), invalidation
.ToString());
389 // Sanity check some pictures exist and others don't.
390 EXPECT_TRUE(pile_
.picture_map()
391 .find(FakePicturePile::PictureMapKey(0, 1))
392 ->second
.GetPicture());
393 EXPECT_FALSE(pile_
.picture_map()
394 .find(FakePicturePile::PictureMapKey(0, 2))
395 ->second
.GetPicture());
397 EXPECT_TRUE(pile_
.CanRasterLayerRect(tile01_noborders
));
398 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(tile01_noborders
));
399 EXPECT_FALSE(pile_
.CanRasterLayerRect(tile02_noborders
));
400 EXPECT_FALSE(pile_
.CanRasterSlowTileCheck(tile02_noborders
));
403 TEST_F(PicturePileTest
, NoInvalidationValidViewport
) {
404 // This test validates that the recorded_viewport cache of full tiles
405 // is still valid for some use cases. If it's not, it's a performance
406 // issue because CanRaster checks will go down the slow path.
407 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
409 // No invalidation, same viewport.
411 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
412 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
413 EXPECT_EQ(Region().ToString(), invalidation
.ToString());
415 // Partial invalidation, same viewport.
416 invalidation
= gfx::Rect(0, 0, 1, 1);
417 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
418 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
419 EXPECT_EQ(gfx::Rect(0, 0, 1, 1).ToString(), invalidation
.ToString());
421 // No invalidation, changing viewport.
422 invalidation
= Region();
423 UpdateAndExpandInvalidation(&invalidation
, tiling_size(),
424 gfx::Rect(5, 5, 5, 5));
425 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
426 EXPECT_EQ(Region().ToString(), invalidation
.ToString());
429 TEST_F(PicturePileTest
, BigFullLayerInvalidation
) {
430 gfx::Size
huge_layer_size(100000000, 100000000);
431 gfx::Rect
viewport(300000, 400000, 5000, 6000);
435 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
437 // Invalidating a huge layer should be fast.
438 base::TimeTicks start
= base::TimeTicks::Now();
439 invalidation
= gfx::Rect(huge_layer_size
);
440 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
441 base::TimeTicks end
= base::TimeTicks::Now();
442 base::TimeDelta length
= end
- start
;
443 // This is verrrry generous to avoid flake.
444 EXPECT_LT(length
.InSeconds(), 5);
447 TEST_F(PicturePileTest
, BigFullLayerInvalidationWithResizeGrow
) {
448 gfx::Size
huge_layer_size(100000000, 100000000);
449 gfx::Rect
viewport(300000, 400000, 5000, 6000);
453 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
455 // Resize the pile even larger, while invalidating everything in the old size.
456 // Invalidating the whole thing should be fast.
457 base::TimeTicks start
= base::TimeTicks::Now();
458 gfx::Size
bigger_layer_size(huge_layer_size
.width() * 2,
459 huge_layer_size
.height() * 2);
460 invalidation
= gfx::Rect(huge_layer_size
);
461 UpdateAndExpandInvalidation(&invalidation
, bigger_layer_size
, viewport
);
462 base::TimeTicks end
= base::TimeTicks::Now();
463 base::TimeDelta length
= end
- start
;
464 // This is verrrry generous to avoid flake.
465 EXPECT_LT(length
.InSeconds(), 5);
468 TEST_F(PicturePileTest
, BigFullLayerInvalidationWithResizeShrink
) {
469 gfx::Size
huge_layer_size(100000000, 100000000);
470 gfx::Rect
viewport(300000, 400000, 5000, 6000);
474 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
476 // Resize the pile smaller, while invalidating everything in the new size.
477 // Invalidating the whole thing should be fast.
478 base::TimeTicks start
= base::TimeTicks::Now();
479 gfx::Size
smaller_layer_size(huge_layer_size
.width() - 1000,
480 huge_layer_size
.height() - 1000);
481 invalidation
= gfx::Rect(smaller_layer_size
);
482 UpdateAndExpandInvalidation(&invalidation
, smaller_layer_size
, viewport
);
483 base::TimeTicks end
= base::TimeTicks::Now();
484 base::TimeDelta length
= end
- start
;
485 // This is verrrry generous to avoid flake.
486 EXPECT_LT(length
.InSeconds(), 5);
489 TEST_F(PicturePileTest
, InvalidationOutsideRecordingRect
) {
490 gfx::Size
huge_layer_size(10000000, 20000000);
491 gfx::Rect
viewport(300000, 400000, 5000, 6000);
493 // Resize the pile and set up the interest rect.
495 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
497 // Invalidation inside the recording rect does not need to be expanded.
498 invalidation
= viewport
;
499 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
500 EXPECT_EQ(viewport
.ToString(), invalidation
.ToString());
502 // Invalidation outside the recording rect should expand to the tiles it
504 gfx::Rect recorded_over_tiles
=
505 pile_
.tiling().ExpandRectToTileBounds(pile_
.recorded_viewport());
506 gfx::Rect
invalidation_outside(
507 recorded_over_tiles
.right(), recorded_over_tiles
.y(), 30, 30);
508 invalidation
= invalidation_outside
;
509 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
510 gfx::Rect expanded_recorded_viewport
=
511 pile_
.tiling().ExpandRectToTileBounds(pile_
.recorded_viewport());
512 Region expected_invalidation
=
513 pile_
.tiling().ExpandRectToTileBounds(invalidation_outside
);
514 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
524 class PicturePileResizeCornerTest
: public PicturePileTestBase
,
525 public testing::TestWithParam
<Corner
> {
527 void SetUp() override
{ InitializeData(); }
529 static gfx::Rect
CornerSinglePixelRect(Corner corner
, const gfx::Size
& s
) {
532 return gfx::Rect(0, 0, 1, 1);
534 return gfx::Rect(s
.width() - 1, 0, 1, 1);
536 return gfx::Rect(0, s
.height() - 1, 1, 1);
538 return gfx::Rect(s
.width() - 1, s
.height() - 1, 1, 1);
545 TEST_P(PicturePileResizeCornerTest
, ResizePileOutsideInterestRect
) {
546 Corner corner
= GetParam();
548 // This size chosen to be larger than the interest rect size, which is
549 // at least kPixelDistanceToRecord * 2 in each dimension.
550 int tile_size
= 100000;
551 // The small number subtracted keeps the last tile in each axis larger than
552 // the interest rect also.
554 gfx::Size
base_tiling_size(6 * tile_size
+ offset
, 6 * tile_size
+ offset
);
555 gfx::Size
grow_down_tiling_size(6 * tile_size
+ offset
,
556 8 * tile_size
+ offset
);
557 gfx::Size
grow_right_tiling_size(8 * tile_size
+ offset
,
558 6 * tile_size
+ offset
);
559 gfx::Size
grow_both_tiling_size(8 * tile_size
+ offset
,
560 8 * tile_size
+ offset
);
563 Region expected_invalidation
;
565 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
566 SetTilingSize(base_tiling_size
);
568 // We should have a recording for every tile.
569 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
570 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
571 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
572 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
573 FakePicturePile::PictureMapKey
key(i
, j
);
574 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
575 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
576 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
580 UpdateAndExpandInvalidation(
582 grow_down_tiling_size
,
583 CornerSinglePixelRect(corner
, grow_down_tiling_size
));
585 // We should have lost all of the recordings in the bottom row as none of them
586 // are in the current interest rect (which is either the above or below it).
587 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
588 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
589 for (int i
= 0; i
< 6; ++i
) {
590 for (int j
= 0; j
< 6; ++j
) {
591 FakePicturePile::PictureMapKey
key(i
, j
);
592 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
593 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
594 EXPECT_EQ(j
< 5, it
!= map
.end() && it
->second
.GetPicture());
598 // We invalidated all new pixels in the recording.
599 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
600 gfx::Rect(base_tiling_size
));
601 // But the new pixels don't cover the whole bottom row.
602 gfx::Rect bottom_row
= gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
603 pile_
.tiling().TileBounds(5, 5));
604 EXPECT_FALSE(expected_invalidation
.Contains(bottom_row
));
605 // We invalidated the entire old bottom row.
606 expected_invalidation
.Union(bottom_row
);
607 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
608 invalidation
.Clear();
611 UpdateAndExpandInvalidation(&invalidation
,
613 CornerSinglePixelRect(corner
, base_tiling_size
));
615 // When shrinking, we should have lost all the recordings in the bottom row
616 // not touching the interest rect.
617 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
618 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
619 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
620 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
621 FakePicturePile::PictureMapKey
key(i
, j
);
622 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
623 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
631 // The interest rect in the bottom left tile means we'll record it.
632 expect_tile
= j
< 5 || (j
== 5 && i
== 0);
635 // The interest rect in the bottom right tile means we'll record it.
636 expect_tile
= j
< 5 || (j
== 5 && i
== 5);
639 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
643 // When shrinking, the previously exposed region is invalidated.
644 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
645 gfx::Rect(base_tiling_size
));
646 // The whole bottom row of tiles (except any with the interest rect) are
648 gfx::Rect bottom_row_minus_existing_corner
= gfx::UnionRects(
649 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(5, 5));
653 // No tiles are kept in the changed region because it doesn't
654 // intersect with the interest rect.
657 bottom_row_minus_existing_corner
.Subtract(
658 pile_
.tiling().TileBounds(0, 5));
661 bottom_row_minus_existing_corner
.Subtract(
662 pile_
.tiling().TileBounds(5, 5));
666 expected_invalidation
.Union(bottom_row_minus_existing_corner
);
667 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
668 invalidation
.Clear();
671 UpdateAndExpandInvalidation(
673 grow_right_tiling_size
,
674 CornerSinglePixelRect(corner
, grow_right_tiling_size
));
676 // We should have lost all of the recordings in the right column as none of
677 // them are in the current interest rect (which is either entirely left or
679 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
680 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
681 for (int i
= 0; i
< 6; ++i
) {
682 for (int j
= 0; j
< 6; ++j
) {
683 FakePicturePile::PictureMapKey
key(i
, j
);
684 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
685 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
686 EXPECT_EQ(i
< 5, it
!= map
.end() && it
->second
.GetPicture());
690 // We invalidated all new pixels in the recording.
691 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
692 gfx::Rect(base_tiling_size
));
693 // But the new pixels don't cover the whole right_column.
694 gfx::Rect right_column
= gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
695 pile_
.tiling().TileBounds(5, 5));
696 EXPECT_FALSE(expected_invalidation
.Contains(right_column
));
697 // We invalidated the entire old right column.
698 expected_invalidation
.Union(right_column
);
699 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
700 invalidation
.Clear();
703 UpdateAndExpandInvalidation(&invalidation
,
705 CornerSinglePixelRect(corner
, base_tiling_size
));
707 // When shrinking, we should have lost all the recordings in the right column
708 // not touching the interest rect.
709 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
710 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
711 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
712 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
713 FakePicturePile::PictureMapKey
key(i
, j
);
714 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
715 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
720 // No tiles are kept in the changed region because it doesn't
721 // intersect with the interest rect.
725 // The interest rect in the top right tile means we'll record it.
726 expect_tile
= i
< 5 || (j
== 0 && i
== 5);
729 // The interest rect in the bottom right tile means we'll record it.
730 expect_tile
= i
< 5 || (j
== 5 && i
== 5);
733 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
737 // When shrinking, the previously exposed region is invalidated.
738 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
739 gfx::Rect(base_tiling_size
));
740 // The whole right column of tiles (except for ones with the interest rect)
742 gfx::Rect right_column_minus_existing_corner
= gfx::UnionRects(
743 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
749 right_column_minus_existing_corner
.Subtract(
750 pile_
.tiling().TileBounds(5, 0));
753 right_column_minus_existing_corner
.Subtract(
754 pile_
.tiling().TileBounds(5, 5));
757 expected_invalidation
.Union(right_column_minus_existing_corner
);
758 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
759 invalidation
.Clear();
762 UpdateAndExpandInvalidation(
764 grow_both_tiling_size
,
765 CornerSinglePixelRect(corner
, grow_both_tiling_size
));
767 // We should have lost the recordings in the right column and bottom row.
768 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
769 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
770 for (int i
= 0; i
< 6; ++i
) {
771 for (int j
= 0; j
< 6; ++j
) {
772 FakePicturePile::PictureMapKey
key(i
, j
);
773 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
774 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
775 EXPECT_EQ(i
< 5 && j
< 5, it
!= map
.end() && it
->second
.GetPicture());
779 // We invalidated all new pixels in the recording.
780 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
781 gfx::Rect(base_tiling_size
));
782 // But the new pixels don't cover the whole right column or bottom row.
783 Region right_column_and_bottom_row
=
784 UnionRegions(gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
785 pile_
.tiling().TileBounds(5, 5)),
786 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
787 pile_
.tiling().TileBounds(5, 5)));
788 EXPECT_FALSE(expected_invalidation
.Contains(right_column_and_bottom_row
));
789 // We invalidated the entire old right column and the old bottom row.
790 expected_invalidation
.Union(right_column_and_bottom_row
);
791 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
792 invalidation
.Clear();
795 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
,
796 CornerSinglePixelRect(corner
, base_tiling_size
));
798 // We should have lost the recordings in the right column and bottom row,
799 // except where it intersects the interest rect.
800 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
801 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
802 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
803 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
804 FakePicturePile::PictureMapKey
key(i
, j
);
805 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
806 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
810 expect_tile
= i
< 5 && j
< 5;
813 // The interest rect in the top right tile means we'll record it.
814 expect_tile
= (i
< 5 && j
< 5) || (j
== 0 && i
== 5);
817 // The interest rect in the bottom left tile means we'll record it.
818 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 0);
821 // The interest rect in the bottom right tile means we'll record it.
822 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 5);
825 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture())
830 // We invalidated all previous pixels in the recording.
831 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
832 gfx::Rect(base_tiling_size
));
833 // The whole right column and bottom row of tiles (except for ones with the
834 // interest rect) are dropped.
835 Region right_column_and_bottom_row_minus_existing_corner
=
836 right_column_and_bottom_row
;
841 right_column_and_bottom_row_minus_existing_corner
.Subtract(
842 pile_
.tiling().TileBounds(0, 5));
845 right_column_and_bottom_row_minus_existing_corner
.Subtract(
846 pile_
.tiling().TileBounds(5, 0));
849 right_column_and_bottom_row_minus_existing_corner
.Subtract(
850 pile_
.tiling().TileBounds(5, 5));
853 expected_invalidation
.Union(
854 right_column_and_bottom_row_minus_existing_corner
);
855 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
856 invalidation
.Clear();
859 TEST_P(PicturePileResizeCornerTest
, SmallResizePileOutsideInterestRect
) {
860 Corner corner
= GetParam();
862 // This size chosen to be larger than the interest rect size, which is
863 // at least kPixelDistanceToRecord * 2 in each dimension.
864 int tile_size
= 100000;
865 // The small number subtracted keeps the last tile in each axis larger than
866 // the interest rect also.
868 gfx::Size
base_tiling_size(6 * tile_size
+ offset
, 6 * tile_size
+ offset
);
869 gfx::Size
grow_down_tiling_size(6 * tile_size
+ offset
,
870 6 * tile_size
+ offset
+ 5);
871 gfx::Size
grow_right_tiling_size(6 * tile_size
+ offset
+ 5,
872 6 * tile_size
+ offset
);
873 gfx::Size
grow_both_tiling_size(6 * tile_size
+ offset
+ 5,
874 6 * tile_size
+ offset
+ 5);
877 Region expected_invalidation
;
879 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
880 SetTilingSize(base_tiling_size
);
882 // We should have a recording for every tile.
883 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
884 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
885 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
886 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
887 FakePicturePile::PictureMapKey
key(i
, j
);
888 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
889 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
890 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
894 // In this test (unlike the large resize test), as all growing and shrinking
895 // happens within tiles, the resulting invalidation is symmetrical, so use
896 // this enum to repeat the test both ways.
897 enum ChangeDirection
{ GROW
, SHRINK
, LAST_DIRECTION
= SHRINK
};
900 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
901 gfx::Size new_tiling_size
=
902 dir
== GROW
? grow_down_tiling_size
: base_tiling_size
;
904 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
905 CornerSinglePixelRect(corner
, new_tiling_size
));
907 // We should have lost the recordings in the bottom row that do not
908 // intersect the interest rect.
909 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
910 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
911 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
912 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
913 FakePicturePile::PictureMapKey
key(i
, j
);
914 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
915 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
923 // The interest rect in the bottom left tile means we'll record it.
924 expect_tile
= j
< 5 || (j
== 5 && i
== 0);
927 // The interest rect in the bottom right tile means we'll record it.
928 expect_tile
= j
< 5 || (j
== 5 && i
== 5);
931 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
935 // We invalidated the bottom row outside the new interest rect. The tile
936 // that insects the interest rect in invalidated only on its newly
937 // exposed or previously exposed pixels.
939 // Only calculate the expected invalidation while growing, as the tile
940 // bounds post-growing is the newly exposed / previously exposed sizes.
941 // Post-shrinking, the tile bounds are smaller, so can't be used.
945 expected_invalidation
= gfx::UnionRects(
946 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(5, 5));
949 expected_invalidation
= gfx::UnionRects(
950 pile_
.tiling().TileBounds(1, 5), pile_
.tiling().TileBounds(5, 5));
951 expected_invalidation
.Union(SubtractRects(
952 pile_
.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size
)));
955 expected_invalidation
= gfx::UnionRects(
956 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(4, 5));
957 expected_invalidation
.Union(SubtractRects(
958 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
962 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
963 invalidation
.Clear();
967 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
968 gfx::Size new_tiling_size
=
969 dir
== GROW
? grow_right_tiling_size
: base_tiling_size
;
971 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
972 CornerSinglePixelRect(corner
, new_tiling_size
));
974 // We should have lost the recordings in the right column.
975 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
976 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
977 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
978 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
979 FakePicturePile::PictureMapKey
key(i
, j
);
980 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
981 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
989 // The interest rect in the top right tile means we'll record it.
990 expect_tile
= i
< 5 || (j
== 0 && i
== 5);
993 // The interest rect in the bottom right tile means we'll record it.
994 expect_tile
= i
< 5 || (j
== 5 && i
== 5);
997 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
1001 // We invalidated the right column outside the new interest rect. The tile
1002 // that insects the interest rect in invalidated only on its new or
1003 // previously exposed pixels.
1005 // Calculate the expected invalidation the first time through the loop.
1009 expected_invalidation
= gfx::UnionRects(
1010 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
1013 expected_invalidation
= gfx::UnionRects(
1014 pile_
.tiling().TileBounds(5, 1), pile_
.tiling().TileBounds(5, 5));
1015 expected_invalidation
.Union(SubtractRects(
1016 pile_
.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size
)));
1019 expected_invalidation
= gfx::UnionRects(
1020 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 4));
1021 expected_invalidation
.Union(SubtractRects(
1022 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
1026 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1027 invalidation
.Clear();
1031 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
1032 gfx::Size new_tiling_size
=
1033 dir
== GROW
? grow_both_tiling_size
: base_tiling_size
;
1035 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
1036 CornerSinglePixelRect(corner
, new_tiling_size
));
1038 // We should have lost the recordings in the right column and bottom row.
1039 // The tile that insects the interest rect in invalidated only on its new
1040 // or previously exposed pixels.
1041 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1042 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1043 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1044 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1045 FakePicturePile::PictureMapKey
key(i
, j
);
1046 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1047 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1051 expect_tile
= i
< 5 && j
< 5;
1054 // The interest rect in the top right tile means we'll record it.
1055 expect_tile
= (i
< 5 && j
< 5) || (j
== 0 && i
== 5);
1058 // The interest rect in the bottom left tile means we'll record it.
1059 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 0);
1062 // The interest rect in the bottom right tile means we'll record it.
1063 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 5);
1066 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture())
1071 // We invalidated the right column and the bottom row outside the new
1072 // interest rect. The tile that insects the interest rect in invalidated
1073 // only on its new or previous exposed pixels.
1075 // Calculate the expected invalidation the first time through the loop.
1078 expected_invalidation
= gfx::UnionRects(
1079 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
1080 expected_invalidation
.Union(
1081 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1082 pile_
.tiling().TileBounds(5, 5)));
1085 expected_invalidation
= gfx::UnionRects(
1086 pile_
.tiling().TileBounds(5, 1), pile_
.tiling().TileBounds(5, 5));
1087 expected_invalidation
.Union(
1088 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1089 pile_
.tiling().TileBounds(5, 5)));
1090 expected_invalidation
.Union(SubtractRects(
1091 pile_
.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size
)));
1094 expected_invalidation
= gfx::UnionRects(
1095 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
1096 expected_invalidation
.Union(
1097 gfx::UnionRects(pile_
.tiling().TileBounds(1, 5),
1098 pile_
.tiling().TileBounds(5, 5)));
1099 expected_invalidation
.Union(SubtractRects(
1100 pile_
.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size
)));
1103 expected_invalidation
= gfx::UnionRects(
1104 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 4));
1105 expected_invalidation
.Union(
1106 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1107 pile_
.tiling().TileBounds(4, 5)));
1108 expected_invalidation
.Union(SubtractRegions(
1109 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
1113 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1114 invalidation
.Clear();
1118 INSTANTIATE_TEST_CASE_P(
1119 PicturePileResizeCornerTests
,
1120 PicturePileResizeCornerTest
,
1121 ::testing::Values(TOP_LEFT
, TOP_RIGHT
, BOTTOM_LEFT
, BOTTOM_RIGHT
));
1123 TEST_F(PicturePileTest
, ResizePileInsideInterestRect
) {
1124 // This size chosen to be small enough that all the rects below fit inside the
1125 // the interest rect, so they are smaller than kPixelDistanceToRecord in each
1127 int tile_size
= 100;
1128 gfx::Size
base_tiling_size(5 * tile_size
, 5 * tile_size
);
1129 gfx::Size
grow_down_tiling_size(5 * tile_size
, 7 * tile_size
);
1130 gfx::Size
grow_right_tiling_size(7 * tile_size
, 5 * tile_size
);
1131 gfx::Size
grow_both_tiling_size(7 * tile_size
, 7 * tile_size
);
1133 Region invalidation
;
1134 Region expected_invalidation
;
1136 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
1137 SetTilingSize(base_tiling_size
);
1139 // We should have a recording for every tile.
1140 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1141 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1142 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1143 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1144 FakePicturePile::PictureMapKey
key(i
, j
);
1145 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1146 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1147 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1151 UpdateAndExpandInvalidation(
1152 &invalidation
, grow_down_tiling_size
, gfx::Rect(1, 1));
1154 // We should have a recording for every tile.
1155 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1156 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
1157 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1158 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1159 FakePicturePile::PictureMapKey
key(i
, j
);
1160 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1161 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1162 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1166 // We invalidated the newly exposed pixels on the bottom row of tiles.
1167 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1168 gfx::Rect(base_tiling_size
));
1169 Region bottom_row_new_pixels
=
1170 SubtractRegions(gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1171 pile_
.tiling().TileBounds(5, 5)),
1172 gfx::Rect(base_tiling_size
));
1173 EXPECT_TRUE(expected_invalidation
.Contains(bottom_row_new_pixels
));
1174 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1175 invalidation
.Clear();
1178 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1180 // We should have a recording for every tile.
1181 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1182 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1183 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1184 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1185 FakePicturePile::PictureMapKey
key(i
, j
);
1186 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1187 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1188 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1192 // We invalidated the previously exposed pixels on the bottom row of tiles.
1193 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1194 gfx::Rect(base_tiling_size
));
1195 EXPECT_TRUE(expected_invalidation
.Contains(bottom_row_new_pixels
));
1196 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1197 invalidation
.Clear();
1200 UpdateAndExpandInvalidation(
1201 &invalidation
, grow_right_tiling_size
, gfx::Rect(1, 1));
1203 // We should have a recording for every tile.
1204 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
1205 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1206 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1207 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1208 FakePicturePile::PictureMapKey
key(i
, j
);
1209 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1210 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1211 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1215 // We invalidated the newly exposed pixels on the right column of tiles.
1216 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1217 gfx::Rect(base_tiling_size
));
1218 Region right_column_new_pixels
=
1219 SubtractRegions(gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
1220 pile_
.tiling().TileBounds(5, 5)),
1221 gfx::Rect(base_tiling_size
));
1222 EXPECT_TRUE(expected_invalidation
.Contains(right_column_new_pixels
));
1223 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1224 invalidation
.Clear();
1227 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1229 // We should have lost the recordings that are now outside the tiling only.
1230 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1231 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1232 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1233 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1234 FakePicturePile::PictureMapKey
key(i
, j
);
1235 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1236 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1237 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1241 // We invalidated the previously exposed pixels on the right column of tiles.
1242 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1243 gfx::Rect(base_tiling_size
));
1244 EXPECT_TRUE(expected_invalidation
.Contains(right_column_new_pixels
));
1245 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1246 invalidation
.Clear();
1249 UpdateAndExpandInvalidation(
1250 &invalidation
, grow_both_tiling_size
, gfx::Rect(1, 1));
1252 // We should have a recording for every tile.
1253 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
1254 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
1255 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1256 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1257 FakePicturePile::PictureMapKey
key(i
, j
);
1258 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1259 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1260 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1264 // We invalidated the newly exposed pixels on the bottom row and right column
1266 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1267 gfx::Rect(base_tiling_size
));
1268 Region bottom_row_and_right_column_new_pixels
= SubtractRegions(
1269 UnionRegions(gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1270 pile_
.tiling().TileBounds(5, 5)),
1271 gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
1272 pile_
.tiling().TileBounds(5, 5))),
1273 gfx::Rect(base_tiling_size
));
1275 expected_invalidation
.Contains(bottom_row_and_right_column_new_pixels
));
1276 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1277 invalidation
.Clear();
1280 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect());
1282 // We should have lost the recordings that are now outside the tiling only.
1283 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1284 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1285 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1286 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1287 FakePicturePile::PictureMapKey
key(i
, j
);
1288 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1289 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1290 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1294 // We invalidated the previously exposed pixels on the bottom row and right
1296 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1297 gfx::Rect(base_tiling_size
));
1299 expected_invalidation
.Contains(bottom_row_and_right_column_new_pixels
));
1300 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1301 invalidation
.Clear();
1304 TEST_F(PicturePileTest
, SmallResizePileInsideInterestRect
) {
1305 // This size chosen to be small enough that all the rects below fit inside the
1306 // the interest rect, so they are smaller than kPixelDistanceToRecord in each
1308 int tile_size
= 100;
1309 gfx::Size
base_tiling_size(5 * tile_size
, 5 * tile_size
);
1310 gfx::Size
grow_down_tiling_size(5 * tile_size
, 5 * tile_size
+ 5);
1311 gfx::Size
grow_right_tiling_size(5 * tile_size
+ 5, 5 * tile_size
);
1312 gfx::Size
grow_both_tiling_size(5 * tile_size
+ 5, 5 * tile_size
+ 5);
1314 Region invalidation
;
1315 Region expected_invalidation
;
1317 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
1318 SetTilingSize(base_tiling_size
);
1320 // We should have a recording for every tile.
1321 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1322 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1323 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1324 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1325 FakePicturePile::PictureMapKey
key(i
, j
);
1326 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1327 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1328 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1332 UpdateAndExpandInvalidation(
1333 &invalidation
, grow_down_tiling_size
, gfx::Rect(1, 1));
1335 // We should have a recording for every tile.
1336 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1337 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1338 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1339 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1340 FakePicturePile::PictureMapKey
key(i
, j
);
1341 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1342 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1343 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1347 // We invalidated the newly exposed pixels.
1348 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1349 gfx::Rect(base_tiling_size
));
1350 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1351 invalidation
.Clear();
1354 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1356 // We should have a recording for every tile.
1357 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1358 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1359 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1360 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1361 FakePicturePile::PictureMapKey
key(i
, j
);
1362 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1363 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1364 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1368 // We invalidated the previously exposed pixels.
1369 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1370 gfx::Rect(base_tiling_size
));
1371 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1372 invalidation
.Clear();
1375 UpdateAndExpandInvalidation(
1376 &invalidation
, grow_right_tiling_size
, gfx::Rect(1, 1));
1378 // We should have a recording for every tile.
1379 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1380 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1381 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1382 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1383 FakePicturePile::PictureMapKey
key(i
, j
);
1384 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1385 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1386 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1390 // We invalidated the newly exposed pixels.
1391 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1392 gfx::Rect(base_tiling_size
));
1393 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1394 invalidation
.Clear();
1397 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1399 // We should have lost the recordings that are now outside the tiling only.
1400 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1401 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1402 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1403 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1404 FakePicturePile::PictureMapKey
key(i
, j
);
1405 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1406 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1407 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1411 // We invalidated the previously exposed pixels.
1412 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1413 gfx::Rect(base_tiling_size
));
1414 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1415 invalidation
.Clear();
1418 UpdateAndExpandInvalidation(
1419 &invalidation
, grow_both_tiling_size
, gfx::Rect(1, 1));
1421 // We should have a recording for every tile.
1422 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1423 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1424 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1425 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1426 FakePicturePile::PictureMapKey
key(i
, j
);
1427 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1428 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1429 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1433 // We invalidated the newly exposed pixels.
1434 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1435 gfx::Rect(base_tiling_size
));
1436 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1437 invalidation
.Clear();
1440 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect());
1442 // We should have lost the recordings that are now outside the tiling only.
1443 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1444 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1445 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1446 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1447 FakePicturePile::PictureMapKey
key(i
, j
);
1448 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1449 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1450 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1454 // We invalidated the previously exposed pixels.
1455 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1456 gfx::Rect(base_tiling_size
));
1457 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1458 invalidation
.Clear();
1461 TEST_F(PicturePileTest
, SolidRectangleIsSolid
) {
1462 // If the client has no contents, the solid state will be true.
1463 Region
invalidation1(tiling_rect());
1464 UpdateAndExpandInvalidation(&invalidation1
, tiling_size(), tiling_rect());
1465 EXPECT_TRUE(pile_
.is_solid_color());
1466 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), pile_
.solid_color());
1468 // If there is a single rect that covers the view, the solid
1469 // state will be true.
1471 paint
.setColor(SK_ColorCYAN
);
1472 client_
.add_draw_rect(tiling_rect(), paint
);
1473 Region
invalidation2(tiling_rect());
1474 UpdateAndExpandInvalidation(&invalidation2
, tiling_size(), tiling_rect());
1475 EXPECT_TRUE(pile_
.is_solid_color());
1476 EXPECT_EQ(SK_ColorCYAN
, pile_
.solid_color());
1478 // If a second smaller rect is draw that doesn't cover the viewport
1479 // completely, the solid state will be false.
1480 gfx::Rect smallRect
= tiling_rect();
1481 smallRect
.Inset(10, 10, 10, 10);
1482 client_
.add_draw_rect(smallRect
, paint
);
1483 Region
invalidation3(tiling_rect());
1484 UpdateAndExpandInvalidation(&invalidation3
, tiling_size(), tiling_rect());
1485 EXPECT_FALSE(pile_
.is_solid_color());
1487 // If a third rect is drawn over everything, we should be solid again.
1488 paint
.setColor(SK_ColorRED
);
1489 client_
.add_draw_rect(tiling_rect(), paint
);
1490 Region
invalidation4(tiling_rect());
1491 UpdateAndExpandInvalidation(&invalidation4
, tiling_size(), tiling_rect());
1492 EXPECT_TRUE(pile_
.is_solid_color());
1493 EXPECT_EQ(SK_ColorRED
, pile_
.solid_color());
1495 // If we draw too many, we don't bother doing the analysis and we should no
1496 // longer be in a solid state. There are 8 rects, two clips and a translate.
1497 client_
.add_draw_rect(tiling_rect(), paint
);
1498 client_
.add_draw_rect(tiling_rect(), paint
);
1499 client_
.add_draw_rect(tiling_rect(), paint
);
1500 client_
.add_draw_rect(tiling_rect(), paint
);
1501 client_
.add_draw_rect(tiling_rect(), paint
);
1502 Region
invalidation5(tiling_rect());
1503 UpdateAndExpandInvalidation(&invalidation5
, tiling_size(), tiling_rect());
1504 EXPECT_FALSE(pile_
.is_solid_color());
1507 TEST_F(PicturePileTest
, NonSolidRectangleOnOffsettedLayerIsNonSolid
) {
1508 gfx::Rect
visible_rect(tiling_rect());
1509 visible_rect
.Offset(gfx::Vector2d(1000, 1000));
1510 // The picture pile requires that the tiling completely encompass the viewport
1511 // to make this test work correctly since the recorded viewport is an
1512 // intersection of the tile size and viewport rect. This is possibly a flaw
1513 // in |PicturePile|.
1514 gfx::Size
tiling_size(visible_rect
.right(), visible_rect
.bottom());
1515 // |Setup()| will create pictures here that mess with the test, clear it!
1519 paint
.setColor(SK_ColorCYAN
);
1521 // Add a rect that doesn't cover the viewport completely, the solid state
1523 gfx::Rect smallRect
= visible_rect
;
1524 smallRect
.Inset(10, 10, 10, 10);
1525 client_
.add_draw_rect(smallRect
, paint
);
1526 Region
invalidation(visible_rect
);
1527 UpdateAndExpandInvalidation(&invalidation
, tiling_size
, visible_rect
);
1528 EXPECT_FALSE(pile_
.is_solid_color());
1531 TEST_F(PicturePileTest
, SetEmptyBounds
) {
1532 EXPECT_TRUE(pile_
.is_solid_color());
1533 EXPECT_FALSE(pile_
.GetSize().IsEmpty());
1534 EXPECT_FALSE(pile_
.picture_map().empty());
1535 EXPECT_TRUE(pile_
.HasRecordings());
1536 pile_
.SetEmptyBounds();
1537 EXPECT_FALSE(pile_
.is_solid_color());
1538 EXPECT_TRUE(pile_
.GetSize().IsEmpty());
1539 EXPECT_TRUE(pile_
.picture_map().empty());
1540 EXPECT_FALSE(pile_
.HasRecordings());