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 FakePicturePile::PictureInfo
& picture_info
=
155 pile_
.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second
;
156 // We should have a picture.
157 EXPECT_TRUE(!!picture_info
.GetPicture());
158 gfx::Rect picture_rect
= gfx::ScaleToEnclosedRect(
159 picture_info
.GetPicture()->LayerRect(), min_scale_
);
161 // The the picture should be large enough that scaling it never makes a rect
162 // smaller than 1 px wide or tall.
163 EXPECT_FALSE(picture_rect
.IsEmpty()) << "Picture rect " <<
164 picture_rect
.ToString();
167 TEST_F(PicturePileTest
, LargeInvalidateInflated
) {
168 // Invalidate something inside a tile.
169 Region
invalidate_rect(gfx::Rect(50, 50, 100, 100));
170 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
171 EXPECT_EQ(gfx::Rect(50, 50, 100, 100).ToString(), invalidate_rect
.ToString());
173 EXPECT_EQ(1, pile_
.tiling().num_tiles_x());
174 EXPECT_EQ(1, pile_
.tiling().num_tiles_y());
176 FakePicturePile::PictureInfo
& picture_info
=
177 pile_
.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second
;
178 EXPECT_TRUE(!!picture_info
.GetPicture());
180 int expected_inflation
= pile_
.buffer_pixels();
182 const Picture
* base_picture
= picture_info
.GetPicture();
183 gfx::Rect
base_picture_rect(tiling_size());
184 base_picture_rect
.Inset(-expected_inflation
, -expected_inflation
);
185 EXPECT_EQ(base_picture_rect
.ToString(),
186 base_picture
->LayerRect().ToString());
189 TEST_F(PicturePileTest
, InvalidateOnTileBoundaryInflated
) {
190 gfx::Size new_tiling_size
=
191 gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 2.f
));
192 // This creates initial pictures.
193 SetTilingSize(new_tiling_size
);
195 // Due to border pixels, we should have 3 tiles.
196 EXPECT_EQ(3, pile_
.tiling().num_tiles_x());
197 EXPECT_EQ(3, pile_
.tiling().num_tiles_y());
199 // We should have 1/.125 - 1 = 7 border pixels.
200 EXPECT_EQ(7, pile_
.buffer_pixels());
201 EXPECT_EQ(7, pile_
.tiling().border_texels());
203 // Invalidate everything to have a non zero invalidation frequency.
206 // Invalidate something just over a tile boundary by a single pixel.
207 // This will invalidate the tile (1, 1), as well as 1 row of pixels in (1, 0).
208 Region
invalidate_rect(
209 gfx::Rect(pile_
.tiling().TileBoundsWithBorder(0, 0).right(),
210 pile_
.tiling().TileBoundsWithBorder(0, 0).bottom() - 1,
213 Region expected_invalidation
= invalidate_rect
;
214 UpdateAndExpandInvalidation(&invalidate_rect
, tiling_size(), tiling_rect());
215 EXPECT_EQ(expected_invalidation
.ToString(), invalidate_rect
.ToString());
217 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
218 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
219 FakePicturePile::PictureInfo
& picture_info
=
221 .find(FakePicturePile::PictureMapKey(i
, j
))
224 // Expect (1, 1) and (1, 0) to be invalidated once more
225 // than the rest of the tiles.
226 if (i
== 1 && (j
== 0 || j
== 1)) {
228 2.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
229 picture_info
.GetInvalidationFrequencyForTesting());
232 1.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
233 picture_info
.GetInvalidationFrequencyForTesting());
239 TEST_F(PicturePileTest
, InvalidateOnFullLayer
) {
242 // Everything was invalidated once so far.
243 for (auto& it
: pile_
.picture_map()) {
245 1.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
246 it
.second
.GetInvalidationFrequencyForTesting());
249 // Invalidate everything,
250 Region invalidation
= tiling_rect();
251 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
253 // Everything was invalidated again.
254 for (auto& it
: pile_
.picture_map()) {
256 2.0f
/ FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED
,
257 it
.second
.GetInvalidationFrequencyForTesting());
261 TEST_F(PicturePileTest
, StopRecordingOffscreenInvalidations
) {
262 gfx::Size new_tiling_size
=
263 gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 4.f
));
264 SetTilingSize(new_tiling_size
);
266 gfx::Rect
viewport(tiling_size().width(), 1);
268 // Update the whole pile until the invalidation frequency is high.
269 for (int frame
= 0; frame
< 33; ++frame
) {
273 // Make sure we have a high invalidation frequency.
274 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
275 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
276 FakePicturePile::PictureInfo
& picture_info
=
278 .find(FakePicturePile::PictureMapKey(i
, j
))
280 EXPECT_FLOAT_EQ(1.0f
, picture_info
.GetInvalidationFrequencyForTesting())
281 << "i " << i
<< " j " << j
;
285 // Update once more with a small viewport.
286 Region
invalidation(tiling_rect());
287 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), viewport
);
288 EXPECT_EQ(tiling_rect().ToString(), invalidation
.ToString());
290 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
291 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
292 FakePicturePile::PictureInfo
& picture_info
=
294 .find(FakePicturePile::PictureMapKey(i
, j
))
296 EXPECT_FLOAT_EQ(1.0f
, picture_info
.GetInvalidationFrequencyForTesting());
298 // If the y far enough away we expect to find no picture (no re-recording
299 // happened). For close y, the picture should change.
301 EXPECT_FALSE(picture_info
.GetPicture()) << "i " << i
<< " j " << j
;
303 EXPECT_TRUE(picture_info
.GetPicture()) << "i " << i
<< " j " << j
;
307 // Update a partial tile that doesn't get recorded. We should expand the
308 // invalidation to the entire tiles that overlap it.
309 Region small_invalidation
=
310 gfx::Rect(pile_
.tiling().TileBounds(3, 4).x(),
311 pile_
.tiling().TileBounds(3, 4).y() + 10,
314 UpdateAndExpandInvalidation(&small_invalidation
, tiling_size(), viewport
);
315 EXPECT_TRUE(small_invalidation
.Contains(gfx::UnionRects(
316 pile_
.tiling().TileBounds(2, 4), pile_
.tiling().TileBounds(3, 4))))
317 << small_invalidation
.ToString();
319 // Now update with no invalidation and full viewport
320 Region empty_invalidation
;
321 UpdateAndExpandInvalidation(&empty_invalidation
, tiling_size(),
323 EXPECT_EQ(Region().ToString(), empty_invalidation
.ToString());
325 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
326 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
327 FakePicturePile::PictureInfo
& picture_info
=
329 .find(FakePicturePile::PictureMapKey(i
, j
))
331 // Expect the invalidation frequency to be less than 1, since we just
332 // updated with no invalidations.
333 EXPECT_LT(picture_info
.GetInvalidationFrequencyForTesting(), 1.f
);
335 // We expect that there are pictures everywhere now.
336 EXPECT_TRUE(picture_info
.GetPicture()) << "i " << i
<< " j " << j
;
341 TEST_F(PicturePileTest
, ClearingInvalidatesRecordedRect
) {
342 gfx::Rect
rect(0, 0, 5, 5);
343 EXPECT_TRUE(pile_
.CanRasterLayerRect(rect
));
344 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(rect
));
348 // Make sure both the cache-aware check (using recorded region) and the normal
349 // check are both false after clearing.
350 EXPECT_FALSE(pile_
.CanRasterLayerRect(rect
));
351 EXPECT_FALSE(pile_
.CanRasterSlowTileCheck(rect
));
354 TEST_F(PicturePileTest
, FrequentInvalidationCanRaster
) {
355 // This test makes sure that if part of the page is frequently invalidated
356 // and doesn't get re-recorded, then CanRaster is not true for any
357 // tiles touching it, but is true for adjacent tiles, even if it
358 // overlaps on borders (edge case).
359 gfx::Size new_tiling_size
=
360 gfx::ToCeiledSize(gfx::ScaleSize(tiling_size(), 4.f
));
361 SetTilingSize(new_tiling_size
);
363 gfx::Rect tile01_borders
= pile_
.tiling().TileBoundsWithBorder(0, 1);
364 gfx::Rect tile02_borders
= pile_
.tiling().TileBoundsWithBorder(0, 2);
365 gfx::Rect tile01_noborders
= pile_
.tiling().TileBounds(0, 1);
366 gfx::Rect tile02_noborders
= pile_
.tiling().TileBounds(0, 2);
368 // Sanity check these two tiles are overlapping with borders, since this is
369 // what the test is trying to repro.
370 EXPECT_TRUE(tile01_borders
.Intersects(tile02_borders
));
371 EXPECT_FALSE(tile01_noborders
.Intersects(tile02_noborders
));
373 EXPECT_TRUE(pile_
.CanRasterLayerRect(tile01_noborders
));
374 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(tile01_noborders
));
375 EXPECT_TRUE(pile_
.CanRasterLayerRect(tile02_noborders
));
376 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(tile02_noborders
));
377 // Sanity check that an initial paint goes down the fast path of having
378 // a valid recorded viewport.
379 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
381 // Update the whole layer until the invalidation frequency is high.
382 for (int frame
= 0; frame
< 33; ++frame
) {
386 // Update once more with a small viewport.
387 gfx::Rect
viewport(tiling_size().width(), 1);
388 Region
invalidation(tiling_rect());
389 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), viewport
);
390 EXPECT_EQ(tiling_rect().ToString(), invalidation
.ToString());
392 // Sanity check some pictures exist and others don't.
393 EXPECT_TRUE(pile_
.picture_map()
394 .find(FakePicturePile::PictureMapKey(0, 1))
395 ->second
.GetPicture());
396 EXPECT_FALSE(pile_
.picture_map()
397 .find(FakePicturePile::PictureMapKey(0, 2))
398 ->second
.GetPicture());
400 EXPECT_TRUE(pile_
.CanRasterLayerRect(tile01_noborders
));
401 EXPECT_TRUE(pile_
.CanRasterSlowTileCheck(tile01_noborders
));
402 EXPECT_FALSE(pile_
.CanRasterLayerRect(tile02_noborders
));
403 EXPECT_FALSE(pile_
.CanRasterSlowTileCheck(tile02_noborders
));
406 TEST_F(PicturePileTest
, NoInvalidationValidViewport
) {
407 // This test validates that the recorded_viewport cache of full tiles
408 // is still valid for some use cases. If it's not, it's a performance
409 // issue because CanRaster checks will go down the slow path.
410 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
412 // No invalidation, same viewport.
414 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
415 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
416 EXPECT_EQ(Region().ToString(), invalidation
.ToString());
418 // Partial invalidation, same viewport.
419 invalidation
= gfx::Rect(0, 0, 1, 1);
420 UpdateAndExpandInvalidation(&invalidation
, tiling_size(), tiling_rect());
421 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
422 EXPECT_EQ(gfx::Rect(0, 0, 1, 1).ToString(), invalidation
.ToString());
424 // No invalidation, changing viewport.
425 invalidation
= Region();
426 UpdateAndExpandInvalidation(&invalidation
, tiling_size(),
427 gfx::Rect(5, 5, 5, 5));
428 EXPECT_TRUE(!pile_
.recorded_viewport().IsEmpty());
429 EXPECT_EQ(Region().ToString(), invalidation
.ToString());
432 TEST_F(PicturePileTest
, BigFullLayerInvalidation
) {
433 gfx::Size
huge_layer_size(100000000, 100000000);
434 gfx::Rect
viewport(300000, 400000, 5000, 6000);
438 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
440 // Invalidating a huge layer should be fast.
441 base::TimeTicks start
= base::TimeTicks::Now();
442 invalidation
= gfx::Rect(huge_layer_size
);
443 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
444 base::TimeTicks end
= base::TimeTicks::Now();
445 base::TimeDelta length
= end
- start
;
446 // This is verrrry generous to avoid flake.
447 EXPECT_LT(length
.InSeconds(), 5);
450 TEST_F(PicturePileTest
, BigFullLayerInvalidationWithResizeGrow
) {
451 gfx::Size
huge_layer_size(100000000, 100000000);
452 gfx::Rect
viewport(300000, 400000, 5000, 6000);
456 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
458 // Resize the pile even larger, while invalidating everything in the old size.
459 // Invalidating the whole thing should be fast.
460 base::TimeTicks start
= base::TimeTicks::Now();
461 gfx::Size
bigger_layer_size(huge_layer_size
.width() * 2,
462 huge_layer_size
.height() * 2);
463 invalidation
= gfx::Rect(huge_layer_size
);
464 UpdateAndExpandInvalidation(&invalidation
, bigger_layer_size
, viewport
);
465 base::TimeTicks end
= base::TimeTicks::Now();
466 base::TimeDelta length
= end
- start
;
467 // This is verrrry generous to avoid flake.
468 EXPECT_LT(length
.InSeconds(), 5);
471 TEST_F(PicturePileTest
, BigFullLayerInvalidationWithResizeShrink
) {
472 gfx::Size
huge_layer_size(100000000, 100000000);
473 gfx::Rect
viewport(300000, 400000, 5000, 6000);
477 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
479 // Resize the pile smaller, while invalidating everything in the new size.
480 // Invalidating the whole thing should be fast.
481 base::TimeTicks start
= base::TimeTicks::Now();
482 gfx::Size
smaller_layer_size(huge_layer_size
.width() - 1000,
483 huge_layer_size
.height() - 1000);
484 invalidation
= gfx::Rect(smaller_layer_size
);
485 UpdateAndExpandInvalidation(&invalidation
, smaller_layer_size
, viewport
);
486 base::TimeTicks end
= base::TimeTicks::Now();
487 base::TimeDelta length
= end
- start
;
488 // This is verrrry generous to avoid flake.
489 EXPECT_LT(length
.InSeconds(), 5);
492 TEST_F(PicturePileTest
, InvalidationOutsideRecordingRect
) {
493 gfx::Size
huge_layer_size(10000000, 20000000);
494 gfx::Rect
viewport(300000, 400000, 5000, 6000);
496 // Resize the pile and set up the interest rect.
498 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
500 // Invalidation inside the recording rect does not need to be expanded.
501 invalidation
= viewport
;
502 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
503 EXPECT_EQ(viewport
.ToString(), invalidation
.ToString());
505 // Invalidation outside the recording rect should expand to the tiles it
507 gfx::Rect recorded_over_tiles
=
508 pile_
.tiling().ExpandRectToTileBounds(pile_
.recorded_viewport());
509 gfx::Rect
invalidation_outside(
510 recorded_over_tiles
.right(), recorded_over_tiles
.y(), 30, 30);
511 invalidation
= invalidation_outside
;
512 UpdateAndExpandInvalidation(&invalidation
, huge_layer_size
, viewport
);
513 gfx::Rect expanded_recorded_viewport
=
514 pile_
.tiling().ExpandRectToTileBounds(pile_
.recorded_viewport());
515 Region expected_invalidation
=
516 pile_
.tiling().ExpandRectToTileBounds(invalidation_outside
);
517 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
527 class PicturePileResizeCornerTest
: public PicturePileTestBase
,
528 public testing::TestWithParam
<Corner
> {
530 void SetUp() override
{ InitializeData(); }
532 static gfx::Rect
CornerSinglePixelRect(Corner corner
, const gfx::Size
& s
) {
535 return gfx::Rect(0, 0, 1, 1);
537 return gfx::Rect(s
.width() - 1, 0, 1, 1);
539 return gfx::Rect(0, s
.height() - 1, 1, 1);
541 return gfx::Rect(s
.width() - 1, s
.height() - 1, 1, 1);
548 TEST_P(PicturePileResizeCornerTest
, ResizePileOutsideInterestRect
) {
549 Corner corner
= GetParam();
551 // This size chosen to be larger than the interest rect size, which is
552 // at least kPixelDistanceToRecord * 2 in each dimension.
553 int tile_size
= 100000;
554 // The small number subtracted keeps the last tile in each axis larger than
555 // the interest rect also.
557 gfx::Size
base_tiling_size(6 * tile_size
+ offset
, 6 * tile_size
+ offset
);
558 gfx::Size
grow_down_tiling_size(6 * tile_size
+ offset
,
559 8 * tile_size
+ offset
);
560 gfx::Size
grow_right_tiling_size(8 * tile_size
+ offset
,
561 6 * tile_size
+ offset
);
562 gfx::Size
grow_both_tiling_size(8 * tile_size
+ offset
,
563 8 * tile_size
+ offset
);
566 Region expected_invalidation
;
568 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
569 SetTilingSize(base_tiling_size
);
571 // We should have a recording for every tile.
572 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
573 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
574 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
575 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
576 FakePicturePile::PictureMapKey
key(i
, j
);
577 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
578 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
579 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
583 UpdateAndExpandInvalidation(
585 grow_down_tiling_size
,
586 CornerSinglePixelRect(corner
, grow_down_tiling_size
));
588 // We should have lost all of the recordings in the bottom row as none of them
589 // are in the current interest rect (which is either the above or below it).
590 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
591 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
592 for (int i
= 0; i
< 6; ++i
) {
593 for (int j
= 0; j
< 6; ++j
) {
594 FakePicturePile::PictureMapKey
key(i
, j
);
595 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
596 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
597 EXPECT_EQ(j
< 5, it
!= map
.end() && it
->second
.GetPicture());
601 // We invalidated all new pixels in the recording.
602 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
603 gfx::Rect(base_tiling_size
));
604 // But the new pixels don't cover the whole bottom row.
605 gfx::Rect bottom_row
= gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
606 pile_
.tiling().TileBounds(5, 5));
607 EXPECT_FALSE(expected_invalidation
.Contains(bottom_row
));
608 // We invalidated the entire old bottom row.
609 expected_invalidation
.Union(bottom_row
);
610 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
611 invalidation
.Clear();
614 UpdateAndExpandInvalidation(&invalidation
,
616 CornerSinglePixelRect(corner
, base_tiling_size
));
618 // When shrinking, we should have lost all the recordings in the bottom row
619 // not touching the interest rect.
620 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
621 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
622 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
623 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
624 FakePicturePile::PictureMapKey
key(i
, j
);
625 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
626 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
634 // The interest rect in the bottom left tile means we'll record it.
635 expect_tile
= j
< 5 || (j
== 5 && i
== 0);
638 // The interest rect in the bottom right tile means we'll record it.
639 expect_tile
= j
< 5 || (j
== 5 && i
== 5);
642 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
646 // When shrinking, the previously exposed region is invalidated.
647 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
648 gfx::Rect(base_tiling_size
));
649 // The whole bottom row of tiles (except any with the interest rect) are
651 gfx::Rect bottom_row_minus_existing_corner
= gfx::UnionRects(
652 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(5, 5));
656 // No tiles are kept in the changed region because it doesn't
657 // intersect with the interest rect.
660 bottom_row_minus_existing_corner
.Subtract(
661 pile_
.tiling().TileBounds(0, 5));
664 bottom_row_minus_existing_corner
.Subtract(
665 pile_
.tiling().TileBounds(5, 5));
669 expected_invalidation
.Union(bottom_row_minus_existing_corner
);
670 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
671 invalidation
.Clear();
674 UpdateAndExpandInvalidation(
676 grow_right_tiling_size
,
677 CornerSinglePixelRect(corner
, grow_right_tiling_size
));
679 // We should have lost all of the recordings in the right column as none of
680 // them are in the current interest rect (which is either entirely left or
682 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
683 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
684 for (int i
= 0; i
< 6; ++i
) {
685 for (int j
= 0; j
< 6; ++j
) {
686 FakePicturePile::PictureMapKey
key(i
, j
);
687 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
688 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
689 EXPECT_EQ(i
< 5, it
!= map
.end() && it
->second
.GetPicture());
693 // We invalidated all new pixels in the recording.
694 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
695 gfx::Rect(base_tiling_size
));
696 // But the new pixels don't cover the whole right_column.
697 gfx::Rect right_column
= gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
698 pile_
.tiling().TileBounds(5, 5));
699 EXPECT_FALSE(expected_invalidation
.Contains(right_column
));
700 // We invalidated the entire old right column.
701 expected_invalidation
.Union(right_column
);
702 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
703 invalidation
.Clear();
706 UpdateAndExpandInvalidation(&invalidation
,
708 CornerSinglePixelRect(corner
, base_tiling_size
));
710 // When shrinking, we should have lost all the recordings in the right column
711 // not touching the interest rect.
712 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
713 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
714 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
715 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
716 FakePicturePile::PictureMapKey
key(i
, j
);
717 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
718 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
723 // No tiles are kept in the changed region because it doesn't
724 // intersect with the interest rect.
728 // The interest rect in the top right tile means we'll record it.
729 expect_tile
= i
< 5 || (j
== 0 && i
== 5);
732 // The interest rect in the bottom right tile means we'll record it.
733 expect_tile
= i
< 5 || (j
== 5 && i
== 5);
736 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
740 // When shrinking, the previously exposed region is invalidated.
741 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
742 gfx::Rect(base_tiling_size
));
743 // The whole right column of tiles (except for ones with the interest rect)
745 gfx::Rect right_column_minus_existing_corner
= gfx::UnionRects(
746 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
752 right_column_minus_existing_corner
.Subtract(
753 pile_
.tiling().TileBounds(5, 0));
756 right_column_minus_existing_corner
.Subtract(
757 pile_
.tiling().TileBounds(5, 5));
760 expected_invalidation
.Union(right_column_minus_existing_corner
);
761 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
762 invalidation
.Clear();
765 UpdateAndExpandInvalidation(
767 grow_both_tiling_size
,
768 CornerSinglePixelRect(corner
, grow_both_tiling_size
));
770 // We should have lost the recordings in the right column and bottom row.
771 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
772 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
773 for (int i
= 0; i
< 6; ++i
) {
774 for (int j
= 0; j
< 6; ++j
) {
775 FakePicturePile::PictureMapKey
key(i
, j
);
776 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
777 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
778 EXPECT_EQ(i
< 5 && j
< 5, it
!= map
.end() && it
->second
.GetPicture());
782 // We invalidated all new pixels in the recording.
783 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
784 gfx::Rect(base_tiling_size
));
785 // But the new pixels don't cover the whole right column or bottom row.
786 Region right_column_and_bottom_row
=
787 UnionRegions(gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
788 pile_
.tiling().TileBounds(5, 5)),
789 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
790 pile_
.tiling().TileBounds(5, 5)));
791 EXPECT_FALSE(expected_invalidation
.Contains(right_column_and_bottom_row
));
792 // We invalidated the entire old right column and the old bottom row.
793 expected_invalidation
.Union(right_column_and_bottom_row
);
794 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
795 invalidation
.Clear();
798 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
,
799 CornerSinglePixelRect(corner
, base_tiling_size
));
801 // We should have lost the recordings in the right column and bottom row,
802 // except where it intersects the interest rect.
803 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
804 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
805 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
806 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
807 FakePicturePile::PictureMapKey
key(i
, j
);
808 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
809 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
813 expect_tile
= i
< 5 && j
< 5;
816 // The interest rect in the top right tile means we'll record it.
817 expect_tile
= (i
< 5 && j
< 5) || (j
== 0 && i
== 5);
820 // The interest rect in the bottom left tile means we'll record it.
821 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 0);
824 // The interest rect in the bottom right tile means we'll record it.
825 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 5);
828 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture())
833 // We invalidated all previous pixels in the recording.
834 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
835 gfx::Rect(base_tiling_size
));
836 // The whole right column and bottom row of tiles (except for ones with the
837 // interest rect) are dropped.
838 Region right_column_and_bottom_row_minus_existing_corner
=
839 right_column_and_bottom_row
;
844 right_column_and_bottom_row_minus_existing_corner
.Subtract(
845 pile_
.tiling().TileBounds(0, 5));
848 right_column_and_bottom_row_minus_existing_corner
.Subtract(
849 pile_
.tiling().TileBounds(5, 0));
852 right_column_and_bottom_row_minus_existing_corner
.Subtract(
853 pile_
.tiling().TileBounds(5, 5));
856 expected_invalidation
.Union(
857 right_column_and_bottom_row_minus_existing_corner
);
858 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
859 invalidation
.Clear();
862 TEST_P(PicturePileResizeCornerTest
, SmallResizePileOutsideInterestRect
) {
863 Corner corner
= GetParam();
865 // This size chosen to be larger than the interest rect size, which is
866 // at least kPixelDistanceToRecord * 2 in each dimension.
867 int tile_size
= 100000;
868 // The small number subtracted keeps the last tile in each axis larger than
869 // the interest rect also.
871 gfx::Size
base_tiling_size(6 * tile_size
+ offset
, 6 * tile_size
+ offset
);
872 gfx::Size
grow_down_tiling_size(6 * tile_size
+ offset
,
873 6 * tile_size
+ offset
+ 5);
874 gfx::Size
grow_right_tiling_size(6 * tile_size
+ offset
+ 5,
875 6 * tile_size
+ offset
);
876 gfx::Size
grow_both_tiling_size(6 * tile_size
+ offset
+ 5,
877 6 * tile_size
+ offset
+ 5);
880 Region expected_invalidation
;
882 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
883 SetTilingSize(base_tiling_size
);
885 // We should have a recording for every tile.
886 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
887 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
888 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
889 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
890 FakePicturePile::PictureMapKey
key(i
, j
);
891 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
892 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
893 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
897 // In this test (unlike the large resize test), as all growing and shrinking
898 // happens within tiles, the resulting invalidation is symmetrical, so use
899 // this enum to repeat the test both ways.
900 enum ChangeDirection
{ GROW
, SHRINK
, LAST_DIRECTION
= SHRINK
};
903 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
904 gfx::Size new_tiling_size
=
905 dir
== GROW
? grow_down_tiling_size
: base_tiling_size
;
907 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
908 CornerSinglePixelRect(corner
, new_tiling_size
));
910 // We should have lost the recordings in the bottom row that do not
911 // intersect the interest rect.
912 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
913 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
914 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
915 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
916 FakePicturePile::PictureMapKey
key(i
, j
);
917 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
918 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
926 // The interest rect in the bottom left tile means we'll record it.
927 expect_tile
= j
< 5 || (j
== 5 && i
== 0);
930 // The interest rect in the bottom right tile means we'll record it.
931 expect_tile
= j
< 5 || (j
== 5 && i
== 5);
934 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
938 // We invalidated the bottom row outside the new interest rect. The tile
939 // that insects the interest rect in invalidated only on its newly
940 // exposed or previously exposed pixels.
942 // Only calculate the expected invalidation while growing, as the tile
943 // bounds post-growing is the newly exposed / previously exposed sizes.
944 // Post-shrinking, the tile bounds are smaller, so can't be used.
948 expected_invalidation
= gfx::UnionRects(
949 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(5, 5));
952 expected_invalidation
= gfx::UnionRects(
953 pile_
.tiling().TileBounds(1, 5), pile_
.tiling().TileBounds(5, 5));
954 expected_invalidation
.Union(SubtractRects(
955 pile_
.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size
)));
958 expected_invalidation
= gfx::UnionRects(
959 pile_
.tiling().TileBounds(0, 5), pile_
.tiling().TileBounds(4, 5));
960 expected_invalidation
.Union(SubtractRects(
961 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
965 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
966 invalidation
.Clear();
970 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
971 gfx::Size new_tiling_size
=
972 dir
== GROW
? grow_right_tiling_size
: base_tiling_size
;
974 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
975 CornerSinglePixelRect(corner
, new_tiling_size
));
977 // We should have lost the recordings in the right column.
978 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
979 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
980 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
981 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
982 FakePicturePile::PictureMapKey
key(i
, j
);
983 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
984 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
992 // The interest rect in the top right tile means we'll record it.
993 expect_tile
= i
< 5 || (j
== 0 && i
== 5);
996 // The interest rect in the bottom right tile means we'll record it.
997 expect_tile
= i
< 5 || (j
== 5 && i
== 5);
1000 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture());
1004 // We invalidated the right column outside the new interest rect. The tile
1005 // that insects the interest rect in invalidated only on its new or
1006 // previously exposed pixels.
1008 // Calculate the expected invalidation the first time through the loop.
1012 expected_invalidation
= gfx::UnionRects(
1013 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
1016 expected_invalidation
= gfx::UnionRects(
1017 pile_
.tiling().TileBounds(5, 1), pile_
.tiling().TileBounds(5, 5));
1018 expected_invalidation
.Union(SubtractRects(
1019 pile_
.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size
)));
1022 expected_invalidation
= gfx::UnionRects(
1023 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 4));
1024 expected_invalidation
.Union(SubtractRects(
1025 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
1029 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1030 invalidation
.Clear();
1034 for (int dir
= 0; dir
<= LAST_DIRECTION
; ++dir
) {
1035 gfx::Size new_tiling_size
=
1036 dir
== GROW
? grow_both_tiling_size
: base_tiling_size
;
1038 UpdateAndExpandInvalidation(&invalidation
, new_tiling_size
,
1039 CornerSinglePixelRect(corner
, new_tiling_size
));
1041 // We should have lost the recordings in the right column and bottom row.
1042 // The tile that insects the interest rect in invalidated only on its new
1043 // or previously exposed pixels.
1044 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1045 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1046 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1047 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1048 FakePicturePile::PictureMapKey
key(i
, j
);
1049 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1050 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1054 expect_tile
= i
< 5 && j
< 5;
1057 // The interest rect in the top right tile means we'll record it.
1058 expect_tile
= (i
< 5 && j
< 5) || (j
== 0 && i
== 5);
1061 // The interest rect in the bottom left tile means we'll record it.
1062 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 0);
1065 // The interest rect in the bottom right tile means we'll record it.
1066 expect_tile
= (i
< 5 && j
< 5) || (j
== 5 && i
== 5);
1069 EXPECT_EQ(expect_tile
, it
!= map
.end() && it
->second
.GetPicture())
1074 // We invalidated the right column and the bottom row outside the new
1075 // interest rect. The tile that insects the interest rect in invalidated
1076 // only on its new or previous exposed pixels.
1078 // Calculate the expected invalidation the first time through the loop.
1081 expected_invalidation
= gfx::UnionRects(
1082 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
1083 expected_invalidation
.Union(
1084 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1085 pile_
.tiling().TileBounds(5, 5)));
1088 expected_invalidation
= gfx::UnionRects(
1089 pile_
.tiling().TileBounds(5, 1), pile_
.tiling().TileBounds(5, 5));
1090 expected_invalidation
.Union(
1091 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1092 pile_
.tiling().TileBounds(5, 5)));
1093 expected_invalidation
.Union(SubtractRects(
1094 pile_
.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size
)));
1097 expected_invalidation
= gfx::UnionRects(
1098 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 5));
1099 expected_invalidation
.Union(
1100 gfx::UnionRects(pile_
.tiling().TileBounds(1, 5),
1101 pile_
.tiling().TileBounds(5, 5)));
1102 expected_invalidation
.Union(SubtractRects(
1103 pile_
.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size
)));
1106 expected_invalidation
= gfx::UnionRects(
1107 pile_
.tiling().TileBounds(5, 0), pile_
.tiling().TileBounds(5, 4));
1108 expected_invalidation
.Union(
1109 gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1110 pile_
.tiling().TileBounds(4, 5)));
1111 expected_invalidation
.Union(SubtractRegions(
1112 pile_
.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size
)));
1116 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1117 invalidation
.Clear();
1121 INSTANTIATE_TEST_CASE_P(
1122 PicturePileResizeCornerTests
,
1123 PicturePileResizeCornerTest
,
1124 ::testing::Values(TOP_LEFT
, TOP_RIGHT
, BOTTOM_LEFT
, BOTTOM_RIGHT
));
1126 TEST_F(PicturePileTest
, ResizePileInsideInterestRect
) {
1127 // This size chosen to be small enough that all the rects below fit inside the
1128 // the interest rect, so they are smaller than kPixelDistanceToRecord in each
1130 int tile_size
= 100;
1131 gfx::Size
base_tiling_size(5 * tile_size
, 5 * tile_size
);
1132 gfx::Size
grow_down_tiling_size(5 * tile_size
, 7 * tile_size
);
1133 gfx::Size
grow_right_tiling_size(7 * tile_size
, 5 * tile_size
);
1134 gfx::Size
grow_both_tiling_size(7 * tile_size
, 7 * tile_size
);
1136 Region invalidation
;
1137 Region expected_invalidation
;
1139 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
1140 SetTilingSize(base_tiling_size
);
1142 // We should have a recording for every tile.
1143 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1144 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1145 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1146 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1147 FakePicturePile::PictureMapKey
key(i
, j
);
1148 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1149 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1150 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1154 UpdateAndExpandInvalidation(
1155 &invalidation
, grow_down_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(8, 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
.GetPicture());
1169 // We invalidated the newly exposed pixels on the bottom row of tiles.
1170 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1171 gfx::Rect(base_tiling_size
));
1172 Region bottom_row_new_pixels
=
1173 SubtractRegions(gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1174 pile_
.tiling().TileBounds(5, 5)),
1175 gfx::Rect(base_tiling_size
));
1176 EXPECT_TRUE(expected_invalidation
.Contains(bottom_row_new_pixels
));
1177 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1178 invalidation
.Clear();
1181 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1183 // We should have a recording for every tile.
1184 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1185 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1186 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1187 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1188 FakePicturePile::PictureMapKey
key(i
, j
);
1189 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1190 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1191 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1195 // We invalidated the previously exposed pixels on the bottom row of tiles.
1196 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1197 gfx::Rect(base_tiling_size
));
1198 EXPECT_TRUE(expected_invalidation
.Contains(bottom_row_new_pixels
));
1199 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1200 invalidation
.Clear();
1203 UpdateAndExpandInvalidation(
1204 &invalidation
, grow_right_tiling_size
, gfx::Rect(1, 1));
1206 // We should have a recording for every tile.
1207 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
1208 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1209 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1210 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1211 FakePicturePile::PictureMapKey
key(i
, j
);
1212 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1213 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1214 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1218 // We invalidated the newly exposed pixels on the right column of tiles.
1219 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1220 gfx::Rect(base_tiling_size
));
1221 Region right_column_new_pixels
=
1222 SubtractRegions(gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
1223 pile_
.tiling().TileBounds(5, 5)),
1224 gfx::Rect(base_tiling_size
));
1225 EXPECT_TRUE(expected_invalidation
.Contains(right_column_new_pixels
));
1226 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1227 invalidation
.Clear();
1230 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1232 // We should have lost the recordings that are now outside the tiling only.
1233 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1234 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1235 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1236 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1237 FakePicturePile::PictureMapKey
key(i
, j
);
1238 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1239 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1240 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1244 // We invalidated the previously exposed pixels on the right column of tiles.
1245 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1246 gfx::Rect(base_tiling_size
));
1247 EXPECT_TRUE(expected_invalidation
.Contains(right_column_new_pixels
));
1248 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1249 invalidation
.Clear();
1252 UpdateAndExpandInvalidation(
1253 &invalidation
, grow_both_tiling_size
, gfx::Rect(1, 1));
1255 // We should have a recording for every tile.
1256 EXPECT_EQ(8, pile_
.tiling().num_tiles_x());
1257 EXPECT_EQ(8, pile_
.tiling().num_tiles_y());
1258 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1259 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1260 FakePicturePile::PictureMapKey
key(i
, j
);
1261 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1262 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1263 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1267 // We invalidated the newly exposed pixels on the bottom row and right column
1269 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1270 gfx::Rect(base_tiling_size
));
1271 Region bottom_row_and_right_column_new_pixels
= SubtractRegions(
1272 UnionRegions(gfx::UnionRects(pile_
.tiling().TileBounds(0, 5),
1273 pile_
.tiling().TileBounds(5, 5)),
1274 gfx::UnionRects(pile_
.tiling().TileBounds(5, 0),
1275 pile_
.tiling().TileBounds(5, 5))),
1276 gfx::Rect(base_tiling_size
));
1278 expected_invalidation
.Contains(bottom_row_and_right_column_new_pixels
));
1279 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1280 invalidation
.Clear();
1283 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect());
1285 // We should have lost the recordings that are now outside the tiling only.
1286 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1287 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1288 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1289 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1290 FakePicturePile::PictureMapKey
key(i
, j
);
1291 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1292 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1293 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1297 // We invalidated the previously exposed pixels on the bottom row and right
1299 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1300 gfx::Rect(base_tiling_size
));
1302 expected_invalidation
.Contains(bottom_row_and_right_column_new_pixels
));
1303 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1304 invalidation
.Clear();
1307 TEST_F(PicturePileTest
, SmallResizePileInsideInterestRect
) {
1308 // This size chosen to be small enough that all the rects below fit inside the
1309 // the interest rect, so they are smaller than kPixelDistanceToRecord in each
1311 int tile_size
= 100;
1312 gfx::Size
base_tiling_size(5 * tile_size
, 5 * tile_size
);
1313 gfx::Size
grow_down_tiling_size(5 * tile_size
, 5 * tile_size
+ 5);
1314 gfx::Size
grow_right_tiling_size(5 * tile_size
+ 5, 5 * tile_size
);
1315 gfx::Size
grow_both_tiling_size(5 * tile_size
+ 5, 5 * tile_size
+ 5);
1317 Region invalidation
;
1318 Region expected_invalidation
;
1320 pile_
.tiling().SetMaxTextureSize(gfx::Size(tile_size
, tile_size
));
1321 SetTilingSize(base_tiling_size
);
1323 // We should have a recording for every tile.
1324 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1325 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1326 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1327 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1328 FakePicturePile::PictureMapKey
key(i
, j
);
1329 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1330 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1331 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1335 UpdateAndExpandInvalidation(
1336 &invalidation
, grow_down_tiling_size
, gfx::Rect(1, 1));
1338 // We should have a recording for every tile.
1339 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1340 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1341 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1342 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1343 FakePicturePile::PictureMapKey
key(i
, j
);
1344 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1345 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1346 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1350 // We invalidated the newly exposed pixels.
1351 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1352 gfx::Rect(base_tiling_size
));
1353 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1354 invalidation
.Clear();
1357 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1359 // We should have a recording for every tile.
1360 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1361 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1362 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1363 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1364 FakePicturePile::PictureMapKey
key(i
, j
);
1365 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1366 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1367 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1371 // We invalidated the previously exposed pixels.
1372 expected_invalidation
= SubtractRegions(gfx::Rect(grow_down_tiling_size
),
1373 gfx::Rect(base_tiling_size
));
1374 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1375 invalidation
.Clear();
1378 UpdateAndExpandInvalidation(
1379 &invalidation
, grow_right_tiling_size
, gfx::Rect(1, 1));
1381 // We should have a recording for every tile.
1382 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1383 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1384 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1385 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1386 FakePicturePile::PictureMapKey
key(i
, j
);
1387 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1388 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1389 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1393 // We invalidated the newly exposed pixels.
1394 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1395 gfx::Rect(base_tiling_size
));
1396 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1397 invalidation
.Clear();
1400 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect(1, 1));
1402 // We should have lost the recordings that are now outside the tiling only.
1403 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1404 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1405 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1406 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1407 FakePicturePile::PictureMapKey
key(i
, j
);
1408 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1409 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1410 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1414 // We invalidated the previously exposed pixels.
1415 expected_invalidation
= SubtractRegions(gfx::Rect(grow_right_tiling_size
),
1416 gfx::Rect(base_tiling_size
));
1417 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1418 invalidation
.Clear();
1421 UpdateAndExpandInvalidation(
1422 &invalidation
, grow_both_tiling_size
, gfx::Rect(1, 1));
1424 // We should have a recording for every tile.
1425 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1426 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1427 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1428 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1429 FakePicturePile::PictureMapKey
key(i
, j
);
1430 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1431 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1432 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1436 // We invalidated the newly exposed pixels.
1437 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1438 gfx::Rect(base_tiling_size
));
1439 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1440 invalidation
.Clear();
1443 UpdateAndExpandInvalidation(&invalidation
, base_tiling_size
, gfx::Rect());
1445 // We should have lost the recordings that are now outside the tiling only.
1446 EXPECT_EQ(6, pile_
.tiling().num_tiles_x());
1447 EXPECT_EQ(6, pile_
.tiling().num_tiles_y());
1448 for (int i
= 0; i
< pile_
.tiling().num_tiles_x(); ++i
) {
1449 for (int j
= 0; j
< pile_
.tiling().num_tiles_y(); ++j
) {
1450 FakePicturePile::PictureMapKey
key(i
, j
);
1451 FakePicturePile::PictureMap
& map
= pile_
.picture_map();
1452 FakePicturePile::PictureMap::iterator it
= map
.find(key
);
1453 EXPECT_TRUE(it
!= map
.end() && it
->second
.GetPicture());
1457 // We invalidated the previously exposed pixels.
1458 expected_invalidation
= SubtractRegions(gfx::Rect(grow_both_tiling_size
),
1459 gfx::Rect(base_tiling_size
));
1460 EXPECT_EQ(expected_invalidation
.ToString(), invalidation
.ToString());
1461 invalidation
.Clear();
1464 TEST_F(PicturePileTest
, SolidRectangleIsSolid
) {
1465 // If the client has no contents, the solid state will be true.
1466 Region
invalidation1(tiling_rect());
1467 UpdateAndExpandInvalidation(&invalidation1
, tiling_size(), tiling_rect());
1468 EXPECT_TRUE(pile_
.is_solid_color());
1469 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), pile_
.solid_color());
1471 // If there is a single rect that covers the view, the solid
1472 // state will be true.
1474 paint
.setColor(SK_ColorCYAN
);
1475 client_
.add_draw_rect(tiling_rect(), paint
);
1476 Region
invalidation2(tiling_rect());
1477 UpdateAndExpandInvalidation(&invalidation2
, tiling_size(), tiling_rect());
1478 EXPECT_TRUE(pile_
.is_solid_color());
1479 EXPECT_EQ(SK_ColorCYAN
, pile_
.solid_color());
1481 // If a second smaller rect is draw that doesn't cover the viewport
1482 // completely, the solid state will be false.
1483 gfx::Rect smallRect
= tiling_rect();
1484 smallRect
.Inset(10, 10, 10, 10);
1485 client_
.add_draw_rect(smallRect
, paint
);
1486 Region
invalidation3(tiling_rect());
1487 UpdateAndExpandInvalidation(&invalidation3
, tiling_size(), tiling_rect());
1488 EXPECT_FALSE(pile_
.is_solid_color());
1490 // If a third rect is drawn over everything, we should be solid again.
1491 paint
.setColor(SK_ColorRED
);
1492 client_
.add_draw_rect(tiling_rect(), paint
);
1493 Region
invalidation4(tiling_rect());
1494 UpdateAndExpandInvalidation(&invalidation4
, tiling_size(), tiling_rect());
1495 EXPECT_TRUE(pile_
.is_solid_color());
1496 EXPECT_EQ(SK_ColorRED
, pile_
.solid_color());
1498 // If we draw too many, we don't bother doing the analysis and we should no
1499 // longer be in a solid state. There are 8 rects, two clips and a translate.
1500 client_
.add_draw_rect(tiling_rect(), paint
);
1501 client_
.add_draw_rect(tiling_rect(), paint
);
1502 client_
.add_draw_rect(tiling_rect(), paint
);
1503 client_
.add_draw_rect(tiling_rect(), paint
);
1504 client_
.add_draw_rect(tiling_rect(), paint
);
1505 Region
invalidation5(tiling_rect());
1506 UpdateAndExpandInvalidation(&invalidation5
, tiling_size(), tiling_rect());
1507 EXPECT_FALSE(pile_
.is_solid_color());
1510 TEST_F(PicturePileTest
, NonSolidRectangleOnOffsettedLayerIsNonSolid
) {
1511 gfx::Rect
visible_rect(tiling_rect());
1512 visible_rect
.Offset(gfx::Vector2d(1000, 1000));
1513 // The picture pile requires that the tiling completely encompass the viewport
1514 // to make this test work correctly since the recorded viewport is an
1515 // intersection of the tile size and viewport rect. This is possibly a flaw
1516 // in |PicturePile|.
1517 gfx::Size
tiling_size(visible_rect
.right(), visible_rect
.bottom());
1518 // |Setup()| will create pictures here that mess with the test, clear it!
1522 paint
.setColor(SK_ColorCYAN
);
1524 // Add a rect that doesn't cover the viewport completely, the solid state
1526 gfx::Rect smallRect
= visible_rect
;
1527 smallRect
.Inset(10, 10, 10, 10);
1528 client_
.add_draw_rect(smallRect
, paint
);
1529 Region
invalidation(visible_rect
);
1530 UpdateAndExpandInvalidation(&invalidation
, tiling_size
, visible_rect
);
1531 EXPECT_FALSE(pile_
.is_solid_color());
1534 TEST_F(PicturePileTest
, SetEmptyBounds
) {
1535 EXPECT_TRUE(pile_
.is_solid_color());
1536 EXPECT_FALSE(pile_
.GetSize().IsEmpty());
1537 EXPECT_FALSE(pile_
.picture_map().empty());
1538 EXPECT_TRUE(pile_
.HasRecordings());
1539 pile_
.SetEmptyBounds();
1540 EXPECT_FALSE(pile_
.is_solid_color());
1541 EXPECT_TRUE(pile_
.GetSize().IsEmpty());
1542 EXPECT_TRUE(pile_
.picture_map().empty());
1543 EXPECT_FALSE(pile_
.HasRecordings());