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 "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"
20
21namespace cc {
22namespace {
23
24static gfx::Rect ViewportInLayerSpace(
25    const gfx::Transform& transform,
26    const gfx::Size& device_viewport) {
27
28  gfx::Transform inverse;
29  if (!transform.GetInverse(&inverse))
30    return gfx::Rect();
31
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);
35}
36
37static 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                                            Occlusion());
48  }
49}
50
51class TestablePictureLayerTiling : public PictureLayerTiling {
52 public:
53  using PictureLayerTiling::SetLiveTilesRect;
54  using PictureLayerTiling::TileAt;
55
56  static scoped_ptr<TestablePictureLayerTiling> Create(
57      float contents_scale,
58      const gfx::Size& layer_bounds,
59      PictureLayerTilingClient* client) {
60    return make_scoped_ptr(new TestablePictureLayerTiling(
61        contents_scale,
62        layer_bounds,
63        client));
64  }
65
66  gfx::Rect live_tiles_rect() const { return live_tiles_rect_; }
67
68  using PictureLayerTiling::ComputeSkewport;
69
70 protected:
71  TestablePictureLayerTiling(float contents_scale,
72                             const gfx::Size& layer_bounds,
73                             PictureLayerTilingClient* client)
74      : PictureLayerTiling(contents_scale, layer_bounds, client) { }
75};
76
77class PictureLayerTilingIteratorTest : public testing::Test {
78 public:
79  PictureLayerTilingIteratorTest() {}
80  virtual ~PictureLayerTilingIteratorTest() {}
81
82  void Initialize(const gfx::Size& tile_size,
83                  float contents_scale,
84                  const gfx::Size& layer_bounds) {
85    client_.SetTileSize(tile_size);
86    client_.set_tree(PENDING_TREE);
87    tiling_ = TestablePictureLayerTiling::Create(contents_scale,
88                                                 layer_bounds,
89                                                 &client_);
90  }
91
92  void SetLiveRectAndVerifyTiles(const gfx::Rect& live_tiles_rect) {
93    tiling_->SetLiveTilesRect(live_tiles_rect);
94
95    std::vector<Tile*> tiles = tiling_->AllTilesForTesting();
96    for (std::vector<Tile*>::iterator iter = tiles.begin();
97         iter != tiles.end();
98         ++iter) {
99      EXPECT_TRUE(live_tiles_rect.Intersects((*iter)->content_rect()));
100    }
101  }
102
103  void VerifyTilesExactlyCoverRect(
104      float rect_scale,
105      const gfx::Rect& request_rect,
106      const gfx::Rect& expect_rect) {
107    EXPECT_TRUE(request_rect.Contains(expect_rect));
108
109    // Iterators are not valid if this ratio is too large (i.e. the
110    // tiling is too high-res for a low-res destination rect.)  This is an
111    // artifact of snapping geometry to integer coordinates and then mapping
112    // back to floating point texture coordinates.
113    float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
114    ASSERT_LE(dest_to_contents_scale, 2.0);
115
116    Region remaining = expect_rect;
117    for (PictureLayerTiling::CoverageIterator
118             iter(tiling_.get(), rect_scale, request_rect);
119         iter;
120         ++iter) {
121      // Geometry cannot overlap previous geometry at all
122      gfx::Rect geometry = iter.geometry_rect();
123      EXPECT_TRUE(expect_rect.Contains(geometry));
124      EXPECT_TRUE(remaining.Contains(geometry));
125      remaining.Subtract(geometry);
126
127      // Sanity check that texture coords are within the texture rect.
128      gfx::RectF texture_rect = iter.texture_rect();
129      EXPECT_GE(texture_rect.x(), 0);
130      EXPECT_GE(texture_rect.y(), 0);
131      EXPECT_LE(texture_rect.right(), client_.TileSize().width());
132      EXPECT_LE(texture_rect.bottom(), client_.TileSize().height());
133
134      EXPECT_EQ(iter.texture_size(), client_.TileSize());
135    }
136
137    // The entire rect must be filled by geometry from the tiling.
138    EXPECT_TRUE(remaining.IsEmpty());
139  }
140
141  void VerifyTilesExactlyCoverRect(float rect_scale, const gfx::Rect& rect) {
142    VerifyTilesExactlyCoverRect(rect_scale, rect, rect);
143  }
144
145  void VerifyTiles(
146      float rect_scale,
147      const gfx::Rect& rect,
148      base::Callback<void(Tile* tile,
149                          const gfx::Rect& geometry_rect)> callback) {
150    VerifyTiles(tiling_.get(),
151                rect_scale,
152                rect,
153                callback);
154  }
155
156  void VerifyTiles(
157      PictureLayerTiling* tiling,
158      float rect_scale,
159      const gfx::Rect& rect,
160      base::Callback<void(Tile* tile,
161                          const gfx::Rect& geometry_rect)> callback) {
162    Region remaining = rect;
163    for (PictureLayerTiling::CoverageIterator iter(tiling, rect_scale, rect);
164         iter;
165         ++iter) {
166      remaining.Subtract(iter.geometry_rect());
167      callback.Run(*iter, iter.geometry_rect());
168    }
169    EXPECT_TRUE(remaining.IsEmpty());
170  }
171
172  void VerifyTilesCoverNonContainedRect(float rect_scale,
173                                        const gfx::Rect& dest_rect) {
174    float dest_to_contents_scale = tiling_->contents_scale() / rect_scale;
175    gfx::Rect clamped_rect = gfx::ScaleToEnclosingRect(
176        gfx::Rect(tiling_->tiling_size()), 1.f / dest_to_contents_scale);
177    clamped_rect.Intersect(dest_rect);
178    VerifyTilesExactlyCoverRect(rect_scale, dest_rect, clamped_rect);
179  }
180
181  void set_max_tiles_for_interest_area(size_t area) {
182    client_.set_max_tiles_for_interest_area(area);
183  }
184
185 protected:
186  FakePictureLayerTilingClient client_;
187  scoped_ptr<TestablePictureLayerTiling> tiling_;
188
189 private:
190  DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest);
191};
192
193TEST_F(PictureLayerTilingIteratorTest, ResizeDeletesTiles) {
194  // Verifies that a resize with invalidation for newly exposed pixels will
195  // deletes tiles that intersect that invalidation.
196  gfx::Size tile_size(100, 100);
197  gfx::Size original_layer_size(10, 10);
198  Initialize(tile_size, 1.f, original_layer_size);
199  SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
200
201  // Tiling only has one tile, since its total size is less than one.
202  EXPECT_TRUE(tiling_->TileAt(0, 0));
203
204  // Stop creating tiles so that any invalidations are left as holes.
205  client_.set_allow_create_tile(false);
206
207  Region invalidation =
208      SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
209  tiling_->UpdateTilesToCurrentPile(invalidation, gfx::Size(200, 200));
210  EXPECT_FALSE(tiling_->TileAt(0, 0));
211}
212
213TEST_F(PictureLayerTilingIteratorTest, CreateMissingTilesStaysInsideLiveRect) {
214  // The tiling has three rows and columns.
215  Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 250));
216  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
217  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_y());
218
219  // The live tiles rect is at the very edge of the right-most and
220  // bottom-most tiles. Their border pixels would still be inside the live
221  // tiles rect, but the tiles should not exist just for that.
222  int right = tiling_->TilingDataForTesting().TileBounds(2, 2).x();
223  int bottom = tiling_->TilingDataForTesting().TileBounds(2, 2).y();
224
225  SetLiveRectAndVerifyTiles(gfx::Rect(right, bottom));
226  EXPECT_FALSE(tiling_->TileAt(2, 0));
227  EXPECT_FALSE(tiling_->TileAt(2, 1));
228  EXPECT_FALSE(tiling_->TileAt(2, 2));
229  EXPECT_FALSE(tiling_->TileAt(1, 2));
230  EXPECT_FALSE(tiling_->TileAt(0, 2));
231
232  // Verify CreateMissingTilesInLiveTilesRect respects this.
233  tiling_->CreateMissingTilesInLiveTilesRect();
234  EXPECT_FALSE(tiling_->TileAt(2, 0));
235  EXPECT_FALSE(tiling_->TileAt(2, 1));
236  EXPECT_FALSE(tiling_->TileAt(2, 2));
237  EXPECT_FALSE(tiling_->TileAt(1, 2));
238  EXPECT_FALSE(tiling_->TileAt(0, 2));
239}
240
241TEST_F(PictureLayerTilingIteratorTest, ResizeTilingOverTileBorders) {
242  // The tiling has four rows and three columns.
243  Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
244  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
245  EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
246
247  // The live tiles rect covers the whole tiling.
248  SetLiveRectAndVerifyTiles(gfx::Rect(250, 350));
249
250  // Tiles in the bottom row and right column exist.
251  EXPECT_TRUE(tiling_->TileAt(2, 0));
252  EXPECT_TRUE(tiling_->TileAt(2, 1));
253  EXPECT_TRUE(tiling_->TileAt(2, 2));
254  EXPECT_TRUE(tiling_->TileAt(2, 3));
255  EXPECT_TRUE(tiling_->TileAt(1, 3));
256  EXPECT_TRUE(tiling_->TileAt(0, 3));
257
258  int right = tiling_->TilingDataForTesting().TileBounds(2, 2).x();
259  int bottom = tiling_->TilingDataForTesting().TileBounds(2, 3).y();
260
261  // Shrink the tiling so that the last tile row/column is entirely in the
262  // border pixels of the interior tiles. That row/column is removed.
263  Region invalidation;
264  tiling_->UpdateTilesToCurrentPile(invalidation,
265                                    gfx::Size(right + 1, bottom + 1));
266  EXPECT_EQ(2, tiling_->TilingDataForTesting().num_tiles_x());
267  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_y());
268
269  // The live tiles rect was clamped to the pile size.
270  EXPECT_EQ(gfx::Rect(right + 1, bottom + 1), tiling_->live_tiles_rect());
271
272  // Since the row/column is gone, the tiles should be gone too.
273  EXPECT_FALSE(tiling_->TileAt(2, 0));
274  EXPECT_FALSE(tiling_->TileAt(2, 1));
275  EXPECT_FALSE(tiling_->TileAt(2, 2));
276  EXPECT_FALSE(tiling_->TileAt(2, 3));
277  EXPECT_FALSE(tiling_->TileAt(1, 3));
278  EXPECT_FALSE(tiling_->TileAt(0, 3));
279
280  // Growing outside the current right/bottom tiles border pixels should create
281  // the tiles again, even though the live rect has not changed size.
282  tiling_->UpdateTilesToCurrentPile(invalidation,
283                                    gfx::Size(right + 2, bottom + 2));
284  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
285  EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
286
287  // Not changed.
288  EXPECT_EQ(gfx::Rect(right + 1, bottom + 1), tiling_->live_tiles_rect());
289
290  // The last row/column tiles are inside the live tiles rect.
291  EXPECT_TRUE(gfx::Rect(right + 1, bottom + 1).Intersects(
292      tiling_->TilingDataForTesting().TileBounds(2, 0)));
293  EXPECT_TRUE(gfx::Rect(right + 1, bottom + 1).Intersects(
294      tiling_->TilingDataForTesting().TileBounds(0, 3)));
295
296  EXPECT_TRUE(tiling_->TileAt(2, 0));
297  EXPECT_TRUE(tiling_->TileAt(2, 1));
298  EXPECT_TRUE(tiling_->TileAt(2, 2));
299  EXPECT_TRUE(tiling_->TileAt(2, 3));
300  EXPECT_TRUE(tiling_->TileAt(1, 3));
301  EXPECT_TRUE(tiling_->TileAt(0, 3));
302}
303
304TEST_F(PictureLayerTilingIteratorTest, ResizeLiveTileRectOverTileBorders) {
305  // The tiling has three rows and columns.
306  Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
307  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
308  EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
309
310  // The live tiles rect covers the whole tiling.
311  SetLiveRectAndVerifyTiles(gfx::Rect(250, 350));
312
313  // Tiles in the bottom row and right column exist.
314  EXPECT_TRUE(tiling_->TileAt(2, 0));
315  EXPECT_TRUE(tiling_->TileAt(2, 1));
316  EXPECT_TRUE(tiling_->TileAt(2, 2));
317  EXPECT_TRUE(tiling_->TileAt(2, 3));
318  EXPECT_TRUE(tiling_->TileAt(1, 3));
319  EXPECT_TRUE(tiling_->TileAt(0, 3));
320
321  // Shrink the live tiles rect to the very edge of the right-most and
322  // bottom-most tiles. Their border pixels would still be inside the live
323  // tiles rect, but the tiles should not exist just for that.
324  int right = tiling_->TilingDataForTesting().TileBounds(2, 3).x();
325  int bottom = tiling_->TilingDataForTesting().TileBounds(2, 3).y();
326
327  SetLiveRectAndVerifyTiles(gfx::Rect(right, bottom));
328  EXPECT_FALSE(tiling_->TileAt(2, 0));
329  EXPECT_FALSE(tiling_->TileAt(2, 1));
330  EXPECT_FALSE(tiling_->TileAt(2, 2));
331  EXPECT_FALSE(tiling_->TileAt(2, 3));
332  EXPECT_FALSE(tiling_->TileAt(1, 3));
333  EXPECT_FALSE(tiling_->TileAt(0, 3));
334
335  // Including the bottom row and right column again, should create the tiles.
336  SetLiveRectAndVerifyTiles(gfx::Rect(right + 1, bottom + 1));
337  EXPECT_TRUE(tiling_->TileAt(2, 0));
338  EXPECT_TRUE(tiling_->TileAt(2, 1));
339  EXPECT_TRUE(tiling_->TileAt(2, 2));
340  EXPECT_TRUE(tiling_->TileAt(2, 3));
341  EXPECT_TRUE(tiling_->TileAt(1, 2));
342  EXPECT_TRUE(tiling_->TileAt(0, 2));
343
344  // Shrink the live tiles rect to the very edge of the left-most and
345  // top-most tiles. Their border pixels would still be inside the live
346  // tiles rect, but the tiles should not exist just for that.
347  int left = tiling_->TilingDataForTesting().TileBounds(0, 0).right();
348  int top = tiling_->TilingDataForTesting().TileBounds(0, 0).bottom();
349
350  SetLiveRectAndVerifyTiles(gfx::Rect(left, top, 250 - left, 350 - top));
351  EXPECT_FALSE(tiling_->TileAt(0, 3));
352  EXPECT_FALSE(tiling_->TileAt(0, 2));
353  EXPECT_FALSE(tiling_->TileAt(0, 1));
354  EXPECT_FALSE(tiling_->TileAt(0, 0));
355  EXPECT_FALSE(tiling_->TileAt(1, 0));
356  EXPECT_FALSE(tiling_->TileAt(2, 0));
357
358  // Including the top row and left column again, should create the tiles.
359  SetLiveRectAndVerifyTiles(
360      gfx::Rect(left - 1, top - 1, 250 - left, 350 - top));
361  EXPECT_TRUE(tiling_->TileAt(0, 3));
362  EXPECT_TRUE(tiling_->TileAt(0, 2));
363  EXPECT_TRUE(tiling_->TileAt(0, 1));
364  EXPECT_TRUE(tiling_->TileAt(0, 0));
365  EXPECT_TRUE(tiling_->TileAt(1, 0));
366  EXPECT_TRUE(tiling_->TileAt(2, 0));
367}
368
369TEST_F(PictureLayerTilingIteratorTest, ResizeLiveTileRectOverSameTiles) {
370  // The tiling has four rows and three columns.
371  Initialize(gfx::Size(100, 100), 1, gfx::Size(250, 350));
372  EXPECT_EQ(3, tiling_->TilingDataForTesting().num_tiles_x());
373  EXPECT_EQ(4, tiling_->TilingDataForTesting().num_tiles_y());
374
375  // The live tiles rect covers the whole tiling.
376  SetLiveRectAndVerifyTiles(gfx::Rect(250, 350));
377
378  // All tiles exist.
379  for (int i = 0; i < 3; ++i) {
380    for (int j = 0; j < 4; ++j)
381      EXPECT_TRUE(tiling_->TileAt(i, j)) << i << "," << j;
382  }
383
384  // Shrink the live tiles rect, but still cover all the tiles.
385  SetLiveRectAndVerifyTiles(gfx::Rect(1, 1, 249, 349));
386
387  // All tiles still exist.
388  for (int i = 0; i < 3; ++i) {
389    for (int j = 0; j < 4; ++j)
390      EXPECT_TRUE(tiling_->TileAt(i, j)) << i << "," << j;
391  }
392
393  // Grow the live tiles rect, but still cover all the same tiles.
394  SetLiveRectAndVerifyTiles(gfx::Rect(0, 0, 250, 350));
395
396  // All tiles still exist.
397  for (int i = 0; i < 3; ++i) {
398    for (int j = 0; j < 4; ++j)
399      EXPECT_TRUE(tiling_->TileAt(i, j)) << i << "," << j;
400  }
401}
402
403TEST_F(PictureLayerTilingIteratorTest, ResizeOverBorderPixelsDeletesTiles) {
404  // Verifies that a resize with invalidation for newly exposed pixels will
405  // deletes tiles that intersect that invalidation.
406  gfx::Size tile_size(100, 100);
407  gfx::Size original_layer_size(99, 99);
408  Initialize(tile_size, 1.f, original_layer_size);
409  SetLiveRectAndVerifyTiles(gfx::Rect(original_layer_size));
410
411  // Tiling only has one tile, since its total size is less than one.
412  EXPECT_TRUE(tiling_->TileAt(0, 0));
413
414  // Stop creating tiles so that any invalidations are left as holes.
415  client_.set_allow_create_tile(false);
416
417  Region invalidation =
418      SubtractRegions(gfx::Rect(tile_size), gfx::Rect(original_layer_size));
419  tiling_->UpdateTilesToCurrentPile(invalidation, gfx::Size(200, 200));
420  EXPECT_FALSE(tiling_->TileAt(0, 0));
421
422  // The original tile was the same size after resize, but it would include new
423  // border pixels.
424  EXPECT_EQ(gfx::Rect(original_layer_size),
425            tiling_->TilingDataForTesting().TileBounds(0, 0));
426}
427
428TEST_F(PictureLayerTilingIteratorTest, LiveTilesExactlyCoverLiveTileRect) {
429  Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
430  SetLiveRectAndVerifyTiles(gfx::Rect(100, 100));
431  SetLiveRectAndVerifyTiles(gfx::Rect(101, 99));
432  SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
433  SetLiveRectAndVerifyTiles(gfx::Rect(1, 801));
434  SetLiveRectAndVerifyTiles(gfx::Rect(1099, 1));
435  SetLiveRectAndVerifyTiles(gfx::Rect(201, 800));
436}
437
438TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsNoScale) {
439  Initialize(gfx::Size(100, 100), 1, gfx::Size(1099, 801));
440  VerifyTilesExactlyCoverRect(1, gfx::Rect());
441  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1099, 801));
442  VerifyTilesExactlyCoverRect(1, gfx::Rect(52, 83, 789, 412));
443
444  // With borders, a size of 3x3 = 1 pixel of content.
445  Initialize(gfx::Size(3, 3), 1, gfx::Size(10, 10));
446  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
447  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
448  VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
449  VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2));
450}
451
452TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsTilingScale) {
453  Initialize(gfx::Size(200, 100), 2.0f, gfx::Size(1005, 2010));
454  VerifyTilesExactlyCoverRect(1, gfx::Rect());
455  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
456  VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
457
458  Initialize(gfx::Size(3, 3), 2.0f, gfx::Size(10, 10));
459  VerifyTilesExactlyCoverRect(1, gfx::Rect());
460  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1, 1));
461  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 2, 2));
462  VerifyTilesExactlyCoverRect(1, gfx::Rect(1, 1, 2, 2));
463  VerifyTilesExactlyCoverRect(1, gfx::Rect(3, 2, 5, 2));
464
465  Initialize(gfx::Size(100, 200), 0.5f, gfx::Size(1005, 2010));
466  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
467  VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
468
469  Initialize(gfx::Size(150, 250), 0.37f, gfx::Size(1005, 2010));
470  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
471  VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
472
473  Initialize(gfx::Size(312, 123), 0.01f, gfx::Size(1005, 2010));
474  VerifyTilesExactlyCoverRect(1, gfx::Rect(0, 0, 1005, 2010));
475  VerifyTilesExactlyCoverRect(1, gfx::Rect(50, 112, 512, 381));
476}
477
478TEST_F(PictureLayerTilingIteratorTest, IteratorCoversLayerBoundsBothScale) {
479  Initialize(gfx::Size(50, 50), 4.0f, gfx::Size(800, 600));
480  VerifyTilesExactlyCoverRect(2.0f, gfx::Rect());
481  VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(0, 0, 1600, 1200));
482  VerifyTilesExactlyCoverRect(2.0f, gfx::Rect(512, 365, 253, 182));
483
484  float scale = 6.7f;
485  gfx::Size bounds(800, 600);
486  gfx::Rect full_rect(gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale)));
487  Initialize(gfx::Size(256, 512), 5.2f, bounds);
488  VerifyTilesExactlyCoverRect(scale, full_rect);
489  VerifyTilesExactlyCoverRect(scale, gfx::Rect(2014, 1579, 867, 1033));
490}
491
492TEST_F(PictureLayerTilingIteratorTest, IteratorEmptyRect) {
493  Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600));
494
495  gfx::Rect empty;
496  PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1.0f, empty);
497  EXPECT_FALSE(iter);
498}
499
500TEST_F(PictureLayerTilingIteratorTest, NonIntersectingRect) {
501  Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(800, 600));
502  gfx::Rect non_intersecting(1000, 1000, 50, 50);
503  PictureLayerTiling::CoverageIterator iter(tiling_.get(), 1, non_intersecting);
504  EXPECT_FALSE(iter);
505}
506
507TEST_F(PictureLayerTilingIteratorTest, LayerEdgeTextureCoordinates) {
508  Initialize(gfx::Size(300, 300), 1.0f, gfx::Size(256, 256));
509  // All of these sizes are 256x256, scaled and ceiled.
510  VerifyTilesExactlyCoverRect(1.0f, gfx::Rect(0, 0, 256, 256));
511  VerifyTilesExactlyCoverRect(0.8f, gfx::Rect(0, 0, 205, 205));
512  VerifyTilesExactlyCoverRect(1.2f, gfx::Rect(0, 0, 308, 308));
513}
514
515TEST_F(PictureLayerTilingIteratorTest, NonContainedDestRect) {
516  Initialize(gfx::Size(100, 100), 1.0f, gfx::Size(400, 400));
517
518  // Too large in all dimensions
519  VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, -1000, 2000, 2000));
520  VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, -1000, 2000, 2000));
521  VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, -1000, 2000, 2000));
522
523  // Partially covering content, but too large
524  VerifyTilesCoverNonContainedRect(1.0f, gfx::Rect(-1000, 100, 2000, 100));
525  VerifyTilesCoverNonContainedRect(1.5f, gfx::Rect(-1000, 100, 2000, 100));
526  VerifyTilesCoverNonContainedRect(0.5f, gfx::Rect(-1000, 100, 2000, 100));
527}
528
529TEST(PictureLayerTilingTest, SkewportLimits) {
530  FakePictureLayerTilingClient client;
531  client.set_skewport_extrapolation_limit_in_content_pixels(75);
532  client.set_tree(ACTIVE_TREE);
533  scoped_ptr<TestablePictureLayerTiling> tiling;
534
535  gfx::Rect viewport(0, 0, 100, 100);
536  gfx::Size layer_bounds(200, 200);
537
538  client.SetTileSize(gfx::Size(100, 100));
539  tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
540
541  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
542
543  // Move viewport down 50 pixels in 0.5 seconds.
544  gfx::Rect down_skewport =
545      tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100));
546
547  EXPECT_EQ(0, down_skewport.x());
548  EXPECT_EQ(50, down_skewport.y());
549  EXPECT_EQ(100, down_skewport.width());
550  EXPECT_EQ(175, down_skewport.height());
551  EXPECT_TRUE(down_skewport.Contains(gfx::Rect(0, 50, 100, 100)));
552
553  // Move viewport down 50 and right 10 pixels.
554  gfx::Rect down_right_skewport =
555      tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100));
556
557  EXPECT_EQ(10, down_right_skewport.x());
558  EXPECT_EQ(50, down_right_skewport.y());
559  EXPECT_EQ(120, down_right_skewport.width());
560  EXPECT_EQ(175, down_right_skewport.height());
561  EXPECT_TRUE(down_right_skewport.Contains(gfx::Rect(10, 50, 100, 100)));
562
563  // Move viewport left.
564  gfx::Rect left_skewport =
565      tiling->ComputeSkewport(1.5, gfx::Rect(-50, 0, 100, 100));
566
567  EXPECT_EQ(-125, left_skewport.x());
568  EXPECT_EQ(0, left_skewport.y());
569  EXPECT_EQ(175, left_skewport.width());
570  EXPECT_EQ(100, left_skewport.height());
571  EXPECT_TRUE(left_skewport.Contains(gfx::Rect(-50, 0, 100, 100)));
572
573  // Expand viewport.
574  gfx::Rect expand_skewport =
575      tiling->ComputeSkewport(1.5, gfx::Rect(-50, -50, 200, 200));
576
577  // x and y moved by -75 (-50 - 75 = -125).
578  // right side and bottom side moved by 75 [(350 - 125) - (200 - 50) = 75].
579  EXPECT_EQ(-125, expand_skewport.x());
580  EXPECT_EQ(-125, expand_skewport.y());
581  EXPECT_EQ(350, expand_skewport.width());
582  EXPECT_EQ(350, expand_skewport.height());
583  EXPECT_TRUE(expand_skewport.Contains(gfx::Rect(-50, -50, 200, 200)));
584
585  // Expand the viewport past the limit.
586  gfx::Rect big_expand_skewport =
587      tiling->ComputeSkewport(1.5, gfx::Rect(-500, -500, 1500, 1500));
588
589  EXPECT_EQ(-575, big_expand_skewport.x());
590  EXPECT_EQ(-575, big_expand_skewport.y());
591  EXPECT_EQ(1650, big_expand_skewport.width());
592  EXPECT_EQ(1650, big_expand_skewport.height());
593  EXPECT_TRUE(big_expand_skewport.Contains(gfx::Rect(-500, -500, 1500, 1500)));
594}
595
596TEST(PictureLayerTilingTest, ComputeSkewport) {
597  FakePictureLayerTilingClient client;
598  scoped_ptr<TestablePictureLayerTiling> tiling;
599
600  gfx::Rect viewport(0, 0, 100, 100);
601  gfx::Size layer_bounds(200, 200);
602
603  client.SetTileSize(gfx::Size(100, 100));
604  client.set_tree(ACTIVE_TREE);
605  tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
606
607  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
608
609  // Move viewport down 50 pixels in 0.5 seconds.
610  gfx::Rect down_skewport =
611      tiling->ComputeSkewport(1.5, gfx::Rect(0, 50, 100, 100));
612
613  EXPECT_EQ(0, down_skewport.x());
614  EXPECT_EQ(50, down_skewport.y());
615  EXPECT_EQ(100, down_skewport.width());
616  EXPECT_EQ(200, down_skewport.height());
617
618  // Shrink viewport.
619  gfx::Rect shrink_skewport =
620      tiling->ComputeSkewport(1.5, gfx::Rect(25, 25, 50, 50));
621
622  EXPECT_EQ(25, shrink_skewport.x());
623  EXPECT_EQ(25, shrink_skewport.y());
624  EXPECT_EQ(50, shrink_skewport.width());
625  EXPECT_EQ(50, shrink_skewport.height());
626
627  // Move viewport down 50 and right 10 pixels.
628  gfx::Rect down_right_skewport =
629      tiling->ComputeSkewport(1.5, gfx::Rect(10, 50, 100, 100));
630
631  EXPECT_EQ(10, down_right_skewport.x());
632  EXPECT_EQ(50, down_right_skewport.y());
633  EXPECT_EQ(120, down_right_skewport.width());
634  EXPECT_EQ(200, down_right_skewport.height());
635
636  // Move viewport left.
637  gfx::Rect left_skewport =
638      tiling->ComputeSkewport(1.5, gfx::Rect(-20, 0, 100, 100));
639
640  EXPECT_EQ(-60, left_skewport.x());
641  EXPECT_EQ(0, left_skewport.y());
642  EXPECT_EQ(140, left_skewport.width());
643  EXPECT_EQ(100, left_skewport.height());
644
645  // Expand viewport in 0.2 seconds.
646  gfx::Rect expanded_skewport =
647      tiling->ComputeSkewport(1.2, gfx::Rect(-5, -5, 110, 110));
648
649  EXPECT_EQ(-30, expanded_skewport.x());
650  EXPECT_EQ(-30, expanded_skewport.y());
651  EXPECT_EQ(160, expanded_skewport.width());
652  EXPECT_EQ(160, expanded_skewport.height());
653}
654
655TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
656  FakePictureLayerTilingClient client;
657  scoped_ptr<TestablePictureLayerTiling> tiling;
658
659  gfx::Rect viewport(0, 0, 100, 100);
660  gfx::Size layer_bounds(1500, 1500);
661
662  client.SetTileSize(gfx::Size(10, 10));
663  client.set_tree(ACTIVE_TREE);
664
665  // Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10.
666  // The reason is that each tile has a one pixel border, so tile at (1, 2)
667  // for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at
668  // (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the
669  // tiling.
670  tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client);
671  gfx::Rect viewport_in_content_space =
672      gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
673
674  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
675
676  gfx::Rect soon_rect = viewport;
677  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
678  gfx::Rect soon_rect_in_content_space =
679      gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
680
681  // Sanity checks.
682  for (int i = 0; i < 47; ++i) {
683    for (int j = 0; j < 47; ++j) {
684      EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j;
685    }
686  }
687  for (int i = 0; i < 47; ++i) {
688    EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i;
689    EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i;
690  }
691
692  // No movement in the viewport implies that tiles will either be NOW
693  // or EVENTUALLY, with the exception of tiles that are between 0 and 312
694  // pixels away from the viewport, which will be in the SOON bin.
695  bool have_now = false;
696  bool have_eventually = false;
697  bool have_soon = false;
698  for (int i = 0; i < 47; ++i) {
699    for (int j = 0; j < 47; ++j) {
700      Tile* tile = tiling->TileAt(i, j);
701      TilePriority priority = tile->priority(ACTIVE_TREE);
702
703      gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j);
704      if (viewport_in_content_space.Intersects(tile_rect)) {
705        EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
706        EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
707        have_now = true;
708      } else if (soon_rect_in_content_space.Intersects(tile_rect)) {
709        EXPECT_EQ(TilePriority::SOON, priority.priority_bin);
710        have_soon = true;
711      } else {
712        EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin);
713        EXPECT_GT(priority.distance_to_visible, 0.f);
714        have_eventually = true;
715      }
716    }
717  }
718
719  EXPECT_TRUE(have_now);
720  EXPECT_TRUE(have_soon);
721  EXPECT_TRUE(have_eventually);
722
723  // Spot check some distances.
724  // Tile at 5, 1 should begin at 41x9 in content space (without borders),
725  // so the distance to a viewport that ends at 25x25 in content space
726  // should be 17 (41 - 25 + 1). In layer space, then that should be
727  // 17 / 0.25 = 68 pixels.
728
729  // We can verify that the content rect (with borders) is one pixel off
730  // 41,9 8x8 on all sides.
731  EXPECT_EQ(tiling->TileAt(5, 1)->content_rect().ToString(), "40,8 10x10");
732
733  TilePriority priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
734  EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
735
736  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
737  EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
738
739  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
740  EXPECT_FLOAT_EQ(40.f, priority.distance_to_visible);
741
742  // Move the viewport down 40 pixels.
743  viewport = gfx::Rect(0, 40, 100, 100);
744  viewport_in_content_space =
745      gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
746  gfx::Rect skewport = tiling->ComputeSkewport(2.0, viewport_in_content_space);
747
748  soon_rect = viewport;
749  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
750  soon_rect_in_content_space =
751      gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
752
753  EXPECT_EQ(0, skewport.x());
754  EXPECT_EQ(10, skewport.y());
755  EXPECT_EQ(25, skewport.width());
756  EXPECT_EQ(35, skewport.height());
757
758  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 2.0, Occlusion());
759
760  have_now = false;
761  have_eventually = false;
762  have_soon = false;
763
764  // Viewport moved, so we expect to find some NOW tiles, some SOON tiles and
765  // some EVENTUALLY tiles.
766  for (int i = 0; i < 47; ++i) {
767    for (int j = 0; j < 47; ++j) {
768      Tile* tile = tiling->TileAt(i, j);
769      TilePriority priority = tile->priority(ACTIVE_TREE);
770
771      gfx::Rect tile_rect = tiling->TilingDataForTesting().TileBounds(i, j);
772      if (viewport_in_content_space.Intersects(tile_rect)) {
773        EXPECT_EQ(TilePriority::NOW, priority.priority_bin) << "i: " << i
774                                                            << " j: " << j;
775        EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i
776                                                           << " j: " << j;
777        have_now = true;
778      } else if (skewport.Intersects(tile_rect) ||
779                 soon_rect_in_content_space.Intersects(tile_rect)) {
780        EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i
781                                                             << " j: " << j;
782        EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
783                                                     << " j: " << j;
784        have_soon = true;
785      } else {
786        EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin)
787            << "i: " << i << " j: " << j;
788        EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
789                                                     << " j: " << j;
790        have_eventually = true;
791      }
792    }
793  }
794
795  EXPECT_TRUE(have_now);
796  EXPECT_TRUE(have_soon);
797  EXPECT_TRUE(have_eventually);
798
799  priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
800  EXPECT_FLOAT_EQ(68.f, priority.distance_to_visible);
801
802  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
803  EXPECT_FLOAT_EQ(28.f, priority.distance_to_visible);
804
805  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
806  EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible);
807
808  // Change the underlying layer scale.
809  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 2.0f, 3.0, Occlusion());
810
811  priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
812  EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible);
813
814  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
815  EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible);
816
817  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
818  EXPECT_FLOAT_EQ(8.f, priority.distance_to_visible);
819
820  // Test additional scales.
821  tiling = TestablePictureLayerTiling::Create(0.2f, layer_bounds, &client);
822  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 4.0, Occlusion());
823
824  priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
825  EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible);
826
827  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
828  EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible);
829
830  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
831  EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible);
832
833  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 0.5f, 5.0, Occlusion());
834
835  priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
836  EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible);
837
838  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
839  EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible);
840
841  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
842  EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible);
843}
844
845TEST(PictureLayerTilingTest, ExpandRectEqual) {
846  gfx::Rect in(40, 50, 100, 200);
847  gfx::Rect bounds(-1000, -1000, 10000, 10000);
848  int64 target_area = 100 * 200;
849  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
850      in, target_area, bounds, NULL);
851  EXPECT_EQ(in.ToString(), out.ToString());
852}
853
854TEST(PictureLayerTilingTest, ExpandRectSmaller) {
855  gfx::Rect in(40, 50, 100, 200);
856  gfx::Rect bounds(-1000, -1000, 10000, 10000);
857  int64 target_area = 100 * 100;
858  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
859      in, target_area, bounds, NULL);
860  EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
861  EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
862  EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
863
864  // |in| represents the visible rect, and |out| represents the eventually rect.
865  // If the eventually rect doesn't contain the visible rect, we will start
866  // losing tiles.
867  EXPECT_TRUE(out.Contains(in));
868  EXPECT_TRUE(bounds.Contains(out));
869}
870
871TEST(PictureLayerTilingTest, ExpandRectUnbounded) {
872  gfx::Rect in(40, 50, 100, 200);
873  gfx::Rect bounds(-1000, -1000, 10000, 10000);
874  int64 target_area = 200 * 200;
875  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
876      in, target_area, bounds, NULL);
877  EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
878  EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
879  EXPECT_EQ(out.width() - in.width(), out.height() - in.height());
880  EXPECT_NEAR(200 * 200, out.width() * out.height(), 100);
881  EXPECT_TRUE(bounds.Contains(out));
882}
883
884TEST(PictureLayerTilingTest, ExpandRectBoundedSmaller) {
885  gfx::Rect in(40, 50, 100, 200);
886  gfx::Rect bounds(50, 60, 40, 30);
887  int64 target_area = 200 * 200;
888  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
889      in, target_area, bounds, NULL);
890  EXPECT_EQ(bounds.ToString(), out.ToString());
891}
892
893TEST(PictureLayerTilingTest, ExpandRectBoundedEqual) {
894  gfx::Rect in(40, 50, 100, 200);
895  gfx::Rect bounds = in;
896  int64 target_area = 200 * 200;
897  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
898      in, target_area, bounds, NULL);
899  EXPECT_EQ(bounds.ToString(), out.ToString());
900}
901
902TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchVertical) {
903  gfx::Rect in(40, 50, 100, 200);
904  gfx::Rect bounds(45, 0, 90, 300);
905  int64 target_area = 200 * 200;
906  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
907      in, target_area, bounds, NULL);
908  EXPECT_EQ(bounds.ToString(), out.ToString());
909}
910
911TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchVertical) {
912  gfx::Rect in(40, 50, 100, 200);
913  gfx::Rect bounds(40, 0, 100, 300);
914  int64 target_area = 200 * 200;
915  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
916      in, target_area, bounds, NULL);
917  EXPECT_EQ(bounds.ToString(), out.ToString());
918}
919
920TEST(PictureLayerTilingTest, ExpandRectBoundedSmallerStretchHorizontal) {
921  gfx::Rect in(40, 50, 100, 200);
922  gfx::Rect bounds(0, 55, 180, 190);
923  int64 target_area = 200 * 200;
924  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
925      in, target_area, bounds, NULL);
926  EXPECT_EQ(bounds.ToString(), out.ToString());
927}
928
929TEST(PictureLayerTilingTest, ExpandRectBoundedEqualStretchHorizontal) {
930  gfx::Rect in(40, 50, 100, 200);
931  gfx::Rect bounds(0, 50, 180, 200);
932  int64 target_area = 200 * 200;
933  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
934      in, target_area, bounds, NULL);
935  EXPECT_EQ(bounds.ToString(), out.ToString());
936}
937
938TEST(PictureLayerTilingTest, ExpandRectBoundedLeft) {
939  gfx::Rect in(40, 50, 100, 200);
940  gfx::Rect bounds(20, -1000, 10000, 10000);
941  int64 target_area = 200 * 200;
942  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
943      in, target_area, bounds, NULL);
944  EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
945  EXPECT_EQ(out.bottom() - in.bottom(), out.right() - in.right());
946  EXPECT_LE(out.width() * out.height(), target_area);
947  EXPECT_GT(out.width() * out.height(),
948            target_area - out.width() - out.height() * 2);
949  EXPECT_TRUE(bounds.Contains(out));
950}
951
952TEST(PictureLayerTilingTest, ExpandRectBoundedRight) {
953  gfx::Rect in(40, 50, 100, 200);
954  gfx::Rect bounds(-1000, -1000, 1000+120, 10000);
955  int64 target_area = 200 * 200;
956  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
957      in, target_area, bounds, NULL);
958  EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
959  EXPECT_EQ(out.bottom() - in.bottom(), in.x() - out.x());
960  EXPECT_LE(out.width() * out.height(), target_area);
961  EXPECT_GT(out.width() * out.height(),
962            target_area - out.width() - out.height() * 2);
963  EXPECT_TRUE(bounds.Contains(out));
964}
965
966TEST(PictureLayerTilingTest, ExpandRectBoundedTop) {
967  gfx::Rect in(40, 50, 100, 200);
968  gfx::Rect bounds(-1000, 30, 10000, 10000);
969  int64 target_area = 200 * 200;
970  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
971      in, target_area, bounds, NULL);
972  EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
973  EXPECT_EQ(out.right() - in.right(), out.bottom() - in.bottom());
974  EXPECT_LE(out.width() * out.height(), target_area);
975  EXPECT_GT(out.width() * out.height(),
976            target_area - out.width() * 2 - out.height());
977  EXPECT_TRUE(bounds.Contains(out));
978}
979
980TEST(PictureLayerTilingTest, ExpandRectBoundedBottom) {
981  gfx::Rect in(40, 50, 100, 200);
982  gfx::Rect bounds(-1000, -1000, 10000, 1000 + 220);
983  int64 target_area = 200 * 200;
984  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
985      in, target_area, bounds, NULL);
986  EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
987  EXPECT_EQ(out.right() - in.right(), in.y() - out.y());
988  EXPECT_LE(out.width() * out.height(), target_area);
989  EXPECT_GT(out.width() * out.height(),
990            target_area - out.width() * 2 - out.height());
991  EXPECT_TRUE(bounds.Contains(out));
992}
993
994TEST(PictureLayerTilingTest, ExpandRectSquishedHorizontally) {
995  gfx::Rect in(40, 50, 100, 200);
996  gfx::Rect bounds(0, -4000, 100+40+20, 100000);
997  int64 target_area = 400 * 400;
998  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
999      in, target_area, bounds, NULL);
1000  EXPECT_EQ(20, out.right() - in.right());
1001  EXPECT_EQ(40, in.x() - out.x());
1002  EXPECT_EQ(out.bottom() - in.bottom(), in.y() - out.y());
1003  EXPECT_LE(out.width() * out.height(), target_area);
1004  EXPECT_GT(out.width() * out.height(),
1005            target_area - out.width() * 2);
1006  EXPECT_TRUE(bounds.Contains(out));
1007}
1008
1009TEST(PictureLayerTilingTest, ExpandRectSquishedVertically) {
1010  gfx::Rect in(40, 50, 100, 200);
1011  gfx::Rect bounds(-4000, 0, 100000, 200+50+30);
1012  int64 target_area = 400 * 400;
1013  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
1014      in, target_area, bounds, NULL);
1015  EXPECT_EQ(30, out.bottom() - in.bottom());
1016  EXPECT_EQ(50, in.y() - out.y());
1017  EXPECT_EQ(out.right() - in.right(), in.x() - out.x());
1018  EXPECT_LE(out.width() * out.height(), target_area);
1019  EXPECT_GT(out.width() * out.height(),
1020            target_area - out.height() * 2);
1021  EXPECT_TRUE(bounds.Contains(out));
1022}
1023
1024TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsFarAway) {
1025  gfx::Rect in(400, 500, 100, 200);
1026  gfx::Rect bounds(0, 0, 10, 10);
1027  int64 target_area = 400 * 400;
1028  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
1029      in, target_area, bounds, NULL);
1030  EXPECT_TRUE(out.IsEmpty());
1031}
1032
1033TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedFullyCover) {
1034  gfx::Rect in(40, 50, 100, 100);
1035  gfx::Rect bounds(0, 0, 10, 10);
1036  int64 target_area = 400 * 400;
1037  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
1038      in, target_area, bounds, NULL);
1039  EXPECT_EQ(bounds.ToString(), out.ToString());
1040}
1041
1042TEST(PictureLayerTilingTest, ExpandRectOutOfBoundsExpandedPartlyCover) {
1043  gfx::Rect in(600, 600, 100, 100);
1044  gfx::Rect bounds(0, 0, 500, 500);
1045  int64 target_area = 400 * 400;
1046  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
1047      in, target_area, bounds, NULL);
1048  EXPECT_EQ(bounds.right(), out.right());
1049  EXPECT_EQ(bounds.bottom(), out.bottom());
1050  EXPECT_LE(out.width() * out.height(), target_area);
1051  EXPECT_GT(out.width() * out.height(),
1052            target_area - out.width() - out.height());
1053  EXPECT_TRUE(bounds.Contains(out));
1054}
1055
1056TEST(PictureLayerTilingTest, EmptyStartingRect) {
1057  // If a layer has a non-invertible transform, then the starting rect
1058  // for the layer would be empty.
1059  gfx::Rect in(40, 40, 0, 0);
1060  gfx::Rect bounds(0, 0, 10, 10);
1061  int64 target_area = 400 * 400;
1062  gfx::Rect out = PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
1063      in, target_area, bounds, NULL);
1064  EXPECT_TRUE(out.IsEmpty());
1065}
1066
1067TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) {
1068  FakePictureLayerTilingClient client;
1069  scoped_ptr<TestablePictureLayerTiling> tiling;
1070
1071  gfx::Rect viewport(50, 50, 100, 100);
1072  gfx::Size layer_bounds(800, 800);
1073
1074  gfx::Rect soon_rect = viewport;
1075  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
1076
1077  client.SetTileSize(gfx::Size(30, 30));
1078  client.set_tree(ACTIVE_TREE);
1079
1080  tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
1081  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
1082
1083  PictureLayerTiling::TilingRasterTileIterator empty_iterator;
1084  EXPECT_FALSE(empty_iterator);
1085
1086  std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
1087
1088  // Sanity check.
1089  EXPECT_EQ(841u, all_tiles.size());
1090
1091  // The explanation of each iteration is as follows:
1092  // 1. First iteration tests that we can get all of the tiles correctly.
1093  // 2. Second iteration ensures that we can get all of the tiles again (first
1094  //    iteration didn't change any tiles), as well set all tiles to be ready to
1095  //    draw.
1096  // 3. Third iteration ensures that no tiles are returned, since they were all
1097  //    marked as ready to draw.
1098  for (int i = 0; i < 3; ++i) {
1099    PictureLayerTiling::TilingRasterTileIterator it(tiling.get(), ACTIVE_TREE);
1100
1101    // There are 3 bins in TilePriority.
1102    bool have_tiles[3] = {};
1103
1104    // On the third iteration, we should get no tiles since everything was
1105    // marked as ready to draw.
1106    if (i == 2) {
1107      EXPECT_FALSE(it);
1108      continue;
1109    }
1110
1111    EXPECT_TRUE(it);
1112    std::set<Tile*> unique_tiles;
1113    unique_tiles.insert(*it);
1114    Tile* last_tile = *it;
1115    have_tiles[last_tile->priority(ACTIVE_TREE).priority_bin] = true;
1116
1117    // On the second iteration, mark everything as ready to draw (solid color).
1118    if (i == 1) {
1119      ManagedTileState::TileVersion& tile_version =
1120          last_tile->GetTileVersionForTesting(
1121              last_tile->DetermineRasterModeForTree(ACTIVE_TREE));
1122      tile_version.SetSolidColorForTesting(SK_ColorRED);
1123    }
1124    ++it;
1125    int eventually_bin_order_correct_count = 0;
1126    int eventually_bin_order_incorrect_count = 0;
1127    while (it) {
1128      Tile* new_tile = *it;
1129      ++it;
1130      unique_tiles.insert(new_tile);
1131
1132      TilePriority last_priority = last_tile->priority(ACTIVE_TREE);
1133      TilePriority new_priority = new_tile->priority(ACTIVE_TREE);
1134      EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
1135      if (last_priority.priority_bin == new_priority.priority_bin) {
1136        if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
1137          bool order_correct = last_priority.distance_to_visible <=
1138                               new_priority.distance_to_visible;
1139          eventually_bin_order_correct_count += order_correct;
1140          eventually_bin_order_incorrect_count += !order_correct;
1141        } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
1142                   !soon_rect.Intersects(last_tile->content_rect())) {
1143          EXPECT_LE(last_priority.distance_to_visible,
1144                    new_priority.distance_to_visible);
1145          EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin);
1146        } else if (new_priority.distance_to_visible > 0.f) {
1147          EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1148        }
1149      }
1150      have_tiles[new_priority.priority_bin] = true;
1151
1152      last_tile = new_tile;
1153
1154      // On the second iteration, mark everything as ready to draw (solid
1155      // color).
1156      if (i == 1) {
1157        ManagedTileState::TileVersion& tile_version =
1158            last_tile->GetTileVersionForTesting(
1159                last_tile->DetermineRasterModeForTree(ACTIVE_TREE));
1160        tile_version.SetSolidColorForTesting(SK_ColorRED);
1161      }
1162    }
1163
1164    EXPECT_GT(eventually_bin_order_correct_count,
1165              eventually_bin_order_incorrect_count);
1166
1167    // We should have now and eventually tiles, as well as soon tiles from
1168    // the border region.
1169    EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1170    EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1171    EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1172
1173    EXPECT_EQ(unique_tiles.size(), all_tiles.size());
1174  }
1175}
1176
1177TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) {
1178  FakePictureLayerTilingClient client;
1179  scoped_ptr<TestablePictureLayerTiling> tiling;
1180
1181  gfx::Rect viewport(50, 0, 100, 100);
1182  gfx::Rect moved_viewport(50, 0, 100, 500);
1183  gfx::Size layer_bounds(1000, 1000);
1184
1185  client.SetTileSize(gfx::Size(30, 30));
1186  client.set_tree(ACTIVE_TREE);
1187
1188  tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client);
1189  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
1190  tiling->UpdateTilePriorities(
1191      ACTIVE_TREE, moved_viewport, 1.0f, 2.0, Occlusion());
1192
1193  gfx::Rect soon_rect = moved_viewport;
1194  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
1195
1196  // There are 3 bins in TilePriority.
1197  bool have_tiles[3] = {};
1198  Tile* last_tile = NULL;
1199  int eventually_bin_order_correct_count = 0;
1200  int eventually_bin_order_incorrect_count = 0;
1201  for (PictureLayerTiling::TilingRasterTileIterator it(tiling.get(),
1202                                                       ACTIVE_TREE);
1203       it;
1204       ++it) {
1205    if (!last_tile)
1206      last_tile = *it;
1207
1208    Tile* new_tile = *it;
1209
1210    TilePriority last_priority = last_tile->priority(ACTIVE_TREE);
1211    TilePriority new_priority = new_tile->priority(ACTIVE_TREE);
1212
1213    have_tiles[new_priority.priority_bin] = true;
1214
1215    EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
1216    if (last_priority.priority_bin == new_priority.priority_bin) {
1217      if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
1218        bool order_correct = last_priority.distance_to_visible <=
1219                             new_priority.distance_to_visible;
1220        eventually_bin_order_correct_count += order_correct;
1221        eventually_bin_order_incorrect_count += !order_correct;
1222      } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
1223                 !soon_rect.Intersects(last_tile->content_rect())) {
1224        EXPECT_LE(last_priority.distance_to_visible,
1225                  new_priority.distance_to_visible);
1226      } else if (new_priority.distance_to_visible > 0.f) {
1227        EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1228      }
1229    }
1230    last_tile = new_tile;
1231  }
1232
1233  EXPECT_GT(eventually_bin_order_correct_count,
1234            eventually_bin_order_incorrect_count);
1235
1236  EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1237  EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1238  EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1239}
1240
1241static void TileExists(bool exists, Tile* tile,
1242                       const gfx::Rect& geometry_rect) {
1243  EXPECT_EQ(exists, tile != NULL) << geometry_rect.ToString();
1244}
1245
1246TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) {
1247  FakeOutputSurfaceClient output_surface_client;
1248  scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d();
1249  CHECK(output_surface->BindToClient(&output_surface_client));
1250  TestSharedBitmapManager shared_bitmap_manager;
1251  scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
1252      output_surface.get(), &shared_bitmap_manager, NULL, 0, false, 1, false);
1253
1254  FakePictureLayerTilingClient client(resource_provider.get());
1255  scoped_ptr<TestablePictureLayerTiling> tiling;
1256
1257  gfx::Rect viewport(50, 50, 100, 100);
1258  gfx::Size layer_bounds(2000, 2000);
1259
1260  client.SetTileSize(gfx::Size(30, 30));
1261  client.set_tree(ACTIVE_TREE);
1262
1263  tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
1264  tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
1265
1266  PictureLayerTiling::TilingRasterTileIterator empty_iterator;
1267  EXPECT_FALSE(empty_iterator);
1268
1269  std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
1270
1271  PictureLayerTiling::TilingEvictionTileIterator it(
1272      tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::NOW);
1273
1274  // Tiles don't have resources to evict.
1275  EXPECT_FALSE(it);
1276
1277  // Sanity check.
1278  EXPECT_EQ(5184u, all_tiles.size());
1279
1280  client.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
1281
1282  std::set<Tile*> all_tiles_set(all_tiles.begin(), all_tiles.end());
1283
1284  std::set<Tile*> eviction_tiles;
1285
1286  it = PictureLayerTiling::TilingEvictionTileIterator(
1287      tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::EVENTUALLY);
1288  EXPECT_TRUE(it);
1289  for (; it; ++it) {
1290    Tile* tile = *it;
1291    EXPECT_TRUE(tile);
1292    EXPECT_EQ(TilePriority::EVENTUALLY,
1293              tile->priority(ACTIVE_TREE).priority_bin);
1294    EXPECT_FALSE(tile->required_for_activation());
1295    eviction_tiles.insert(tile);
1296  }
1297
1298  it = PictureLayerTiling::TilingEvictionTileIterator(
1299      tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::SOON);
1300  EXPECT_TRUE(it);
1301  for (; it; ++it) {
1302    Tile* tile = *it;
1303    EXPECT_TRUE(tile);
1304    EXPECT_EQ(TilePriority::SOON, tile->priority(ACTIVE_TREE).priority_bin);
1305    EXPECT_FALSE(tile->required_for_activation());
1306    eviction_tiles.insert(tile);
1307  }
1308
1309  it = PictureLayerTiling::TilingEvictionTileIterator(
1310      tiling.get(), SMOOTHNESS_TAKES_PRIORITY, PictureLayerTiling::NOW);
1311  EXPECT_TRUE(it);
1312  for (; it; ++it) {
1313    Tile* tile = *it;
1314    EXPECT_TRUE(tile);
1315    EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin);
1316    EXPECT_FALSE(tile->required_for_activation());
1317    eviction_tiles.insert(tile);
1318  }
1319
1320  it = PictureLayerTiling::TilingEvictionTileIterator(
1321      tiling.get(),
1322      SMOOTHNESS_TAKES_PRIORITY,
1323      PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION);
1324  EXPECT_FALSE(it);
1325
1326  EXPECT_GT(all_tiles_set.size(), 0u);
1327  EXPECT_EQ(all_tiles_set, eviction_tiles);
1328}
1329
1330TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
1331  gfx::Size layer_bounds(1099, 801);
1332  Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1333  VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1334  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1335
1336  client_.set_tree(ACTIVE_TREE);
1337  tiling_->UpdateTilePriorities(
1338      ACTIVE_TREE,
1339      gfx::Rect(layer_bounds),  // visible content rect
1340      1.f,                      // current contents scale
1341      1.0,                      // current frame time
1342      Occlusion());
1343  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1344
1345  // Make the viewport rect empty. All tiles are killed and become zombies.
1346  tiling_->UpdateTilePriorities(ACTIVE_TREE,
1347                                gfx::Rect(),  // visible content rect
1348                                1.f,          // current contents scale
1349                                2.0,          // current frame time
1350                                Occlusion());
1351  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1352}
1353
1354TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
1355  gfx::Size layer_bounds(1099, 801);
1356  Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1357  VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1358  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1359
1360  gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000);
1361
1362  client_.set_tree(ACTIVE_TREE);
1363  tiling_->UpdateTilePriorities(
1364      ACTIVE_TREE,
1365      gfx::Rect(layer_bounds),  // visible content rect
1366      1.f,                      // current contents scale
1367      1.0,                      // current frame time
1368      Occlusion());
1369  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1370
1371  // If the visible content rect is empty, it should still have live tiles.
1372  tiling_->UpdateTilePriorities(ACTIVE_TREE,
1373                                giant_rect,  // visible content rect
1374                                1.f,         // current contents scale
1375                                2.0,         // current frame time
1376                                Occlusion());
1377  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1378}
1379
1380TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
1381  gfx::Size layer_bounds(1099, 801);
1382  Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1383  VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1384  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1385
1386  // This rect does not intersect with the layer, as the layer is outside the
1387  // viewport.
1388  gfx::Rect viewport_rect(1100, 0, 1000, 1000);
1389  EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds)));
1390
1391  client_.set_tree(ACTIVE_TREE);
1392  tiling_->UpdateTilePriorities(ACTIVE_TREE,
1393                                viewport_rect,  // visible content rect
1394                                1.f,            // current contents scale
1395                                1.0,            // current frame time
1396                                Occlusion());
1397  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
1398}
1399
1400static void TilesIntersectingRectExist(const gfx::Rect& rect,
1401                                       bool intersect_exists,
1402                                       Tile* tile,
1403                                       const gfx::Rect& geometry_rect) {
1404  bool intersects = rect.Intersects(geometry_rect);
1405  bool expected_exists = intersect_exists ? intersects : !intersects;
1406  EXPECT_EQ(expected_exists, tile != NULL)
1407      << "Rects intersecting " << rect.ToString() << " should exist. "
1408      << "Current tile rect is " << geometry_rect.ToString();
1409}
1410
1411TEST_F(PictureLayerTilingIteratorTest,
1412       TilesExistLargeViewportAndLayerWithSmallVisibleArea) {
1413  gfx::Size layer_bounds(10000, 10000);
1414  Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
1415  VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
1416  VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
1417
1418  gfx::Rect visible_rect(8000, 8000, 50, 50);
1419
1420  client_.set_tree(ACTIVE_TREE);
1421  set_max_tiles_for_interest_area(1);
1422  tiling_->UpdateTilePriorities(ACTIVE_TREE,
1423                                visible_rect,  // visible content rect
1424                                1.f,           // current contents scale
1425                                1.0,           // current frame time
1426                                Occlusion());
1427  VerifyTiles(1.f,
1428              gfx::Rect(layer_bounds),
1429              base::Bind(&TilesIntersectingRectExist, visible_rect, true));
1430}
1431
1432TEST_F(PictureLayerTilingIteratorTest, AddTilingsToMatchScale) {
1433  gfx::Size layer_bounds(1099, 801);
1434  gfx::Size tile_size(100, 100);
1435
1436  client_.SetTileSize(tile_size);
1437  client_.set_tree(PENDING_TREE);
1438
1439  PictureLayerTilingSet active_set(&client_, layer_bounds);
1440
1441  active_set.AddTiling(1.f);
1442
1443  VerifyTiles(active_set.tiling_at(0),
1444              1.f,
1445              gfx::Rect(layer_bounds),
1446              base::Bind(&TileExists, false));
1447
1448  UpdateAllTilePriorities(&active_set,
1449                          PENDING_TREE,
1450                          gfx::Rect(layer_bounds),  // visible content rect
1451                          1.f,                      // current contents scale
1452                          1.0);                     // current frame time
1453
1454  // The active tiling has tiles now.
1455  VerifyTiles(active_set.tiling_at(0),
1456              1.f,
1457              gfx::Rect(layer_bounds),
1458              base::Bind(&TileExists, true));
1459
1460  // Add the same tilings to the pending set.
1461  PictureLayerTilingSet pending_set(&client_, layer_bounds);
1462  Region invalidation;
1463  pending_set.SyncTilings(active_set, layer_bounds, invalidation, 0.f);
1464
1465  // The pending tiling starts with no tiles.
1466  VerifyTiles(pending_set.tiling_at(0),
1467              1.f,
1468              gfx::Rect(layer_bounds),
1469              base::Bind(&TileExists, false));
1470
1471  // UpdateTilePriorities on the pending tiling at the same frame time. The
1472  // pending tiling should get tiles.
1473  UpdateAllTilePriorities(&pending_set,
1474                          PENDING_TREE,
1475                          gfx::Rect(layer_bounds),  // visible content rect
1476                          1.f,                      // current contents scale
1477                          1.0);                     // current frame time
1478
1479  VerifyTiles(pending_set.tiling_at(0),
1480              1.f,
1481              gfx::Rect(layer_bounds),
1482              base::Bind(&TileExists, true));
1483}
1484
1485TEST(UpdateTilePrioritiesTest, VisibleTiles) {
1486  // The TilePriority of visible tiles should have zero distance_to_visible
1487  // and time_to_visible.
1488
1489  FakePictureLayerTilingClient client;
1490  scoped_ptr<TestablePictureLayerTiling> tiling;
1491
1492  gfx::Size device_viewport(800, 600);
1493  gfx::Size last_layer_bounds(200, 200);
1494  gfx::Size current_layer_bounds(200, 200);
1495  float current_layer_contents_scale = 1.f;
1496  gfx::Transform current_screen_transform;
1497  double current_frame_time_in_seconds = 1.0;
1498
1499  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1500      current_screen_transform, device_viewport);
1501
1502  client.SetTileSize(gfx::Size(100, 100));
1503  client.set_tree(ACTIVE_TREE);
1504  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1505                                              current_layer_bounds,
1506                                              &client);
1507
1508  tiling->UpdateTilePriorities(ACTIVE_TREE,
1509                               viewport_in_layer_space,
1510                               current_layer_contents_scale,
1511                               current_frame_time_in_seconds,
1512                               Occlusion());
1513
1514  ASSERT_TRUE(tiling->TileAt(0, 0));
1515  ASSERT_TRUE(tiling->TileAt(0, 1));
1516  ASSERT_TRUE(tiling->TileAt(1, 0));
1517  ASSERT_TRUE(tiling->TileAt(1, 1));
1518
1519  TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1520  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1521  EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1522
1523  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1524  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1525  EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1526
1527  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1528  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1529  EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1530
1531  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1532  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1533  EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1534}
1535
1536TEST(UpdateTilePrioritiesTest, OffscreenTiles) {
1537  // The TilePriority of offscreen tiles (without movement) should have nonzero
1538  // distance_to_visible and infinite time_to_visible.
1539
1540  FakePictureLayerTilingClient client;
1541  scoped_ptr<TestablePictureLayerTiling> tiling;
1542
1543  gfx::Size device_viewport(800, 600);
1544  gfx::Size last_layer_bounds(200, 200);
1545  gfx::Size current_layer_bounds(200, 200);
1546  float current_layer_contents_scale = 1.f;
1547  gfx::Transform last_screen_transform;
1548  gfx::Transform current_screen_transform;
1549  double current_frame_time_in_seconds = 1.0;
1550
1551  current_screen_transform.Translate(850, 0);
1552  last_screen_transform = current_screen_transform;
1553
1554  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1555      current_screen_transform, device_viewport);
1556
1557  client.SetTileSize(gfx::Size(100, 100));
1558  client.set_tree(ACTIVE_TREE);
1559  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1560                                              current_layer_bounds,
1561                                              &client);
1562
1563  tiling->UpdateTilePriorities(ACTIVE_TREE,
1564                               viewport_in_layer_space,
1565                               current_layer_contents_scale,
1566                               current_frame_time_in_seconds,
1567                               Occlusion());
1568
1569  ASSERT_TRUE(tiling->TileAt(0, 0));
1570  ASSERT_TRUE(tiling->TileAt(0, 1));
1571  ASSERT_TRUE(tiling->TileAt(1, 0));
1572  ASSERT_TRUE(tiling->TileAt(1, 1));
1573
1574  TilePriority priority = tiling->TileAt(0, 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(0, 1)->priority(ACTIVE_TREE);
1579  EXPECT_GT(priority.distance_to_visible, 0.f);
1580  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1581
1582  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1583  EXPECT_GT(priority.distance_to_visible, 0.f);
1584  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1585
1586  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1587  EXPECT_GT(priority.distance_to_visible, 0.f);
1588  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1589
1590  // Furthermore, in this scenario tiles on the right hand side should have a
1591  // larger distance to visible.
1592  TilePriority left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1593  TilePriority right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1594  EXPECT_GT(right.distance_to_visible, left.distance_to_visible);
1595
1596  left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1597  right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1598  EXPECT_GT(right.distance_to_visible, left.distance_to_visible);
1599}
1600
1601TEST(UpdateTilePrioritiesTest, PartiallyOffscreenLayer) {
1602  // Sanity check that a layer with some tiles visible and others offscreen has
1603  // correct TilePriorities for each tile.
1604
1605  FakePictureLayerTilingClient client;
1606  scoped_ptr<TestablePictureLayerTiling> tiling;
1607
1608  gfx::Size device_viewport(800, 600);
1609  gfx::Size last_layer_bounds(200, 200);
1610  gfx::Size current_layer_bounds(200, 200);
1611  float current_layer_contents_scale = 1.f;
1612  gfx::Transform last_screen_transform;
1613  gfx::Transform current_screen_transform;
1614  double current_frame_time_in_seconds = 1.0;
1615
1616  current_screen_transform.Translate(705, 505);
1617  last_screen_transform = current_screen_transform;
1618
1619  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1620      current_screen_transform, device_viewport);
1621
1622  client.SetTileSize(gfx::Size(100, 100));
1623  client.set_tree(ACTIVE_TREE);
1624  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1625                                              current_layer_bounds,
1626                                              &client);
1627
1628  tiling->UpdateTilePriorities(ACTIVE_TREE,
1629                               viewport_in_layer_space,
1630                               current_layer_contents_scale,
1631                               current_frame_time_in_seconds,
1632                               Occlusion());
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_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1642
1643  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1644  EXPECT_GT(priority.distance_to_visible, 0.f);
1645  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1646
1647  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1648  EXPECT_GT(priority.distance_to_visible, 0.f);
1649  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1650
1651  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1652  EXPECT_GT(priority.distance_to_visible, 0.f);
1653  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1654}
1655
1656TEST(UpdateTilePrioritiesTest, PartiallyOffscreenRotatedLayer) {
1657  // Each tile of a layer may be affected differently by a transform; Check
1658  // that UpdateTilePriorities correctly accounts for the transform between
1659  // layer space and screen space.
1660
1661  FakePictureLayerTilingClient client;
1662  scoped_ptr<TestablePictureLayerTiling> tiling;
1663
1664  gfx::Size device_viewport(800, 600);
1665  gfx::Size last_layer_bounds(200, 200);
1666  gfx::Size current_layer_bounds(200, 200);
1667  float current_layer_contents_scale = 1.f;
1668  gfx::Transform last_screen_transform;
1669  gfx::Transform current_screen_transform;
1670  double current_frame_time_in_seconds = 1.0;
1671
1672  // A diagonally rotated layer that is partially off the bottom of the screen.
1673  // In this configuration, only the top-left tile would be visible.
1674  current_screen_transform.Translate(600, 750);
1675  current_screen_transform.RotateAboutZAxis(45);
1676  last_screen_transform = current_screen_transform;
1677
1678  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1679      current_screen_transform, device_viewport);
1680
1681  client.SetTileSize(gfx::Size(100, 100));
1682  client.set_tree(ACTIVE_TREE);
1683  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1684                                              current_layer_bounds,
1685                                              &client);
1686
1687  tiling->UpdateTilePriorities(ACTIVE_TREE,
1688                               viewport_in_layer_space,
1689                               current_layer_contents_scale,
1690                               current_frame_time_in_seconds,
1691                               Occlusion());
1692
1693  ASSERT_TRUE(tiling->TileAt(0, 0));
1694  ASSERT_TRUE(tiling->TileAt(0, 1));
1695  ASSERT_TRUE(tiling->TileAt(1, 0));
1696  ASSERT_TRUE(tiling->TileAt(1, 1));
1697
1698  TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1699  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1700  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1701
1702  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1703  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1704  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1705
1706  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1707  EXPECT_GT(priority.distance_to_visible, 0.f);
1708  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1709
1710  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1711  EXPECT_GT(priority.distance_to_visible, 0.f);
1712  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1713
1714  // Furthermore, in this scenario the bottom-right tile should have the larger
1715  // distance to visible.
1716  TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1717  TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1718  TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1719  EXPECT_GT(top_right.distance_to_visible, top_left.distance_to_visible);
1720
1721  EXPECT_EQ(bottom_right.distance_to_visible, top_right.distance_to_visible);
1722}
1723
1724TEST(UpdateTilePrioritiesTest, PerspectiveLayer) {
1725  // Perspective transforms need to take a different code path.
1726  // This test checks tile priorities of a perspective layer.
1727
1728  FakePictureLayerTilingClient client;
1729  scoped_ptr<TestablePictureLayerTiling> tiling;
1730
1731  gfx::Size device_viewport(800, 600);
1732  gfx::Rect visible_layer_rect(0, 0, 0, 0);  // offscreen.
1733  gfx::Size last_layer_bounds(200, 200);
1734  gfx::Size current_layer_bounds(200, 200);
1735  float current_layer_contents_scale = 1.f;
1736  gfx::Transform last_screen_transform;
1737  gfx::Transform current_screen_transform;
1738  double current_frame_time_in_seconds = 1.0;
1739
1740  // A 3d perspective layer rotated about its Y axis, translated to almost
1741  // fully offscreen. The left side will appear closer (i.e. larger in 2d) than
1742  // the right side, so the top-left tile will technically be closer than the
1743  // top-right.
1744
1745  // Translate layer to offscreen
1746  current_screen_transform.Translate(400.0, 630.0);
1747  // Apply perspective about the center of the layer
1748  current_screen_transform.Translate(100.0, 100.0);
1749  current_screen_transform.ApplyPerspectiveDepth(100.0);
1750  current_screen_transform.RotateAboutYAxis(10.0);
1751  current_screen_transform.Translate(-100.0, -100.0);
1752  last_screen_transform = current_screen_transform;
1753
1754  // Sanity check that this transform wouldn't cause w<0 clipping.
1755  bool clipped;
1756  MathUtil::MapQuad(current_screen_transform,
1757                    gfx::QuadF(gfx::RectF(0, 0, 200, 200)),
1758                    &clipped);
1759  ASSERT_FALSE(clipped);
1760
1761  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1762      current_screen_transform, device_viewport);
1763
1764  client.SetTileSize(gfx::Size(100, 100));
1765  client.set_tree(ACTIVE_TREE);
1766  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1767                                              current_layer_bounds,
1768                                              &client);
1769
1770  tiling->UpdateTilePriorities(ACTIVE_TREE,
1771                               viewport_in_layer_space,
1772                               current_layer_contents_scale,
1773                               current_frame_time_in_seconds,
1774                               Occlusion());
1775
1776  ASSERT_TRUE(tiling->TileAt(0, 0));
1777  ASSERT_TRUE(tiling->TileAt(0, 1));
1778  ASSERT_TRUE(tiling->TileAt(1, 0));
1779  ASSERT_TRUE(tiling->TileAt(1, 1));
1780
1781  // All tiles will have a positive distance_to_visible
1782  // and an infinite time_to_visible.
1783  TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1784  EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1785  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1786
1787  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1788  EXPECT_GT(priority.distance_to_visible, 0.f);
1789  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1790
1791  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1792  EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1793  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1794
1795  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1796  EXPECT_GT(priority.distance_to_visible, 0.f);
1797  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1798
1799  // Furthermore, in this scenario the top-left distance_to_visible
1800  // will be smallest, followed by top-right. The bottom layers
1801  // will of course be further than the top layers.
1802  TilePriority top_left = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1803  TilePriority top_right = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1804  TilePriority bottom_left = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1805  TilePriority bottom_right = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1806
1807  EXPECT_GT(bottom_right.distance_to_visible, top_right.distance_to_visible);
1808
1809  EXPECT_GT(bottom_left.distance_to_visible, top_left.distance_to_visible);
1810}
1811
1812TEST(UpdateTilePrioritiesTest, PerspectiveLayerClippedByW) {
1813  // Perspective transforms need to take a different code path.
1814  // This test checks tile priorities of a perspective layer.
1815
1816  FakePictureLayerTilingClient client;
1817  scoped_ptr<TestablePictureLayerTiling> tiling;
1818
1819  gfx::Size device_viewport(800, 600);
1820  gfx::Size last_layer_bounds(200, 200);
1821  gfx::Size current_layer_bounds(200, 200);
1822  float current_layer_contents_scale = 1.f;
1823  gfx::Transform last_screen_transform;
1824  gfx::Transform current_screen_transform;
1825  double current_frame_time_in_seconds = 1.0;
1826
1827  // A 3d perspective layer rotated about its Y axis, translated to almost
1828  // fully offscreen. The left side will appear closer (i.e. larger in 2d) than
1829  // the right side, so the top-left tile will technically be closer than the
1830  // top-right.
1831
1832  // Translate layer to offscreen
1833  current_screen_transform.Translate(400.0, 970.0);
1834  // Apply perspective and rotation about the center of the layer
1835  current_screen_transform.Translate(100.0, 100.0);
1836  current_screen_transform.ApplyPerspectiveDepth(10.0);
1837  current_screen_transform.RotateAboutYAxis(10.0);
1838  current_screen_transform.Translate(-100.0, -100.0);
1839  last_screen_transform = current_screen_transform;
1840
1841  // Sanity check that this transform does cause w<0 clipping for the left side
1842  // of the layer, but not the right side.
1843  bool clipped;
1844  MathUtil::MapQuad(current_screen_transform,
1845                    gfx::QuadF(gfx::RectF(0, 0, 100, 200)),
1846                    &clipped);
1847  ASSERT_TRUE(clipped);
1848
1849  MathUtil::MapQuad(current_screen_transform,
1850                    gfx::QuadF(gfx::RectF(100, 0, 100, 200)),
1851                    &clipped);
1852  ASSERT_FALSE(clipped);
1853
1854  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1855      current_screen_transform, device_viewport);
1856
1857  client.SetTileSize(gfx::Size(100, 100));
1858  client.set_tree(ACTIVE_TREE);
1859  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1860                                              current_layer_bounds,
1861                                              &client);
1862
1863  tiling->UpdateTilePriorities(ACTIVE_TREE,
1864                               viewport_in_layer_space,
1865                               current_layer_contents_scale,
1866                               current_frame_time_in_seconds,
1867                               Occlusion());
1868
1869  ASSERT_TRUE(tiling->TileAt(0, 0));
1870  ASSERT_TRUE(tiling->TileAt(0, 1));
1871  ASSERT_TRUE(tiling->TileAt(1, 0));
1872  ASSERT_TRUE(tiling->TileAt(1, 1));
1873
1874  // Left-side tiles will be clipped by the transform, so we have to assume
1875  // they are visible just in case.
1876  TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1877  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
1878  EXPECT_FLOAT_EQ(TilePriority::NOW, priority.priority_bin);
1879
1880  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1881  EXPECT_GT(priority.distance_to_visible, 0.f);
1882  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1883
1884  // Right-side tiles will have a positive distance_to_visible
1885  // and an infinite time_to_visible.
1886  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1887  EXPECT_FLOAT_EQ(priority.distance_to_visible, 0.f);
1888  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
1889
1890  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1891  EXPECT_GT(priority.distance_to_visible, 0.f);
1892  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1893}
1894
1895TEST(UpdateTilePrioritiesTest, BasicMotion) {
1896  // Test that time_to_visible is computed correctly when
1897  // there is some motion.
1898
1899  FakePictureLayerTilingClient client;
1900  scoped_ptr<TestablePictureLayerTiling> tiling;
1901
1902  gfx::Size device_viewport(800, 600);
1903  gfx::Rect visible_layer_rect(0, 0, 0, 0);
1904  gfx::Size last_layer_bounds(200, 200);
1905  gfx::Size current_layer_bounds(200, 200);
1906  float last_layer_contents_scale = 1.f;
1907  float current_layer_contents_scale = 1.f;
1908  gfx::Transform last_screen_transform;
1909  gfx::Transform current_screen_transform;
1910  double last_frame_time_in_seconds = 1.0;
1911  double current_frame_time_in_seconds = 2.0;
1912
1913  // Offscreen layer is coming closer to viewport at 1000 pixels per second.
1914  current_screen_transform.Translate(1800, 0);
1915  last_screen_transform.Translate(2800, 0);
1916
1917  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1918      current_screen_transform, device_viewport);
1919
1920  client.SetTileSize(gfx::Size(100, 100));
1921  client.set_tree(ACTIVE_TREE);
1922  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
1923                                              current_layer_bounds,
1924                                              &client);
1925
1926  // previous ("last") frame
1927  tiling->UpdateTilePriorities(ACTIVE_TREE,
1928                               viewport_in_layer_space,
1929                               last_layer_contents_scale,
1930                               last_frame_time_in_seconds,
1931                               Occlusion());
1932
1933  // current frame
1934  tiling->UpdateTilePriorities(ACTIVE_TREE,
1935                               viewport_in_layer_space,
1936                               current_layer_contents_scale,
1937                               current_frame_time_in_seconds,
1938                               Occlusion());
1939
1940  ASSERT_TRUE(tiling->TileAt(0, 0));
1941  ASSERT_TRUE(tiling->TileAt(0, 1));
1942  ASSERT_TRUE(tiling->TileAt(1, 0));
1943  ASSERT_TRUE(tiling->TileAt(1, 1));
1944
1945  TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
1946  EXPECT_GT(priority.distance_to_visible, 0.f);
1947  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1948
1949  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
1950  EXPECT_GT(priority.distance_to_visible, 0.f);
1951  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1952
1953  // time_to_visible for the right hand side layers needs an extra 0.099
1954  // seconds because this tile is 99 pixels further away.
1955  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
1956  EXPECT_GT(priority.distance_to_visible, 0.f);
1957  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1958
1959  priority = tiling->TileAt(1, 1)->priority(ACTIVE_TREE);
1960  EXPECT_GT(priority.distance_to_visible, 0.f);
1961  EXPECT_NE(TilePriority::NOW, priority.priority_bin);
1962}
1963
1964TEST(UpdateTilePrioritiesTest, RotationMotion) {
1965  // Each tile of a layer may be affected differently by a transform; Check
1966  // that UpdateTilePriorities correctly accounts for the transform between
1967  // layer space and screen space.
1968
1969  FakePictureLayerTilingClient client;
1970  scoped_ptr<TestablePictureLayerTiling> tiling;
1971
1972  gfx::Size device_viewport(800, 600);
1973  gfx::Rect visible_layer_rect(0, 0, 0, 0);  // offscren.
1974  gfx::Size last_layer_bounds(200, 200);
1975  gfx::Size current_layer_bounds(200, 200);
1976  float last_layer_contents_scale = 1.f;
1977  float current_layer_contents_scale = 1.f;
1978  gfx::Transform last_screen_transform;
1979  gfx::Transform current_screen_transform;
1980  double last_frame_time_in_seconds = 1.0;
1981  double current_frame_time_in_seconds = 2.0;
1982
1983  // Rotation motion is set up specifically so that:
1984  //  - rotation occurs about the center of the layer
1985  //  - the top-left tile becomes visible on rotation
1986  //  - the top-right tile will have an infinite time_to_visible
1987  //    because it is rotating away from viewport.
1988  //  - bottom-left layer will have a positive non-zero time_to_visible
1989  //    because it is rotating toward the viewport.
1990  current_screen_transform.Translate(400, 550);
1991  current_screen_transform.RotateAboutZAxis(45);
1992
1993  last_screen_transform.Translate(400, 550);
1994
1995  gfx::Rect viewport_in_layer_space = ViewportInLayerSpace(
1996      current_screen_transform, device_viewport);
1997
1998  client.SetTileSize(gfx::Size(100, 100));
1999  client.set_tree(ACTIVE_TREE);
2000  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
2001                                              current_layer_bounds,
2002                                              &client);
2003
2004  // previous ("last") frame
2005  tiling->UpdateTilePriorities(ACTIVE_TREE,
2006                               viewport_in_layer_space,
2007                               last_layer_contents_scale,
2008                               last_frame_time_in_seconds,
2009                               Occlusion());
2010
2011  // current frame
2012  tiling->UpdateTilePriorities(ACTIVE_TREE,
2013                               viewport_in_layer_space,
2014                               current_layer_contents_scale,
2015                               current_frame_time_in_seconds,
2016                               Occlusion());
2017
2018  ASSERT_TRUE(tiling->TileAt(0, 0));
2019  ASSERT_TRUE(tiling->TileAt(0, 1));
2020  ASSERT_TRUE(tiling->TileAt(1, 0));
2021  ASSERT_TRUE(tiling->TileAt(1, 1));
2022
2023  TilePriority priority = tiling->TileAt(0, 0)->priority(ACTIVE_TREE);
2024  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
2025  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
2026
2027  priority = tiling->TileAt(0, 1)->priority(ACTIVE_TREE);
2028  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
2029  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
2030
2031  priority = tiling->TileAt(1, 0)->priority(ACTIVE_TREE);
2032  EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
2033  EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
2034}
2035
2036TEST(PictureLayerTilingTest, ResetClearsPriorities) {
2037  FakePictureLayerTilingClient client;
2038  scoped_ptr<TestablePictureLayerTiling> tiling;
2039
2040  client.SetTileSize(gfx::Size(100, 100));
2041  client.set_tree(ACTIVE_TREE);
2042  tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
2043                                              gfx::Size(100, 100),
2044                                              &client);
2045  tiling->UpdateTilePriorities(
2046      ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
2047
2048  std::vector<scoped_refptr<Tile> > tiles = tiling->AllRefTilesForTesting();
2049  ASSERT_GT(tiles.size(), 0u);
2050  for (std::vector<scoped_refptr<Tile> >::const_iterator it = tiles.begin();
2051       it != tiles.end();
2052       ++it) {
2053    EXPECT_NE(TilePriority(), (*it)->priority(ACTIVE_TREE));
2054  }
2055
2056  tiling->Reset();
2057  for (std::vector<scoped_refptr<Tile> >::const_iterator it = tiles.begin();
2058       it != tiles.end();
2059       ++it) {
2060    EXPECT_EQ(TilePriority(), (*it)->priority(ACTIVE_TREE));
2061  }
2062  tiles.clear();
2063}
2064
2065TEST(PictureLayerTilingTest, RecycledTilesCleared) {
2066  // This test performs the following:
2067  // Setup:
2068  // - Two tilings, one active one recycled with all tiles shared.
2069  // Procedure:
2070  // - Viewport moves somewhere far away and active tiling clears tiles.
2071  // - Viewport moves back and a new active tiling tile is created.
2072  // Result:
2073  // - Recycle tiling does _not_ have the tile in the same location (thus it
2074  //   will be shared next time a pending tiling is created).
2075
2076  FakePictureLayerTilingClient active_client;
2077  scoped_ptr<TestablePictureLayerTiling> active_tiling;
2078
2079  active_client.SetTileSize(gfx::Size(100, 100));
2080  active_client.set_tree(ACTIVE_TREE);
2081  active_client.set_max_tiles_for_interest_area(10);
2082  active_tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
2083                                                     gfx::Size(10000, 10000),
2084                                                     &active_client);
2085  // Create all tiles on this tiling.
2086  active_tiling->UpdateTilePriorities(
2087      ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
2088
2089  FakePictureLayerTilingClient recycle_client;
2090  recycle_client.SetTileSize(gfx::Size(100, 100));
2091  recycle_client.set_tree(PENDING_TREE);
2092  recycle_client.set_twin_tiling(active_tiling.get());
2093  recycle_client.set_max_tiles_for_interest_area(10);
2094
2095  scoped_ptr<TestablePictureLayerTiling> recycle_tiling;
2096  recycle_tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
2097                                                      gfx::Size(10000, 10000),
2098                                                      &recycle_client);
2099
2100  // Create all tiles on the second tiling. All tiles should be shared.
2101  recycle_tiling->UpdateTilePriorities(
2102      PENDING_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
2103
2104  // Set the second tiling as recycled.
2105  active_client.set_twin_tiling(NULL);
2106  active_client.set_recycled_twin_tiling(recycle_tiling.get());
2107  recycle_client.set_twin_tiling(NULL);
2108
2109  // Verify that tiles exist and are shared.
2110  EXPECT_TRUE(active_tiling->TileAt(0, 0));
2111  EXPECT_TRUE(recycle_tiling->TileAt(0, 0));
2112  EXPECT_EQ(active_tiling->TileAt(0, 0), recycle_tiling->TileAt(0, 0));
2113
2114  // Move the viewport far away from the (0, 0) tile.
2115  active_tiling->UpdateTilePriorities(
2116      ACTIVE_TREE, gfx::Rect(9000, 9000, 100, 100), 1.0f, 2.0, Occlusion());
2117  // Ensure the tile was deleted on both tilings.
2118  EXPECT_FALSE(active_tiling->TileAt(0, 0));
2119  EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
2120
2121  // Move the viewport back to (0, 0) tile.
2122  active_tiling->UpdateTilePriorities(
2123      ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 3.0, Occlusion());
2124
2125  // Ensure that we now have a tile here, but the recycle tiling does not.
2126  EXPECT_TRUE(active_tiling->TileAt(0, 0));
2127  EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
2128}
2129
2130TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) {
2131  FakePictureLayerTilingClient active_client;
2132  scoped_ptr<TestablePictureLayerTiling> active_tiling;
2133
2134  active_client.SetTileSize(gfx::Size(100, 100));
2135  active_client.set_tree(ACTIVE_TREE);
2136  active_tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
2137                                                     gfx::Size(100, 100),
2138                                                     &active_client);
2139  // Create all tiles on this tiling.
2140  active_tiling->UpdateTilePriorities(
2141      ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
2142
2143  FakePictureLayerTilingClient recycle_client;
2144  recycle_client.SetTileSize(gfx::Size(100, 100));
2145  recycle_client.set_tree(PENDING_TREE);
2146  recycle_client.set_twin_tiling(active_tiling.get());
2147  recycle_client.set_max_tiles_for_interest_area(10);
2148
2149  scoped_ptr<TestablePictureLayerTiling> recycle_tiling;
2150  recycle_tiling = TestablePictureLayerTiling::Create(1.0f,  // contents_scale
2151                                                      gfx::Size(100, 100),
2152                                                      &recycle_client);
2153
2154  // Create all tiles on the recycle tiling. All tiles should be shared.
2155  recycle_tiling->UpdateTilePriorities(
2156      PENDING_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
2157
2158  // Set the second tiling as recycled.
2159  active_client.set_twin_tiling(NULL);
2160  active_client.set_recycled_twin_tiling(recycle_tiling.get());
2161  recycle_client.set_twin_tiling(NULL);
2162
2163  // Verify that tiles exist and are shared.
2164  EXPECT_TRUE(active_tiling->TileAt(0, 0));
2165  EXPECT_TRUE(recycle_tiling->TileAt(0, 0));
2166  EXPECT_EQ(active_tiling->TileAt(0, 0), recycle_tiling->TileAt(0, 0));
2167
2168  // Reset the active tiling. The recycle tiles should be released too.
2169  active_tiling->Reset();
2170  EXPECT_FALSE(active_tiling->TileAt(0, 0));
2171  EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
2172}
2173
2174}  // namespace
2175}  // namespace cc
2176