1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/picture_layer_tiling_set.h"
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 "testing/gtest/include/gtest/gtest.h"
17 #include "ui/gfx/size_conversions.h"
22 TEST(PictureLayerTilingSetTest, NoResources) {
23 FakePictureLayerTilingClient client;
24 gfx::Size layer_bounds(1000, 800);
25 PictureLayerTilingSet set(&client, layer_bounds);
26 client.SetTileSize(gfx::Size(256, 256));
32 float contents_scale = 2.0;
33 gfx::Size content_bounds(
34 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
35 gfx::Rect content_rect(content_bounds);
37 Region remaining(content_rect);
38 PictureLayerTilingSet::CoverageIterator iter(
43 for (; iter; ++iter) {
44 gfx::Rect geometry_rect = iter.geometry_rect();
45 EXPECT_TRUE(content_rect.Contains(geometry_rect));
46 ASSERT_TRUE(remaining.Contains(geometry_rect));
47 remaining.Subtract(geometry_rect);
49 // No tiles have resources, so no iter represents a real tile.
52 EXPECT_TRUE(remaining.IsEmpty());
55 class PictureLayerTilingSetTestWithResources : public testing::Test {
60 float scale_increment,
61 float ideal_contents_scale,
62 float expected_scale) {
63 FakeOutputSurfaceClient output_surface_client;
64 scoped_ptr<FakeOutputSurface> output_surface =
65 FakeOutputSurface::Create3d();
66 CHECK(output_surface->BindToClient(&output_surface_client));
68 scoped_ptr<ResourceProvider> resource_provider =
69 ResourceProvider::Create(output_surface.get(), NULL, 0, false, 1);
71 FakePictureLayerTilingClient client;
72 client.SetTileSize(gfx::Size(256, 256));
73 gfx::Size layer_bounds(1000, 800);
74 PictureLayerTilingSet set(&client, layer_bounds);
76 float scale = min_scale;
77 for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
78 PictureLayerTiling* tiling = set.AddTiling(scale);
79 tiling->CreateAllTilesForTesting();
80 std::vector<Tile*> tiles = tiling->AllTilesForTesting();
81 client.tile_manager()->InitializeTilesWithResourcesForTesting(
82 tiles, resource_provider.get());
85 float max_contents_scale = scale;
86 gfx::Size content_bounds(
87 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, max_contents_scale)));
88 gfx::Rect content_rect(content_bounds);
90 Region remaining(content_rect);
91 PictureLayerTilingSet::CoverageIterator iter(
95 ideal_contents_scale);
96 for (; iter; ++iter) {
97 gfx::Rect geometry_rect = iter.geometry_rect();
98 EXPECT_TRUE(content_rect.Contains(geometry_rect));
99 ASSERT_TRUE(remaining.Contains(geometry_rect));
100 remaining.Subtract(geometry_rect);
102 float scale = iter.CurrentTiling()->contents_scale();
103 EXPECT_EQ(expected_scale, scale);
110 EXPECT_TRUE(remaining.IsEmpty());
114 TEST_F(PictureLayerTilingSetTestWithResources, NoTilings) {
115 runTest(0, 0.f, 0.f, 2.f, 0.f);
117 TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Smaller) {
118 runTest(1, 1.f, 0.f, 2.f, 1.f);
120 TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Larger) {
121 runTest(1, 3.f, 0.f, 2.f, 3.f);
123 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Smaller) {
124 runTest(2, 1.f, 1.f, 3.f, 2.f);
127 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_SmallerEqual) {
128 runTest(2, 1.f, 1.f, 2.f, 2.f);
131 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_LargerEqual) {
132 runTest(2, 1.f, 1.f, 1.f, 1.f);
135 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Larger) {
136 runTest(2, 2.f, 8.f, 1.f, 2.f);
139 TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_Equal) {
140 runTest(10, 1.f, 1.f, 5.f, 5.f);
143 TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_NotEqual) {
144 runTest(10, 1.f, 1.f, 4.5f, 5.f);
147 class PictureLayerTilingSetSyncTest : public testing::Test {
149 PictureLayerTilingSetSyncTest()
150 : tile_size_(gfx::Size(10, 10)),
151 source_bounds_(gfx::Size(30, 20)),
152 target_bounds_(gfx::Size(30, 30)) {
153 source_client_.SetTileSize(tile_size_);
154 target_client_.SetTileSize(tile_size_);
155 source_.reset(new PictureLayerTilingSet(&source_client_, source_bounds_));
156 target_.reset(new PictureLayerTilingSet(&target_client_, target_bounds_));
159 // Sync from source to target.
160 void SyncTilings(gfx::Size new_bounds,
161 const Region& invalidation,
162 float minimum_scale) {
163 for (size_t i = 0; i < source_->num_tilings(); ++i)
164 source_->tiling_at(i)->CreateAllTilesForTesting();
165 for (size_t i = 0; i < target_->num_tilings(); ++i)
166 target_->tiling_at(i)->CreateAllTilesForTesting();
168 target_->SyncTilings(
169 *source_.get(), new_bounds, invalidation, minimum_scale);
171 void SyncTilings(gfx::Size new_bounds) {
173 SyncTilings(new_bounds, invalidation, 0.f);
175 void SyncTilings(gfx::Size new_bounds, const Region& invalidation) {
176 SyncTilings(new_bounds, invalidation, 0.f);
178 void SyncTilings(gfx::Size new_bounds, float minimum_scale) {
180 SyncTilings(new_bounds, invalidation, minimum_scale);
183 void VerifyTargetEqualsSource(gfx::Size new_bounds) const {
184 ASSERT_FALSE(new_bounds.IsEmpty());
185 EXPECT_EQ(target_->num_tilings(), source_->num_tilings());
186 EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString());
188 for (size_t i = 0; i < target_->num_tilings(); ++i) {
189 ASSERT_GT(source_->num_tilings(), i);
190 const PictureLayerTiling* source_tiling = source_->tiling_at(i);
191 const PictureLayerTiling* target_tiling = target_->tiling_at(i);
192 EXPECT_EQ(target_tiling->layer_bounds().ToString(),
193 new_bounds.ToString());
194 EXPECT_EQ(source_tiling->contents_scale(),
195 target_tiling->contents_scale());
198 EXPECT_EQ(source_->client(), &source_client_);
199 EXPECT_EQ(target_->client(), &target_client_);
200 ValidateTargetTilingSet();
203 void ValidateTargetTilingSet() const {
204 // Tilings should be sorted largest to smallest.
205 if (target_->num_tilings() > 0) {
206 float last_scale = target_->tiling_at(0)->contents_scale();
207 for (size_t i = 1; i < target_->num_tilings(); ++i) {
208 const PictureLayerTiling* target_tiling = target_->tiling_at(i);
209 EXPECT_LT(target_tiling->contents_scale(), last_scale);
210 last_scale = target_tiling->contents_scale();
214 for (size_t i = 0; i < target_->num_tilings(); ++i)
215 ValidateTiling(target_->tiling_at(i), target_client_.pile());
218 void ValidateTiling(const PictureLayerTiling* tiling,
219 const PicturePileImpl* pile) const {
220 if (tiling->ContentRect().IsEmpty())
221 EXPECT_TRUE(tiling->live_tiles_rect().IsEmpty());
222 else if (!tiling->live_tiles_rect().IsEmpty())
223 EXPECT_TRUE(tiling->ContentRect().Contains(tiling->live_tiles_rect()));
225 std::vector<Tile*> tiles = tiling->AllTilesForTesting();
226 for (size_t i = 0; i < tiles.size(); ++i) {
227 const Tile* tile = tiles[i];
229 EXPECT_EQ(tile->picture_pile(), pile);
230 EXPECT_TRUE(tile->content_rect().Intersects(tiling->live_tiles_rect()))
231 << "All tiles must be inside the live tiles rect.";
234 for (PictureLayerTiling::CoverageIterator iter(
235 tiling, tiling->contents_scale(), tiling->live_tiles_rect());
238 EXPECT_TRUE(*iter) << "The live tiles rect must be full.";
242 gfx::Size tile_size_;
244 FakePictureLayerTilingClient source_client_;
245 gfx::Size source_bounds_;
246 scoped_ptr<PictureLayerTilingSet> source_;
248 FakePictureLayerTilingClient target_client_;
249 gfx::Size target_bounds_;
250 scoped_ptr<PictureLayerTilingSet> target_;
253 TEST_F(PictureLayerTilingSetSyncTest, EmptyBounds) {
254 float source_scales[] = {1.f, 1.2f};
255 for (size_t i = 0; i < arraysize(source_scales); ++i)
256 source_->AddTiling(source_scales[i]);
258 gfx::Size new_bounds;
259 SyncTilings(new_bounds);
260 EXPECT_EQ(target_->num_tilings(), 0u);
261 EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString());
264 TEST_F(PictureLayerTilingSetSyncTest, AllNew) {
265 float source_scales[] = {0.5f, 1.f, 1.2f};
266 for (size_t i = 0; i < arraysize(source_scales); ++i)
267 source_->AddTiling(source_scales[i]);
268 float target_scales[] = {0.75f, 1.4f, 3.f};
269 for (size_t i = 0; i < arraysize(target_scales); ++i)
270 target_->AddTiling(target_scales[i]);
272 gfx::Size new_bounds(15, 40);
273 SyncTilings(new_bounds);
274 VerifyTargetEqualsSource(new_bounds);
277 Tile* FindTileAtOrigin(PictureLayerTiling* tiling) {
278 std::vector<Tile*> tiles = tiling->AllTilesForTesting();
279 for (size_t i = 0; i < tiles.size(); ++i) {
280 if (tiles[i]->content_rect().origin() == gfx::Point())
286 TEST_F(PictureLayerTilingSetSyncTest, KeepExisting) {
287 float source_scales[] = {0.7f, 1.f, 1.1f, 2.f};
288 for (size_t i = 0; i < arraysize(source_scales); ++i)
289 source_->AddTiling(source_scales[i]);
290 float target_scales[] = {0.5f, 1.f, 2.f};
291 for (size_t i = 0; i < arraysize(target_scales); ++i)
292 target_->AddTiling(target_scales[i]);
294 PictureLayerTiling* tiling1 = source_->TilingAtScale(1.f);
295 ASSERT_TRUE(tiling1);
296 tiling1->CreateAllTilesForTesting();
297 EXPECT_EQ(tiling1->contents_scale(), 1.f);
298 Tile* tile1 = FindTileAtOrigin(tiling1);
301 PictureLayerTiling* tiling2 = source_->TilingAtScale(2.f);
302 tiling2->CreateAllTilesForTesting();
303 ASSERT_TRUE(tiling2);
304 EXPECT_EQ(tiling2->contents_scale(), 2.f);
305 Tile* tile2 = FindTileAtOrigin(tiling2);
308 gfx::Size new_bounds(15, 40);
309 SyncTilings(new_bounds);
310 VerifyTargetEqualsSource(new_bounds);
312 EXPECT_EQ(tiling1, source_->TilingAtScale(1.f));
313 EXPECT_EQ(tile1, FindTileAtOrigin(tiling1));
314 EXPECT_FALSE(tiling1->live_tiles_rect().IsEmpty());
316 EXPECT_EQ(tiling2, source_->TilingAtScale(2.f));
317 EXPECT_EQ(tile2, FindTileAtOrigin(tiling2));
318 EXPECT_FALSE(tiling2->live_tiles_rect().IsEmpty());
321 TEST_F(PictureLayerTilingSetSyncTest, EmptySet) {
322 float target_scales[] = {0.2f, 1.f};
323 for (size_t i = 0; i < arraysize(target_scales); ++i)
324 target_->AddTiling(target_scales[i]);
326 gfx::Size new_bounds(15, 40);
327 SyncTilings(new_bounds);
328 VerifyTargetEqualsSource(new_bounds);
331 TEST_F(PictureLayerTilingSetSyncTest, MinimumScale) {
332 float source_scales[] = {0.7f, 1.f, 1.1f, 2.f};
333 for (size_t i = 0; i < arraysize(source_scales); ++i)
334 source_->AddTiling(source_scales[i]);
335 float target_scales[] = {0.5f, 0.7f, 1.f, 1.1f, 2.f};
336 for (size_t i = 0; i < arraysize(target_scales); ++i)
337 target_->AddTiling(target_scales[i]);
339 gfx::Size new_bounds(15, 40);
340 float minimum_scale = 1.5f;
341 SyncTilings(new_bounds, minimum_scale);
343 EXPECT_EQ(target_->num_tilings(), 1u);
344 EXPECT_EQ(target_->tiling_at(0)->contents_scale(), 2.f);
345 ValidateTargetTilingSet();
348 TEST_F(PictureLayerTilingSetSyncTest, Invalidation) {
349 source_->AddTiling(2.f);
350 target_->AddTiling(2.f);
351 target_->tiling_at(0)->CreateAllTilesForTesting();
353 Region layer_invalidation;
354 layer_invalidation.Union(gfx::Rect(0, 0, 1, 1));
355 layer_invalidation.Union(gfx::Rect(0, 15, 1, 1));
356 // Out of bounds layer_invalidation.
357 layer_invalidation.Union(gfx::Rect(100, 100, 1, 1));
359 Region content_invalidation;
360 for (Region::Iterator iter(layer_invalidation); iter.has_rect();
362 gfx::Rect content_rect = gfx::ScaleToEnclosingRect(iter.rect(), 2.f);
363 content_invalidation.Union(content_rect);
366 std::vector<Tile*> old_tiles = target_->tiling_at(0)->AllTilesForTesting();
367 std::map<gfx::Point, scoped_refptr<Tile> > old_tile_map;
368 for (size_t i = 0; i < old_tiles.size(); ++i)
369 old_tile_map[old_tiles[i]->content_rect().origin()] = old_tiles[i];
371 SyncTilings(target_bounds_, layer_invalidation);
372 VerifyTargetEqualsSource(target_bounds_);
374 std::vector<Tile*> new_tiles = target_->tiling_at(0)->AllTilesForTesting();
375 for (size_t i = 0; i < new_tiles.size(); ++i) {
376 const Tile* tile = new_tiles[i];
377 std::map<gfx::Point, scoped_refptr<Tile> >::iterator find =
378 old_tile_map.find(tile->content_rect().origin());
379 if (content_invalidation.Intersects(tile->content_rect()))
380 EXPECT_NE(tile, find->second.get());
382 EXPECT_EQ(tile, find->second.get());
386 TEST_F(PictureLayerTilingSetSyncTest, TileSizeChange) {
387 source_->AddTiling(1.f);
388 target_->AddTiling(1.f);
390 target_->tiling_at(0)->CreateAllTilesForTesting();
391 std::vector<Tile*> original_tiles =
392 target_->tiling_at(0)->AllTilesForTesting();
393 EXPECT_GT(original_tiles.size(), 0u);
394 gfx::Size new_tile_size(100, 100);
395 target_client_.SetTileSize(new_tile_size);
396 EXPECT_NE(target_->tiling_at(0)->tile_size().ToString(),
397 new_tile_size.ToString());
399 gfx::Size new_bounds(15, 40);
400 SyncTilings(new_bounds);
401 VerifyTargetEqualsSource(new_bounds);
403 EXPECT_EQ(target_->tiling_at(0)->tile_size().ToString(),
404 new_tile_size.ToString());
406 // All old tiles should not be present in new tiles.
407 std::vector<Tile*> new_tiles = target_->tiling_at(0)->AllTilesForTesting();
408 for (size_t i = 0; i < original_tiles.size(); ++i) {
409 std::vector<Tile*>::iterator find =
410 std::find(new_tiles.begin(), new_tiles.end(), original_tiles[i]);
411 EXPECT_TRUE(find == new_tiles.end());