• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_set.h"
6 
7 #include <map>
8 #include <vector>
9 
10 #include "cc/resources/resource_pool.h"
11 #include "cc/resources/resource_provider.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/fake_tile_manager_client.h"
16 #include "cc/test/test_shared_bitmap_manager.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/gfx/size_conversions.h"
19 
20 namespace cc {
21 namespace {
22 
TEST(PictureLayerTilingSetTest,NoResources)23 TEST(PictureLayerTilingSetTest, NoResources) {
24   FakePictureLayerTilingClient client;
25   gfx::Size layer_bounds(1000, 800);
26   PictureLayerTilingSet set(&client, layer_bounds);
27   client.SetTileSize(gfx::Size(256, 256));
28 
29   set.AddTiling(1.0);
30   set.AddTiling(1.5);
31   set.AddTiling(2.0);
32 
33   float contents_scale = 2.0;
34   gfx::Size content_bounds(
35       gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
36   gfx::Rect content_rect(content_bounds);
37 
38   Region remaining(content_rect);
39   PictureLayerTilingSet::CoverageIterator iter(
40       &set,
41       contents_scale,
42       content_rect,
43       contents_scale);
44   for (; iter; ++iter) {
45     gfx::Rect geometry_rect = iter.geometry_rect();
46     EXPECT_TRUE(content_rect.Contains(geometry_rect));
47     ASSERT_TRUE(remaining.Contains(geometry_rect));
48     remaining.Subtract(geometry_rect);
49 
50     // No tiles have resources, so no iter represents a real tile.
51     EXPECT_FALSE(*iter);
52   }
53   EXPECT_TRUE(remaining.IsEmpty());
54 }
55 
56 class PictureLayerTilingSetTestWithResources : public testing::Test {
57  public:
runTest(int num_tilings,float min_scale,float scale_increment,float ideal_contents_scale,float expected_scale)58   void runTest(
59       int num_tilings,
60       float min_scale,
61       float scale_increment,
62       float ideal_contents_scale,
63       float expected_scale) {
64     FakeOutputSurfaceClient output_surface_client;
65     scoped_ptr<FakeOutputSurface> output_surface =
66         FakeOutputSurface::Create3d();
67     CHECK(output_surface->BindToClient(&output_surface_client));
68 
69     scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
70         new TestSharedBitmapManager());
71     scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
72         output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false);
73 
74     FakePictureLayerTilingClient client(resource_provider.get());
75     client.SetTileSize(gfx::Size(256, 256));
76     gfx::Size layer_bounds(1000, 800);
77     PictureLayerTilingSet set(&client, layer_bounds);
78 
79     float scale = min_scale;
80     for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
81       PictureLayerTiling* tiling = set.AddTiling(scale);
82       tiling->CreateAllTilesForTesting();
83       std::vector<Tile*> tiles = tiling->AllTilesForTesting();
84       client.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
85     }
86 
87     float max_contents_scale = scale;
88     gfx::Size content_bounds(
89         gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, max_contents_scale)));
90     gfx::Rect content_rect(content_bounds);
91 
92     Region remaining(content_rect);
93     PictureLayerTilingSet::CoverageIterator iter(
94         &set,
95         max_contents_scale,
96         content_rect,
97         ideal_contents_scale);
98     for (; iter; ++iter) {
99       gfx::Rect geometry_rect = iter.geometry_rect();
100       EXPECT_TRUE(content_rect.Contains(geometry_rect));
101       ASSERT_TRUE(remaining.Contains(geometry_rect));
102       remaining.Subtract(geometry_rect);
103 
104       float scale = iter.CurrentTiling()->contents_scale();
105       EXPECT_EQ(expected_scale, scale);
106 
107       if (num_tilings)
108         EXPECT_TRUE(*iter);
109       else
110         EXPECT_FALSE(*iter);
111     }
112     EXPECT_TRUE(remaining.IsEmpty());
113   }
114 };
115 
TEST_F(PictureLayerTilingSetTestWithResources,NoTilings)116 TEST_F(PictureLayerTilingSetTestWithResources, NoTilings) {
117   runTest(0, 0.f, 0.f, 2.f, 0.f);
118 }
TEST_F(PictureLayerTilingSetTestWithResources,OneTiling_Smaller)119 TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Smaller) {
120   runTest(1, 1.f, 0.f, 2.f, 1.f);
121 }
TEST_F(PictureLayerTilingSetTestWithResources,OneTiling_Larger)122 TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Larger) {
123   runTest(1, 3.f, 0.f, 2.f, 3.f);
124 }
TEST_F(PictureLayerTilingSetTestWithResources,TwoTilings_Smaller)125 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Smaller) {
126   runTest(2, 1.f, 1.f, 3.f, 2.f);
127 }
128 
TEST_F(PictureLayerTilingSetTestWithResources,TwoTilings_SmallerEqual)129 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_SmallerEqual) {
130   runTest(2, 1.f, 1.f, 2.f, 2.f);
131 }
132 
TEST_F(PictureLayerTilingSetTestWithResources,TwoTilings_LargerEqual)133 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_LargerEqual) {
134   runTest(2, 1.f, 1.f, 1.f, 1.f);
135 }
136 
TEST_F(PictureLayerTilingSetTestWithResources,TwoTilings_Larger)137 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Larger) {
138   runTest(2, 2.f, 8.f, 1.f, 2.f);
139 }
140 
TEST_F(PictureLayerTilingSetTestWithResources,ManyTilings_Equal)141 TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_Equal) {
142   runTest(10, 1.f, 1.f, 5.f, 5.f);
143 }
144 
TEST_F(PictureLayerTilingSetTestWithResources,ManyTilings_NotEqual)145 TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_NotEqual) {
146   runTest(10, 1.f, 1.f, 4.5f, 5.f);
147 }
148 
149 class PictureLayerTilingSetSyncTest : public testing::Test {
150  public:
PictureLayerTilingSetSyncTest()151   PictureLayerTilingSetSyncTest()
152       : tile_size_(gfx::Size(10, 10)),
153         source_bounds_(gfx::Size(30, 20)),
154         target_bounds_(gfx::Size(30, 30)) {
155     source_client_.SetTileSize(tile_size_);
156     target_client_.SetTileSize(tile_size_);
157     source_.reset(new PictureLayerTilingSet(&source_client_, source_bounds_));
158     target_.reset(new PictureLayerTilingSet(&target_client_, target_bounds_));
159   }
160 
161   // Sync from source to target.
SyncTilings(const gfx::Size & new_bounds,const Region & invalidation,float minimum_scale)162   void SyncTilings(const gfx::Size& new_bounds,
163                    const Region& invalidation,
164                    float minimum_scale) {
165     for (size_t i = 0; i < source_->num_tilings(); ++i)
166       source_->tiling_at(i)->CreateAllTilesForTesting();
167     for (size_t i = 0; i < target_->num_tilings(); ++i)
168       target_->tiling_at(i)->CreateAllTilesForTesting();
169 
170     target_->SyncTilings(
171         *source_.get(), new_bounds, invalidation, minimum_scale);
172   }
SyncTilings(const gfx::Size & new_bounds)173   void SyncTilings(const gfx::Size& new_bounds) {
174     Region invalidation;
175     SyncTilings(new_bounds, invalidation, 0.f);
176   }
SyncTilings(const gfx::Size & new_bounds,const Region & invalidation)177   void SyncTilings(const gfx::Size& new_bounds, const Region& invalidation) {
178     SyncTilings(new_bounds, invalidation, 0.f);
179   }
SyncTilings(const gfx::Size & new_bounds,float minimum_scale)180   void SyncTilings(const gfx::Size& new_bounds, float minimum_scale) {
181     Region invalidation;
182     SyncTilings(new_bounds, invalidation, minimum_scale);
183   }
184 
VerifyTargetEqualsSource(const gfx::Size & new_bounds) const185   void VerifyTargetEqualsSource(const gfx::Size& new_bounds) const {
186     ASSERT_FALSE(new_bounds.IsEmpty());
187     EXPECT_EQ(target_->num_tilings(), source_->num_tilings());
188     EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString());
189 
190     for (size_t i = 0; i < target_->num_tilings(); ++i) {
191       ASSERT_GT(source_->num_tilings(), i);
192       const PictureLayerTiling* source_tiling = source_->tiling_at(i);
193       const PictureLayerTiling* target_tiling = target_->tiling_at(i);
194       EXPECT_EQ(target_tiling->layer_bounds().ToString(),
195                 new_bounds.ToString());
196       EXPECT_EQ(source_tiling->contents_scale(),
197                 target_tiling->contents_scale());
198     }
199 
200     EXPECT_EQ(source_->client(), &source_client_);
201     EXPECT_EQ(target_->client(), &target_client_);
202     ValidateTargetTilingSet();
203   }
204 
ValidateTargetTilingSet() const205   void ValidateTargetTilingSet() const {
206     // Tilings should be sorted largest to smallest.
207     if (target_->num_tilings() > 0) {
208       float last_scale = target_->tiling_at(0)->contents_scale();
209       for (size_t i = 1; i < target_->num_tilings(); ++i) {
210         const PictureLayerTiling* target_tiling = target_->tiling_at(i);
211         EXPECT_LT(target_tiling->contents_scale(), last_scale);
212         last_scale = target_tiling->contents_scale();
213       }
214     }
215 
216     for (size_t i = 0; i < target_->num_tilings(); ++i)
217       ValidateTiling(target_->tiling_at(i), target_client_.pile());
218   }
219 
ValidateTiling(const PictureLayerTiling * tiling,const PicturePileImpl * pile) const220   void ValidateTiling(const PictureLayerTiling* tiling,
221                       const PicturePileImpl* pile) const {
222     if (tiling->TilingRect().IsEmpty())
223       EXPECT_TRUE(tiling->live_tiles_rect().IsEmpty());
224     else if (!tiling->live_tiles_rect().IsEmpty())
225       EXPECT_TRUE(tiling->TilingRect().Contains(tiling->live_tiles_rect()));
226 
227     std::vector<Tile*> tiles = tiling->AllTilesForTesting();
228     for (size_t i = 0; i < tiles.size(); ++i) {
229       const Tile* tile = tiles[i];
230       ASSERT_TRUE(!!tile);
231       EXPECT_EQ(tile->picture_pile(), pile);
232       EXPECT_TRUE(tile->content_rect().Intersects(tiling->live_tiles_rect()))
233           << "All tiles must be inside the live tiles rect.";
234     }
235 
236     for (PictureLayerTiling::CoverageIterator iter(
237              tiling, tiling->contents_scale(), tiling->live_tiles_rect());
238          iter;
239          ++iter) {
240       EXPECT_TRUE(*iter) << "The live tiles rect must be full.";
241     }
242   }
243 
244   gfx::Size tile_size_;
245 
246   FakePictureLayerTilingClient source_client_;
247   gfx::Size source_bounds_;
248   scoped_ptr<PictureLayerTilingSet> source_;
249 
250   FakePictureLayerTilingClient target_client_;
251   gfx::Size target_bounds_;
252   scoped_ptr<PictureLayerTilingSet> target_;
253 };
254 
TEST_F(PictureLayerTilingSetSyncTest,EmptyBounds)255 TEST_F(PictureLayerTilingSetSyncTest, EmptyBounds) {
256   float source_scales[] = {1.f, 1.2f};
257   for (size_t i = 0; i < arraysize(source_scales); ++i)
258     source_->AddTiling(source_scales[i]);
259 
260   gfx::Size new_bounds;
261   SyncTilings(new_bounds);
262   EXPECT_EQ(target_->num_tilings(), 0u);
263   EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString());
264 }
265 
TEST_F(PictureLayerTilingSetSyncTest,AllNew)266 TEST_F(PictureLayerTilingSetSyncTest, AllNew) {
267   float source_scales[] = {0.5f, 1.f, 1.2f};
268   for (size_t i = 0; i < arraysize(source_scales); ++i)
269     source_->AddTiling(source_scales[i]);
270   float target_scales[] = {0.75f, 1.4f, 3.f};
271   for (size_t i = 0; i < arraysize(target_scales); ++i)
272     target_->AddTiling(target_scales[i]);
273 
274   gfx::Size new_bounds(15, 40);
275   SyncTilings(new_bounds);
276   VerifyTargetEqualsSource(new_bounds);
277 }
278 
FindTileAtOrigin(PictureLayerTiling * tiling)279 Tile* FindTileAtOrigin(PictureLayerTiling* tiling) {
280   std::vector<Tile*> tiles = tiling->AllTilesForTesting();
281   for (size_t i = 0; i < tiles.size(); ++i) {
282     if (tiles[i]->content_rect().origin() == gfx::Point())
283       return tiles[i];
284   }
285   return NULL;
286 }
287 
TEST_F(PictureLayerTilingSetSyncTest,KeepExisting)288 TEST_F(PictureLayerTilingSetSyncTest, KeepExisting) {
289   float source_scales[] = {0.7f, 1.f, 1.1f, 2.f};
290   for (size_t i = 0; i < arraysize(source_scales); ++i)
291     source_->AddTiling(source_scales[i]);
292   float target_scales[] = {0.5f, 1.f, 2.f};
293   for (size_t i = 0; i < arraysize(target_scales); ++i)
294     target_->AddTiling(target_scales[i]);
295 
296   PictureLayerTiling* tiling1 = source_->TilingAtScale(1.f);
297   ASSERT_TRUE(tiling1);
298   tiling1->CreateAllTilesForTesting();
299   EXPECT_EQ(tiling1->contents_scale(), 1.f);
300   Tile* tile1 = FindTileAtOrigin(tiling1);
301   ASSERT_TRUE(tile1);
302 
303   PictureLayerTiling* tiling2 = source_->TilingAtScale(2.f);
304   tiling2->CreateAllTilesForTesting();
305   ASSERT_TRUE(tiling2);
306   EXPECT_EQ(tiling2->contents_scale(), 2.f);
307   Tile* tile2 = FindTileAtOrigin(tiling2);
308   ASSERT_TRUE(tile2);
309 
310   gfx::Size new_bounds(15, 40);
311   SyncTilings(new_bounds);
312   VerifyTargetEqualsSource(new_bounds);
313 
314   EXPECT_EQ(tiling1, source_->TilingAtScale(1.f));
315   EXPECT_EQ(tile1, FindTileAtOrigin(tiling1));
316   EXPECT_FALSE(tiling1->live_tiles_rect().IsEmpty());
317 
318   EXPECT_EQ(tiling2, source_->TilingAtScale(2.f));
319   EXPECT_EQ(tile2, FindTileAtOrigin(tiling2));
320   EXPECT_FALSE(tiling2->live_tiles_rect().IsEmpty());
321 }
322 
TEST_F(PictureLayerTilingSetSyncTest,EmptySet)323 TEST_F(PictureLayerTilingSetSyncTest, EmptySet) {
324   float target_scales[] = {0.2f, 1.f};
325   for (size_t i = 0; i < arraysize(target_scales); ++i)
326     target_->AddTiling(target_scales[i]);
327 
328   gfx::Size new_bounds(15, 40);
329   SyncTilings(new_bounds);
330   VerifyTargetEqualsSource(new_bounds);
331 }
332 
TEST_F(PictureLayerTilingSetSyncTest,MinimumScale)333 TEST_F(PictureLayerTilingSetSyncTest, MinimumScale) {
334   float source_scales[] = {0.7f, 1.f, 1.1f, 2.f};
335   for (size_t i = 0; i < arraysize(source_scales); ++i)
336     source_->AddTiling(source_scales[i]);
337   float target_scales[] = {0.5f, 0.7f, 1.f, 1.1f, 2.f};
338   for (size_t i = 0; i < arraysize(target_scales); ++i)
339     target_->AddTiling(target_scales[i]);
340 
341   gfx::Size new_bounds(15, 40);
342   float minimum_scale = 1.5f;
343   SyncTilings(new_bounds, minimum_scale);
344 
345   EXPECT_EQ(target_->num_tilings(), 1u);
346   EXPECT_EQ(target_->tiling_at(0)->contents_scale(), 2.f);
347   ValidateTargetTilingSet();
348 }
349 
TEST_F(PictureLayerTilingSetSyncTest,Invalidation)350 TEST_F(PictureLayerTilingSetSyncTest, Invalidation) {
351   source_->AddTiling(2.f);
352   target_->AddTiling(2.f);
353   target_->tiling_at(0)->CreateAllTilesForTesting();
354 
355   Region layer_invalidation;
356   layer_invalidation.Union(gfx::Rect(0, 0, 1, 1));
357   layer_invalidation.Union(gfx::Rect(0, 15, 1, 1));
358   // Out of bounds layer_invalidation.
359   layer_invalidation.Union(gfx::Rect(100, 100, 1, 1));
360 
361   Region content_invalidation;
362   for (Region::Iterator iter(layer_invalidation); iter.has_rect();
363        iter.next()) {
364     gfx::Rect content_rect = gfx::ScaleToEnclosingRect(iter.rect(), 2.f);
365     content_invalidation.Union(content_rect);
366   }
367 
368   std::vector<Tile*> old_tiles = target_->tiling_at(0)->AllTilesForTesting();
369   std::map<gfx::Point, scoped_refptr<Tile> > old_tile_map;
370   for (size_t i = 0; i < old_tiles.size(); ++i)
371     old_tile_map[old_tiles[i]->content_rect().origin()] = old_tiles[i];
372 
373   SyncTilings(target_bounds_, layer_invalidation);
374   VerifyTargetEqualsSource(target_bounds_);
375 
376   std::vector<Tile*> new_tiles = target_->tiling_at(0)->AllTilesForTesting();
377   for (size_t i = 0; i < new_tiles.size(); ++i) {
378     const Tile* tile = new_tiles[i];
379     std::map<gfx::Point, scoped_refptr<Tile> >::iterator find =
380         old_tile_map.find(tile->content_rect().origin());
381     if (content_invalidation.Intersects(tile->content_rect()))
382       EXPECT_NE(tile, find->second.get());
383     else
384       EXPECT_EQ(tile, find->second.get());
385   }
386 }
387 
TEST_F(PictureLayerTilingSetSyncTest,TileSizeChange)388 TEST_F(PictureLayerTilingSetSyncTest, TileSizeChange) {
389   source_->AddTiling(1.f);
390   target_->AddTiling(1.f);
391 
392   target_->tiling_at(0)->CreateAllTilesForTesting();
393   std::vector<Tile*> original_tiles =
394       target_->tiling_at(0)->AllTilesForTesting();
395   EXPECT_GT(original_tiles.size(), 0u);
396   gfx::Size new_tile_size(100, 100);
397   target_client_.SetTileSize(new_tile_size);
398   EXPECT_NE(target_->tiling_at(0)->tile_size().ToString(),
399             new_tile_size.ToString());
400 
401   gfx::Size new_bounds(15, 40);
402   SyncTilings(new_bounds);
403   VerifyTargetEqualsSource(new_bounds);
404 
405   EXPECT_EQ(target_->tiling_at(0)->tile_size().ToString(),
406             new_tile_size.ToString());
407 
408   // All old tiles should not be present in new tiles.
409   std::vector<Tile*> new_tiles = target_->tiling_at(0)->AllTilesForTesting();
410   for (size_t i = 0; i < original_tiles.size(); ++i) {
411     std::vector<Tile*>::iterator find =
412         std::find(new_tiles.begin(), new_tiles.end(), original_tiles[i]);
413     EXPECT_TRUE(find == new_tiles.end());
414   }
415 }
416 
417 }  // namespace
418 }  // namespace cc
419