OLD | NEW |
| (Empty) |
1 // Copyright 2013 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/picture_layer_impl.h" | |
6 | |
7 #include "cc/picture_layer.h" | |
8 #include "cc/test/fake_content_layer_client.h" | |
9 #include "cc/test/fake_impl_proxy.h" | |
10 #include "cc/test/fake_layer_tree_host_impl.h" | |
11 #include "cc/test/fake_output_surface.h" | |
12 #include "cc/trees/layer_tree_impl.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 #include "third_party/skia/include/core/SkDevice.h" | |
15 #include "ui/gfx/rect_conversions.h" | |
16 | |
17 namespace cc { | |
18 namespace { | |
19 | |
20 class TestablePictureLayerImpl : public PictureLayerImpl { | |
21 public: | |
22 static scoped_ptr<TestablePictureLayerImpl> Create( | |
23 LayerTreeImpl* tree_impl, | |
24 int id, | |
25 scoped_refptr<PicturePileImpl> pile) | |
26 { | |
27 return make_scoped_ptr(new TestablePictureLayerImpl(tree_impl, id, pile)); | |
28 } | |
29 | |
30 PictureLayerTilingSet& tilings() { return *tilings_; } | |
31 Region& invalidation() { return invalidation_; } | |
32 | |
33 virtual gfx::Size CalculateTileSize( | |
34 gfx::Size current_tile_size, | |
35 gfx::Size content_bounds) OVERRIDE { | |
36 if (current_tile_size.IsEmpty()) | |
37 return gfx::Size(100, 100); | |
38 return current_tile_size; | |
39 } | |
40 | |
41 using PictureLayerImpl::AddTiling; | |
42 using PictureLayerImpl::CleanUpTilingsOnActiveLayer; | |
43 | |
44 private: | |
45 TestablePictureLayerImpl( | |
46 LayerTreeImpl* tree_impl, | |
47 int id, | |
48 scoped_refptr<PicturePileImpl> pile) | |
49 : PictureLayerImpl(tree_impl, id) { | |
50 pile_ = pile; | |
51 SetBounds(pile_->size()); | |
52 CreateTilingSet(); | |
53 } | |
54 }; | |
55 | |
56 class ImplSidePaintingSettings : public LayerTreeSettings { | |
57 public: | |
58 ImplSidePaintingSettings() { | |
59 implSidePainting = true; | |
60 } | |
61 }; | |
62 | |
63 class TestablePicturePileImpl : public PicturePileImpl { | |
64 public: | |
65 static scoped_refptr<TestablePicturePileImpl> CreateFilledPile( | |
66 gfx::Size tile_size, | |
67 gfx::Size layer_bounds) { | |
68 scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl()); | |
69 pile->tiling().SetTotalSize(layer_bounds); | |
70 pile->tiling().SetMaxTextureSize(tile_size); | |
71 pile->SetTileGridSize(ImplSidePaintingSettings().defaultTileSize); | |
72 for (int x = 0; x < pile->tiling().num_tiles_x(); ++x) { | |
73 for (int y = 0; y < pile->tiling().num_tiles_y(); ++y) | |
74 pile->AddRecordingAt(x, y); | |
75 } | |
76 pile->UpdateRecordedRegion(); | |
77 return pile; | |
78 } | |
79 | |
80 static scoped_refptr<TestablePicturePileImpl> CreateEmptyPile( | |
81 gfx::Size tile_size, | |
82 gfx::Size layer_bounds) { | |
83 scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl()); | |
84 pile->tiling().SetTotalSize(layer_bounds); | |
85 pile->tiling().SetMaxTextureSize(tile_size); | |
86 pile->SetTileGridSize(ImplSidePaintingSettings().defaultTileSize); | |
87 pile->UpdateRecordedRegion(); | |
88 return pile; | |
89 } | |
90 | |
91 TilingData& tiling() { return tiling_; } | |
92 | |
93 void AddRecordingAt(int x, int y) { | |
94 EXPECT_GE(x, 0); | |
95 EXPECT_GE(y, 0); | |
96 EXPECT_LT(x, tiling_.num_tiles_x()); | |
97 EXPECT_LT(y, tiling_.num_tiles_y()); | |
98 | |
99 if (HasRecordingAt(x, y)) | |
100 return; | |
101 gfx::Rect bounds(tiling().TileBounds(x, y)); | |
102 scoped_refptr<Picture> picture(Picture::Create(bounds)); | |
103 picture->Record(&client_, NULL, tile_grid_info_); | |
104 picture_list_map_[std::pair<int, int>(x, y)].push_back(picture); | |
105 EXPECT_TRUE(HasRecordingAt(x, y)); | |
106 | |
107 UpdateRecordedRegion(); | |
108 } | |
109 | |
110 void RemoveRecordingAt(int x, int y) { | |
111 EXPECT_GE(x, 0); | |
112 EXPECT_GE(y, 0); | |
113 EXPECT_LT(x, tiling_.num_tiles_x()); | |
114 EXPECT_LT(y, tiling_.num_tiles_y()); | |
115 | |
116 if (!HasRecordingAt(x, y)) | |
117 return; | |
118 picture_list_map_.erase(std::pair<int, int>(x, y)); | |
119 EXPECT_FALSE(HasRecordingAt(x, y)); | |
120 | |
121 UpdateRecordedRegion(); | |
122 } | |
123 | |
124 void addDrawRect(const gfx::Rect& rect) { | |
125 client_.addDrawRect(rect); | |
126 } | |
127 | |
128 protected: | |
129 virtual ~TestablePicturePileImpl() { | |
130 } | |
131 | |
132 FakeContentLayerClient client_; | |
133 }; | |
134 | |
135 class MockCanvas : public SkCanvas { | |
136 public: | |
137 explicit MockCanvas(SkDevice* device) : SkCanvas(device) {} | |
138 | |
139 virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE { | |
140 // Capture calls before SkCanvas quickReject kicks in | |
141 rects_.push_back(rect); | |
142 } | |
143 | |
144 std::vector<SkRect> rects_; | |
145 }; | |
146 | |
147 class PictureLayerImplTest : public testing::Test { | |
148 public: | |
149 PictureLayerImplTest() | |
150 : host_impl_(ImplSidePaintingSettings(), &proxy_), | |
151 id_(7) { | |
152 host_impl_.InitializeRenderer(createFakeOutputSurface()); | |
153 } | |
154 | |
155 virtual ~PictureLayerImplTest() { | |
156 } | |
157 | |
158 void SetupTrees( | |
159 scoped_refptr<PicturePileImpl> pending_pile, | |
160 scoped_refptr<PicturePileImpl> active_pile) { | |
161 SetupPendingTree(active_pile); | |
162 host_impl_.ActivatePendingTree(); | |
163 | |
164 active_layer_ = static_cast<TestablePictureLayerImpl*>( | |
165 host_impl_.active_tree()->LayerById(id_)); | |
166 | |
167 SetupPendingTree(pending_pile); | |
168 pending_layer_ = static_cast<TestablePictureLayerImpl*>( | |
169 host_impl_.pending_tree()->LayerById(id_)); | |
170 } | |
171 | |
172 void AddDefaultTilingsWithInvalidation(const Region& invalidation) { | |
173 active_layer_->AddTiling(2.3f); | |
174 active_layer_->AddTiling(1.0f); | |
175 active_layer_->AddTiling(0.5f); | |
176 pending_layer_->invalidation() = invalidation; | |
177 pending_layer_->SyncFromActiveLayer(); | |
178 } | |
179 | |
180 void SetupPendingTree( | |
181 scoped_refptr<PicturePileImpl> pile) { | |
182 host_impl_.CreatePendingTree(); | |
183 LayerTreeImpl* pending_tree = host_impl_.pending_tree(); | |
184 // Clear recycled tree. | |
185 pending_tree->DetachLayerTree(); | |
186 | |
187 scoped_ptr<TestablePictureLayerImpl> pending_layer = | |
188 TestablePictureLayerImpl::Create(pending_tree, id_, pile); | |
189 pending_layer->SetDrawsContent(true); | |
190 pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>()); | |
191 } | |
192 | |
193 static void VerifyAllTilesExistAndHavePile( | |
194 const PictureLayerTiling* tiling, | |
195 PicturePileImpl* pile) { | |
196 for (PictureLayerTiling::Iterator | |
197 iter(tiling, | |
198 tiling->contents_scale(), | |
199 tiling->ContentRect(), | |
200 PictureLayerTiling::LayerDeviceAlignmentUnknown); | |
201 iter; | |
202 ++iter) { | |
203 EXPECT_TRUE(*iter); | |
204 EXPECT_EQ(pile, iter->picture_pile()); | |
205 } | |
206 } | |
207 | |
208 void SetContentsScaleOnBothLayers(float scale, bool animating_transform) { | |
209 float result_scale_x, result_scale_y; | |
210 gfx::Size result_bounds; | |
211 pending_layer_->CalculateContentsScale( | |
212 scale, animating_transform, | |
213 &result_scale_x, &result_scale_y, &result_bounds); | |
214 active_layer_->CalculateContentsScale( | |
215 scale, animating_transform, | |
216 &result_scale_x, &result_scale_y, &result_bounds); | |
217 } | |
218 | |
219 protected: | |
220 void TestTileGridAlignmentCommon() { | |
221 // Layer to span 4 raster tiles in x and in y | |
222 ImplSidePaintingSettings settings; | |
223 gfx::Size layer_size( | |
224 settings.defaultTileSize.width() * 7 / 2, | |
225 settings.defaultTileSize.height() * 7 / 2); | |
226 | |
227 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
228 TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size); | |
229 scoped_refptr<TestablePicturePileImpl> active_pile = | |
230 TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size); | |
231 | |
232 SetupTrees(pending_pile, active_pile); | |
233 | |
234 host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f); | |
235 float result_scale_x, result_scale_y; | |
236 gfx::Size result_bounds; | |
237 active_layer_->CalculateContentsScale( | |
238 1.f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
239 | |
240 // Add 1x1 rects at the centers of each tile, then re-record pile contents | |
241 std::vector<Tile*> tiles = | |
242 active_layer_->tilings().tiling_at(0)->AllTilesForTesting(); | |
243 EXPECT_EQ(16, tiles.size()); | |
244 std::vector<SkRect> rects; | |
245 std::vector<Tile*>::const_iterator tile_iter; | |
246 for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) { | |
247 gfx::Point tile_center = (*tile_iter)->content_rect().CenterPoint(); | |
248 gfx::Rect rect(tile_center.x(), tile_center.y(), 1, 1); | |
249 active_pile->addDrawRect(rect); | |
250 rects.push_back(SkRect::MakeXYWH(rect.x(), rect.y(), 1, 1)); | |
251 } | |
252 // Force re-record with newly injected content | |
253 active_pile->RemoveRecordingAt(0, 0); | |
254 active_pile->AddRecordingAt(0, 0); | |
255 | |
256 SkBitmap store; | |
257 store.setConfig(SkBitmap::kNo_Config, 1000, 1000); | |
258 SkDevice device(store); | |
259 int64 pixelsRasterized; | |
260 | |
261 std::vector<SkRect>::const_iterator rect_iter = rects.begin(); | |
262 for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) { | |
263 MockCanvas mock_canvas(&device); | |
264 active_pile->Raster(&mock_canvas, (*tile_iter)->content_rect(), | |
265 1.0f, &pixelsRasterized); | |
266 | |
267 // This test verifies that when drawing the contents of a specific tile | |
268 // at content scale 1.0, the playback canvas never receives content from | |
269 // neighboring tiles which indicates that the tile grid embedded in | |
270 // SkPicture is perfectly aligned with the compositor's tiles. | |
271 // Note: There are two rects: the initial clear and the explicitly | |
272 // recorded rect. We only care about the second one. | |
273 EXPECT_EQ(2, mock_canvas.rects_.size()); | |
274 EXPECT_EQ(*rect_iter, mock_canvas.rects_[1]); | |
275 rect_iter++; | |
276 } | |
277 } | |
278 | |
279 FakeImplProxy proxy_; | |
280 FakeLayerTreeHostImpl host_impl_; | |
281 int id_; | |
282 TestablePictureLayerImpl* pending_layer_; | |
283 TestablePictureLayerImpl* active_layer_; | |
284 | |
285 DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest); | |
286 }; | |
287 | |
288 TEST_F(PictureLayerImplTest, tileGridAlignment) { | |
289 host_impl_.SetDeviceScaleFactor(1.f); | |
290 TestTileGridAlignmentCommon(); | |
291 } | |
292 | |
293 TEST_F(PictureLayerImplTest, tileGridAlignmentHiDPI) { | |
294 host_impl_.SetDeviceScaleFactor(2.f); | |
295 TestTileGridAlignmentCommon(); | |
296 } | |
297 | |
298 TEST_F(PictureLayerImplTest, cloneNoInvalidation) { | |
299 gfx::Size tile_size(100, 100); | |
300 gfx::Size layer_bounds(400, 400); | |
301 | |
302 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
303 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
304 scoped_refptr<TestablePicturePileImpl> active_pile = | |
305 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
306 | |
307 SetupTrees(pending_pile, active_pile); | |
308 | |
309 Region invalidation; | |
310 AddDefaultTilingsWithInvalidation(invalidation); | |
311 | |
312 EXPECT_EQ(pending_layer_->tilings().num_tilings(), | |
313 active_layer_->tilings().num_tilings()); | |
314 | |
315 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); | |
316 EXPECT_GT(tilings.num_tilings(), 0u); | |
317 for (size_t i = 0; i < tilings.num_tilings(); ++i) | |
318 VerifyAllTilesExistAndHavePile(tilings.tiling_at(i), active_pile.get()); | |
319 } | |
320 | |
321 TEST_F(PictureLayerImplTest, clonePartialInvalidation) { | |
322 gfx::Size tile_size(100, 100); | |
323 gfx::Size layer_bounds(400, 400); | |
324 gfx::Rect layer_invalidation(150, 200, 30, 180); | |
325 | |
326 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
327 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
328 scoped_refptr<TestablePicturePileImpl> active_pile = | |
329 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
330 | |
331 SetupTrees(pending_pile, active_pile); | |
332 | |
333 Region invalidation(layer_invalidation); | |
334 AddDefaultTilingsWithInvalidation(invalidation); | |
335 | |
336 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); | |
337 EXPECT_GT(tilings.num_tilings(), 0u); | |
338 for (size_t i = 0; i < tilings.num_tilings(); ++i) { | |
339 const PictureLayerTiling* tiling = tilings.tiling_at(i); | |
340 gfx::Rect content_invalidation = gfx::ToEnclosingRect(gfx::ScaleRect( | |
341 layer_invalidation, | |
342 tiling->contents_scale())); | |
343 for (PictureLayerTiling::Iterator | |
344 iter(tiling, | |
345 tiling->contents_scale(), | |
346 tiling->ContentRect(), | |
347 PictureLayerTiling::LayerDeviceAlignmentUnknown); | |
348 iter; | |
349 ++iter) { | |
350 EXPECT_TRUE(*iter); | |
351 EXPECT_FALSE(iter.geometry_rect().IsEmpty()); | |
352 if (iter.geometry_rect().Intersects(content_invalidation)) | |
353 EXPECT_EQ(pending_pile, iter->picture_pile()); | |
354 else | |
355 EXPECT_EQ(active_pile, iter->picture_pile()); | |
356 } | |
357 } | |
358 } | |
359 | |
360 TEST_F(PictureLayerImplTest, cloneFullInvalidation) { | |
361 gfx::Size tile_size(90, 80); | |
362 gfx::Size layer_bounds(300, 500); | |
363 | |
364 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
365 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
366 scoped_refptr<TestablePicturePileImpl> active_pile = | |
367 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
368 | |
369 SetupTrees(pending_pile, active_pile); | |
370 | |
371 Region invalidation((gfx::Rect(layer_bounds))); | |
372 AddDefaultTilingsWithInvalidation(invalidation); | |
373 | |
374 EXPECT_EQ(pending_layer_->tilings().num_tilings(), | |
375 active_layer_->tilings().num_tilings()); | |
376 | |
377 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); | |
378 EXPECT_GT(tilings.num_tilings(), 0u); | |
379 for (size_t i = 0; i < tilings.num_tilings(); ++i) | |
380 VerifyAllTilesExistAndHavePile(tilings.tiling_at(i), pending_pile.get()); | |
381 } | |
382 | |
383 TEST_F(PictureLayerImplTest, noInvalidationBoundsChange) { | |
384 gfx::Size tile_size(90, 80); | |
385 gfx::Size active_layer_bounds(300, 500); | |
386 gfx::Size pending_layer_bounds(400, 800); | |
387 | |
388 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
389 TestablePicturePileImpl::CreateFilledPile(tile_size, | |
390 pending_layer_bounds); | |
391 scoped_refptr<TestablePicturePileImpl> active_pile = | |
392 TestablePicturePileImpl::CreateFilledPile(tile_size, active_layer_bounds); | |
393 | |
394 SetupTrees(pending_pile, active_pile); | |
395 | |
396 Region invalidation; | |
397 AddDefaultTilingsWithInvalidation(invalidation); | |
398 | |
399 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); | |
400 EXPECT_GT(tilings.num_tilings(), 0u); | |
401 for (size_t i = 0; i < tilings.num_tilings(); ++i) { | |
402 const PictureLayerTiling* tiling = tilings.tiling_at(i); | |
403 gfx::Rect active_content_bounds = gfx::ToEnclosingRect(gfx::ScaleRect( | |
404 gfx::Rect(active_layer_bounds), | |
405 tiling->contents_scale())); | |
406 for (PictureLayerTiling::Iterator | |
407 iter(tiling, | |
408 tiling->contents_scale(), | |
409 tiling->ContentRect(), | |
410 PictureLayerTiling::LayerDeviceAlignmentUnknown); | |
411 iter; | |
412 ++iter) { | |
413 EXPECT_TRUE(*iter); | |
414 EXPECT_FALSE(iter.geometry_rect().IsEmpty()); | |
415 if (iter.geometry_rect().right() >= active_content_bounds.width() || | |
416 iter.geometry_rect().bottom() >= active_content_bounds.height()) { | |
417 EXPECT_EQ(pending_pile, iter->picture_pile()); | |
418 } else { | |
419 EXPECT_EQ(active_pile, iter->picture_pile()); | |
420 } | |
421 } | |
422 } | |
423 } | |
424 | |
425 TEST_F(PictureLayerImplTest, addTilesFromNewRecording) { | |
426 gfx::Size tile_size(400, 400); | |
427 gfx::Size layer_bounds(1300, 1900); | |
428 | |
429 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
430 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); | |
431 scoped_refptr<TestablePicturePileImpl> active_pile = | |
432 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); | |
433 | |
434 // Fill in some of active pile, but more of pending pile. | |
435 int hole_count = 0; | |
436 for (int x = 0; x < active_pile->tiling().num_tiles_x(); ++x) { | |
437 for (int y = 0; y < active_pile->tiling().num_tiles_y(); ++y) { | |
438 if ((x + y) % 2) { | |
439 pending_pile->AddRecordingAt(x, y); | |
440 active_pile->AddRecordingAt(x, y); | |
441 } else { | |
442 hole_count++; | |
443 if (hole_count % 2) | |
444 pending_pile->AddRecordingAt(x, y); | |
445 } | |
446 } | |
447 } | |
448 | |
449 SetupTrees(pending_pile, active_pile); | |
450 Region invalidation; | |
451 AddDefaultTilingsWithInvalidation(invalidation); | |
452 | |
453 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); | |
454 EXPECT_GT(tilings.num_tilings(), 0u); | |
455 for (size_t i = 0; i < tilings.num_tilings(); ++i) { | |
456 const PictureLayerTiling* tiling = tilings.tiling_at(i); | |
457 | |
458 for (PictureLayerTiling::Iterator | |
459 iter(tiling, | |
460 tiling->contents_scale(), | |
461 tiling->ContentRect(), | |
462 PictureLayerTiling::LayerDeviceAlignmentUnknown); | |
463 iter; | |
464 ++iter) { | |
465 EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty()); | |
466 // Ensure there is a recording for this tile. | |
467 gfx::Rect layer_rect = gfx::ToEnclosingRect(gfx::ScaleRect( | |
468 iter.full_tile_geometry_rect(), 1.f / tiling->contents_scale())); | |
469 layer_rect.Intersect(gfx::Rect(layer_bounds)); | |
470 | |
471 bool in_pending = pending_pile->recorded_region().Contains(layer_rect); | |
472 bool in_active = active_pile->recorded_region().Contains(layer_rect); | |
473 | |
474 if (in_pending && !in_active) | |
475 EXPECT_EQ(pending_pile, iter->picture_pile()); | |
476 else if (in_active) | |
477 EXPECT_EQ(active_pile, iter->picture_pile()); | |
478 else | |
479 EXPECT_FALSE(*iter); | |
480 } | |
481 } | |
482 } | |
483 | |
484 TEST_F(PictureLayerImplTest, ManageTilingsWithNoRecording) { | |
485 gfx::Size tile_size(400, 400); | |
486 gfx::Size layer_bounds(1300, 1900); | |
487 | |
488 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
489 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); | |
490 scoped_refptr<TestablePicturePileImpl> active_pile = | |
491 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); | |
492 | |
493 float result_scale_x, result_scale_y; | |
494 gfx::Size result_bounds; | |
495 | |
496 SetupTrees(pending_pile, active_pile); | |
497 | |
498 // These are included in the scale given to the layer. | |
499 host_impl_.SetDeviceScaleFactor(1.f); | |
500 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f); | |
501 | |
502 pending_layer_->CalculateContentsScale( | |
503 1.f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
504 | |
505 EXPECT_EQ(0u, pending_layer_->tilings().num_tilings()); | |
506 } | |
507 | |
508 TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) { | |
509 gfx::Size tile_size(400, 400); | |
510 gfx::Size layer_bounds(1300, 1900); | |
511 | |
512 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
513 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
514 scoped_refptr<TestablePicturePileImpl> active_pile = | |
515 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
516 | |
517 float result_scale_x, result_scale_y; | |
518 gfx::Size result_bounds; | |
519 | |
520 SetupTrees(pending_pile, active_pile); | |
521 EXPECT_EQ(0u, pending_layer_->tilings().num_tilings()); | |
522 | |
523 float low_res_factor = host_impl_.settings().lowResContentsScaleFactor; | |
524 EXPECT_LT(low_res_factor, 1.f); | |
525 | |
526 // These are included in the scale given to the layer. | |
527 host_impl_.SetDeviceScaleFactor(1.7f); | |
528 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f); | |
529 | |
530 pending_layer_->CalculateContentsScale( | |
531 1.3f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
532 ASSERT_EQ(2u, pending_layer_->tilings().num_tilings()); | |
533 EXPECT_FLOAT_EQ( | |
534 1.3f, | |
535 pending_layer_->tilings().tiling_at(0)->contents_scale()); | |
536 EXPECT_FLOAT_EQ( | |
537 1.3f * low_res_factor, | |
538 pending_layer_->tilings().tiling_at(1)->contents_scale()); | |
539 | |
540 // If we change the layer's CSS scale factor, then we should not get new | |
541 // tilings. | |
542 pending_layer_->CalculateContentsScale( | |
543 1.8f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
544 ASSERT_EQ(2u, pending_layer_->tilings().num_tilings()); | |
545 EXPECT_FLOAT_EQ( | |
546 1.3f, | |
547 pending_layer_->tilings().tiling_at(0)->contents_scale()); | |
548 EXPECT_FLOAT_EQ( | |
549 1.3f * low_res_factor, | |
550 pending_layer_->tilings().tiling_at(1)->contents_scale()); | |
551 | |
552 // If we change the page scale factor, then we should get new tilings. | |
553 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(2.2f, 2.2f, 2.2f); | |
554 | |
555 pending_layer_->CalculateContentsScale( | |
556 1.8f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
557 ASSERT_EQ(4u, pending_layer_->tilings().num_tilings()); | |
558 EXPECT_FLOAT_EQ( | |
559 1.8f, | |
560 pending_layer_->tilings().tiling_at(0)->contents_scale()); | |
561 EXPECT_FLOAT_EQ( | |
562 1.8f * low_res_factor, | |
563 pending_layer_->tilings().tiling_at(2)->contents_scale()); | |
564 | |
565 // If we change the device scale factor, then we should get new tilings. | |
566 host_impl_.SetDeviceScaleFactor(1.4f); | |
567 | |
568 pending_layer_->CalculateContentsScale( | |
569 1.9f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
570 ASSERT_EQ(6u, pending_layer_->tilings().num_tilings()); | |
571 EXPECT_FLOAT_EQ( | |
572 1.9f, | |
573 pending_layer_->tilings().tiling_at(0)->contents_scale()); | |
574 EXPECT_FLOAT_EQ( | |
575 1.9f * low_res_factor, | |
576 pending_layer_->tilings().tiling_at(3)->contents_scale()); | |
577 | |
578 // If we change the device scale factor, but end up at the same total scale | |
579 // factor somehow, then we don't get new tilings. | |
580 host_impl_.SetDeviceScaleFactor(2.2f); | |
581 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.4f, 1.4f, 1.4f); | |
582 | |
583 pending_layer_->CalculateContentsScale( | |
584 1.9f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
585 ASSERT_EQ(6u, pending_layer_->tilings().num_tilings()); | |
586 EXPECT_FLOAT_EQ( | |
587 1.9f, | |
588 pending_layer_->tilings().tiling_at(0)->contents_scale()); | |
589 EXPECT_FLOAT_EQ( | |
590 1.9f * low_res_factor, | |
591 pending_layer_->tilings().tiling_at(3)->contents_scale()); | |
592 } | |
593 | |
594 TEST_F(PictureLayerImplTest, CleanUpTilings) { | |
595 gfx::Size tile_size(400, 400); | |
596 gfx::Size layer_bounds(1300, 1900); | |
597 | |
598 scoped_refptr<TestablePicturePileImpl> pending_pile = | |
599 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
600 scoped_refptr<TestablePicturePileImpl> active_pile = | |
601 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
602 | |
603 float result_scale_x, result_scale_y; | |
604 gfx::Size result_bounds; | |
605 std::vector<PictureLayerTiling*> used_tilings; | |
606 | |
607 SetupTrees(pending_pile, active_pile); | |
608 EXPECT_EQ(0u, pending_layer_->tilings().num_tilings()); | |
609 | |
610 float low_res_factor = host_impl_.settings().lowResContentsScaleFactor; | |
611 EXPECT_LT(low_res_factor, 1.f); | |
612 | |
613 // These are included in the scale given to the layer. | |
614 host_impl_.SetDeviceScaleFactor(1.7f); | |
615 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f); | |
616 host_impl_.active_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f); | |
617 | |
618 SetContentsScaleOnBothLayers(1.f, false); | |
619 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); | |
620 | |
621 // We only have ideal tilings, so they aren't removed. | |
622 used_tilings.clear(); | |
623 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
624 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); | |
625 | |
626 // Changing the ideal but not creating new tilings. | |
627 SetContentsScaleOnBothLayers(1.5f, false); | |
628 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); | |
629 | |
630 // The tilings are still our target scale, so they aren't removed. | |
631 used_tilings.clear(); | |
632 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
633 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); | |
634 | |
635 // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. | |
636 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.2f, 1.2f, 1.2f); | |
637 host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.2f, 1.2f, 1.2f); | |
638 SetContentsScaleOnBothLayers(1.2f, false); | |
639 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); | |
640 EXPECT_FLOAT_EQ( | |
641 1.f, | |
642 active_layer_->tilings().tiling_at(1)->contents_scale()); | |
643 EXPECT_FLOAT_EQ( | |
644 1.f * low_res_factor, | |
645 active_layer_->tilings().tiling_at(3)->contents_scale()); | |
646 | |
647 // Mark the non-ideal tilings as used. They won't be removed. | |
648 used_tilings.clear(); | |
649 used_tilings.push_back(active_layer_->tilings().tiling_at(1)); | |
650 used_tilings.push_back(active_layer_->tilings().tiling_at(3)); | |
651 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
652 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); | |
653 | |
654 // Now move the ideal scale to 0.5. Our target stays 1.2. | |
655 SetContentsScaleOnBothLayers(0.5f, false); | |
656 | |
657 // All the tilings are between are target and the ideal, so they are not | |
658 // removed. | |
659 used_tilings.clear(); | |
660 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
661 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); | |
662 | |
663 // Now move the ideal scale to 1.0. Our target stays 1.2. | |
664 SetContentsScaleOnBothLayers(1.f, false); | |
665 | |
666 // All the tilings are between are target and the ideal, so they are not | |
667 // removed. | |
668 used_tilings.clear(); | |
669 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
670 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); | |
671 | |
672 // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2. | |
673 active_layer_->CalculateContentsScale( | |
674 1.1f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
675 | |
676 // Because the pending layer's ideal scale is still 1.0, our tilings fall | |
677 // in the range [1.0,1.2] and are kept. | |
678 used_tilings.clear(); | |
679 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
680 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); | |
681 | |
682 // Move the ideal scale on the pending layer to 1.1 as well. Our target stays | |
683 // 1.2 still. | |
684 pending_layer_->CalculateContentsScale( | |
685 1.1f, false, &result_scale_x, &result_scale_y, &result_bounds); | |
686 | |
687 // Our 1.0 tiling now falls outside the range between our ideal scale and our | |
688 // target raster scale. But it is in our used tilings set, so nothing is | |
689 // deleted. | |
690 used_tilings.clear(); | |
691 used_tilings.push_back(active_layer_->tilings().tiling_at(1)); | |
692 used_tilings.push_back(active_layer_->tilings().tiling_at(3)); | |
693 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
694 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); | |
695 | |
696 // If we remove it from our used tilings set, it is outside the range to keep | |
697 // so it is deleted. Try one tiling at a time. | |
698 used_tilings.clear(); | |
699 used_tilings.push_back(active_layer_->tilings().tiling_at(1)); | |
700 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
701 ASSERT_EQ(3u, active_layer_->tilings().num_tilings()); | |
702 used_tilings.clear(); | |
703 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); | |
704 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); | |
705 } | |
706 | |
707 } // namespace | |
708 } // namespace cc | |
OLD | NEW |