OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include <map> | |
6 #include <utility> | |
7 | |
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" | |
14 | |
15 namespace cc { | |
16 namespace { | |
17 | |
18 class PicturePileTestBase { | |
19 public: | |
20 PicturePileTestBase() | |
21 : min_scale_(0.125), | |
22 pile_(min_scale_, gfx::Size(1000, 1000)), | |
23 frame_number_(0) {} | |
24 | |
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()); | |
30 } | |
31 | |
32 void SetTilingSize(const gfx::Size& tiling_size) { | |
33 Region invalidation; | |
34 gfx::Rect viewport_rect(tiling_size); | |
35 UpdateAndExpandInvalidation(&invalidation, tiling_size, viewport_rect); | |
36 } | |
37 | |
38 gfx::Size tiling_size() const { return pile_.GetSize(); } | |
39 gfx::Rect tiling_rect() const { return gfx::Rect(pile_.GetSize()); } | |
40 | |
41 bool UpdateAndExpandInvalidation(Region* invalidation, | |
42 const gfx::Size& layer_size, | |
43 const gfx::Rect& visible_layer_rect) { | |
44 frame_number_++; | |
45 return pile_.UpdateAndExpandInvalidation(&client_, invalidation, layer_size, | |
46 visible_layer_rect, frame_number_, | |
47 RecordingSource::RECORD_NORMALLY); | |
48 } | |
49 | |
50 bool UpdateWholePile() { | |
51 Region invalidation = tiling_rect(); | |
52 bool result = UpdateAndExpandInvalidation(&invalidation, tiling_size(), | |
53 tiling_rect()); | |
54 EXPECT_EQ(tiling_rect().ToString(), invalidation.ToString()); | |
55 return result; | |
56 } | |
57 | |
58 FakeContentLayerClient client_; | |
59 float min_scale_; | |
60 FakePicturePile pile_; | |
61 int frame_number_; | |
62 }; | |
63 | |
64 class PicturePileTest : public PicturePileTestBase, public testing::Test { | |
65 public: | |
66 void SetUp() override { InitializeData(); } | |
67 }; | |
68 | |
69 TEST_F(PicturePileTest, InvalidationOnTileBorderOutsideInterestRect) { | |
70 // Don't expand the interest rect past what we invalidate. | |
71 pile_.SetPixelRecordDistance(0); | |
72 | |
73 gfx::Size tile_size(100, 100); | |
74 pile_.tiling().SetMaxTextureSize(tile_size); | |
75 | |
76 gfx::Size pile_size(400, 400); | |
77 SetTilingSize(pile_size); | |
78 | |
79 // We have multiple tiles. | |
80 EXPECT_GT(pile_.tiling().num_tiles_x(), 2); | |
81 EXPECT_GT(pile_.tiling().num_tiles_y(), 2); | |
82 | |
83 // Record everything. | |
84 Region invalidation(tiling_rect()); | |
85 UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect()); | |
86 | |
87 // +----------+-----------------+-----------+ | |
88 // | | VVVV 1,0| | | |
89 // | | VVVV | | | |
90 // | | VVVV | | | |
91 // | ...|.................|... | | |
92 // | ...|.................|... | | |
93 // +----------+-----------------+-----------+ | |
94 // | ...| |... | | |
95 // | ...| |... | | |
96 // | ...| |... | | |
97 // | ...| |... | | |
98 // | ...| 1,1|... | | |
99 // +----------+-----------------+-----------+ | |
100 // | ...|.................|... | | |
101 // | ...|.................|... | | |
102 // +----------+-----------------+-----------+ | |
103 // | |
104 // .. = border pixels for tile 1,1 | |
105 // VV = interest rect (what we will record) | |
106 // | |
107 // The first invalidation is inside VV, so it does not touch border pixels of | |
108 // tile 1,1. | |
109 // | |
110 // The second invalidation goes below VV into the .. border pixels of 1,1. | |
111 | |
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(), | |
116 0, | |
117 10, | |
118 pile_.tiling().TileSizeY(0) - pile_.tiling().border_texels()); | |
119 | |
120 // Invalidate tile 1,0 only. This is a rect that avoids the borders of any | |
121 // other tiles. | |
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); | |
128 | |
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()); | |
143 } | |
144 | |
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()); | |
150 | |
151 EXPECT_EQ(1, pile_.tiling().num_tiles_x()); | |
152 EXPECT_EQ(1, pile_.tiling().num_tiles_y()); | |
153 | |
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_); | |
160 | |
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(); | |
165 } | |
166 | |
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()); | |
172 | |
173 EXPECT_EQ(1, pile_.tiling().num_tiles_x()); | |
174 EXPECT_EQ(1, pile_.tiling().num_tiles_y()); | |
175 | |
176 FakePicturePile::PictureInfo& picture_info = | |
177 pile_.picture_map().find(FakePicturePile::PictureMapKey(0, 0))->second; | |
178 EXPECT_TRUE(!!picture_info.GetPicture()); | |
179 | |
180 int expected_inflation = pile_.buffer_pixels(); | |
181 | |
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()); | |
187 } | |
188 | |
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); | |
194 | |
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()); | |
198 | |
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()); | |
202 | |
203 // Invalidate everything to have a non zero invalidation frequency. | |
204 UpdateWholePile(); | |
205 | |
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, | |
211 50, | |
212 50)); | |
213 Region expected_invalidation = invalidate_rect; | |
214 UpdateAndExpandInvalidation(&invalidate_rect, tiling_size(), tiling_rect()); | |
215 EXPECT_EQ(expected_invalidation.ToString(), invalidate_rect.ToString()); | |
216 | |
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 = | |
220 pile_.picture_map() | |
221 .find(FakePicturePile::PictureMapKey(i, j)) | |
222 ->second; | |
223 | |
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)) { | |
227 EXPECT_FLOAT_EQ( | |
228 2.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED, | |
229 picture_info.GetInvalidationFrequencyForTesting()); | |
230 } else { | |
231 EXPECT_FLOAT_EQ( | |
232 1.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED, | |
233 picture_info.GetInvalidationFrequencyForTesting()); | |
234 } | |
235 } | |
236 } | |
237 } | |
238 | |
239 TEST_F(PicturePileTest, InvalidateOnFullLayer) { | |
240 UpdateWholePile(); | |
241 | |
242 // Everything was invalidated once so far. | |
243 for (auto& it : pile_.picture_map()) { | |
244 EXPECT_FLOAT_EQ( | |
245 1.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED, | |
246 it.second.GetInvalidationFrequencyForTesting()); | |
247 } | |
248 | |
249 // Invalidate everything, | |
250 Region invalidation = tiling_rect(); | |
251 UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect()); | |
252 | |
253 // Everything was invalidated again. | |
254 for (auto& it : pile_.picture_map()) { | |
255 EXPECT_FLOAT_EQ( | |
256 2.0f / FakePicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED, | |
257 it.second.GetInvalidationFrequencyForTesting()); | |
258 } | |
259 } | |
260 | |
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); | |
265 | |
266 gfx::Rect viewport(tiling_size().width(), 1); | |
267 | |
268 // Update the whole pile until the invalidation frequency is high. | |
269 for (int frame = 0; frame < 33; ++frame) { | |
270 UpdateWholePile(); | |
271 } | |
272 | |
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 = | |
277 pile_.picture_map() | |
278 .find(FakePicturePile::PictureMapKey(i, j)) | |
279 ->second; | |
280 EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting()) | |
281 << "i " << i << " j " << j; | |
282 } | |
283 } | |
284 | |
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()); | |
289 | |
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 = | |
293 pile_.picture_map() | |
294 .find(FakePicturePile::PictureMapKey(i, j)) | |
295 ->second; | |
296 EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting()); | |
297 | |
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. | |
300 if (j >= 2) | |
301 EXPECT_FALSE(picture_info.GetPicture()) << "i " << i << " j " << j; | |
302 else | |
303 EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j; | |
304 } | |
305 } | |
306 | |
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, | |
312 1, | |
313 1); | |
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(); | |
318 | |
319 // Now update with no invalidation and full viewport | |
320 Region empty_invalidation; | |
321 UpdateAndExpandInvalidation(&empty_invalidation, tiling_size(), | |
322 tiling_rect()); | |
323 EXPECT_EQ(Region().ToString(), empty_invalidation.ToString()); | |
324 | |
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 = | |
328 pile_.picture_map() | |
329 .find(FakePicturePile::PictureMapKey(i, j)) | |
330 ->second; | |
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); | |
334 | |
335 // We expect that there are pictures everywhere now. | |
336 EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j; | |
337 } | |
338 } | |
339 } | |
340 | |
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)); | |
345 | |
346 pile_.Clear(); | |
347 | |
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)); | |
352 } | |
353 | |
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); | |
362 | |
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); | |
367 | |
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)); | |
372 UpdateWholePile(); | |
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()); | |
380 | |
381 // Update the whole layer until the invalidation frequency is high. | |
382 for (int frame = 0; frame < 33; ++frame) { | |
383 UpdateWholePile(); | |
384 } | |
385 | |
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()); | |
391 | |
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()); | |
399 | |
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)); | |
404 } | |
405 | |
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()); | |
411 | |
412 // No invalidation, same viewport. | |
413 Region invalidation; | |
414 UpdateAndExpandInvalidation(&invalidation, tiling_size(), tiling_rect()); | |
415 EXPECT_TRUE(!pile_.recorded_viewport().IsEmpty()); | |
416 EXPECT_EQ(Region().ToString(), invalidation.ToString()); | |
417 | |
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()); | |
423 | |
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()); | |
430 } | |
431 | |
432 TEST_F(PicturePileTest, BigFullLayerInvalidation) { | |
433 gfx::Size huge_layer_size(100000000, 100000000); | |
434 gfx::Rect viewport(300000, 400000, 5000, 6000); | |
435 | |
436 // Resize the pile. | |
437 Region invalidation; | |
438 UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport); | |
439 | |
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); | |
448 } | |
449 | |
450 TEST_F(PicturePileTest, BigFullLayerInvalidationWithResizeGrow) { | |
451 gfx::Size huge_layer_size(100000000, 100000000); | |
452 gfx::Rect viewport(300000, 400000, 5000, 6000); | |
453 | |
454 // Resize the pile. | |
455 Region invalidation; | |
456 UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport); | |
457 | |
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); | |
469 } | |
470 | |
471 TEST_F(PicturePileTest, BigFullLayerInvalidationWithResizeShrink) { | |
472 gfx::Size huge_layer_size(100000000, 100000000); | |
473 gfx::Rect viewport(300000, 400000, 5000, 6000); | |
474 | |
475 // Resize the pile. | |
476 Region invalidation; | |
477 UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport); | |
478 | |
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); | |
490 } | |
491 | |
492 TEST_F(PicturePileTest, InvalidationOutsideRecordingRect) { | |
493 gfx::Size huge_layer_size(10000000, 20000000); | |
494 gfx::Rect viewport(300000, 400000, 5000, 6000); | |
495 | |
496 // Resize the pile and set up the interest rect. | |
497 Region invalidation; | |
498 UpdateAndExpandInvalidation(&invalidation, huge_layer_size, viewport); | |
499 | |
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()); | |
504 | |
505 // Invalidation outside the recording rect should expand to the tiles it | |
506 // covers. | |
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()); | |
518 } | |
519 | |
520 enum Corner { | |
521 TOP_LEFT, | |
522 TOP_RIGHT, | |
523 BOTTOM_LEFT, | |
524 BOTTOM_RIGHT, | |
525 }; | |
526 | |
527 class PicturePileResizeCornerTest : public PicturePileTestBase, | |
528 public testing::TestWithParam<Corner> { | |
529 protected: | |
530 void SetUp() override { InitializeData(); } | |
531 | |
532 static gfx::Rect CornerSinglePixelRect(Corner corner, const gfx::Size& s) { | |
533 switch (corner) { | |
534 case TOP_LEFT: | |
535 return gfx::Rect(0, 0, 1, 1); | |
536 case TOP_RIGHT: | |
537 return gfx::Rect(s.width() - 1, 0, 1, 1); | |
538 case BOTTOM_LEFT: | |
539 return gfx::Rect(0, s.height() - 1, 1, 1); | |
540 case BOTTOM_RIGHT: | |
541 return gfx::Rect(s.width() - 1, s.height() - 1, 1, 1); | |
542 } | |
543 NOTREACHED(); | |
544 return gfx::Rect(); | |
545 } | |
546 }; | |
547 | |
548 TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) { | |
549 Corner corner = GetParam(); | |
550 | |
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. | |
556 int offset = -100; | |
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); | |
564 | |
565 Region invalidation; | |
566 Region expected_invalidation; | |
567 | |
568 pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size)); | |
569 SetTilingSize(base_tiling_size); | |
570 | |
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()); | |
580 } | |
581 } | |
582 | |
583 UpdateAndExpandInvalidation( | |
584 &invalidation, | |
585 grow_down_tiling_size, | |
586 CornerSinglePixelRect(corner, grow_down_tiling_size)); | |
587 | |
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()); | |
598 } | |
599 } | |
600 | |
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(); | |
612 | |
613 UpdateWholePile(); | |
614 UpdateAndExpandInvalidation(&invalidation, | |
615 base_tiling_size, | |
616 CornerSinglePixelRect(corner, base_tiling_size)); | |
617 | |
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); | |
627 bool expect_tile; | |
628 switch (corner) { | |
629 case TOP_LEFT: | |
630 case TOP_RIGHT: | |
631 expect_tile = j < 5; | |
632 break; | |
633 case BOTTOM_LEFT: | |
634 // The interest rect in the bottom left tile means we'll record it. | |
635 expect_tile = j < 5 || (j == 5 && i == 0); | |
636 break; | |
637 case BOTTOM_RIGHT: | |
638 // The interest rect in the bottom right tile means we'll record it. | |
639 expect_tile = j < 5 || (j == 5 && i == 5); | |
640 break; | |
641 } | |
642 EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); | |
643 } | |
644 } | |
645 | |
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 | |
650 // dropped. | |
651 gfx::Rect bottom_row_minus_existing_corner = gfx::UnionRects( | |
652 pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5)); | |
653 switch (corner) { | |
654 case TOP_LEFT: | |
655 case TOP_RIGHT: | |
656 // No tiles are kept in the changed region because it doesn't | |
657 // intersect with the interest rect. | |
658 break; | |
659 case BOTTOM_LEFT: | |
660 bottom_row_minus_existing_corner.Subtract( | |
661 pile_.tiling().TileBounds(0, 5)); | |
662 break; | |
663 case BOTTOM_RIGHT: | |
664 bottom_row_minus_existing_corner.Subtract( | |
665 pile_.tiling().TileBounds(5, 5)); | |
666 break; | |
667 } | |
668 | |
669 expected_invalidation.Union(bottom_row_minus_existing_corner); | |
670 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
671 invalidation.Clear(); | |
672 | |
673 UpdateWholePile(); | |
674 UpdateAndExpandInvalidation( | |
675 &invalidation, | |
676 grow_right_tiling_size, | |
677 CornerSinglePixelRect(corner, grow_right_tiling_size)); | |
678 | |
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 | |
681 // right of it). | |
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()); | |
690 } | |
691 } | |
692 | |
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(); | |
704 | |
705 UpdateWholePile(); | |
706 UpdateAndExpandInvalidation(&invalidation, | |
707 base_tiling_size, | |
708 CornerSinglePixelRect(corner, base_tiling_size)); | |
709 | |
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); | |
719 bool expect_tile; | |
720 switch (corner) { | |
721 case TOP_LEFT: | |
722 case BOTTOM_LEFT: | |
723 // No tiles are kept in the changed region because it doesn't | |
724 // intersect with the interest rect. | |
725 expect_tile = i < 5; | |
726 break; | |
727 case TOP_RIGHT: | |
728 // The interest rect in the top right tile means we'll record it. | |
729 expect_tile = i < 5 || (j == 0 && i == 5); | |
730 break; | |
731 case BOTTOM_RIGHT: | |
732 // The interest rect in the bottom right tile means we'll record it. | |
733 expect_tile = i < 5 || (j == 5 && i == 5); | |
734 break; | |
735 } | |
736 EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); | |
737 } | |
738 } | |
739 | |
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) | |
744 // are dropped. | |
745 gfx::Rect right_column_minus_existing_corner = gfx::UnionRects( | |
746 pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5)); | |
747 switch (corner) { | |
748 case TOP_LEFT: | |
749 case BOTTOM_LEFT: | |
750 break; | |
751 case TOP_RIGHT: | |
752 right_column_minus_existing_corner.Subtract( | |
753 pile_.tiling().TileBounds(5, 0)); | |
754 break; | |
755 case BOTTOM_RIGHT: | |
756 right_column_minus_existing_corner.Subtract( | |
757 pile_.tiling().TileBounds(5, 5)); | |
758 break; | |
759 } | |
760 expected_invalidation.Union(right_column_minus_existing_corner); | |
761 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
762 invalidation.Clear(); | |
763 | |
764 UpdateWholePile(); | |
765 UpdateAndExpandInvalidation( | |
766 &invalidation, | |
767 grow_both_tiling_size, | |
768 CornerSinglePixelRect(corner, grow_both_tiling_size)); | |
769 | |
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()); | |
779 } | |
780 } | |
781 | |
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(); | |
796 | |
797 UpdateWholePile(); | |
798 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, | |
799 CornerSinglePixelRect(corner, base_tiling_size)); | |
800 | |
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); | |
810 bool expect_tile; | |
811 switch (corner) { | |
812 case TOP_LEFT: | |
813 expect_tile = i < 5 && j < 5; | |
814 break; | |
815 case TOP_RIGHT: | |
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); | |
818 break; | |
819 case BOTTOM_LEFT: | |
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); | |
822 break; | |
823 case BOTTOM_RIGHT: | |
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); | |
826 break; | |
827 } | |
828 EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()) | |
829 << i << "," << j; | |
830 } | |
831 } | |
832 | |
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; | |
840 switch (corner) { | |
841 case TOP_LEFT: | |
842 break; | |
843 case BOTTOM_LEFT: | |
844 right_column_and_bottom_row_minus_existing_corner.Subtract( | |
845 pile_.tiling().TileBounds(0, 5)); | |
846 break; | |
847 case TOP_RIGHT: | |
848 right_column_and_bottom_row_minus_existing_corner.Subtract( | |
849 pile_.tiling().TileBounds(5, 0)); | |
850 break; | |
851 case BOTTOM_RIGHT: | |
852 right_column_and_bottom_row_minus_existing_corner.Subtract( | |
853 pile_.tiling().TileBounds(5, 5)); | |
854 break; | |
855 } | |
856 expected_invalidation.Union( | |
857 right_column_and_bottom_row_minus_existing_corner); | |
858 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
859 invalidation.Clear(); | |
860 } | |
861 | |
862 TEST_P(PicturePileResizeCornerTest, SmallResizePileOutsideInterestRect) { | |
863 Corner corner = GetParam(); | |
864 | |
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. | |
870 int offset = -100; | |
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); | |
878 | |
879 Region invalidation; | |
880 Region expected_invalidation; | |
881 | |
882 pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size)); | |
883 SetTilingSize(base_tiling_size); | |
884 | |
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()); | |
894 } | |
895 } | |
896 | |
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 }; | |
901 | |
902 // Grow downward. | |
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; | |
906 UpdateWholePile(); | |
907 UpdateAndExpandInvalidation(&invalidation, new_tiling_size, | |
908 CornerSinglePixelRect(corner, new_tiling_size)); | |
909 | |
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); | |
919 bool expect_tile; | |
920 switch (corner) { | |
921 case TOP_LEFT: | |
922 case TOP_RIGHT: | |
923 expect_tile = j < 5; | |
924 break; | |
925 case BOTTOM_LEFT: | |
926 // The interest rect in the bottom left tile means we'll record it. | |
927 expect_tile = j < 5 || (j == 5 && i == 0); | |
928 break; | |
929 case BOTTOM_RIGHT: | |
930 // The interest rect in the bottom right tile means we'll record it. | |
931 expect_tile = j < 5 || (j == 5 && i == 5); | |
932 break; | |
933 } | |
934 EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); | |
935 } | |
936 } | |
937 | |
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. | |
941 if (dir == GROW) { | |
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. | |
945 switch (corner) { | |
946 case TOP_LEFT: | |
947 case TOP_RIGHT: | |
948 expected_invalidation = gfx::UnionRects( | |
949 pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5)); | |
950 break; | |
951 case BOTTOM_LEFT: | |
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))); | |
956 break; | |
957 case BOTTOM_RIGHT: | |
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))); | |
962 break; | |
963 } | |
964 } | |
965 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
966 invalidation.Clear(); | |
967 } | |
968 | |
969 // Grow right. | |
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; | |
973 UpdateWholePile(); | |
974 UpdateAndExpandInvalidation(&invalidation, new_tiling_size, | |
975 CornerSinglePixelRect(corner, new_tiling_size)); | |
976 | |
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); | |
985 bool expect_tile; | |
986 switch (corner) { | |
987 case TOP_LEFT: | |
988 case BOTTOM_LEFT: | |
989 expect_tile = i < 5; | |
990 break; | |
991 case TOP_RIGHT: | |
992 // The interest rect in the top right tile means we'll record it. | |
993 expect_tile = i < 5 || (j == 0 && i == 5); | |
994 break; | |
995 case BOTTOM_RIGHT: | |
996 // The interest rect in the bottom right tile means we'll record it. | |
997 expect_tile = i < 5 || (j == 5 && i == 5); | |
998 break; | |
999 } | |
1000 EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()); | |
1001 } | |
1002 } | |
1003 | |
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. | |
1007 if (dir == GROW) { | |
1008 // Calculate the expected invalidation the first time through the loop. | |
1009 switch (corner) { | |
1010 case TOP_LEFT: | |
1011 case BOTTOM_LEFT: | |
1012 expected_invalidation = gfx::UnionRects( | |
1013 pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5)); | |
1014 break; | |
1015 case TOP_RIGHT: | |
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))); | |
1020 break; | |
1021 case BOTTOM_RIGHT: | |
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))); | |
1026 break; | |
1027 } | |
1028 } | |
1029 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
1030 invalidation.Clear(); | |
1031 } | |
1032 | |
1033 // Grow both. | |
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; | |
1037 UpdateWholePile(); | |
1038 UpdateAndExpandInvalidation(&invalidation, new_tiling_size, | |
1039 CornerSinglePixelRect(corner, new_tiling_size)); | |
1040 | |
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); | |
1051 bool expect_tile; | |
1052 switch (corner) { | |
1053 case TOP_LEFT: | |
1054 expect_tile = i < 5 && j < 5; | |
1055 break; | |
1056 case TOP_RIGHT: | |
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); | |
1059 break; | |
1060 case BOTTOM_LEFT: | |
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); | |
1063 break; | |
1064 case BOTTOM_RIGHT: | |
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); | |
1067 break; | |
1068 } | |
1069 EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture()) | |
1070 << i << "," << j; | |
1071 } | |
1072 } | |
1073 | |
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. | |
1077 if (dir == GROW) { | |
1078 // Calculate the expected invalidation the first time through the loop. | |
1079 switch (corner) { | |
1080 case TOP_LEFT: | |
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))); | |
1086 break; | |
1087 case TOP_RIGHT: | |
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))); | |
1095 break; | |
1096 case BOTTOM_LEFT: | |
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))); | |
1104 break; | |
1105 case BOTTOM_RIGHT: | |
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))); | |
1113 break; | |
1114 } | |
1115 } | |
1116 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
1117 invalidation.Clear(); | |
1118 } | |
1119 } | |
1120 | |
1121 INSTANTIATE_TEST_CASE_P( | |
1122 PicturePileResizeCornerTests, | |
1123 PicturePileResizeCornerTest, | |
1124 ::testing::Values(TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT)); | |
1125 | |
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 | |
1129 // dimension. | |
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); | |
1135 | |
1136 Region invalidation; | |
1137 Region expected_invalidation; | |
1138 | |
1139 pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size)); | |
1140 SetTilingSize(base_tiling_size); | |
1141 | |
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()); | |
1151 } | |
1152 } | |
1153 | |
1154 UpdateAndExpandInvalidation( | |
1155 &invalidation, grow_down_tiling_size, gfx::Rect(1, 1)); | |
1156 | |
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()); | |
1166 } | |
1167 } | |
1168 | |
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(); | |
1179 | |
1180 UpdateWholePile(); | |
1181 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1)); | |
1182 | |
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()); | |
1192 } | |
1193 } | |
1194 | |
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(); | |
1201 | |
1202 UpdateWholePile(); | |
1203 UpdateAndExpandInvalidation( | |
1204 &invalidation, grow_right_tiling_size, gfx::Rect(1, 1)); | |
1205 | |
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()); | |
1215 } | |
1216 } | |
1217 | |
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(); | |
1228 | |
1229 UpdateWholePile(); | |
1230 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1)); | |
1231 | |
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()); | |
1241 } | |
1242 } | |
1243 | |
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(); | |
1250 | |
1251 UpdateWholePile(); | |
1252 UpdateAndExpandInvalidation( | |
1253 &invalidation, grow_both_tiling_size, gfx::Rect(1, 1)); | |
1254 | |
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()); | |
1264 } | |
1265 } | |
1266 | |
1267 // We invalidated the newly exposed pixels on the bottom row and right column | |
1268 // of tiles. | |
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)); | |
1277 EXPECT_TRUE( | |
1278 expected_invalidation.Contains(bottom_row_and_right_column_new_pixels)); | |
1279 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
1280 invalidation.Clear(); | |
1281 | |
1282 UpdateWholePile(); | |
1283 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect()); | |
1284 | |
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()); | |
1294 } | |
1295 } | |
1296 | |
1297 // We invalidated the previously exposed pixels on the bottom row and right | |
1298 // column of tiles. | |
1299 expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size), | |
1300 gfx::Rect(base_tiling_size)); | |
1301 EXPECT_TRUE( | |
1302 expected_invalidation.Contains(bottom_row_and_right_column_new_pixels)); | |
1303 EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString()); | |
1304 invalidation.Clear(); | |
1305 } | |
1306 | |
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 | |
1310 // dimension. | |
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); | |
1316 | |
1317 Region invalidation; | |
1318 Region expected_invalidation; | |
1319 | |
1320 pile_.tiling().SetMaxTextureSize(gfx::Size(tile_size, tile_size)); | |
1321 SetTilingSize(base_tiling_size); | |
1322 | |
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()); | |
1332 } | |
1333 } | |
1334 | |
1335 UpdateAndExpandInvalidation( | |
1336 &invalidation, grow_down_tiling_size, gfx::Rect(1, 1)); | |
1337 | |
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()); | |
1347 } | |
1348 } | |
1349 | |
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(); | |
1355 | |
1356 UpdateWholePile(); | |
1357 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1)); | |
1358 | |
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()); | |
1368 } | |
1369 } | |
1370 | |
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(); | |
1376 | |
1377 UpdateWholePile(); | |
1378 UpdateAndExpandInvalidation( | |
1379 &invalidation, grow_right_tiling_size, gfx::Rect(1, 1)); | |
1380 | |
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()); | |
1390 } | |
1391 } | |
1392 | |
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(); | |
1398 | |
1399 UpdateWholePile(); | |
1400 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1)); | |
1401 | |
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()); | |
1411 } | |
1412 } | |
1413 | |
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(); | |
1419 | |
1420 UpdateWholePile(); | |
1421 UpdateAndExpandInvalidation( | |
1422 &invalidation, grow_both_tiling_size, gfx::Rect(1, 1)); | |
1423 | |
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()); | |
1433 } | |
1434 } | |
1435 | |
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(); | |
1441 | |
1442 UpdateWholePile(); | |
1443 UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect()); | |
1444 | |
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()); | |
1454 } | |
1455 } | |
1456 | |
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(); | |
1462 } | |
1463 | |
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()); | |
1470 | |
1471 // If there is a single rect that covers the view, the solid | |
1472 // state will be true. | |
1473 SkPaint paint; | |
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()); | |
1480 | |
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()); | |
1489 | |
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()); | |
1497 | |
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()); | |
1508 } | |
1509 | |
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! | |
1519 pile_.Clear(); | |
1520 | |
1521 SkPaint paint; | |
1522 paint.setColor(SK_ColorCYAN); | |
1523 | |
1524 // Add a rect that doesn't cover the viewport completely, the solid state | |
1525 // will be false. | |
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()); | |
1532 } | |
1533 | |
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()); | |
1544 } | |
1545 | |
1546 } // namespace | |
1547 } // namespace cc | |
OLD | NEW |