Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / cc / resources / picture_layer_tiling_unittest.cc
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.
4
5 #include "cc/resources/picture_layer_tiling.h"
6
7 #include <limits>
8 #include <set>
9
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 "testing/gtest/include/gtest/gtest.h"
17 #include "ui/gfx/rect_conversions.h"
18 #include "ui/gfx/size_conversions.h"
19
20 namespace cc {
21 namespace {
22
23 static gfx::Rect ViewportInLayerSpace(
24     const gfx::Transform& transform,
25     const gfx::Size& device_viewport) {
26
27   gfx::Transform inverse;
28   if (!transform.GetInverse(&inverse))
29     return gfx::Rect();
30
31   gfx::RectF viewport_in_layer_space = MathUtil::ProjectClippedRect(
32       inverse, gfx::RectF(gfx::Point(0, 0), device_viewport));
33   return ToEnclosingRect(viewport_in_layer_space);
34 }
35
36 class TestablePictureLayerTiling : public PictureLayerTiling {
37  public:
38   using PictureLayerTiling::SetLiveTilesRect;
39   using PictureLayerTiling::TileAt;
40
41   static scoped_ptr<TestablePictureLayerTiling> Create(
42       float contents_scale,
43       const gfx::Size& layer_bounds,
44       PictureLayerTilingClient* client) {
45     return make_scoped_ptr(new TestablePictureLayerTiling(
46         contents_scale,
47         layer_bounds,
48         client));
49   }
50
51   using PictureLayerTiling::ComputeSkewport;
52
53  protected:
54   TestablePictureLayerTiling(float contents_scale,
55                              const gfx::Size& layer_bounds,
56                              PictureLayerTilingClient* client)
57       : PictureLayerTiling(contents_scale, layer_bounds, client) { }
58 };
59
60 class PictureLayerTilingIteratorTest : public testing::Test {
61  public:
62   PictureLayerTilingIteratorTest() {}
63   virtual ~PictureLayerTilingIteratorTest() {}
64
65   void Initialize(const gfx::Size& tile_size,
66                   float contents_scale,
67                   const gfx::Size& layer_bounds) {
68     client_.SetTileSize(tile_size);
69     tiling_ = TestablePictureLayerTiling::Create(contents_scale,
70                                                  layer_bounds,
71                                                  &client_);
72   }
73
74   void SetLiveRectAndVerifyTiles(const gfx::Rect& live_tiles_rect) {
75     tiling_->SetLiveTilesRect(live_tiles_rect);
76
77     std::vector<Tile*> tiles = tiling_->AllTilesForTesting();
78     for (std::vector<Tile*>::iterator iter = tiles.begin();
79          iter != tiles.end();
80          ++iter) {
81       EXPECT_TRUE(live_tiles_rect.Intersects((*iter)->content_rect()));
82     }
83   }
84
85   void VerifyTilesExactlyCoverRect(
86       float rect_scale,
87       const gfx::Rect& request_rect,
88       const gfx::Rect& expect_rect) {
89     EXPECT_TRUE(request_rect.Contains(expect_rect));
90
91     // Iterators are not valid if this ratio is too large (i.e. the
92     // tiling is too high-res for a low-res destination rect.)  This is an
93     // artifact of snapping geometry to integer coordinates and then mapping
94     // back to floating point texture coordinates.
95     float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
96     ASSERT_LE(dest_to_contents_scale, 2.0);
97
98     Region remaining = expect_rect;
99     for (PictureLayerTiling::CoverageIterator
100              iter(tiling_.get(), rect_scale, request_rect);
101          iter;
102          ++iter) {
103       // Geometry cannot overlap previous geometry at all
104       gfx::Rect geometry = iter.geometry_rect();
105       EXPECT_TRUE(expect_rect.Contains(geometry));
106       EXPECT_TRUE(remaining.Contains(geometry));
107       remaining.Subtract(geometry);
108
109       // Sanity check that texture coords are within the texture rect.
110       gfx::RectF texture_rect = iter.texture_rect();
111       EXPECT_GE(texture_rect.x(), 0);
112       EXPECT_GE(texture_rect.y(), 0);
113       EXPECT_LE(texture_rect.right(), client_.TileSize().width());
114       EXPECT_LE(texture_rect.bottom(), client_.TileSize().height());
115
116       EXPECT_EQ(iter.texture_size(), client_.TileSize());
117     }
118
119     // The entire rect must be filled by geometry from the tiling.
120     EXPECT_TRUE(remaining.IsEmpty());
121   }
122
123   void VerifyTilesExactlyCoverRect(float rect_scale, const gfx::Rect& rect) {
124     VerifyTilesExactlyCoverRect(rect_scale, rect, rect);
125   }
126
127   void VerifyTiles(
128       float rect_scale,
129       const gfx::Rect& rect,
130       base::Callback<void(Tile* tile,
131                           const gfx::Rect& geometry_rect)> callback) {
132     VerifyTiles(tiling_.get(),
133                 rect_scale,
134                 rect,
135                 callback);
136   }
137
138   void VerifyTiles(
139       PictureLayerTiling* tiling,
140       float rect_scale,
141       const gfx::Rect& rect,
142       base::Callback<void(Tile* tile,
143                           const gfx::Rect& geometry_rect)> callback) {
144     Region remaining = rect;
145     for (PictureLayerTiling::CoverageIterator iter(tiling, rect_scale, rect);
146          iter;
147          ++iter) {
148       remaining.Subtract(iter.geometry_rect());
149       callback.Run(*iter, iter.geometry_rect());
150     }
151     EXPECT_TRUE(remaining.IsEmpty());
152   }
153
154   void VerifyTilesCoverNonContainedRect(float rect_scale,
155                                         const gfx::Rect& dest_rect) {
156     float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
157     gfx::Rect clamped_rect = gfx::ScaleToEnclosingRect(
158         tiling_->ContentRect(), 1.f / dest_to_contents_scale);
159     clamped_rect.Intersect(dest_rect);
160     VerifyTilesExactlyCoverRect(rect_scale, dest_rect, clamped_rect);
161   }
162
163   void set_max_tiles_for_interest_area(size_t area) {
164     client_.set_max_tiles_for_interest_area(area);
165   }
166
167  protected:
168   FakePictureLayerTilingClient client_;
169   scoped_ptr<TestablePictureLayerTiling> tiling_;
170
171  private:
172   DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest);
173 };
174
175 TEST_F(PictureLayerTilingIteratorTest, ResizeDeletesTiles) {
176   // Verifies that a resize deletes tiles that used to be on the edge.
177   gfx::Size tile_size(100, 100);
178   gfx::Size original_layer_size(10, 10);
179   Initialize(tile_size, 1.f, original_layer_size);
180   SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
181
182   // Tiling only has one tile, since its total size is less than one.
183   EXPECT_TRUE(tiling_->TileAt(0, 0));
184
185   // Stop creating tiles so that any invalidations are left as holes.
186   client_.set_allow_create_tile(false);
187
188   tiling_->SetLayerBounds(gfx::Size(200, 200));
189   EXPECT_FALSE(tiling_->TileAt(0, 0));
190 }
191
192 TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) {
193   Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
194   SetLiveRectAndVerifyTiles(gfx::Rect(100, 100));
195   SetLiveRectAndVerifyTiles(gfx::Rect(101, 99));
196   SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
197   SetLiveRectAndVerifyTiles(gfx::Rect(1, 801));
198   SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
199   SetLiveRectAndVerifyTiles(gfx::Rect(201, 800));
200 }
201
202 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsNoScale) {
203   Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
204   VerifyTilesExactlyCoverRect(1, gfx::Rect());
205   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1099, 801));
206   VerifyTilesExactlyCoverRect(1, gfx::Rect(52, 83, 789, 412));
207
208   // With borders, a size of 3x3 = 1 pixel of content.
209   Initialize(gfx::Size(3, 3), 1, gfx::Size(10, 10));
210   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
211   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
212   VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
213   VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2));
214 }
215
216 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsTilingScale) {
217   Initialize(gfx::Size(200, 100), 2.0f, gfx::Size(1005, 2010));
218   VerifyTilesExactlyCoverRect(1, gfx::Rect());
219   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
220   VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
221
222   Initialize(gfx::Size(3, 3), 2.0f, gfx::Size(10, 10));
223   VerifyTilesExactlyCoverRect(1, gfx::Rect());
224   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
225   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
226   VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
227   VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2));
228
229   Initialize(gfx::Size(100, 200), 0.5f, gfx::Size(1005, 2010));
230   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
231   VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
232
233   Initialize(gfx::Size(150, 250), 0.37f, gfx::Size(1005, 2010));
234   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
235   VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
236
237   Initialize(gfx::Size(312, 123), 0.01f, gfx::Size(1005, 2010));
238   VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
239   VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
240 }
241
242 TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsBothScale) {
243   Initialize(gfx::Size(50, 50), 4.0f, gfx::Size(800, 600));
244   VerifyTilesExactlyCoverRect(2.0f, gfx::Rect());
245   VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(0, 0, 1600, 1200));
246   VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(512, 365, 253, 182));
247
248   float scale = 6.7f;
249   gfx::Size bounds(800, 600);
250   gfx::Rect full_rect(gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale)));
251   Initialize(gfx::Size(256, 512), 5.2f, bounds);
252   VerifyTilesExactlyCoverRect(scale, full_rect);
253   VerifyTilesExactlyCoverRect(scale, gfx::Rect(2014, 1579, 867, 1033));
254 }
255
256 TEST_F(PictureLayerTilingIteratorTest, IteratorEmptyRect) {
257   Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600));
258
259   gfx::Rect empty;
260   PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1.0f, empty);
261   EXPECT_FALSE(iter);
262 }
263
264 TEST_F(PictureLayerTilingIteratorTest, NonIntersectingRect) {
265   Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600));
266   gfx::Rect non_intersecting(1000, 1000, 50, 50);
267   PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1, non_intersecting);
268   EXPECT_FALSE(iter);
269 }
270
271 TEST_F(PictureLayerTilingIteratorTest, LayerEdgeTextureCoordinates) {
272   Initialize(gfx::Size(300, 300), 1.0f, gfx::Size(256, 256));
273   // All of these sizes are 256x256, scaled and ceiled.
274   VerifyTilesExactlyCoverRect(1.0f, gfx::Rect(0, 0, 256, 256));
275   VerifyTilesExactlyCoverRect(0.8f, gfx::Rect(0, 0, 205, 205));
276   VerifyTilesExactlyCoverRect(1.2f, gfx::Rect(0, 0, 308, 308));
277 }
278
279 TEST_F(PictureLayerTilingIteratorTest, NonContainedDestRect) {
280   Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(400, 400));
281
282   // Too large in all dimensions
283   VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, -1000, 2000, 2000));
284   VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, -1000, 2000, 2000));
285   VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, -1000, 2000, 2000));
286
287   // Partially covering content, but too large
288   VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, 100, 2000, 100));
289   VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, 100, 2000, 100));
290   VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, 100, 2000, 100));
291 }
292
293 TEST(PictureLayerTilingTest, SkewportLimits) {
294   FakePictureLayerTilingClient client;
295   client.set_skewport_extrapolation_limit_in_content_pixels(75);
296   scoped_ptr<TestablePictureLayerTiling> tiling;
297
298   gfx::Rect viewport(0, 0, 100, 100);
299   gfx::Size layer_bounds(200, 200);
300
301   client.SetTileSize(gfx::Size(100, 100));
302   tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
303
304   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
305
306   // Move viewport down 50 pixels in 0.5 seconds.
307   gfx::Rect down_skewport =
308       tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100));
309
310   EXPECT_EQ(0, down_skewport.x());
311   EXPECT_EQ(50, down_skewport.y());
312   EXPECT_EQ(100, down_skewport.width());
313   EXPECT_EQ(175, down_skewport.height());
314   EXPECT_TRUE(down_skewport.Contains(gfx::Rect(0, 50, 100, 100)));
315
316   // Move viewport down 50 and right 10 pixels.
317   gfx::Rect down_right_skewport =
318       tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100));
319
320   EXPECT_EQ(10, down_right_skewport.x());
321   EXPECT_EQ(50, down_right_skewport.y());
322   EXPECT_EQ(120, down_right_skewport.width());
323   EXPECT_EQ(175, down_right_skewport.height());
324   EXPECT_TRUE(down_right_skewport.Contains(gfx::Rect(10, 50, 100, 100)));
325
326   // Move viewport left.
327   gfx::Rect left_skewport =
328       tiling->ComputeSkewport(1.5, gfx::Rect(-50, 0, 100, 100));
329
330   EXPECT_EQ(-125, left_skewport.x());
331   EXPECT_EQ(0, left_skewport.y());
332   EXPECT_EQ(175, left_skewport.width());
333   EXPECT_EQ(100, left_skewport.height());
334   EXPECT_TRUE(left_skewport.Contains(gfx::Rect(-50, 0, 100, 100)));
335
336   // Expand viewport.
337   gfx::Rect expand_skewport =
338       tiling->ComputeSkewport(1.5, gfx::Rect(-50, -50, 200, 200));
339
340   // x and y moved by -75 (-50 - 75 = -125).
341   // right side and bottom side moved by 75 [(350 - 125) - (200 - 50) = 75].
342   EXPECT_EQ(-125, expand_skewport.x());
343   EXPECT_EQ(-125, expand_skewport.y());
344   EXPECT_EQ(350, expand_skewport.width());
345   EXPECT_EQ(350, expand_skewport.height());
346   EXPECT_TRUE(expand_skewport.Contains(gfx::Rect(-50, -50, 200, 200)));
347
348   // Expand the viewport past the limit.
349   gfx::Rect big_expand_skewport =
350       tiling->ComputeSkewport(1.5, gfx::Rect(-500, -500, 1500, 1500));
351
352   EXPECT_EQ(-575, big_expand_skewport.x());
353   EXPECT_EQ(-575, big_expand_skewport.y());
354   EXPECT_EQ(1650, big_expand_skewport.width());
355   EXPECT_EQ(1650, big_expand_skewport.height());
356   EXPECT_TRUE(big_expand_skewport.Contains(gfx::Rect(-500, -500, 1500, 1500)));
357 }
358
359 TEST(PictureLayerTilingTest, ComputeSkewport) {
360   FakePictureLayerTilingClient client;
361   scoped_ptr<TestablePictureLayerTiling> tiling;
362
363   gfx::Rect viewport(0, 0, 100, 100);
364   gfx::Size layer_bounds(200, 200);
365
366   client.SetTileSize(gfx::Size(100, 100));
367   tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
368
369   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
370
371   // Move viewport down 50 pixels in 0.5 seconds.
372   gfx::Rect down_skewport =
373       tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100));
374
375   EXPECT_EQ(0, down_skewport.x());
376   EXPECT_EQ(50, down_skewport.y());
377   EXPECT_EQ(100, down_skewport.width());
378   EXPECT_EQ(200, down_skewport.height());
379
380   // Shrink viewport.
381   gfx::Rect shrink_skewport =
382       tiling->ComputeSkewport(1.5, gfx::Rect(25, 25, 50, 50));
383
384   EXPECT_EQ(25, shrink_skewport.x());
385   EXPECT_EQ(25, shrink_skewport.y());
386   EXPECT_EQ(50, shrink_skewport.width());
387   EXPECT_EQ(50, shrink_skewport.height());
388
389   // Move viewport down 50 and right 10 pixels.
390   gfx::Rect down_right_skewport =
391       tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100));
392
393   EXPECT_EQ(10, down_right_skewport.x());
394   EXPECT_EQ(50, down_right_skewport.y());
395   EXPECT_EQ(120, down_right_skewport.width());
396   EXPECT_EQ(200, down_right_skewport.height());
397
398   // Move viewport left.
399   gfx::Rect left_skewport =
400       tiling->ComputeSkewport(1.5, gfx::Rect(-20, 0, 100, 100));
401
402   EXPECT_EQ(-60, left_skewport.x());
403   EXPECT_EQ(0, left_skewport.y());
404   EXPECT_EQ(140, left_skewport.width());
405   EXPECT_EQ(100, left_skewport.height());
406
407   // Expand viewport in 0.2 seconds.
408   gfx::Rect expanded_skewport =
409       tiling->ComputeSkewport(1.2, gfx::Rect(-5, -5, 110, 110));
410
411   EXPECT_EQ(-30, expanded_skewport.x());
412   EXPECT_EQ(-30, expanded_skewport.y());
413   EXPECT_EQ(160, expanded_skewport.width());
414   EXPECT_EQ(160, expanded_skewport.height());
415 }
416
417 TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
418   FakePictureLayerTilingClient client;
419   scoped_ptr<TestablePictureLayerTiling> tiling;
420
421   gfx::Rect viewport(0, 0, 100, 100);
422   gfx::Size layer_bounds(200, 200);
423
424   client.SetTileSize(gfx::Size(10, 10));
425
426   // Tiling at 0.25 scale: this should create 36 tiles (6x6) of size 10x10.
427   // The reason is that each tile has a one pixel border, so tile at (1, 2)
428   // for instance begins at (8, 16) pixels. So tile at (5, 5) will begin at
429   // (40, 40) and extend right to the end of 200 * 0.25 = 50 edge of the
430   // tiling.
431   tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client);
432   gfx::Rect viewport_in_content_space =
433       gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
434
435   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
436
437   // Sanity checks.
438   for (int i = 0; i < 6; ++i) {
439     for (int j = 0; j < 6; ++j) {
440       EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j;
441     }
442   }
443   for (int i = 0; i < 7; ++i) {
444     EXPECT_FALSE(tiling->TileAt(i, 6)) << "i: " << i;
445     EXPECT_FALSE(tiling->TileAt(6, i)) << "i: " << i;
446   }
447
448   // No movement in the viewport implies that tiles will either be NOW
449   // or EVENTUALLY.
450   bool have_now = false;
451   bool have_eventually = false;
452   for (int i = 0; i < 6; ++i) {
453     for (int j = 0; j < 6; ++j) {
454       Tile* tile = tiling->TileAt(i, j);
455       TilePriority priority = tile->priority(ACTIVE_TREE);
456
457       if (viewport_in_content_space.Intersects(tile->content_rect())) {
458         EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
459         EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
460         have_now = true;
461       } else {
462         EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin);
463         EXPECT_GT(priority.distance_to_visible, 0.f);
464         have_eventually = true;
465       }
466     }
467   }
468
469   EXPECT_TRUE(have_now);
470   EXPECT_TRUE(have_eventually);
471
472   // Spot check some distances.
473   // Tile at 5, 1 should begin at 41x9 in content space (without borders),
474   // so the distance to a viewport that ends at 25x25 in content space
475   // should be 17 (41 - 25 + 1). In layer space, then that should be
476   // 17 / 0.25 = 68 pixels.
477
478   // We can verify that the content rect (with borders) is one pixel off
479   // 41,9 8x8 on all sides.
480   EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10");
481
482   TilePriority priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
483   EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
484
485   priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
486   EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
487
488   priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
489   EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible);
490
491   // Move the viewport down 40 pixels.
492   viewport = gfx::Rect(0, 40, 100, 100);
493   viewport_in_content_space =
494       gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
495   gfx::Rect skewport = tiling->ComputeSkewport(2.0, viewport_in_content_space);
496
497   EXPECT_EQ(0, skewport.x());
498   EXPECT_EQ(10, skewport.y());
499   EXPECT_EQ(25, skewport.width());
500   EXPECT_EQ(35, skewport.height());
501
502   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 2.0);
503
504   have_now = false;
505   have_eventually = false;
506   bool have_soon = false;
507
508   // Viewport moved, so we expect to find some NOW tiles, some SOON tiles and
509   // some EVENTUALLY tiles.
510   for (int i = 0; i < 6; ++i) {
511     for (int j = 0; j < 6; ++j) {
512       Tile* tile = tiling->TileAt(i, j);
513       TilePriority priority = tile->priority(ACTIVE_TREE);
514
515       if (viewport_in_content_space.Intersects(tile->content_rect())) {
516         EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i
517                                                             << " j: " << j;
518         EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i
519                                                            << " j: " << j;
520         have_now = true;
521       } else if (skewport.Intersects(tile->content_rect())) {
522         EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i
523                                                              << " j: " << j;
524         EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
525                                                      << " j: " << j;
526         have_soon = true;
527       } else {
528         EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin)
529             << "i: " << i << " j: " << j;
530         EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
531                                                      << " j: " << j;
532         have_eventually = true;
533       }
534     }
535   }
536
537   EXPECT_TRUE(have_now);
538   EXPECT_TRUE(have_soon);
539   EXPECT_TRUE(have_eventually);
540
541   priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
542   EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
543
544   priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
545   EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible);
546
547   priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
548   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
549
550   // Change the underlying layer scale.
551   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 2.0f, 3.0);
552
553   priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
554   EXPECT_FLOAT_EQ(34.f, priority.distance_to_visible);
555
556   priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
557   EXPECT_FLOAT_EQ(14.f, priority.distance_to_visible);
558
559   priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
560   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
561 }
562
563 TEST(PictureLayerTilingTest, ExpandRectEqual) {
564   gfx::Rect in(40, 50, 100, 200);
565   gfx::Rect bounds(-1000, -1000, 10000, 10000);
566   int64 target_area = 100 * 200;
567   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
568       in, target_area, bounds, NULL);
569   EXPECT_EQ(in.ToString(), out.ToString());
570 }
571
572 TEST(PictureLayerTilingTest, ExpandRectSmaller) {
573   gfx::Rect in(40, 50, 100, 200);
574   gfx::Rect bounds(-1000, -1000, 10000, 10000);
575   int64 target_area = 100 * 100;
576   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
577       in, target_area, bounds, NULL);
578   EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
579   EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
580   EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
581   EXPECT_NEAR(100 * 100, out.width() * out.height(), 50);
582   EXPECT_TRUE(bounds.Contains(out));
583 }
584
585 TEST(PictureLayerTilingTest, ExpandRectUnbounded) {
586   gfx::Rect in(40, 50, 100, 200);
587   gfx::Rect bounds(-1000, -1000, 10000, 10000);
588   int64 target_area = 200 * 200;
589   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
590       in, target_area, bounds, NULL);
591   EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
592   EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
593   EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
594   EXPECT_NEAR(200 * 200, out.width() * out.height(), 100);
595   EXPECT_TRUE(bounds.Contains(out));
596 }
597
598 TEST(PictureLayerTilingTest, ExpandRectBoundedSmaller) {
599   gfx::Rect in(40, 50, 100, 200);
600   gfx::Rect bounds(50, 60, 40, 30);
601   int64 target_area = 200 * 200;
602   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
603       in, target_area, bounds, NULL);
604   EXPECT_EQ(bounds.ToString(), out.ToString());
605 }
606
607 TEST(PictureLayerTilingTest, ExpandRectBoundedEqual) {
608   gfx::Rect in(40, 50, 100, 200);
609   gfx::Rect bounds = in;
610   int64 target_area = 200 * 200;
611   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
612       in, target_area, bounds, NULL);
613   EXPECT_EQ(bounds.ToString(), out.ToString());
614 }
615
616 TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchVertical) {
617   gfx::Rect in(40, 50, 100, 200);
618   gfx::Rect bounds(45, 0, 90, 300);
619   int64 target_area = 200 * 200;
620   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
621       in, target_area, bounds, NULL);
622   EXPECT_EQ(bounds.ToString(), out.ToString());
623 }
624
625 TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchVertical) {
626   gfx::Rect in(40, 50, 100, 200);
627   gfx::Rect bounds(40, 0, 100, 300);
628   int64 target_area = 200 * 200;
629   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
630       in, target_area, bounds, NULL);
631   EXPECT_EQ(bounds.ToString(), out.ToString());
632 }
633
634 TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchHorizontal) {
635   gfx::Rect in(40, 50, 100, 200);
636   gfx::Rect bounds(0, 55, 180, 190);
637   int64 target_area = 200 * 200;
638   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
639       in, target_area, bounds, NULL);
640   EXPECT_EQ(bounds.ToString(), out.ToString());
641 }
642
643 TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchHorizontal) {
644   gfx::Rect in(40, 50, 100, 200);
645   gfx::Rect bounds(0, 50, 180, 200);
646   int64 target_area = 200 * 200;
647   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
648       in, target_area, bounds, NULL);
649   EXPECT_EQ(bounds.ToString(), out.ToString());
650 }
651
652 TEST(PictureLayerTilingTest, ExpandRectBoundedLeft) {
653   gfx::Rect in(40, 50, 100, 200);
654   gfx::Rect bounds(20, -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.bottom() - in.bottom(), out.right() - in.right());
660   EXPECT_LE(out.width() * out.height(), target_area);
661   EXPECT_GT(out.width() * out.height(),
662             target_area - out.width() - out.height() * 2);
663   EXPECT_TRUE(bounds.Contains(out));
664 }
665
666 TEST(PictureLayerTilingTest, ExpandRectBoundedRight) {
667   gfx::Rect in(40, 50, 100, 200);
668   gfx::Rect bounds(-1000, -1000, 1000+120, 10000);
669   int64 target_area = 200 * 200;
670   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
671       in, target_area, bounds, NULL);
672   EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
673   EXPECT_EQ(out.bottom() - in.bottom(), in.x() - out.x());
674   EXPECT_LE(out.width() * out.height(), target_area);
675   EXPECT_GT(out.width() * out.height(),
676             target_area - out.width() - out.height() * 2);
677   EXPECT_TRUE(bounds.Contains(out));
678 }
679
680 TEST(PictureLayerTilingTest, ExpandRectBoundedTop) {
681   gfx::Rect in(40, 50, 100, 200);
682   gfx::Rect bounds(-1000, 30, 10000, 10000);
683   int64 target_area = 200 * 200;
684   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
685       in, target_area, bounds, NULL);
686   EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
687   EXPECT_EQ(out.right() - in.right(), out.bottom() - in.bottom());
688   EXPECT_LE(out.width() * out.height(), target_area);
689   EXPECT_GT(out.width() * out.height(),
690             target_area - out.width() * 2 - out.height());
691   EXPECT_TRUE(bounds.Contains(out));
692 }
693
694 TEST(PictureLayerTilingTest, ExpandRectBoundedBottom) {
695   gfx::Rect in(40, 50, 100, 200);
696   gfx::Rect bounds(-1000, -1000, 10000, 1000 + 220);
697   int64 target_area = 200 * 200;
698   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
699       in, target_area, bounds, NULL);
700   EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
701   EXPECT_EQ(out.right() - in.right(), in.y() - out.y());
702   EXPECT_LE(out.width() * out.height(), target_area);
703   EXPECT_GT(out.width() * out.height(),
704             target_area - out.width() * 2 - out.height());
705   EXPECT_TRUE(bounds.Contains(out));
706 }
707
708 TEST(PictureLayerTilingTest, ExpandRectSquishedHorizontally) {
709   gfx::Rect in(40, 50, 100, 200);
710   gfx::Rect bounds(0, -4000, 100+40+20, 100000);
711   int64 target_area = 400 * 400;
712   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
713       in, target_area, bounds, NULL);
714   EXPECT_EQ(20, out.right() - in.right());
715   EXPECT_EQ(40, in.x() - out.x());
716   EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
717   EXPECT_LE(out.width() * out.height(), target_area);
718   EXPECT_GT(out.width() * out.height(),
719             target_area - out.width() * 2);
720   EXPECT_TRUE(bounds.Contains(out));
721 }
722
723 TEST(PictureLayerTilingTest, ExpandRectSquishedVertically) {
724   gfx::Rect in(40, 50, 100, 200);
725   gfx::Rect bounds(-4000, 0, 100000, 200+50+30);
726   int64 target_area = 400 * 400;
727   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
728       in, target_area, bounds, NULL);
729   EXPECT_EQ(30, out.bottom() - in.bottom());
730   EXPECT_EQ(50, in.y() - out.y());
731   EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
732   EXPECT_LE(out.width() * out.height(), target_area);
733   EXPECT_GT(out.width() * out.height(),
734             target_area - out.height() * 2);
735   EXPECT_TRUE(bounds.Contains(out));
736 }
737
738 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsFarAway) {
739   gfx::Rect in(400, 500, 100, 200);
740   gfx::Rect bounds(0, 0, 10, 10);
741   int64 target_area = 400 * 400;
742   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
743       in, target_area, bounds, NULL);
744   EXPECT_TRUE(out.IsEmpty());
745 }
746
747 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedFullyCover) {
748   gfx::Rect in(40, 50, 100, 100);
749   gfx::Rect bounds(0, 0, 10, 10);
750   int64 target_area = 400 * 400;
751   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
752       in, target_area, bounds, NULL);
753   EXPECT_EQ(bounds.ToString(), out.ToString());
754 }
755
756 TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedPartlyCover) {
757   gfx::Rect in(600, 600, 100, 100);
758   gfx::Rect bounds(0, 0, 500, 500);
759   int64 target_area = 400 * 400;
760   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
761       in, target_area, bounds, NULL);
762   EXPECT_EQ(bounds.right(), out.right());
763   EXPECT_EQ(bounds.bottom(), out.bottom());
764   EXPECT_LE(out.width() * out.height(), target_area);
765   EXPECT_GT(out.width() * out.height(),
766             target_area - out.width() - out.height());
767   EXPECT_TRUE(bounds.Contains(out));
768 }
769
770 TEST(PictureLayerTilingTest, EmptyStartingRect) {
771   // If a layer has a non-invertible transform, then the starting rect
772   // for the layer would be empty.
773   gfx::Rect in(40, 40, 0, 0);
774   gfx::Rect bounds(0, 0, 10, 10);
775   int64 target_area = 400 * 400;
776   gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
777       in, target_area, bounds, NULL);
778   EXPECT_TRUE(out.IsEmpty());
779 }
780
781 TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) {
782   FakePictureLayerTilingClient client;
783   scoped_ptr<TestablePictureLayerTiling> tiling;
784
785   gfx::Rect viewport(50, 50, 100, 100);
786   gfx::Size layer_bounds(200, 200);
787
788   client.SetTileSize(gfx::Size(30, 30));
789
790   tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
791   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0);
792
793   PictureLayerTiling::TilingRasterTileIterator empty_iterator;
794   EXPECT_FALSE(empty_iterator);
795
796   std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
797
798   // Sanity check.
799   EXPECT_EQ(64u, all_tiles.size());
800
801   // The explanation of each iteration is as follows:
802   // 1. First iteration tests that we can get all of the tiles correctly.
803   // 2. Second iteration ensures that we can get all of the tiles again (first
804   //    iteration didn't change any tiles), as well set all tiles to be ready to
805   //    draw.
806   // 3. Third iteration ensures that no tiles are returned, since they were all
807   //    marked as ready to draw.
808   for (int i = 0; i < 3; ++i) {
809     PictureLayerTiling::TilingRasterTileIterator it(tiling.get(), ACTIVE_TREE);
810
811     // There are 3 bins in TilePriority.
812     bool have_tiles[3] = {};
813
814     // On the third iteration, we should get no tiles since everything was
815     // marked as ready to draw.
816     if (i == 2) {
817       EXPECT_FALSE(it);
818       continue;
819     }
820
821     EXPECT_TRUE(it);
822     std::set<Tile*> unique_tiles;
823     unique_tiles.insert(*it);
824     Tile* last_tile = *it;
825     have_tiles[last_tile->priority(ACTIVE_TREE).priority_bin] = true;
826
827     // On the second iteration, mark everything as ready to draw (solid color).
828     if (i == 1) {
829       ManagedTileState::TileVersion& tile_version =
830           last_tile->GetTileVersionForTesting(
831               last_tile->DetermineRasterModeForTree(ACTIVE_TREE));
832       tile_version.SetSolidColorForTesting(SK_ColorRED);
833     }
834     ++it;
835     int eventually_bin_order_correct_count = 0;
836     int eventually_bin_order_incorrect_count = 0;
837     while (it) {
838       Tile* new_tile = *it;
839       ++it;
840       unique_tiles.insert(new_tile);
841
842       TilePriority last_priority = last_tile->priority(ACTIVE_TREE);
843       TilePriority new_priority = new_tile->priority(ACTIVE_TREE);
844       EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
845       if (last_priority.priority_bin == new_priority.priority_bin) {
846         if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
847           bool order_correct = last_priority.distance_to_visible <=
848                                new_priority.distance_to_visible;
849           eventually_bin_order_correct_count += order_correct;
850           eventually_bin_order_incorrect_count += !order_correct;
851         } else {
852           EXPECT_LE(last_priority.distance_to_visible,
853                     new_priority.distance_to_visible);
854         }
855       }
856       have_tiles[new_priority.priority_bin] = true;
857
858       last_tile = new_tile;
859
860       // On the second iteration, mark everything as ready to draw (solid
861       // color).
862       if (i == 1) {
863         ManagedTileState::TileVersion& tile_version =
864             last_tile->GetTileVersionForTesting(
865                 last_tile->DetermineRasterModeForTree(ACTIVE_TREE));
866         tile_version.SetSolidColorForTesting(SK_ColorRED);
867       }
868     }
869
870     EXPECT_GT(eventually_bin_order_correct_count,
871               eventually_bin_order_incorrect_count);
872
873     // We should have now and eventually tiles, but not soon tiles because the
874     // viewport is static.
875     EXPECT_TRUE(have_tiles[TilePriority::NOW]);
876     EXPECT_FALSE(have_tiles[TilePriority::SOON]);
877     EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
878
879     EXPECT_EQ(unique_tiles.size(), all_tiles.size());
880   }
881 }
882
883 TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) {
884   FakePictureLayerTilingClient client;
885   scoped_ptr<TestablePictureLayerTiling> tiling;
886
887   gfx::Rect viewport(50, 0, 100, 100);
888   gfx::Rect moved_viewport(50, 0, 100, 250);
889   gfx::Size layer_bounds(500, 500);
890
891   client.SetTileSize(gfx::Size(30, 30));
892
893   tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client);
894   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0);
895   tiling->UpdateTilePriorities(ACTIVE_TREE, moved_viewport, 1.0f, 2.0);
896
897   // There are 3 bins in TilePriority.
898   bool have_tiles[3] = {};
899   Tile* last_tile = NULL;
900   int eventually_bin_order_correct_count = 0;
901   int eventually_bin_order_incorrect_count = 0;
902   for (PictureLayerTiling::TilingRasterTileIterator it(tiling.get(),
903                                                        ACTIVE_TREE);
904        it;
905        ++it) {
906     if (!last_tile)
907       last_tile = *it;
908
909     Tile* new_tile = *it;
910
911     TilePriority last_priority = last_tile->priority(ACTIVE_TREE);
912     TilePriority new_priority = new_tile->priority(ACTIVE_TREE);
913
914     have_tiles[new_priority.priority_bin] = true;
915
916     EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
917     if (last_priority.priority_bin == new_priority.priority_bin) {
918       if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
919         bool order_correct = last_priority.distance_to_visible <=
920                              new_priority.distance_to_visible;
921         eventually_bin_order_correct_count += order_correct;
922         eventually_bin_order_incorrect_count += !order_correct;
923       } else {
924         EXPECT_LE(last_priority.distance_to_visible,
925                   new_priority.distance_to_visible);
926       }
927     }
928     last_tile = new_tile;
929   }
930
931   EXPECT_GT(eventually_bin_order_correct_count,
932             eventually_bin_order_incorrect_count);
933
934   EXPECT_TRUE(have_tiles[TilePriority::NOW]);
935   EXPECT_TRUE(have_tiles[TilePriority::SOON]);
936   EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
937 }
938
939 static void TileExists(bool exists, Tile* tile,
940                        const gfx::Rect& geometry_rect) {
941   EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString();
942 }
943
944 TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
945   gfx::Size layer_bounds(1099, 801);
946   Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
947   VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
948   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
949
950   tiling_->UpdateTilePriorities(
951       ACTIVE_TREE,
952       gfx::Rect(layer_bounds),  // visible content rect
953       1.f,                      // current contents scale
954       1.0);                     // current frame time
955   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
956
957   // Make the viewport rect empty. All tiles are killed and become zombies.
958   tiling_->UpdateTilePriorities(ACTIVE_TREE,
959                                 gfx::Rect(),  // visible content rect
960                                 1.f,          // current contents scale
961                                 2.0);         // current frame time
962   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
963 }
964
965 TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
966   gfx::Size layer_bounds(1099, 801);
967   Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
968   VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
969   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
970
971   gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000);
972
973   tiling_->UpdateTilePriorities(
974       ACTIVE_TREE,
975       gfx::Rect(layer_bounds),  // visible content rect
976       1.f,                      // current contents scale
977       1.0);                     // current frame time
978   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
979
980   // If the visible content rect is empty, it should still have live tiles.
981   tiling_->UpdateTilePriorities(ACTIVE_TREE,
982                                 giant_rect,  // visible content rect
983                                 1.f,         // current contents scale
984                                 2.0);        // current frame time
985   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
986 }
987
988 TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
989   gfx::Size layer_bounds(1099, 801);
990   Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
991   VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
992   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
993
994   // This rect does not intersect with the layer, as the layer is outside the
995   // viewport.
996   gfx::Rect viewport_rect(1100, 0, 1000, 1000);
997   EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds)));
998
999   tiling_->UpdateTilePriorities(ACTIVE_TREE,
1000                                 viewport_rect,  // visible content rect
1001                                 1.f,            // current contents scale
1002                                 1.0);           // current frame time
1003   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1004 }
1005
1006 static void TilesIntersectingRectExist(const gfx::Rect& rect,
1007                                        bool intersect_exists,
1008                                        Tile* tile,
1009                                        const gfx::Rect& geometry_rect) {
1010   bool intersects = rect.Intersects(geometry_rect);
1011   bool expected_exists = intersect_exists ? intersects : !intersects;
1012   EXPECT_EQ(expected_exists, tile != NULL)
1013       << "Rects intersecting " << rect.ToString() << " should exist. "
1014       << "Current tile rect is " << geometry_rect.ToString();
1015 }
1016
1017 TEST_F(PictureLayerTilingIteratorTest,
1018        TilesExistLargeViewportAndLayerWithSmallVisibleArea) {
1019   gfx::Size layer_bounds(10000, 10000);
1020   Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1021   VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1022   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1023
1024   gfx::Rect visible_rect(8000, 8000, 50, 50);
1025
1026   set_max_tiles_for_interest_area(1);
1027   tiling_->UpdateTilePriorities(ACTIVE_TREE,
1028                                 visible_rect,  // visible content rect
1029                                 1.f,           // current contents scale
1030                                 1.0);          // current frame time
1031   VerifyTiles(1.f,
1032               gfx::Rect(layer_bounds),
1033               base::Bind(&TilesIntersectingRectExist, visible_rect, true));
1034 }
1035
1036 static void CountExistingTiles(int *count,
1037                                Tile* tile,
1038                                const gfx::Rect& geometry_rect) {
1039   if (tile != NULL)
1040     ++(*count);
1041 }
1042
1043 TEST_F(PictureLayerTilingIteratorTest,
1044        TilesExistLargeViewportAndLayerWithLargeVisibleArea) {
1045   gfx::Size layer_bounds(10000, 10000);
1046   Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1047   VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1048   VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1049
1050   set_max_tiles_for_interest_area(1);
1051   tiling_->UpdateTilePriorities(
1052       ACTIVE_TREE,
1053       gfx::Rect(layer_bounds),  // visible content rect
1054       1.f,                      // current contents scale
1055       1.0);                     // current frame time
1056
1057   int num_tiles = 0;
1058   VerifyTiles(1.f,
1059               gfx::Rect(layer_bounds),
1060               base::Bind(&CountExistingTiles, &num_tiles));
1061   // If we're making a rect the size of one tile, it can only overlap up to 4
1062   // tiles depending on its position.
1063   EXPECT_LE(num_tiles, 4);
1064   VerifyTiles(1.f, gfx::Rect(), base::Bind(&TileExists, false));
1065 }
1066
1067 TEST_F(PictureLayerTilingIteratorTest, AddTilingsToMatchScale) {
1068   gfx::Size layer_bounds(1099, 801);
1069   gfx::Size tile_size(100, 100);
1070
1071   client_.SetTileSize(tile_size);
1072
1073   PictureLayerTilingSet active_set(&client_, layer_bounds);
1074
1075   active_set.AddTiling(1.f);
1076
1077   VerifyTiles(active_set.tiling_at(0),
1078               1.f,
1079               gfx::Rect(layer_bounds),
1080               base::Bind(&TileExists, false));
1081
1082   active_set.UpdateTilePriorities(
1083       PENDING_TREE,
1084       gfx::Rect(layer_bounds),  // visible content rect
1085       1.f,                      // current contents scale
1086       1.0);                     // current frame time
1087
1088   // The active tiling has tiles now.
1089   VerifyTiles(active_set.tiling_at(0),
1090               1.f,
1091               gfx::Rect(layer_bounds),
1092               base::Bind(&TileExists, true));
1093
1094   // Add the same tilings to the pending set.
1095   PictureLayerTilingSet pending_set(&client_, layer_bounds);
1096   Region invalidation;
1097   pending_set.SyncTilings(active_set, layer_bounds, invalidation, 0.f);
1098
1099   // The pending tiling starts with no tiles.
1100   VerifyTiles(pending_set.tiling_at(0),
1101               1.f,
1102               gfx::Rect(layer_bounds),
1103               base::Bind(&TileExists, false));
1104
1105   // UpdateTilePriorities on the pending tiling at the same frame time. The
1106   // pending tiling should get tiles.
1107   pending_set.UpdateTilePriorities(
1108       PENDING_TREE,
1109       gfx::Rect(layer_bounds),  // visible content rect
1110       1.f,                      // current contents scale
1111       1.0);                     // current frame time
1112
1113   VerifyTiles(pending_set.tiling_at(0),
1114               1.f,
1115               gfx::Rect(layer_bounds),
1116               base::Bind(&TileExists, true));
1117 }
1118
1119 TEST(UpdateTilePrioritiesTest, VisibleTiles) {
1120   // The TilePriority of visible tiles should have zero distance_to_visible
1121   // and time_to_visible.
1122
1123   FakePictureLayerTilingClient client;
1124   scoped_ptr<TestablePictureLayerTiling> tiling;
1125
1126   gfx::Size device_viewport(800, 600);
1127   gfx::Size last_layer_bounds(200, 200);
1128   gfx::Size current_layer_bounds(200, 200);
1129   float current_layer_contents_scale = 1.f;
1130   gfx::Transform current_screen_transform;
1131   double current_frame_time_in_seconds = 1.0;
1132
1133   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1134       current_screen_transform, device_viewport);
1135
1136   client.SetTileSize(gfx::Size(100, 100));
1137   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1138                                               current_layer_bounds,
1139                                               &client);
1140
1141   tiling->UpdateTilePriorities(ACTIVE_TREE,
1142                                viewport_in_layer_space,
1143                                current_layer_contents_scale,
1144                                current_frame_time_in_seconds);
1145
1146   ASSERT_TRUE(tiling->TileAt(0, 0));
1147   ASSERT_TRUE(tiling->TileAt(0, 1));
1148   ASSERT_TRUE(tiling->TileAt(1, 0));
1149   ASSERT_TRUE(tiling->TileAt(1, 1));
1150
1151   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1152   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1153   EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1154
1155   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1156   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1157   EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1158
1159   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1160   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1161   EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1162
1163   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1164   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1165   EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1166 }
1167
1168 TEST(UpdateTilePrioritiesTest, OffscreenTiles) {
1169   // The TilePriority of offscreen tiles (without movement) should have nonzero
1170   // distance_to_visible and infinite time_to_visible.
1171
1172   FakePictureLayerTilingClient client;
1173   scoped_ptr<TestablePictureLayerTiling> tiling;
1174
1175   gfx::Size device_viewport(800, 600);
1176   gfx::Size last_layer_bounds(200, 200);
1177   gfx::Size current_layer_bounds(200, 200);
1178   float current_layer_contents_scale = 1.f;
1179   gfx::Transform last_screen_transform;
1180   gfx::Transform current_screen_transform;
1181   double current_frame_time_in_seconds = 1.0;
1182
1183   current_screen_transform.Translate(850, 0);
1184   last_screen_transform = current_screen_transform;
1185
1186   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1187       current_screen_transform, device_viewport);
1188
1189   client.SetTileSize(gfx::Size(100, 100));
1190   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1191                                               current_layer_bounds,
1192                                               &client);
1193
1194   tiling->UpdateTilePriorities(ACTIVE_TREE,
1195                                viewport_in_layer_space,
1196                                current_layer_contents_scale,
1197                                current_frame_time_in_seconds);
1198
1199   ASSERT_TRUE(tiling->TileAt(0, 0));
1200   ASSERT_TRUE(tiling->TileAt(0, 1));
1201   ASSERT_TRUE(tiling->TileAt(1, 0));
1202   ASSERT_TRUE(tiling->TileAt(1, 1));
1203
1204   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1205   EXPECT_GT(priority.distance_to_visible, 0.f);
1206   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1207
1208   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1209   EXPECT_GT(priority.distance_to_visible, 0.f);
1210   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1211
1212   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1213   EXPECT_GT(priority.distance_to_visible, 0.f);
1214   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1215
1216   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1217   EXPECT_GT(priority.distance_to_visible, 0.f);
1218   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1219
1220   // Furthermore, in this scenario tiles on the right hand side should have a
1221   // larger distance to visible.
1222   TilePriority left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1223   TilePriority right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1224   EXPECT_GT(right.distance_to_visible, left.distance_to_visible);
1225
1226   left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1227   right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1228   EXPECT_GT(right.distance_to_visible, left.distance_to_visible);
1229 }
1230
1231 TEST(UpdateTilePrioritiesTest, PartiallyOffscreenLayer) {
1232   // Sanity check that a layer with some tiles visible and others offscreen has
1233   // correct TilePriorities for each tile.
1234
1235   FakePictureLayerTilingClient client;
1236   scoped_ptr<TestablePictureLayerTiling> tiling;
1237
1238   gfx::Size device_viewport(800, 600);
1239   gfx::Size last_layer_bounds(200, 200);
1240   gfx::Size current_layer_bounds(200, 200);
1241   float current_layer_contents_scale = 1.f;
1242   gfx::Transform last_screen_transform;
1243   gfx::Transform current_screen_transform;
1244   double current_frame_time_in_seconds = 1.0;
1245
1246   current_screen_transform.Translate(705, 505);
1247   last_screen_transform = current_screen_transform;
1248
1249   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1250       current_screen_transform, device_viewport);
1251
1252   client.SetTileSize(gfx::Size(100, 100));
1253   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1254                                               current_layer_bounds,
1255                                               &client);
1256
1257   tiling->UpdateTilePriorities(ACTIVE_TREE,
1258                                viewport_in_layer_space,
1259                                current_layer_contents_scale,
1260                                current_frame_time_in_seconds);
1261
1262   ASSERT_TRUE(tiling->TileAt(0, 0));
1263   ASSERT_TRUE(tiling->TileAt(0, 1));
1264   ASSERT_TRUE(tiling->TileAt(1, 0));
1265   ASSERT_TRUE(tiling->TileAt(1, 1));
1266
1267   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1268   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1269   EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1270
1271   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1272   EXPECT_GT(priority.distance_to_visible, 0.f);
1273   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1274
1275   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1276   EXPECT_GT(priority.distance_to_visible, 0.f);
1277   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1278
1279   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1280   EXPECT_GT(priority.distance_to_visible, 0.f);
1281   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1282 }
1283
1284 TEST(UpdateTilePrioritiesTest, PartiallyOffscreenRotatedLayer) {
1285   // Each tile of a layer may be affected differently by a transform; Check
1286   // that UpdateTilePriorities correctly accounts for the transform between
1287   // layer space and screen space.
1288
1289   FakePictureLayerTilingClient client;
1290   scoped_ptr<TestablePictureLayerTiling> tiling;
1291
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 last_screen_transform;
1297   gfx::Transform current_screen_transform;
1298   double current_frame_time_in_seconds = 1.0;
1299
1300   // A diagonally rotated layer that is partially off the bottom of the screen.
1301   // In this configuration, only the top-left tile would be visible.
1302   current_screen_transform.Translate(600, 750);
1303   current_screen_transform.RotateAboutZAxis(45);
1304   last_screen_transform = current_screen_transform;
1305
1306   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1307       current_screen_transform, device_viewport);
1308
1309   client.SetTileSize(gfx::Size(100, 100));
1310   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1311                                               current_layer_bounds,
1312                                               &client);
1313
1314   tiling->UpdateTilePriorities(ACTIVE_TREE,
1315                                viewport_in_layer_space,
1316                                current_layer_contents_scale,
1317                                current_frame_time_in_seconds);
1318
1319   ASSERT_TRUE(tiling->TileAt(0, 0));
1320   ASSERT_TRUE(tiling->TileAt(0, 1));
1321   ASSERT_TRUE(tiling->TileAt(1, 0));
1322   ASSERT_TRUE(tiling->TileAt(1, 1));
1323
1324   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1325   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1326   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1327
1328   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1329   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1330   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1331
1332   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1333   EXPECT_GT(priority.distance_to_visible, 0.f);
1334   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1335
1336   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1337   EXPECT_GT(priority.distance_to_visible, 0.f);
1338   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1339
1340   // Furthermore, in this scenario the bottom-right tile should have the larger
1341   // distance to visible.
1342   TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1343   TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1344   TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1345   EXPECT_GT(top_right.distance_to_visible, top_left.distance_to_visible);
1346
1347   EXPECT_EQ(bottom_right.distance_to_visible, top_right.distance_to_visible);
1348 }
1349
1350 TEST(UpdateTilePrioritiesTest, PerspectiveLayer) {
1351   // Perspective transforms need to take a different code path.
1352   // This test checks tile priorities of a perspective layer.
1353
1354   FakePictureLayerTilingClient client;
1355   scoped_ptr<TestablePictureLayerTiling> tiling;
1356
1357   gfx::Size device_viewport(800, 600);
1358   gfx::Rect visible_layer_rect(0, 0, 0, 0);  // offscreen.
1359   gfx::Size last_layer_bounds(200, 200);
1360   gfx::Size current_layer_bounds(200, 200);
1361   float current_layer_contents_scale = 1.f;
1362   gfx::Transform last_screen_transform;
1363   gfx::Transform current_screen_transform;
1364   double current_frame_time_in_seconds = 1.0;
1365
1366   // A 3d perspective layer rotated about its Y axis, translated to almost
1367   // fully offscreen. The left side will appear closer (i.e. larger in 2d) than
1368   // the right side, so the top-left tile will technically be closer than the
1369   // top-right.
1370
1371   // Translate layer to offscreen
1372   current_screen_transform.Translate(400.0, 630.0);
1373   // Apply perspective about the center of the layer
1374   current_screen_transform.Translate(100.0, 100.0);
1375   current_screen_transform.ApplyPerspectiveDepth(100.0);
1376   current_screen_transform.RotateAboutYAxis(10.0);
1377   current_screen_transform.Translate(-100.0, -100.0);
1378   last_screen_transform = current_screen_transform;
1379
1380   // Sanity check that this transform wouldn't cause w<0 clipping.
1381   bool clipped;
1382   MathUtil::MapQuad(current_screen_transform,
1383                     gfx::QuadF(gfx::RectF(0, 0, 200, 200)),
1384                     &clipped);
1385   ASSERT_FALSE(clipped);
1386
1387   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1388       current_screen_transform, device_viewport);
1389
1390   client.SetTileSize(gfx::Size(100, 100));
1391   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1392                                               current_layer_bounds,
1393                                               &client);
1394
1395   tiling->UpdateTilePriorities(ACTIVE_TREE,
1396                                viewport_in_layer_space,
1397                                current_layer_contents_scale,
1398                                current_frame_time_in_seconds);
1399
1400   ASSERT_TRUE(tiling->TileAt(0, 0));
1401   ASSERT_TRUE(tiling->TileAt(0, 1));
1402   ASSERT_TRUE(tiling->TileAt(1, 0));
1403   ASSERT_TRUE(tiling->TileAt(1, 1));
1404
1405   // All tiles will have a positive distance_to_visible
1406   // and an infinite time_to_visible.
1407   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1408   EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1409   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1410
1411   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1412   EXPECT_GT(priority.distance_to_visible, 0.f);
1413   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1414
1415   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1416   EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1417   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1418
1419   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1420   EXPECT_GT(priority.distance_to_visible, 0.f);
1421   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1422
1423   // Furthermore, in this scenario the top-left distance_to_visible
1424   // will be smallest, followed by top-right. The bottom layers
1425   // will of course be further than the top layers.
1426   TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1427   TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1428   TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1429   TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1430
1431   EXPECT_GT(bottom_right.distance_to_visible, top_right.distance_to_visible);
1432
1433   EXPECT_GT(bottom_left.distance_to_visible, top_left.distance_to_visible);
1434 }
1435
1436 TEST(UpdateTilePrioritiesTest, PerspectiveLayerClippedByW) {
1437   // Perspective transforms need to take a different code path.
1438   // This test checks tile priorities of a perspective layer.
1439
1440   FakePictureLayerTilingClient client;
1441   scoped_ptr<TestablePictureLayerTiling> tiling;
1442
1443   gfx::Size device_viewport(800, 600);
1444   gfx::Size last_layer_bounds(200, 200);
1445   gfx::Size current_layer_bounds(200, 200);
1446   float current_layer_contents_scale = 1.f;
1447   gfx::Transform last_screen_transform;
1448   gfx::Transform current_screen_transform;
1449   double current_frame_time_in_seconds = 1.0;
1450
1451   // A 3d perspective layer rotated about its Y axis, translated to almost
1452   // fully offscreen. The left side will appear closer (i.e. larger in 2d) than
1453   // the right side, so the top-left tile will technically be closer than the
1454   // top-right.
1455
1456   // Translate layer to offscreen
1457   current_screen_transform.Translate(400.0, 970.0);
1458   // Apply perspective and rotation about the center of the layer
1459   current_screen_transform.Translate(100.0, 100.0);
1460   current_screen_transform.ApplyPerspectiveDepth(10.0);
1461   current_screen_transform.RotateAboutYAxis(10.0);
1462   current_screen_transform.Translate(-100.0, -100.0);
1463   last_screen_transform = current_screen_transform;
1464
1465   // Sanity check that this transform does cause w<0 clipping for the left side
1466   // of the layer, but not the right side.
1467   bool clipped;
1468   MathUtil::MapQuad(current_screen_transform,
1469                     gfx::QuadF(gfx::RectF(0, 0, 100, 200)),
1470                     &clipped);
1471   ASSERT_TRUE(clipped);
1472
1473   MathUtil::MapQuad(current_screen_transform,
1474                     gfx::QuadF(gfx::RectF(100, 0, 100, 200)),
1475                     &clipped);
1476   ASSERT_FALSE(clipped);
1477
1478   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1479       current_screen_transform, device_viewport);
1480
1481   client.SetTileSize(gfx::Size(100, 100));
1482   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1483                                               current_layer_bounds,
1484                                               &client);
1485
1486   tiling->UpdateTilePriorities(ACTIVE_TREE,
1487                                viewport_in_layer_space,
1488                                current_layer_contents_scale,
1489                                current_frame_time_in_seconds);
1490
1491   ASSERT_TRUE(tiling->TileAt(0, 0));
1492   ASSERT_TRUE(tiling->TileAt(0, 1));
1493   ASSERT_TRUE(tiling->TileAt(1, 0));
1494   ASSERT_TRUE(tiling->TileAt(1, 1));
1495
1496   // Left-side tiles will be clipped by the transform, so we have to assume
1497   // they are visible just in case.
1498   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1499   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1500   EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1501
1502   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1503   EXPECT_GT(priority.distance_to_visible, 0.f);
1504   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1505
1506   // Right-side tiles will have a positive distance_to_visible
1507   // and an infinite time_to_visible.
1508   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1509   EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1510   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1511
1512   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1513   EXPECT_GT(priority.distance_to_visible, 0.f);
1514   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1515 }
1516
1517 TEST(UpdateTilePrioritiesTest, BasicMotion) {
1518   // Test that time_to_visible is computed correctly when
1519   // there is some motion.
1520
1521   FakePictureLayerTilingClient client;
1522   scoped_ptr<TestablePictureLayerTiling> tiling;
1523
1524   gfx::Size device_viewport(800, 600);
1525   gfx::Rect visible_layer_rect(0, 0, 0, 0);
1526   gfx::Size last_layer_bounds(200, 200);
1527   gfx::Size current_layer_bounds(200, 200);
1528   float last_layer_contents_scale = 1.f;
1529   float current_layer_contents_scale = 1.f;
1530   gfx::Transform last_screen_transform;
1531   gfx::Transform current_screen_transform;
1532   double last_frame_time_in_seconds = 1.0;
1533   double current_frame_time_in_seconds = 2.0;
1534
1535   // Offscreen layer is coming closer to viewport at 1000 pixels per second.
1536   current_screen_transform.Translate(1800, 0);
1537   last_screen_transform.Translate(2800, 0);
1538
1539   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1540       current_screen_transform, device_viewport);
1541
1542   client.SetTileSize(gfx::Size(100, 100));
1543   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1544                                               current_layer_bounds,
1545                                               &client);
1546
1547   // previous ("last") frame
1548   tiling->UpdateTilePriorities(ACTIVE_TREE,
1549                                viewport_in_layer_space,
1550                                last_layer_contents_scale,
1551                                last_frame_time_in_seconds);
1552
1553   // current frame
1554   tiling->UpdateTilePriorities(ACTIVE_TREE,
1555                                viewport_in_layer_space,
1556                                current_layer_contents_scale,
1557                                current_frame_time_in_seconds);
1558
1559   ASSERT_TRUE(tiling->TileAt(0, 0));
1560   ASSERT_TRUE(tiling->TileAt(0, 1));
1561   ASSERT_TRUE(tiling->TileAt(1, 0));
1562   ASSERT_TRUE(tiling->TileAt(1, 1));
1563
1564   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1565   EXPECT_GT(priority.distance_to_visible, 0.f);
1566   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1567
1568   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1569   EXPECT_GT(priority.distance_to_visible, 0.f);
1570   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1571
1572   // time_to_visible for the right hand side layers needs an extra 0.099
1573   // seconds because this tile is 99 pixels further away.
1574   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1575   EXPECT_GT(priority.distance_to_visible, 0.f);
1576   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1577
1578   priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1579   EXPECT_GT(priority.distance_to_visible, 0.f);
1580   EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1581 }
1582
1583 TEST(UpdateTilePrioritiesTest, RotationMotion) {
1584   // Each tile of a layer may be affected differently by a transform; Check
1585   // that UpdateTilePriorities correctly accounts for the transform between
1586   // layer space and screen space.
1587
1588   FakePictureLayerTilingClient client;
1589   scoped_ptr<TestablePictureLayerTiling> tiling;
1590
1591   gfx::Size device_viewport(800, 600);
1592   gfx::Rect visible_layer_rect(0, 0, 0, 0);  // offscren.
1593   gfx::Size last_layer_bounds(200, 200);
1594   gfx::Size current_layer_bounds(200, 200);
1595   float last_layer_contents_scale = 1.f;
1596   float current_layer_contents_scale = 1.f;
1597   gfx::Transform last_screen_transform;
1598   gfx::Transform current_screen_transform;
1599   double last_frame_time_in_seconds = 1.0;
1600   double current_frame_time_in_seconds = 2.0;
1601
1602   // Rotation motion is set up specifically so that:
1603   //  - rotation occurs about the center of the layer
1604   //  - the top-left tile becomes visible on rotation
1605   //  - the top-right tile will have an infinite time_to_visible
1606   //    because it is rotating away from viewport.
1607   //  - bottom-left layer will have a positive non-zero time_to_visible
1608   //    because it is rotating toward the viewport.
1609   current_screen_transform.Translate(400, 550);
1610   current_screen_transform.RotateAboutZAxis(45);
1611
1612   last_screen_transform.Translate(400, 550);
1613
1614   gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1615       current_screen_transform, device_viewport);
1616
1617   client.SetTileSize(gfx::Size(100, 100));
1618   tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1619                                               current_layer_bounds,
1620                                               &client);
1621
1622   // previous ("last") frame
1623   tiling->UpdateTilePriorities(ACTIVE_TREE,
1624                                viewport_in_layer_space,
1625                                last_layer_contents_scale,
1626                                last_frame_time_in_seconds);
1627
1628   // current frame
1629   tiling->UpdateTilePriorities(ACTIVE_TREE,
1630                                viewport_in_layer_space,
1631                                current_layer_contents_scale,
1632                                current_frame_time_in_seconds);
1633
1634   ASSERT_TRUE(tiling->TileAt(0, 0));
1635   ASSERT_TRUE(tiling->TileAt(0, 1));
1636   ASSERT_TRUE(tiling->TileAt(1, 0));
1637   ASSERT_TRUE(tiling->TileAt(1, 1));
1638
1639   TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1640   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1641   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1642
1643   priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1644   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1645   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1646
1647   priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1648   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1649   EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1650 }
1651
1652 }  // namespace
1653 }  // namespace cc