EnrollmentScreen source code cosmetics.
[chromium-blink-merge.git] / cc / resources / picture_layer_tiling_unittest.cc
blob86f60ac877309014e4acd2c4cbf4ac7231ec5ee7
1 // Copyright 2012 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.
5 #include "cc/resources/picture_layer_tiling.h"
7 #include <limits>
8 #include <set>
10 #include "cc/base/math_util.h"
11 #include "cc/resources/picture_layer_tiling_set.h"
12 #include "cc/test/fake_output_surface.h"
13 #include "cc/test/fake_output_surface_client.h"
14 #include "cc/test/fake_picture_layer_tiling_client.h"
15 #include "cc/test/test_context_provider.h"
16 #include "cc/test/test_shared_bitmap_manager.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/gfx/rect_conversions.h"
19 #include "ui/gfx/size_conversions.h"
21 namespace cc {
22 namespace {
24 static gfx::Rect ViewportInLayerSpace(
25 const gfx::Transform& transform,
26 const gfx::Size& device_viewport) {
28 gfx::Transform inverse;
29 if (!transform.GetInverse(&inverse))
30 return gfx::Rect();
32 gfx::RectF viewport_in_layer_space = MathUtil::ProjectClippedRect(
33 inverse, gfx::RectF(gfx::Point(0, 0), device_viewport));
34 return ToEnclosingRect(viewport_in_layer_space);
37 static void UpdateAllTilePriorities(PictureLayerTilingSet* set,
38 WhichTree tree,
39 const gfx::Rect& visible_layer_rect,
40 float layer_contents_scale,
41 double current_frame_time_in_seconds) {
42 for (size_t i = 0; i < set->num_tilings(); ++i) {
43 set->tiling_at(i)->UpdateTilePriorities(tree,
44 visible_layer_rect,
45 layer_contents_scale,
46 current_frame_time_in_seconds,
47 NULL,
48 NULL,
49 gfx::Transform());
53 class TestablePictureLayerTiling : public PictureLayerTiling {
54 public:
55 using PictureLayerTiling::SetLiveTilesRect;
56 using PictureLayerTiling::TileAt;
58 static scoped_ptr<TestablePictureLayerTiling> Create(
59 float contents_scale,
60 const gfx::Size& layer_bounds,
61 PictureLayerTilingClient* client) {
62 return make_scoped_ptr(new TestablePictureLayerTiling(
63 contents_scale,
64 layer_bounds,
65 client));
68 using PictureLayerTiling::ComputeSkewport;
70 protected:
71 TestablePictureLayerTiling(float contents_scale,
72 const gfx::Size& layer_bounds,
73 PictureLayerTilingClient* client)
74 : PictureLayerTiling(contents_scale, layer_bounds, client) { }
77 class PictureLayerTilingIteratorTest : public testing::Test {
78 public:
79 PictureLayerTilingIteratorTest() {}
80 virtual ~PictureLayerTilingIteratorTest() {}
82 void Initialize(const gfx::Size& tile_size,
83 float contents_scale,
84 const gfx::Size& layer_bounds) {
85 client_.SetTileSize(tile_size);
86 tiling_ = TestablePictureLayerTiling::Create(contents_scale,
87 layer_bounds,
88 &client_);
91 void SetLiveRectAndVerifyTiles(const gfx::Rect& live_tiles_rect) {
92 tiling_->SetLiveTilesRect(live_tiles_rect);
94 std::vector<Tile*> tiles = tiling_->AllTilesForTesting();
95 for (std::vector<Tile*>::iterator iter = tiles.begin();
96 iter != tiles.end();
97 ++iter) {
98 EXPECT_TRUE(live_tiles_rect.Intersects((*iter)->content_rect()));
102 void VerifyTilesExactlyCoverRect(
103 float rect_scale,
104 const gfx::Rect& request_rect,
105 const gfx::Rect& expect_rect) {
106 EXPECT_TRUE(request_rect.Contains(expect_rect));
108 // Iterators are not valid if this ratio is too large (i.e. the
109 // tiling is too high-res for a low-res destination rect.) This is an
110 // artifact of snapping geometry to integer coordinates and then mapping
111 // back to floating point texture coordinates.
112 float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
113 ASSERT_LE(dest_to_contents_scale, 2.0);
115 Region remaining = expect_rect;
116 for (PictureLayerTiling::CoverageIterator
117 iter(tiling_.get(), rect_scale, request_rect);
118 iter;
119 ++iter) {
120 // Geometry cannot overlap previous geometry at all
121 gfx::Rect geometry = iter.geometry_rect();
122 EXPECT_TRUE(expect_rect.Contains(geometry));
123 EXPECT_TRUE(remaining.Contains(geometry));
124 remaining.Subtract(geometry);
126 // Sanity check that texture coords are within the texture rect.
127 gfx::RectF texture_rect = iter.texture_rect();
128 EXPECT_GE(texture_rect.x(), 0);
129 EXPECT_GE(texture_rect.y(), 0);
130 EXPECT_LE(texture_rect.right(), client_.TileSize().width());
131 EXPECT_LE(texture_rect.bottom(), client_.TileSize().height());
133 EXPECT_EQ(iter.texture_size(), client_.TileSize());
136 // The entire rect must be filled by geometry from the tiling.
137 EXPECT_TRUE(remaining.IsEmpty());
140 void VerifyTilesExactlyCoverRect(float rect_scale, const gfx::Rect& rect) {
141 VerifyTilesExactlyCoverRect(rect_scale, rect, rect);
144 void VerifyTiles(
145 float rect_scale,
146 const gfx::Rect& rect,
147 base::Callback<void(Tile* tile,
148 const gfx::Rect& geometry_rect)> callback) {
149 VerifyTiles(tiling_.get(),
150 rect_scale,
151 rect,
152 callback);
155 void VerifyTiles(
156 PictureLayerTiling* tiling,
157 float rect_scale,
158 const gfx::Rect& rect,
159 base::Callback<void(Tile* tile,
160 const gfx::Rect& geometry_rect)> callback) {
161 Region remaining = rect;
162 for (PictureLayerTiling::CoverageIterator iter(tiling, rect_scale, rect);
163 iter;
164 ++iter) {
165 remaining.Subtract(iter.geometry_rect());
166 callback.Run(*iter, iter.geometry_rect());
168 EXPECT_TRUE(remaining.IsEmpty());
171 void VerifyTilesCoverNonContainedRect(float rect_scale,
172 const gfx::Rect& dest_rect) {
173 float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
174 gfx::Rect clamped_rect = gfx::ScaleToEnclosingRect(
175 gfx::Rect(tiling_->tiling_size()), 1.f / dest_to_contents_scale);
176 clamped_rect.Intersect(dest_rect);
177 VerifyTilesExactlyCoverRect(rect_scale, dest_rect, clamped_rect);
180 void set_max_tiles_for_interest_area(size_t area) {
181 client_.set_max_tiles_for_interest_area(area);
184 protected:
185 FakePictureLayerTilingClient client_;
186 scoped_ptr<TestablePictureLayerTiling> tiling_;
188 private:
189 DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest);
192 TEST_F(PictureLayerTilingIteratorTest, ResizeDeletesTiles) {
193 // Verifies that a resize with invalidation for newly exposed pixels will
194 // deletes tiles that intersect that invalidation.
195 gfx::Size tile_size(100, 100);
196 gfx::Size original_layer_size(10, 10);
197 Initialize(tile_size, 1.f, original_layer_size);
198 SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
200 // Tiling only has one tile, since its total size is less than one.
201 EXPECT_TRUE(tiling_->TileAt(0, 0));
203 // Stop creating tiles so that any invalidations are left as holes.
204 client_.set_allow_create_tile(false);
206 Region invalidation =
207 SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
208 tiling_->UpdateTilesToCurrentPile(invalidation, gfx::Size(200, 200));
209 EXPECT_FALSE(tiling_->TileAt(0, 0));
212 TEST_F(PictureLayerTilingIteratorTest, ResizeOverBorderPixelsDeletesTiles) {
213 // Verifies that a resize with invalidation for newly exposed pixels will
214 // deletes tiles that intersect that invalidation.
215 gfx::Size tile_size(100, 100);
216 gfx::Size original_layer_size(99, 99);
217 Initialize(tile_size, 1.f, original_layer_size);
218 SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
220 // Tiling only has one tile, since its total size is less than one.
221 EXPECT_TRUE(tiling_->TileAt(0, 0));
223 // Stop creating tiles so that any invalidations are left as holes.
224 client_.set_allow_create_tile(false);
226 Region invalidation =
227 SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
228 tiling_->UpdateTilesToCurrentPile(invalidation, gfx::Size(200, 200));
229 EXPECT_FALSE(tiling_->TileAt(0, 0));
231 // The original tile was the same size after resize, but it would include new
232 // border pixels.
233 EXPECT_EQ(gfx::Rect(original_layer_size),
234 tiling_->TilingDataForTesting().TileBounds(0, 0));
237 TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) {
238 Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
239 SetLiveRectAndVerifyTiles(gfx::Rect(100, 100));
240 SetLiveRectAndVerifyTiles(gfx::Rect(101, 99));
241 SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
242 SetLiveRectAndVerifyTiles(gfx::Rect(1, 801));
243 SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
244 SetLiveRectAndVerifyTiles(gfx::Rect(201, 800));
247 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsNoScale) {
248 Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
249 VerifyTilesExactlyCoverRect(1, gfx::Rect());
250 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1099, 801));
251 VerifyTilesExactlyCoverRect(1, gfx::Rect(52, 83, 789, 412));
253 // With borders, a size of 3x3 = 1 pixel of content.
254 Initialize(gfx::Size(3, 3), 1, gfx::Size(10, 10));
255 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
256 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
257 VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
258 VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2));
261 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsTilingScale) {
262 Initialize(gfx::Size(200, 100), 2.0f, gfx::Size(1005, 2010));
263 VerifyTilesExactlyCoverRect(1, gfx::Rect());
264 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
265 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
267 Initialize(gfx::Size(3, 3), 2.0f, gfx::Size(10, 10));
268 VerifyTilesExactlyCoverRect(1, gfx::Rect());
269 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
270 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
271 VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
272 VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2));
274 Initialize(gfx::Size(100, 200), 0.5f, gfx::Size(1005, 2010));
275 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
276 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
278 Initialize(gfx::Size(150, 250), 0.37f, gfx::Size(1005, 2010));
279 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
280 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
282 Initialize(gfx::Size(312, 123), 0.01f, gfx::Size(1005, 2010));
283 VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
284 VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
287 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsBothScale) {
288 Initialize(gfx::Size(50, 50), 4.0f, gfx::Size(800, 600));
289 VerifyTilesExactlyCoverRect(2.0f, gfx::Rect());
290 VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(0, 0, 1600, 1200));
291 VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(512, 365, 253, 182));
293 float scale = 6.7f;
294 gfx::Size bounds(800, 600);
295 gfx::Rect full_rect(gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale)));
296 Initialize(gfx::Size(256, 512), 5.2f, bounds);
297 VerifyTilesExactlyCoverRect(scale, full_rect);
298 VerifyTilesExactlyCoverRect(scale, gfx::Rect(2014, 1579, 867, 1033));
301 TEST_F(PictureLayerTilingIteratorTest, IteratorEmptyRect) {
302 Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600));
304 gfx::Rect empty;
305 PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1.0f, empty);
306 EXPECT_FALSE(iter);
309 TEST_F(PictureLayerTilingIteratorTest, NonIntersectingRect) {
310 Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600));
311 gfx::Rect non_intersecting(1000, 1000, 50, 50);
312 PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1, non_intersecting);
313 EXPECT_FALSE(iter);
316 TEST_F(PictureLayerTilingIteratorTest, LayerEdgeTextureCoordinates) {
317 Initialize(gfx::Size(300, 300), 1.0f, gfx::Size(256, 256));
318 // All of these sizes are 256x256, scaled and ceiled.
319 VerifyTilesExactlyCoverRect(1.0f, gfx::Rect(0, 0, 256, 256));
320 VerifyTilesExactlyCoverRect(0.8f, gfx::Rect(0, 0, 205, 205));
321 VerifyTilesExactlyCoverRect(1.2f, gfx::Rect(0, 0, 308, 308));
324 TEST_F(PictureLayerTilingIteratorTest, NonContainedDestRect) {
325 Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(400, 400));
327 // Too large in all dimensions
328 VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, -1000, 2000, 2000));
329 VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, -1000, 2000, 2000));
330 VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, -1000, 2000, 2000));
332 // Partially covering content, but too large
333 VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, 100, 2000, 100));
334 VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, 100, 2000, 100));
335 VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, 100, 2000, 100));
338 TEST(PictureLayerTilingTest, SkewportLimits) {
339 FakePictureLayerTilingClient client;
340 client.set_skewport_extrapolation_limit_in_content_pixels(75);
341 scoped_ptr<TestablePictureLayerTiling> tiling;
343 gfx::Rect viewport(0, 0, 100, 100);
344 gfx::Size layer_bounds(200, 200);
346 client.SetTileSize(gfx::Size(100, 100));
347 tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
349 tiling->UpdateTilePriorities(
350 ACTIVE_TREE, viewport, 1.f, 1.0, NULL, NULL, gfx::Transform());
352 // Move viewport down 50 pixels in 0.5 seconds.
353 gfx::Rect down_skewport =
354 tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100));
356 EXPECT_EQ(0, down_skewport.x());
357 EXPECT_EQ(50, down_skewport.y());
358 EXPECT_EQ(100, down_skewport.width());
359 EXPECT_EQ(175, down_skewport.height());
360 EXPECT_TRUE(down_skewport.Contains(gfx::Rect(0, 50, 100, 100)));
362 // Move viewport down 50 and right 10 pixels.
363 gfx::Rect down_right_skewport =
364 tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100));
366 EXPECT_EQ(10, down_right_skewport.x());
367 EXPECT_EQ(50, down_right_skewport.y());
368 EXPECT_EQ(120, down_right_skewport.width());
369 EXPECT_EQ(175, down_right_skewport.height());
370 EXPECT_TRUE(down_right_skewport.Contains(gfx::Rect(10, 50, 100, 100)));
372 // Move viewport left.
373 gfx::Rect left_skewport =
374 tiling->ComputeSkewport(1.5, gfx::Rect(-50, 0, 100, 100));
376 EXPECT_EQ(-125, left_skewport.x());
377 EXPECT_EQ(0, left_skewport.y());
378 EXPECT_EQ(175, left_skewport.width());
379 EXPECT_EQ(100, left_skewport.height());
380 EXPECT_TRUE(left_skewport.Contains(gfx::Rect(-50, 0, 100, 100)));
382 // Expand viewport.
383 gfx::Rect expand_skewport =
384 tiling->ComputeSkewport(1.5, gfx::Rect(-50, -50, 200, 200));
386 // x and y moved by -75 (-50 - 75 = -125).
387 // right side and bottom side moved by 75 [(350 - 125) - (200 - 50) = 75].
388 EXPECT_EQ(-125, expand_skewport.x());
389 EXPECT_EQ(-125, expand_skewport.y());
390 EXPECT_EQ(350, expand_skewport.width());
391 EXPECT_EQ(350, expand_skewport.height());
392 EXPECT_TRUE(expand_skewport.Contains(gfx::Rect(-50, -50, 200, 200)));
394 // Expand the viewport past the limit.
395 gfx::Rect big_expand_skewport =
396 tiling->ComputeSkewport(1.5, gfx::Rect(-500, -500, 1500, 1500));
398 EXPECT_EQ(-575, big_expand_skewport.x());
399 EXPECT_EQ(-575, big_expand_skewport.y());
400 EXPECT_EQ(1650, big_expand_skewport.width());
401 EXPECT_EQ(1650, big_expand_skewport.height());
402 EXPECT_TRUE(big_expand_skewport.Contains(gfx::Rect(-500, -500, 1500, 1500)));
405 TEST(PictureLayerTilingTest, ComputeSkewport) {
406 FakePictureLayerTilingClient client;
407 scoped_ptr<TestablePictureLayerTiling> tiling;
409 gfx::Rect viewport(0, 0, 100, 100);
410 gfx::Size layer_bounds(200, 200);
412 client.SetTileSize(gfx::Size(100, 100));
413 tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
415 tiling->UpdateTilePriorities(
416 ACTIVE_TREE, viewport, 1.f, 1.0, NULL, NULL, gfx::Transform());
418 // Move viewport down 50 pixels in 0.5 seconds.
419 gfx::Rect down_skewport =
420 tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100));
422 EXPECT_EQ(0, down_skewport.x());
423 EXPECT_EQ(50, down_skewport.y());
424 EXPECT_EQ(100, down_skewport.width());
425 EXPECT_EQ(200, down_skewport.height());
427 // Shrink viewport.
428 gfx::Rect shrink_skewport =
429 tiling->ComputeSkewport(1.5, gfx::Rect(25, 25, 50, 50));
431 EXPECT_EQ(25, shrink_skewport.x());
432 EXPECT_EQ(25, shrink_skewport.y());
433 EXPECT_EQ(50, shrink_skewport.width());
434 EXPECT_EQ(50, shrink_skewport.height());
436 // Move viewport down 50 and right 10 pixels.
437 gfx::Rect down_right_skewport =
438 tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100));
440 EXPECT_EQ(10, down_right_skewport.x());
441 EXPECT_EQ(50, down_right_skewport.y());
442 EXPECT_EQ(120, down_right_skewport.width());
443 EXPECT_EQ(200, down_right_skewport.height());
445 // Move viewport left.
446 gfx::Rect left_skewport =
447 tiling->ComputeSkewport(1.5, gfx::Rect(-20, 0, 100, 100));
449 EXPECT_EQ(-60, left_skewport.x());
450 EXPECT_EQ(0, left_skewport.y());
451 EXPECT_EQ(140, left_skewport.width());
452 EXPECT_EQ(100, left_skewport.height());
454 // Expand viewport in 0.2 seconds.
455 gfx::Rect expanded_skewport =
456 tiling->ComputeSkewport(1.2, gfx::Rect(-5, -5, 110, 110));
458 EXPECT_EQ(-30, expanded_skewport.x());
459 EXPECT_EQ(-30, expanded_skewport.y());
460 EXPECT_EQ(160, expanded_skewport.width());
461 EXPECT_EQ(160, expanded_skewport.height());
464 TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
465 FakePictureLayerTilingClient client;
466 scoped_ptr<TestablePictureLayerTiling> tiling;
468 gfx::Rect viewport(0, 0, 100, 100);
469 gfx::Size layer_bounds(1500, 1500);
471 client.SetTileSize(gfx::Size(10, 10));
473 // Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10.
474 // The reason is that each tile has a one pixel border, so tile at (1, 2)
475 // for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at
476 // (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the
477 // tiling.
478 tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client);
479 gfx::Rect viewport_in_content_space =
480 gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
482 tiling->UpdateTilePriorities(
483 ACTIVE_TREE, viewport, 1.f, 1.0, NULL, NULL, gfx::Transform());
485 gfx::Rect soon_rect = viewport;
486 soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
487 gfx::Rect soon_rect_in_content_space =
488 gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
490 // Sanity checks.
491 for (int i = 0; i < 47; ++i) {
492 for (int j = 0; j < 47; ++j) {
493 EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j;
496 for (int i = 0; i < 47; ++i) {
497 EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i;
498 EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i;
501 // No movement in the viewport implies that tiles will either be NOW
502 // or EVENTUALLY, with the exception of tiles that are between 0 and 312
503 // pixels away from the viewport, which will be in the SOON bin.
504 bool have_now = false;
505 bool have_eventually = false;
506 bool have_soon = false;
507 for (int i = 0; i < 47; ++i) {
508 for (int j = 0; j < 47; ++j) {
509 Tile* tile = tiling->TileAt(i, j);
510 TilePriority priority = tile->priority(ACTIVE_TREE);
512 if (viewport_in_content_space.Intersects(tile->content_rect())) {
513 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
514 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
515 have_now = true;
516 } else if (soon_rect_in_content_space.Intersects(tile->content_rect())) {
517 EXPECT_EQ(TilePriority::SOON, priority.priority_bin);
518 have_soon = true;
519 } else {
520 EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin);
521 EXPECT_GT(priority.distance_to_visible, 0.f);
522 have_eventually = true;
527 EXPECT_TRUE(have_now);
528 EXPECT_TRUE(have_soon);
529 EXPECT_TRUE(have_eventually);
531 // Spot check some distances.
532 // Tile at 5, 1 should begin at 41x9 in content space (without borders),
533 // so the distance to a viewport that ends at 25x25 in content space
534 // should be 17 (41 - 25 + 1). In layer space, then that should be
535 // 17 / 0.25 = 68 pixels.
537 // We can verify that the content rect (with borders) is one pixel off
538 // 41,9 8x8 on all sides.
539 EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10");
541 TilePriority priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
542 EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
544 priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
545 EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
547 priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
548 EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible);
550 // Move the viewport down 40 pixels.
551 viewport = gfx::Rect(0, 40, 100, 100);
552 viewport_in_content_space =
553 gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
554 gfx::Rect skewport = tiling->ComputeSkewport(2.0, viewport_in_content_space);
556 soon_rect = viewport;
557 soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
558 soon_rect_in_content_space =
559 gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
561 EXPECT_EQ(0, skewport.x());
562 EXPECT_EQ(10, skewport.y());
563 EXPECT_EQ(25, skewport.width());
564 EXPECT_EQ(35, skewport.height());
566 tiling->UpdateTilePriorities(
567 ACTIVE_TREE, viewport, 1.f, 2.0, NULL, NULL, gfx::Transform());
569 have_now = false;
570 have_eventually = false;
571 have_soon = false;
573 // Viewport moved, so we expect to find some NOW tiles, some SOON tiles and
574 // some EVENTUALLY tiles.
575 for (int i = 0; i < 47; ++i) {
576 for (int j = 0; j < 47; ++j) {
577 Tile* tile = tiling->TileAt(i, j);
578 TilePriority priority = tile->priority(ACTIVE_TREE);
580 if (viewport_in_content_space.Intersects(tile->content_rect())) {
581 EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i
582 << " j: " << j;
583 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i
584 << " j: " << j;
585 have_now = true;
586 } else if (skewport.Intersects(tile->content_rect()) ||
587 soon_rect_in_content_space.Intersects(tile->content_rect())) {
588 EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i
589 << " j: " << j;
590 EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
591 << " j: " << j;
592 have_soon = true;
593 } else {
594 EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin)
595 << "i: " << i << " j: " << j;
596 EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
597 << " j: " << j;
598 have_eventually = true;
603 EXPECT_TRUE(have_now);
604 EXPECT_TRUE(have_soon);
605 EXPECT_TRUE(have_eventually);
607 priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
608 EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
610 priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
611 EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible);
613 priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
614 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
616 // Change the underlying layer scale.
617 tiling->UpdateTilePriorities(
618 ACTIVE_TREE, viewport, 2.0f, 3.0, NULL, NULL, gfx::Transform());
620 priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
621 EXPECT_FLOAT_EQ(34.f, priority.distance_to_visible);
623 priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
624 EXPECT_FLOAT_EQ(14.f, priority.distance_to_visible);
626 priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
627 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
630 TEST(PictureLayerTilingTest, ExpandRectEqual) {
631 gfx::Rect in(40, 50, 100, 200);
632 gfx::Rect bounds(-1000, -1000, 10000, 10000);
633 int64 target_area = 100 * 200;
634 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
635 in, target_area, bounds, NULL);
636 EXPECT_EQ(in.ToString(), out.ToString());
639 TEST(PictureLayerTilingTest, ExpandRectSmaller) {
640 gfx::Rect in(40, 50, 100, 200);
641 gfx::Rect bounds(-1000, -1000, 10000, 10000);
642 int64 target_area = 100 * 100;
643 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
644 in, target_area, bounds, NULL);
645 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
646 EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
647 EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
648 EXPECT_NEAR(100 * 100, out.width() * out.height(), 50);
649 EXPECT_TRUE(bounds.Contains(out));
652 TEST(PictureLayerTilingTest, ExpandRectUnbounded) {
653 gfx::Rect in(40, 50, 100, 200);
654 gfx::Rect bounds(-1000, -1000, 10000, 10000);
655 int64 target_area = 200 * 200;
656 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
657 in, target_area, bounds, NULL);
658 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
659 EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
660 EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
661 EXPECT_NEAR(200 * 200, out.width() * out.height(), 100);
662 EXPECT_TRUE(bounds.Contains(out));
665 TEST(PictureLayerTilingTest, ExpandRectBoundedSmaller) {
666 gfx::Rect in(40, 50, 100, 200);
667 gfx::Rect bounds(50, 60, 40, 30);
668 int64 target_area = 200 * 200;
669 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
670 in, target_area, bounds, NULL);
671 EXPECT_EQ(bounds.ToString(), out.ToString());
674 TEST(PictureLayerTilingTest, ExpandRectBoundedEqual) {
675 gfx::Rect in(40, 50, 100, 200);
676 gfx::Rect bounds = in;
677 int64 target_area = 200 * 200;
678 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
679 in, target_area, bounds, NULL);
680 EXPECT_EQ(bounds.ToString(), out.ToString());
683 TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchVertical) {
684 gfx::Rect in(40, 50, 100, 200);
685 gfx::Rect bounds(45, 0, 90, 300);
686 int64 target_area = 200 * 200;
687 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
688 in, target_area, bounds, NULL);
689 EXPECT_EQ(bounds.ToString(), out.ToString());
692 TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchVertical) {
693 gfx::Rect in(40, 50, 100, 200);
694 gfx::Rect bounds(40, 0, 100, 300);
695 int64 target_area = 200 * 200;
696 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
697 in, target_area, bounds, NULL);
698 EXPECT_EQ(bounds.ToString(), out.ToString());
701 TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchHorizontal) {
702 gfx::Rect in(40, 50, 100, 200);
703 gfx::Rect bounds(0, 55, 180, 190);
704 int64 target_area = 200 * 200;
705 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
706 in, target_area, bounds, NULL);
707 EXPECT_EQ(bounds.ToString(), out.ToString());
710 TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchHorizontal) {
711 gfx::Rect in(40, 50, 100, 200);
712 gfx::Rect bounds(0, 50, 180, 200);
713 int64 target_area = 200 * 200;
714 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
715 in, target_area, bounds, NULL);
716 EXPECT_EQ(bounds.ToString(), out.ToString());
719 TEST(PictureLayerTilingTest, ExpandRectBoundedLeft) {
720 gfx::Rect in(40, 50, 100, 200);
721 gfx::Rect bounds(20, -1000, 10000, 10000);
722 int64 target_area = 200 * 200;
723 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
724 in, target_area, bounds, NULL);
725 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
726 EXPECT_EQ(out.bottom() - in.bottom(), out.right() - in.right());
727 EXPECT_LE(out.width() * out.height(), target_area);
728 EXPECT_GT(out.width() * out.height(),
729 target_area - out.width() - out.height() * 2);
730 EXPECT_TRUE(bounds.Contains(out));
733 TEST(PictureLayerTilingTest, ExpandRectBoundedRight) {
734 gfx::Rect in(40, 50, 100, 200);
735 gfx::Rect bounds(-1000, -1000, 1000+120, 10000);
736 int64 target_area = 200 * 200;
737 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
738 in, target_area, bounds, NULL);
739 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
740 EXPECT_EQ(out.bottom() - in.bottom(), in.x() - out.x());
741 EXPECT_LE(out.width() * out.height(), target_area);
742 EXPECT_GT(out.width() * out.height(),
743 target_area - out.width() - out.height() * 2);
744 EXPECT_TRUE(bounds.Contains(out));
747 TEST(PictureLayerTilingTest, ExpandRectBoundedTop) {
748 gfx::Rect in(40, 50, 100, 200);
749 gfx::Rect bounds(-1000, 30, 10000, 10000);
750 int64 target_area = 200 * 200;
751 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
752 in, target_area, bounds, NULL);
753 EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
754 EXPECT_EQ(out.right() - in.right(), out.bottom() - in.bottom());
755 EXPECT_LE(out.width() * out.height(), target_area);
756 EXPECT_GT(out.width() * out.height(),
757 target_area - out.width() * 2 - out.height());
758 EXPECT_TRUE(bounds.Contains(out));
761 TEST(PictureLayerTilingTest, ExpandRectBoundedBottom) {
762 gfx::Rect in(40, 50, 100, 200);
763 gfx::Rect bounds(-1000, -1000, 10000, 1000 + 220);
764 int64 target_area = 200 * 200;
765 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
766 in, target_area, bounds, NULL);
767 EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
768 EXPECT_EQ(out.right() - in.right(), in.y() - out.y());
769 EXPECT_LE(out.width() * out.height(), target_area);
770 EXPECT_GT(out.width() * out.height(),
771 target_area - out.width() * 2 - out.height());
772 EXPECT_TRUE(bounds.Contains(out));
775 TEST(PictureLayerTilingTest, ExpandRectSquishedHorizontally) {
776 gfx::Rect in(40, 50, 100, 200);
777 gfx::Rect bounds(0, -4000, 100+40+20, 100000);
778 int64 target_area = 400 * 400;
779 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
780 in, target_area, bounds, NULL);
781 EXPECT_EQ(20, out.right() - in.right());
782 EXPECT_EQ(40, in.x() - out.x());
783 EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
784 EXPECT_LE(out.width() * out.height(), target_area);
785 EXPECT_GT(out.width() * out.height(),
786 target_area - out.width() * 2);
787 EXPECT_TRUE(bounds.Contains(out));
790 TEST(PictureLayerTilingTest, ExpandRectSquishedVertically) {
791 gfx::Rect in(40, 50, 100, 200);
792 gfx::Rect bounds(-4000, 0, 100000, 200+50+30);
793 int64 target_area = 400 * 400;
794 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
795 in, target_area, bounds, NULL);
796 EXPECT_EQ(30, out.bottom() - in.bottom());
797 EXPECT_EQ(50, in.y() - out.y());
798 EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
799 EXPECT_LE(out.width() * out.height(), target_area);
800 EXPECT_GT(out.width() * out.height(),
801 target_area - out.height() * 2);
802 EXPECT_TRUE(bounds.Contains(out));
805 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsFarAway) {
806 gfx::Rect in(400, 500, 100, 200);
807 gfx::Rect bounds(0, 0, 10, 10);
808 int64 target_area = 400 * 400;
809 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
810 in, target_area, bounds, NULL);
811 EXPECT_TRUE(out.IsEmpty());
814 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedFullyCover) {
815 gfx::Rect in(40, 50, 100, 100);
816 gfx::Rect bounds(0, 0, 10, 10);
817 int64 target_area = 400 * 400;
818 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
819 in, target_area, bounds, NULL);
820 EXPECT_EQ(bounds.ToString(), out.ToString());
823 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedPartlyCover) {
824 gfx::Rect in(600, 600, 100, 100);
825 gfx::Rect bounds(0, 0, 500, 500);
826 int64 target_area = 400 * 400;
827 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
828 in, target_area, bounds, NULL);
829 EXPECT_EQ(bounds.right(), out.right());
830 EXPECT_EQ(bounds.bottom(), out.bottom());
831 EXPECT_LE(out.width() * out.height(), target_area);
832 EXPECT_GT(out.width() * out.height(),
833 target_area - out.width() - out.height());
834 EXPECT_TRUE(bounds.Contains(out));
837 TEST(PictureLayerTilingTest, EmptyStartingRect) {
838 // If a layer has a non-invertible transform, then the starting rect
839 // for the layer would be empty.
840 gfx::Rect in(40, 40, 0, 0);
841 gfx::Rect bounds(0, 0, 10, 10);
842 int64 target_area = 400 * 400;
843 gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
844 in, target_area, bounds, NULL);
845 EXPECT_TRUE(out.IsEmpty());
848 TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) {
849 FakePictureLayerTilingClient client;
850 scoped_ptr<TestablePictureLayerTiling> tiling;
852 gfx::Rect viewport(50, 50, 100, 100);
853 gfx::Size layer_bounds(800, 800);
855 gfx::Rect soon_rect = viewport;
856 soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
858 client.SetTileSize(gfx::Size(30, 30));
860 tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
861 tiling->UpdateTilePriorities(
862 ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
864 PictureLayerTiling::TilingRasterTileIterator empty_iterator;
865 EXPECT_FALSE(empty_iterator);
867 std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
869 // Sanity check.
870 EXPECT_EQ(841u, all_tiles.size());
872 // The explanation of each iteration is as follows:
873 // 1. First iteration tests that we can get all of the tiles correctly.
874 // 2. Second iteration ensures that we can get all of the tiles again (first
875 // iteration didn't change any tiles), as well set all tiles to be ready to
876 // draw.
877 // 3. Third iteration ensures that no tiles are returned, since they were all
878 // marked as ready to draw.
879 for (int i = 0; i < 3; ++i) {
880 PictureLayerTiling::TilingRasterTileIterator it(tiling.get(), ACTIVE_TREE);
882 // There are 3 bins in TilePriority.
883 bool have_tiles[3] = {};
885 // On the third iteration, we should get no tiles since everything was
886 // marked as ready to draw.
887 if (i == 2) {
888 EXPECT_FALSE(it);
889 continue;
892 EXPECT_TRUE(it);
893 std::set<Tile*> unique_tiles;
894 unique_tiles.insert(*it);
895 Tile* last_tile = *it;
896 have_tiles[last_tile->priority(ACTIVE_TREE).priority_bin] = true;
898 // On the second iteration, mark everything as ready to draw (solid color).
899 if (i == 1) {
900 ManagedTileState::TileVersion& tile_version =
901 last_tile->GetTileVersionForTesting(
902 last_tile->DetermineRasterModeForTree(ACTIVE_TREE));
903 tile_version.SetSolidColorForTesting(SK_ColorRED);
905 ++it;
906 int eventually_bin_order_correct_count = 0;
907 int eventually_bin_order_incorrect_count = 0;
908 while (it) {
909 Tile* new_tile = *it;
910 ++it;
911 unique_tiles.insert(new_tile);
913 TilePriority last_priority = last_tile->priority(ACTIVE_TREE);
914 TilePriority new_priority = new_tile->priority(ACTIVE_TREE);
915 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
916 if (last_priority.priority_bin == new_priority.priority_bin) {
917 if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
918 bool order_correct = last_priority.distance_to_visible <=
919 new_priority.distance_to_visible;
920 eventually_bin_order_correct_count += order_correct;
921 eventually_bin_order_incorrect_count += !order_correct;
922 } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
923 !soon_rect.Intersects(last_tile->content_rect())) {
924 EXPECT_LE(last_priority.distance_to_visible,
925 new_priority.distance_to_visible);
926 EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin);
927 } else if (new_priority.distance_to_visible > 0.f) {
928 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
931 have_tiles[new_priority.priority_bin] = true;
933 last_tile = new_tile;
935 // On the second iteration, mark everything as ready to draw (solid
936 // color).
937 if (i == 1) {
938 ManagedTileState::TileVersion& tile_version =
939 last_tile->GetTileVersionForTesting(
940 last_tile->DetermineRasterModeForTree(ACTIVE_TREE));
941 tile_version.SetSolidColorForTesting(SK_ColorRED);
945 EXPECT_GT(eventually_bin_order_correct_count,
946 eventually_bin_order_incorrect_count);
948 // We should have now and eventually tiles, as well as soon tiles from
949 // the border region.
950 EXPECT_TRUE(have_tiles[TilePriority::NOW]);
951 EXPECT_TRUE(have_tiles[TilePriority::SOON]);
952 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
954 EXPECT_EQ(unique_tiles.size(), all_tiles.size());
958 TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) {
959 FakePictureLayerTilingClient client;
960 scoped_ptr<TestablePictureLayerTiling> tiling;
962 gfx::Rect viewport(50, 0, 100, 100);
963 gfx::Rect moved_viewport(50, 0, 100, 500);
964 gfx::Size layer_bounds(1000, 1000);
966 client.SetTileSize(gfx::Size(30, 30));
968 tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client);
969 tiling->UpdateTilePriorities(
970 ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
971 tiling->UpdateTilePriorities(
972 ACTIVE_TREE, moved_viewport, 1.0f, 2.0, NULL, NULL, gfx::Transform());
974 gfx::Rect soon_rect = moved_viewport;
975 soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
977 // There are 3 bins in TilePriority.
978 bool have_tiles[3] = {};
979 Tile* last_tile = NULL;
980 int eventually_bin_order_correct_count = 0;
981 int eventually_bin_order_incorrect_count = 0;
982 for (PictureLayerTiling::TilingRasterTileIterator it(tiling.get(),
983 ACTIVE_TREE);
985 ++it) {
986 if (!last_tile)
987 last_tile = *it;
989 Tile* new_tile = *it;
991 TilePriority last_priority = last_tile->priority(ACTIVE_TREE);
992 TilePriority new_priority = new_tile->priority(ACTIVE_TREE);
994 have_tiles[new_priority.priority_bin] = true;
996 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
997 if (last_priority.priority_bin == new_priority.priority_bin) {
998 if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
999 bool order_correct = last_priority.distance_to_visible <=
1000 new_priority.distance_to_visible;
1001 eventually_bin_order_correct_count += order_correct;
1002 eventually_bin_order_incorrect_count += !order_correct;
1003 } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
1004 !soon_rect.Intersects(last_tile->content_rect())) {
1005 EXPECT_LE(last_priority.distance_to_visible,
1006 new_priority.distance_to_visible);
1007 } else if (new_priority.distance_to_visible > 0.f) {
1008 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1011 last_tile = new_tile;
1014 EXPECT_GT(eventually_bin_order_correct_count,
1015 eventually_bin_order_incorrect_count);
1017 EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1018 EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1019 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1022 static void TileExists(bool exists, Tile* tile,
1023 const gfx::Rect& geometry_rect) {
1024 EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString();
1027 TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) {
1028 FakeOutputSurfaceClient output_surface_client;
1029 scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d();
1030 CHECK(output_surface->BindToClient(&output_surface_client));
1031 TestSharedBitmapManager shared_bitmap_manager;
1032 scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
1033 output_surface.get(), &shared_bitmap_manager, 0, false, 1, false);
1035 FakePictureLayerTilingClient client(resource_provider.get());
1036 scoped_ptr<TestablePictureLayerTiling> tiling;
1038 gfx::Rect viewport(50, 50, 100, 100);
1039 gfx::Size layer_bounds(200, 200);
1041 client.SetTileSize(gfx::Size(30, 30));
1043 tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
1044 tiling->UpdateTilePriorities(
1045 ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
1047 PictureLayerTiling::TilingRasterTileIterator empty_iterator;
1048 EXPECT_FALSE(empty_iterator);
1050 std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
1052 PictureLayerTiling::TilingEvictionTileIterator it(tiling.get(),
1053 SMOOTHNESS_TAKES_PRIORITY);
1055 // Tiles don't have resources to evict.
1056 EXPECT_FALSE(it);
1058 // Sanity check.
1059 EXPECT_EQ(64u, all_tiles.size());
1061 client.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
1063 std::set<Tile*> all_tiles_set(all_tiles.begin(), all_tiles.end());
1065 it = PictureLayerTiling::TilingEvictionTileIterator(
1066 tiling.get(), SMOOTHNESS_TAKES_PRIORITY);
1067 EXPECT_TRUE(it);
1069 std::set<Tile*> eviction_tiles;
1070 Tile* last_tile = *it;
1071 for (; it; ++it) {
1072 Tile* tile = *it;
1073 EXPECT_TRUE(tile);
1074 EXPECT_LE(tile->priority(ACTIVE_TREE).priority_bin,
1075 last_tile->priority(ACTIVE_TREE).priority_bin);
1076 if (tile->priority(ACTIVE_TREE).priority_bin ==
1077 last_tile->priority(ACTIVE_TREE).priority_bin) {
1078 EXPECT_LE(tile->priority(ACTIVE_TREE).distance_to_visible,
1079 last_tile->priority(ACTIVE_TREE).distance_to_visible);
1081 last_tile = tile;
1082 eviction_tiles.insert(tile);
1085 EXPECT_GT(all_tiles_set.size(), 0u);
1086 EXPECT_EQ(all_tiles_set, eviction_tiles);
1089 TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
1090 gfx::Size layer_bounds(1099, 801);
1091 Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1092 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1093 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1095 tiling_->UpdateTilePriorities(
1096 ACTIVE_TREE,
1097 gfx::Rect(layer_bounds), // visible content rect
1098 1.f, // current contents scale
1099 1.0, // current frame time
1100 NULL, // occlusion tracker
1101 NULL, // render target
1102 gfx::Transform()); // draw transform
1103 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1105 // Make the viewport rect empty. All tiles are killed and become zombies.
1106 tiling_->UpdateTilePriorities(ACTIVE_TREE,
1107 gfx::Rect(), // visible content rect
1108 1.f, // current contents scale
1109 2.0, // current frame time
1110 NULL, // occlusion tracker
1111 NULL, // render target
1112 gfx::Transform()); // draw transform
1113 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1116 TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
1117 gfx::Size layer_bounds(1099, 801);
1118 Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1119 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1120 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1122 gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000);
1124 tiling_->UpdateTilePriorities(
1125 ACTIVE_TREE,
1126 gfx::Rect(layer_bounds), // visible content rect
1127 1.f, // current contents scale
1128 1.0, // current frame time
1129 NULL, // occlusion tracker
1130 NULL, // render target
1131 gfx::Transform()); // draw transform
1132 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1134 // If the visible content rect is empty, it should still have live tiles.
1135 tiling_->UpdateTilePriorities(ACTIVE_TREE,
1136 giant_rect, // visible content rect
1137 1.f, // current contents scale
1138 2.0, // current frame time
1139 NULL, // occlusion tracker
1140 NULL, // render target
1141 gfx::Transform()); // draw transform
1142 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1145 TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
1146 gfx::Size layer_bounds(1099, 801);
1147 Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1148 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1149 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1151 // This rect does not intersect with the layer, as the layer is outside the
1152 // viewport.
1153 gfx::Rect viewport_rect(1100, 0, 1000, 1000);
1154 EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds)));
1156 tiling_->UpdateTilePriorities(ACTIVE_TREE,
1157 viewport_rect, // visible content rect
1158 1.f, // current contents scale
1159 1.0, // current frame time
1160 NULL, // occlusion tracker
1161 NULL, // render target
1162 gfx::Transform()); // draw transform
1163 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1166 static void TilesIntersectingRectExist(const gfx::Rect& rect,
1167 bool intersect_exists,
1168 Tile* tile,
1169 const gfx::Rect& geometry_rect) {
1170 bool intersects = rect.Intersects(geometry_rect);
1171 bool expected_exists = intersect_exists ? intersects : !intersects;
1172 EXPECT_EQ(expected_exists, tile != NULL)
1173 << "Rects intersecting " << rect.ToString() << " should exist. "
1174 << "Current tile rect is " << geometry_rect.ToString();
1177 TEST_F(PictureLayerTilingIteratorTest,
1178 TilesExistLargeViewportAndLayerWithSmallVisibleArea) {
1179 gfx::Size layer_bounds(10000, 10000);
1180 Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1181 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1182 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1184 gfx::Rect visible_rect(8000, 8000, 50, 50);
1186 set_max_tiles_for_interest_area(1);
1187 tiling_->UpdateTilePriorities(ACTIVE_TREE,
1188 visible_rect, // visible content rect
1189 1.f, // current contents scale
1190 1.0, // current frame time
1191 NULL, // occlusion tracker
1192 NULL, // render target
1193 gfx::Transform()); // draw transform
1194 VerifyTiles(1.f,
1195 gfx::Rect(layer_bounds),
1196 base::Bind(&TilesIntersectingRectExist, visible_rect, true));
1199 static void CountExistingTiles(int *count,
1200 Tile* tile,
1201 const gfx::Rect& geometry_rect) {
1202 if (tile != NULL)
1203 ++(*count);
1206 TEST_F(PictureLayerTilingIteratorTest,
1207 TilesExistLargeViewportAndLayerWithLargeVisibleArea) {
1208 gfx::Size layer_bounds(10000, 10000);
1209 Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1210 VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1211 VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1213 set_max_tiles_for_interest_area(1);
1214 tiling_->UpdateTilePriorities(
1215 ACTIVE_TREE,
1216 gfx::Rect(layer_bounds), // visible content rect
1217 1.f, // current contents scale
1218 1.0, // current frame time
1219 NULL, // occlusion tracker
1220 NULL, // render target
1221 gfx::Transform()); // draw transform
1223 int num_tiles = 0;
1224 VerifyTiles(1.f,
1225 gfx::Rect(layer_bounds),
1226 base::Bind(&CountExistingTiles, &num_tiles));
1227 // If we're making a rect the size of one tile, it can only overlap up to 4
1228 // tiles depending on its position.
1229 EXPECT_LE(num_tiles, 4);
1230 VerifyTiles(1.f, gfx::Rect(), base::Bind(&TileExists, false));
1233 TEST_F(PictureLayerTilingIteratorTest, AddTilingsToMatchScale) {
1234 gfx::Size layer_bounds(1099, 801);
1235 gfx::Size tile_size(100, 100);
1237 client_.SetTileSize(tile_size);
1239 PictureLayerTilingSet active_set(&client_, layer_bounds);
1241 active_set.AddTiling(1.f);
1243 VerifyTiles(active_set.tiling_at(0),
1244 1.f,
1245 gfx::Rect(layer_bounds),
1246 base::Bind(&TileExists, false));
1248 UpdateAllTilePriorities(&active_set,
1249 PENDING_TREE,
1250 gfx::Rect(layer_bounds), // visible content rect
1251 1.f, // current contents scale
1252 1.0); // current frame time
1254 // The active tiling has tiles now.
1255 VerifyTiles(active_set.tiling_at(0),
1256 1.f,
1257 gfx::Rect(layer_bounds),
1258 base::Bind(&TileExists, true));
1260 // Add the same tilings to the pending set.
1261 PictureLayerTilingSet pending_set(&client_, layer_bounds);
1262 Region invalidation;
1263 pending_set.SyncTilings(active_set, layer_bounds, invalidation, 0.f);
1265 // The pending tiling starts with no tiles.
1266 VerifyTiles(pending_set.tiling_at(0),
1267 1.f,
1268 gfx::Rect(layer_bounds),
1269 base::Bind(&TileExists, false));
1271 // UpdateTilePriorities on the pending tiling at the same frame time. The
1272 // pending tiling should get tiles.
1273 UpdateAllTilePriorities(&pending_set,
1274 PENDING_TREE,
1275 gfx::Rect(layer_bounds), // visible content rect
1276 1.f, // current contents scale
1277 1.0); // current frame time
1279 VerifyTiles(pending_set.tiling_at(0),
1280 1.f,
1281 gfx::Rect(layer_bounds),
1282 base::Bind(&TileExists, true));
1285 TEST(UpdateTilePrioritiesTest, VisibleTiles) {
1286 // The TilePriority of visible tiles should have zero distance_to_visible
1287 // and time_to_visible.
1289 FakePictureLayerTilingClient client;
1290 scoped_ptr<TestablePictureLayerTiling> tiling;
1292 gfx::Size device_viewport(800, 600);
1293 gfx::Size last_layer_bounds(200, 200);
1294 gfx::Size current_layer_bounds(200, 200);
1295 float current_layer_contents_scale = 1.f;
1296 gfx::Transform current_screen_transform;
1297 double current_frame_time_in_seconds = 1.0;
1299 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1300 current_screen_transform, device_viewport);
1302 client.SetTileSize(gfx::Size(100, 100));
1303 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1304 current_layer_bounds,
1305 &client);
1307 tiling->UpdateTilePriorities(ACTIVE_TREE,
1308 viewport_in_layer_space,
1309 current_layer_contents_scale,
1310 current_frame_time_in_seconds,
1311 NULL, // occlusion tracker
1312 NULL, // render target
1313 gfx::Transform()); // draw transform
1315 ASSERT_TRUE(tiling->TileAt(0, 0));
1316 ASSERT_TRUE(tiling->TileAt(0, 1));
1317 ASSERT_TRUE(tiling->TileAt(1, 0));
1318 ASSERT_TRUE(tiling->TileAt(1, 1));
1320 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1321 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1322 EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1324 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1325 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1326 EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1328 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1329 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1330 EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1332 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1333 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1334 EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1337 TEST(UpdateTilePrioritiesTest, OffscreenTiles) {
1338 // The TilePriority of offscreen tiles (without movement) should have nonzero
1339 // distance_to_visible and infinite time_to_visible.
1341 FakePictureLayerTilingClient client;
1342 scoped_ptr<TestablePictureLayerTiling> tiling;
1344 gfx::Size device_viewport(800, 600);
1345 gfx::Size last_layer_bounds(200, 200);
1346 gfx::Size current_layer_bounds(200, 200);
1347 float current_layer_contents_scale = 1.f;
1348 gfx::Transform last_screen_transform;
1349 gfx::Transform current_screen_transform;
1350 double current_frame_time_in_seconds = 1.0;
1352 current_screen_transform.Translate(850, 0);
1353 last_screen_transform = current_screen_transform;
1355 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1356 current_screen_transform, device_viewport);
1358 client.SetTileSize(gfx::Size(100, 100));
1359 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1360 current_layer_bounds,
1361 &client);
1363 tiling->UpdateTilePriorities(ACTIVE_TREE,
1364 viewport_in_layer_space,
1365 current_layer_contents_scale,
1366 current_frame_time_in_seconds,
1367 NULL, // occlusion tracker
1368 NULL, // render target
1369 gfx::Transform()); // draw transform
1371 ASSERT_TRUE(tiling->TileAt(0, 0));
1372 ASSERT_TRUE(tiling->TileAt(0, 1));
1373 ASSERT_TRUE(tiling->TileAt(1, 0));
1374 ASSERT_TRUE(tiling->TileAt(1, 1));
1376 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1377 EXPECT_GT(priority.distance_to_visible, 0.f);
1378 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1380 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1381 EXPECT_GT(priority.distance_to_visible, 0.f);
1382 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1384 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1385 EXPECT_GT(priority.distance_to_visible, 0.f);
1386 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1388 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1389 EXPECT_GT(priority.distance_to_visible, 0.f);
1390 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1392 // Furthermore, in this scenario tiles on the right hand side should have a
1393 // larger distance to visible.
1394 TilePriority left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1395 TilePriority right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1396 EXPECT_GT(right.distance_to_visible, left.distance_to_visible);
1398 left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1399 right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1400 EXPECT_GT(right.distance_to_visible, left.distance_to_visible);
1403 TEST(UpdateTilePrioritiesTest, PartiallyOffscreenLayer) {
1404 // Sanity check that a layer with some tiles visible and others offscreen has
1405 // correct TilePriorities for each tile.
1407 FakePictureLayerTilingClient client;
1408 scoped_ptr<TestablePictureLayerTiling> tiling;
1410 gfx::Size device_viewport(800, 600);
1411 gfx::Size last_layer_bounds(200, 200);
1412 gfx::Size current_layer_bounds(200, 200);
1413 float current_layer_contents_scale = 1.f;
1414 gfx::Transform last_screen_transform;
1415 gfx::Transform current_screen_transform;
1416 double current_frame_time_in_seconds = 1.0;
1418 current_screen_transform.Translate(705, 505);
1419 last_screen_transform = current_screen_transform;
1421 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1422 current_screen_transform, device_viewport);
1424 client.SetTileSize(gfx::Size(100, 100));
1425 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1426 current_layer_bounds,
1427 &client);
1429 tiling->UpdateTilePriorities(ACTIVE_TREE,
1430 viewport_in_layer_space,
1431 current_layer_contents_scale,
1432 current_frame_time_in_seconds,
1433 NULL, // occlusion tracker
1434 NULL, // render target
1435 gfx::Transform()); // draw transform
1437 ASSERT_TRUE(tiling->TileAt(0, 0));
1438 ASSERT_TRUE(tiling->TileAt(0, 1));
1439 ASSERT_TRUE(tiling->TileAt(1, 0));
1440 ASSERT_TRUE(tiling->TileAt(1, 1));
1442 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1443 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1444 EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1446 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1447 EXPECT_GT(priority.distance_to_visible, 0.f);
1448 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1450 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1451 EXPECT_GT(priority.distance_to_visible, 0.f);
1452 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1454 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1455 EXPECT_GT(priority.distance_to_visible, 0.f);
1456 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1459 TEST(UpdateTilePrioritiesTest, PartiallyOffscreenRotatedLayer) {
1460 // Each tile of a layer may be affected differently by a transform; Check
1461 // that UpdateTilePriorities correctly accounts for the transform between
1462 // layer space and screen space.
1464 FakePictureLayerTilingClient client;
1465 scoped_ptr<TestablePictureLayerTiling> tiling;
1467 gfx::Size device_viewport(800, 600);
1468 gfx::Size last_layer_bounds(200, 200);
1469 gfx::Size current_layer_bounds(200, 200);
1470 float current_layer_contents_scale = 1.f;
1471 gfx::Transform last_screen_transform;
1472 gfx::Transform current_screen_transform;
1473 double current_frame_time_in_seconds = 1.0;
1475 // A diagonally rotated layer that is partially off the bottom of the screen.
1476 // In this configuration, only the top-left tile would be visible.
1477 current_screen_transform.Translate(600, 750);
1478 current_screen_transform.RotateAboutZAxis(45);
1479 last_screen_transform = current_screen_transform;
1481 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1482 current_screen_transform, device_viewport);
1484 client.SetTileSize(gfx::Size(100, 100));
1485 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1486 current_layer_bounds,
1487 &client);
1489 tiling->UpdateTilePriorities(ACTIVE_TREE,
1490 viewport_in_layer_space,
1491 current_layer_contents_scale,
1492 current_frame_time_in_seconds,
1493 NULL, // occlusion tracker
1494 NULL, // render target
1495 gfx::Transform()); // draw transform
1497 ASSERT_TRUE(tiling->TileAt(0, 0));
1498 ASSERT_TRUE(tiling->TileAt(0, 1));
1499 ASSERT_TRUE(tiling->TileAt(1, 0));
1500 ASSERT_TRUE(tiling->TileAt(1, 1));
1502 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1503 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1504 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1506 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1507 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1508 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1510 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1511 EXPECT_GT(priority.distance_to_visible, 0.f);
1512 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1514 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1515 EXPECT_GT(priority.distance_to_visible, 0.f);
1516 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1518 // Furthermore, in this scenario the bottom-right tile should have the larger
1519 // distance to visible.
1520 TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1521 TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1522 TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1523 EXPECT_GT(top_right.distance_to_visible, top_left.distance_to_visible);
1525 EXPECT_EQ(bottom_right.distance_to_visible, top_right.distance_to_visible);
1528 TEST(UpdateTilePrioritiesTest, PerspectiveLayer) {
1529 // Perspective transforms need to take a different code path.
1530 // This test checks tile priorities of a perspective layer.
1532 FakePictureLayerTilingClient client;
1533 scoped_ptr<TestablePictureLayerTiling> tiling;
1535 gfx::Size device_viewport(800, 600);
1536 gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscreen.
1537 gfx::Size last_layer_bounds(200, 200);
1538 gfx::Size current_layer_bounds(200, 200);
1539 float current_layer_contents_scale = 1.f;
1540 gfx::Transform last_screen_transform;
1541 gfx::Transform current_screen_transform;
1542 double current_frame_time_in_seconds = 1.0;
1544 // A 3d perspective layer rotated about its Y axis, translated to almost
1545 // fully offscreen. The left side will appear closer (i.e. larger in 2d) than
1546 // the right side, so the top-left tile will technically be closer than the
1547 // top-right.
1549 // Translate layer to offscreen
1550 current_screen_transform.Translate(400.0, 630.0);
1551 // Apply perspective about the center of the layer
1552 current_screen_transform.Translate(100.0, 100.0);
1553 current_screen_transform.ApplyPerspectiveDepth(100.0);
1554 current_screen_transform.RotateAboutYAxis(10.0);
1555 current_screen_transform.Translate(-100.0, -100.0);
1556 last_screen_transform = current_screen_transform;
1558 // Sanity check that this transform wouldn't cause w<0 clipping.
1559 bool clipped;
1560 MathUtil::MapQuad(current_screen_transform,
1561 gfx::QuadF(gfx::RectF(0, 0, 200, 200)),
1562 &clipped);
1563 ASSERT_FALSE(clipped);
1565 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1566 current_screen_transform, device_viewport);
1568 client.SetTileSize(gfx::Size(100, 100));
1569 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1570 current_layer_bounds,
1571 &client);
1573 tiling->UpdateTilePriorities(ACTIVE_TREE,
1574 viewport_in_layer_space,
1575 current_layer_contents_scale,
1576 current_frame_time_in_seconds,
1577 NULL, // occlusion tracker
1578 NULL, // render target
1579 gfx::Transform()); // draw transform
1581 ASSERT_TRUE(tiling->TileAt(0, 0));
1582 ASSERT_TRUE(tiling->TileAt(0, 1));
1583 ASSERT_TRUE(tiling->TileAt(1, 0));
1584 ASSERT_TRUE(tiling->TileAt(1, 1));
1586 // All tiles will have a positive distance_to_visible
1587 // and an infinite time_to_visible.
1588 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1589 EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1590 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1592 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1593 EXPECT_GT(priority.distance_to_visible, 0.f);
1594 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1596 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1597 EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1598 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1600 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1601 EXPECT_GT(priority.distance_to_visible, 0.f);
1602 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1604 // Furthermore, in this scenario the top-left distance_to_visible
1605 // will be smallest, followed by top-right. The bottom layers
1606 // will of course be further than the top layers.
1607 TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1608 TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1609 TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1610 TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1612 EXPECT_GT(bottom_right.distance_to_visible, top_right.distance_to_visible);
1614 EXPECT_GT(bottom_left.distance_to_visible, top_left.distance_to_visible);
1617 TEST(UpdateTilePrioritiesTest, PerspectiveLayerClippedByW) {
1618 // Perspective transforms need to take a different code path.
1619 // This test checks tile priorities of a perspective layer.
1621 FakePictureLayerTilingClient client;
1622 scoped_ptr<TestablePictureLayerTiling> tiling;
1624 gfx::Size device_viewport(800, 600);
1625 gfx::Size last_layer_bounds(200, 200);
1626 gfx::Size current_layer_bounds(200, 200);
1627 float current_layer_contents_scale = 1.f;
1628 gfx::Transform last_screen_transform;
1629 gfx::Transform current_screen_transform;
1630 double current_frame_time_in_seconds = 1.0;
1632 // A 3d perspective layer rotated about its Y axis, translated to almost
1633 // fully offscreen. The left side will appear closer (i.e. larger in 2d) than
1634 // the right side, so the top-left tile will technically be closer than the
1635 // top-right.
1637 // Translate layer to offscreen
1638 current_screen_transform.Translate(400.0, 970.0);
1639 // Apply perspective and rotation about the center of the layer
1640 current_screen_transform.Translate(100.0, 100.0);
1641 current_screen_transform.ApplyPerspectiveDepth(10.0);
1642 current_screen_transform.RotateAboutYAxis(10.0);
1643 current_screen_transform.Translate(-100.0, -100.0);
1644 last_screen_transform = current_screen_transform;
1646 // Sanity check that this transform does cause w<0 clipping for the left side
1647 // of the layer, but not the right side.
1648 bool clipped;
1649 MathUtil::MapQuad(current_screen_transform,
1650 gfx::QuadF(gfx::RectF(0, 0, 100, 200)),
1651 &clipped);
1652 ASSERT_TRUE(clipped);
1654 MathUtil::MapQuad(current_screen_transform,
1655 gfx::QuadF(gfx::RectF(100, 0, 100, 200)),
1656 &clipped);
1657 ASSERT_FALSE(clipped);
1659 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1660 current_screen_transform, device_viewport);
1662 client.SetTileSize(gfx::Size(100, 100));
1663 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1664 current_layer_bounds,
1665 &client);
1667 tiling->UpdateTilePriorities(ACTIVE_TREE,
1668 viewport_in_layer_space,
1669 current_layer_contents_scale,
1670 current_frame_time_in_seconds,
1671 NULL, // occlusion tracker
1672 NULL, // render target
1673 gfx::Transform()); // draw transform
1675 ASSERT_TRUE(tiling->TileAt(0, 0));
1676 ASSERT_TRUE(tiling->TileAt(0, 1));
1677 ASSERT_TRUE(tiling->TileAt(1, 0));
1678 ASSERT_TRUE(tiling->TileAt(1, 1));
1680 // Left-side tiles will be clipped by the transform, so we have to assume
1681 // they are visible just in case.
1682 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1683 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1684 EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1686 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1687 EXPECT_GT(priority.distance_to_visible, 0.f);
1688 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1690 // Right-side tiles will have a positive distance_to_visible
1691 // and an infinite time_to_visible.
1692 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1693 EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1694 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1696 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1697 EXPECT_GT(priority.distance_to_visible, 0.f);
1698 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1701 TEST(UpdateTilePrioritiesTest, BasicMotion) {
1702 // Test that time_to_visible is computed correctly when
1703 // there is some motion.
1705 FakePictureLayerTilingClient client;
1706 scoped_ptr<TestablePictureLayerTiling> tiling;
1708 gfx::Size device_viewport(800, 600);
1709 gfx::Rect visible_layer_rect(0, 0, 0, 0);
1710 gfx::Size last_layer_bounds(200, 200);
1711 gfx::Size current_layer_bounds(200, 200);
1712 float last_layer_contents_scale = 1.f;
1713 float current_layer_contents_scale = 1.f;
1714 gfx::Transform last_screen_transform;
1715 gfx::Transform current_screen_transform;
1716 double last_frame_time_in_seconds = 1.0;
1717 double current_frame_time_in_seconds = 2.0;
1719 // Offscreen layer is coming closer to viewport at 1000 pixels per second.
1720 current_screen_transform.Translate(1800, 0);
1721 last_screen_transform.Translate(2800, 0);
1723 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1724 current_screen_transform, device_viewport);
1726 client.SetTileSize(gfx::Size(100, 100));
1727 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1728 current_layer_bounds,
1729 &client);
1731 // previous ("last") frame
1732 tiling->UpdateTilePriorities(ACTIVE_TREE,
1733 viewport_in_layer_space,
1734 last_layer_contents_scale,
1735 last_frame_time_in_seconds,
1736 NULL, // occlusion tracker
1737 NULL, // render target
1738 gfx::Transform()); // draw transform
1740 // current frame
1741 tiling->UpdateTilePriorities(ACTIVE_TREE,
1742 viewport_in_layer_space,
1743 current_layer_contents_scale,
1744 current_frame_time_in_seconds,
1745 NULL, // occlusion tracker
1746 NULL, // render target
1747 gfx::Transform()); // draw transform
1749 ASSERT_TRUE(tiling->TileAt(0, 0));
1750 ASSERT_TRUE(tiling->TileAt(0, 1));
1751 ASSERT_TRUE(tiling->TileAt(1, 0));
1752 ASSERT_TRUE(tiling->TileAt(1, 1));
1754 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1755 EXPECT_GT(priority.distance_to_visible, 0.f);
1756 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1758 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1759 EXPECT_GT(priority.distance_to_visible, 0.f);
1760 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1762 // time_to_visible for the right hand side layers needs an extra 0.099
1763 // seconds because this tile is 99 pixels further away.
1764 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1765 EXPECT_GT(priority.distance_to_visible, 0.f);
1766 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1768 priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1769 EXPECT_GT(priority.distance_to_visible, 0.f);
1770 EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1773 TEST(UpdateTilePrioritiesTest, RotationMotion) {
1774 // Each tile of a layer may be affected differently by a transform; Check
1775 // that UpdateTilePriorities correctly accounts for the transform between
1776 // layer space and screen space.
1778 FakePictureLayerTilingClient client;
1779 scoped_ptr<TestablePictureLayerTiling> tiling;
1781 gfx::Size device_viewport(800, 600);
1782 gfx::Rect visible_layer_rect(0, 0, 0, 0); // offscren.
1783 gfx::Size last_layer_bounds(200, 200);
1784 gfx::Size current_layer_bounds(200, 200);
1785 float last_layer_contents_scale = 1.f;
1786 float current_layer_contents_scale = 1.f;
1787 gfx::Transform last_screen_transform;
1788 gfx::Transform current_screen_transform;
1789 double last_frame_time_in_seconds = 1.0;
1790 double current_frame_time_in_seconds = 2.0;
1792 // Rotation motion is set up specifically so that:
1793 // - rotation occurs about the center of the layer
1794 // - the top-left tile becomes visible on rotation
1795 // - the top-right tile will have an infinite time_to_visible
1796 // because it is rotating away from viewport.
1797 // - bottom-left layer will have a positive non-zero time_to_visible
1798 // because it is rotating toward the viewport.
1799 current_screen_transform.Translate(400, 550);
1800 current_screen_transform.RotateAboutZAxis(45);
1802 last_screen_transform.Translate(400, 550);
1804 gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1805 current_screen_transform, device_viewport);
1807 client.SetTileSize(gfx::Size(100, 100));
1808 tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
1809 current_layer_bounds,
1810 &client);
1812 // previous ("last") frame
1813 tiling->UpdateTilePriorities(ACTIVE_TREE,
1814 viewport_in_layer_space,
1815 last_layer_contents_scale,
1816 last_frame_time_in_seconds,
1817 NULL, // occlusion tracker
1818 NULL, // render target
1819 gfx::Transform()); // draw transform
1821 // current frame
1822 tiling->UpdateTilePriorities(ACTIVE_TREE,
1823 viewport_in_layer_space,
1824 current_layer_contents_scale,
1825 current_frame_time_in_seconds,
1826 NULL, // occlusion tracker
1827 NULL, // render target
1828 gfx::Transform()); // draw transform
1830 ASSERT_TRUE(tiling->TileAt(0, 0));
1831 ASSERT_TRUE(tiling->TileAt(0, 1));
1832 ASSERT_TRUE(tiling->TileAt(1, 0));
1833 ASSERT_TRUE(tiling->TileAt(1, 1));
1835 TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1836 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1837 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1839 priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1840 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1841 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1843 priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1844 EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1845 EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1848 } // namespace
1849 } // namespace cc