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 "cc/test/test_shared_bitmap_manager.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/gfx/size_conversions.h"
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));
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
);
38 Region
remaining(content_rect
);
39 PictureLayerTilingSet::CoverageIterator
iter(
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
);
50 // No tiles have resources, so no iter represents a real tile.
53 EXPECT_TRUE(remaining
.IsEmpty());
56 class PictureLayerTilingSetTestWithResources
: public testing::Test
{
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
));
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);
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
);
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
);
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
);
92 Region
remaining(content_rect
);
93 PictureLayerTilingSet::CoverageIterator
iter(
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
);
104 float scale
= iter
.CurrentTiling()->contents_scale();
105 EXPECT_EQ(expected_scale
, scale
);
112 EXPECT_TRUE(remaining
.IsEmpty());
116 TEST_F(PictureLayerTilingSetTestWithResources
, NoTilings
) {
117 runTest(0, 0.f
, 0.f
, 2.f
, 0.f
);
119 TEST_F(PictureLayerTilingSetTestWithResources
, OneTiling_Smaller
) {
120 runTest(1, 1.f
, 0.f
, 2.f
, 1.f
);
122 TEST_F(PictureLayerTilingSetTestWithResources
, OneTiling_Larger
) {
123 runTest(1, 3.f
, 0.f
, 2.f
, 3.f
);
125 TEST_F(PictureLayerTilingSetTestWithResources
, TwoTilings_Smaller
) {
126 runTest(2, 1.f
, 1.f
, 3.f
, 2.f
);
129 TEST_F(PictureLayerTilingSetTestWithResources
, TwoTilings_SmallerEqual
) {
130 runTest(2, 1.f
, 1.f
, 2.f
, 2.f
);
133 TEST_F(PictureLayerTilingSetTestWithResources
, TwoTilings_LargerEqual
) {
134 runTest(2, 1.f
, 1.f
, 1.f
, 1.f
);
137 TEST_F(PictureLayerTilingSetTestWithResources
, TwoTilings_Larger
) {
138 runTest(2, 2.f
, 8.f
, 1.f
, 2.f
);
141 TEST_F(PictureLayerTilingSetTestWithResources
, ManyTilings_Equal
) {
142 runTest(10, 1.f
, 1.f
, 5.f
, 5.f
);
145 TEST_F(PictureLayerTilingSetTestWithResources
, ManyTilings_NotEqual
) {
146 runTest(10, 1.f
, 1.f
, 4.5f
, 5.f
);
149 class PictureLayerTilingSetSyncTest
: public testing::Test
{
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_
));
161 // Sync from source to target.
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();
170 target_
->SyncTilings(
171 *source_
.get(), new_bounds
, invalidation
, minimum_scale
);
173 void SyncTilings(const gfx::Size
& new_bounds
) {
175 SyncTilings(new_bounds
, invalidation
, 0.f
);
177 void SyncTilings(const gfx::Size
& new_bounds
, const Region
& invalidation
) {
178 SyncTilings(new_bounds
, invalidation
, 0.f
);
180 void SyncTilings(const gfx::Size
& new_bounds
, float minimum_scale
) {
182 SyncTilings(new_bounds
, invalidation
, minimum_scale
);
185 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());
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());
200 EXPECT_EQ(source_
->client(), &source_client_
);
201 EXPECT_EQ(target_
->client(), &target_client_
);
202 ValidateTargetTilingSet();
205 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();
216 for (size_t i
= 0; i
< target_
->num_tilings(); ++i
)
217 ValidateTiling(target_
->tiling_at(i
), target_client_
.pile());
220 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()));
227 std::vector
<Tile
*> tiles
= tiling
->AllTilesForTesting();
228 for (size_t i
= 0; i
< tiles
.size(); ++i
) {
229 const Tile
* tile
= tiles
[i
];
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.";
236 for (PictureLayerTiling::CoverageIterator
iter(
237 tiling
, tiling
->contents_scale(), tiling
->live_tiles_rect());
240 EXPECT_TRUE(*iter
) << "The live tiles rect must be full.";
244 gfx::Size tile_size_
;
246 FakePictureLayerTilingClient source_client_
;
247 gfx::Size source_bounds_
;
248 scoped_ptr
<PictureLayerTilingSet
> source_
;
250 FakePictureLayerTilingClient target_client_
;
251 gfx::Size target_bounds_
;
252 scoped_ptr
<PictureLayerTilingSet
> target_
;
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
]);
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());
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
]);
274 gfx::Size
new_bounds(15, 40);
275 SyncTilings(new_bounds
);
276 VerifyTargetEqualsSource(new_bounds
);
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())
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
]);
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
);
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
);
310 gfx::Size
new_bounds(15, 40);
311 SyncTilings(new_bounds
);
312 VerifyTargetEqualsSource(new_bounds
);
314 EXPECT_EQ(tiling1
, source_
->TilingAtScale(1.f
));
315 EXPECT_EQ(tile1
, FindTileAtOrigin(tiling1
));
316 EXPECT_FALSE(tiling1
->live_tiles_rect().IsEmpty());
318 EXPECT_EQ(tiling2
, source_
->TilingAtScale(2.f
));
319 EXPECT_EQ(tile2
, FindTileAtOrigin(tiling2
));
320 EXPECT_FALSE(tiling2
->live_tiles_rect().IsEmpty());
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
]);
328 gfx::Size
new_bounds(15, 40);
329 SyncTilings(new_bounds
);
330 VerifyTargetEqualsSource(new_bounds
);
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
]);
341 gfx::Size
new_bounds(15, 40);
342 float minimum_scale
= 1.5f
;
343 SyncTilings(new_bounds
, minimum_scale
);
345 EXPECT_EQ(target_
->num_tilings(), 1u);
346 EXPECT_EQ(target_
->tiling_at(0)->contents_scale(), 2.f
);
347 ValidateTargetTilingSet();
350 TEST_F(PictureLayerTilingSetSyncTest
, Invalidation
) {
351 source_
->AddTiling(2.f
);
352 target_
->AddTiling(2.f
);
353 target_
->tiling_at(0)->CreateAllTilesForTesting();
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));
361 Region content_invalidation
;
362 for (Region::Iterator
iter(layer_invalidation
); iter
.has_rect();
364 gfx::Rect content_rect
= gfx::ScaleToEnclosingRect(iter
.rect(), 2.f
);
365 content_invalidation
.Union(content_rect
);
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
];
373 SyncTilings(target_bounds_
, layer_invalidation
);
374 VerifyTargetEqualsSource(target_bounds_
);
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());
384 EXPECT_EQ(tile
, find
->second
.get());
388 TEST_F(PictureLayerTilingSetSyncTest
, TileSizeChange
) {
389 source_
->AddTiling(1.f
);
390 target_
->AddTiling(1.f
);
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());
401 gfx::Size
new_bounds(15, 40);
402 SyncTilings(new_bounds
);
403 VerifyTargetEqualsSource(new_bounds
);
405 EXPECT_EQ(target_
->tiling_at(0)->tile_size().ToString(),
406 new_tile_size
.ToString());
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());