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/resources/eviction_tile_priority_queue.h" | |
6 #include "cc/resources/raster_tile_priority_queue.h" | |
7 #include "cc/resources/tile.h" | |
8 #include "cc/resources/tile_priority.h" | |
9 #include "cc/resources/tiling_set_raster_queue_all.h" | |
10 #include "cc/test/begin_frame_args_test.h" | |
11 #include "cc/test/fake_impl_proxy.h" | |
12 #include "cc/test/fake_layer_tree_host_impl.h" | |
13 #include "cc/test/fake_output_surface.h" | |
14 #include "cc/test/fake_output_surface_client.h" | |
15 #include "cc/test/fake_picture_layer_impl.h" | |
16 #include "cc/test/fake_picture_layer_tiling_client.h" | |
17 #include "cc/test/fake_picture_pile_impl.h" | |
18 #include "cc/test/fake_tile_manager.h" | |
19 #include "cc/test/impl_side_painting_settings.h" | |
20 #include "cc/test/test_shared_bitmap_manager.h" | |
21 #include "cc/test/test_task_graph_runner.h" | |
22 #include "cc/test/test_tile_priorities.h" | |
23 #include "cc/trees/layer_tree_impl.h" | |
24 #include "testing/gtest/include/gtest/gtest.h" | |
25 | |
26 namespace cc { | |
27 namespace { | |
28 | |
29 class LowResTilingsSettings : public ImplSidePaintingSettings { | |
30 public: | |
31 LowResTilingsSettings() { create_low_res_tiling = true; } | |
32 }; | |
33 | |
34 class TileManagerTilePriorityQueueTest : public testing::Test { | |
35 public: | |
36 TileManagerTilePriorityQueueTest() | |
37 : memory_limit_policy_(ALLOW_ANYTHING), | |
38 max_tiles_(10000), | |
39 ready_to_activate_(false), | |
40 id_(7), | |
41 proxy_(base::MessageLoopProxy::current()), | |
42 host_impl_(LowResTilingsSettings(), | |
43 &proxy_, | |
44 &shared_bitmap_manager_, | |
45 &task_graph_runner_) {} | |
46 | |
47 void SetTreePriority(TreePriority tree_priority) { | |
48 GlobalStateThatImpactsTilePriority state; | |
49 gfx::Size tile_size(256, 256); | |
50 | |
51 state.soft_memory_limit_in_bytes = 100 * 1000 * 1000; | |
52 state.num_resources_limit = max_tiles_; | |
53 state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2; | |
54 state.memory_limit_policy = memory_limit_policy_; | |
55 state.tree_priority = tree_priority; | |
56 | |
57 global_state_ = state; | |
58 host_impl_.resource_pool()->SetResourceUsageLimits( | |
59 state.soft_memory_limit_in_bytes, | |
60 state.soft_memory_limit_in_bytes, | |
61 state.num_resources_limit); | |
62 host_impl_.tile_manager()->SetGlobalStateForTesting(state); | |
63 } | |
64 | |
65 void SetUp() override { | |
66 InitializeRenderer(); | |
67 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES); | |
68 } | |
69 | |
70 virtual void InitializeRenderer() { | |
71 host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()); | |
72 } | |
73 | |
74 void SetupDefaultTrees(const gfx::Size& layer_bounds) { | |
75 gfx::Size tile_size(100, 100); | |
76 | |
77 scoped_refptr<FakePicturePileImpl> pending_pile = | |
78 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
79 scoped_refptr<FakePicturePileImpl> active_pile = | |
80 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
81 | |
82 SetupTrees(pending_pile, active_pile); | |
83 } | |
84 | |
85 void ActivateTree() { | |
86 host_impl_.ActivateSyncTree(); | |
87 CHECK(!host_impl_.pending_tree()); | |
88 pending_layer_ = NULL; | |
89 active_layer_ = static_cast<FakePictureLayerImpl*>( | |
90 host_impl_.active_tree()->LayerById(id_)); | |
91 } | |
92 | |
93 void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, | |
94 const gfx::Size& tile_size) { | |
95 SetupDefaultTrees(layer_bounds); | |
96 pending_layer_->set_fixed_tile_size(tile_size); | |
97 active_layer_->set_fixed_tile_size(tile_size); | |
98 } | |
99 | |
100 void SetupTrees(scoped_refptr<PicturePileImpl> pending_pile, | |
101 scoped_refptr<PicturePileImpl> active_pile) { | |
102 SetupPendingTree(active_pile); | |
103 ActivateTree(); | |
104 SetupPendingTree(pending_pile); | |
105 } | |
106 | |
107 void SetupPendingTree(scoped_refptr<PicturePileImpl> pile) { | |
108 host_impl_.CreatePendingTree(); | |
109 LayerTreeImpl* pending_tree = host_impl_.pending_tree(); | |
110 | |
111 // Steal from the recycled tree. | |
112 scoped_ptr<LayerImpl> old_pending_root = pending_tree->DetachLayerTree(); | |
113 DCHECK_IMPLIES(old_pending_root, old_pending_root->id() == id_); | |
114 | |
115 scoped_ptr<FakePictureLayerImpl> pending_layer; | |
116 if (old_pending_root) { | |
117 pending_layer.reset( | |
118 static_cast<FakePictureLayerImpl*>(old_pending_root.release())); | |
119 pending_layer->SetRasterSourceOnPending(pile, Region()); | |
120 } else { | |
121 pending_layer = | |
122 FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, pile); | |
123 pending_layer->SetDrawsContent(true); | |
124 pending_layer->SetHasRenderSurface(true); | |
125 } | |
126 // The bounds() just mirror the pile size. | |
127 pending_layer->SetBounds(pending_layer->raster_source()->GetSize()); | |
128 pending_tree->SetRootLayer(pending_layer.Pass()); | |
129 | |
130 pending_layer_ = static_cast<FakePictureLayerImpl*>( | |
131 host_impl_.pending_tree()->LayerById(id_)); | |
132 | |
133 // Add tilings/tiles for the layer. | |
134 bool update_lcd_text = false; | |
135 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); | |
136 } | |
137 | |
138 TileManager* tile_manager() { return host_impl_.tile_manager(); } | |
139 | |
140 protected: | |
141 GlobalStateThatImpactsTilePriority global_state_; | |
142 | |
143 TestSharedBitmapManager shared_bitmap_manager_; | |
144 TestTaskGraphRunner task_graph_runner_; | |
145 TileMemoryLimitPolicy memory_limit_policy_; | |
146 int max_tiles_; | |
147 bool ready_to_activate_; | |
148 int id_; | |
149 FakeImplProxy proxy_; | |
150 FakeLayerTreeHostImpl host_impl_; | |
151 FakePictureLayerImpl* pending_layer_; | |
152 FakePictureLayerImpl* active_layer_; | |
153 }; | |
154 | |
155 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) { | |
156 const gfx::Size layer_bounds(1000, 1000); | |
157 host_impl_.SetViewportSize(layer_bounds); | |
158 SetupDefaultTrees(layer_bounds); | |
159 | |
160 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( | |
161 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
162 EXPECT_FALSE(queue->IsEmpty()); | |
163 | |
164 size_t tile_count = 0; | |
165 std::set<Tile*> all_tiles; | |
166 while (!queue->IsEmpty()) { | |
167 EXPECT_TRUE(queue->Top()); | |
168 all_tiles.insert(queue->Top()); | |
169 ++tile_count; | |
170 queue->Pop(); | |
171 } | |
172 | |
173 EXPECT_EQ(tile_count, all_tiles.size()); | |
174 EXPECT_EQ(16u, tile_count); | |
175 | |
176 // Sanity check, all tiles should be visible. | |
177 std::set<Tile*> smoothness_tiles; | |
178 queue = host_impl_.BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY, | |
179 RasterTilePriorityQueue::Type::ALL); | |
180 bool had_low_res = false; | |
181 while (!queue->IsEmpty()) { | |
182 Tile* tile = queue->Top(); | |
183 EXPECT_TRUE(tile); | |
184 EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin); | |
185 EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin); | |
186 if (tile->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) | |
187 had_low_res = true; | |
188 else | |
189 smoothness_tiles.insert(tile); | |
190 queue->Pop(); | |
191 } | |
192 EXPECT_EQ(all_tiles, smoothness_tiles); | |
193 EXPECT_TRUE(had_low_res); | |
194 | |
195 // Check that everything is required for activation. | |
196 queue = host_impl_.BuildRasterQueue( | |
197 SMOOTHNESS_TAKES_PRIORITY, | |
198 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); | |
199 std::set<Tile*> required_for_activation_tiles; | |
200 while (!queue->IsEmpty()) { | |
201 Tile* tile = queue->Top(); | |
202 EXPECT_TRUE(tile->required_for_activation()); | |
203 required_for_activation_tiles.insert(tile); | |
204 queue->Pop(); | |
205 } | |
206 EXPECT_EQ(all_tiles, required_for_activation_tiles); | |
207 | |
208 // Check that everything is required for draw. | |
209 queue = host_impl_.BuildRasterQueue( | |
210 SMOOTHNESS_TAKES_PRIORITY, | |
211 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); | |
212 std::set<Tile*> required_for_draw_tiles; | |
213 while (!queue->IsEmpty()) { | |
214 Tile* tile = queue->Top(); | |
215 EXPECT_TRUE(tile->required_for_draw()); | |
216 required_for_draw_tiles.insert(tile); | |
217 queue->Pop(); | |
218 } | |
219 EXPECT_EQ(all_tiles, required_for_draw_tiles); | |
220 | |
221 Region invalidation(gfx::Rect(0, 0, 500, 500)); | |
222 | |
223 // Invalidate the pending tree. | |
224 pending_layer_->set_invalidation(invalidation); | |
225 pending_layer_->HighResTiling()->Invalidate(invalidation); | |
226 pending_layer_->LowResTiling()->Invalidate(invalidation); | |
227 | |
228 active_layer_->ResetAllTilesPriorities(); | |
229 pending_layer_->ResetAllTilesPriorities(); | |
230 | |
231 // Renew all of the tile priorities. | |
232 gfx::Rect viewport(50, 50, 100, 100); | |
233 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
234 Occlusion()); | |
235 pending_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
236 Occlusion()); | |
237 active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
238 Occlusion()); | |
239 active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
240 Occlusion()); | |
241 | |
242 // Populate all tiles directly from the tilings. | |
243 all_tiles.clear(); | |
244 std::set<Tile*> high_res_tiles; | |
245 std::vector<Tile*> pending_high_res_tiles = | |
246 pending_layer_->HighResTiling()->AllTilesForTesting(); | |
247 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) { | |
248 all_tiles.insert(pending_high_res_tiles[i]); | |
249 high_res_tiles.insert(pending_high_res_tiles[i]); | |
250 } | |
251 | |
252 std::vector<Tile*> pending_low_res_tiles = | |
253 pending_layer_->LowResTiling()->AllTilesForTesting(); | |
254 for (size_t i = 0; i < pending_low_res_tiles.size(); ++i) | |
255 all_tiles.insert(pending_low_res_tiles[i]); | |
256 | |
257 std::vector<Tile*> active_high_res_tiles = | |
258 active_layer_->HighResTiling()->AllTilesForTesting(); | |
259 for (size_t i = 0; i < active_high_res_tiles.size(); ++i) { | |
260 all_tiles.insert(active_high_res_tiles[i]); | |
261 high_res_tiles.insert(active_high_res_tiles[i]); | |
262 } | |
263 | |
264 std::vector<Tile*> active_low_res_tiles = | |
265 active_layer_->LowResTiling()->AllTilesForTesting(); | |
266 for (size_t i = 0; i < active_low_res_tiles.size(); ++i) | |
267 all_tiles.insert(active_low_res_tiles[i]); | |
268 | |
269 Tile* last_tile = NULL; | |
270 smoothness_tiles.clear(); | |
271 tile_count = 0; | |
272 size_t correct_order_tiles = 0u; | |
273 // Here we expect to get increasing ACTIVE_TREE priority_bin. | |
274 queue = host_impl_.BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY, | |
275 RasterTilePriorityQueue::Type::ALL); | |
276 std::set<Tile*> expected_required_for_draw_tiles; | |
277 std::set<Tile*> expected_required_for_activation_tiles; | |
278 while (!queue->IsEmpty()) { | |
279 Tile* tile = queue->Top(); | |
280 EXPECT_TRUE(tile); | |
281 | |
282 if (!last_tile) | |
283 last_tile = tile; | |
284 | |
285 EXPECT_LE(last_tile->priority(ACTIVE_TREE).priority_bin, | |
286 tile->priority(ACTIVE_TREE).priority_bin); | |
287 bool skip_updating_last_tile = false; | |
288 if (last_tile->priority(ACTIVE_TREE).priority_bin == | |
289 tile->priority(ACTIVE_TREE).priority_bin) { | |
290 correct_order_tiles += | |
291 last_tile->priority(ACTIVE_TREE).distance_to_visible <= | |
292 tile->priority(ACTIVE_TREE).distance_to_visible; | |
293 } else if (tile->priority(ACTIVE_TREE).priority_bin == | |
294 TilePriority::EVENTUALLY && | |
295 tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW) { | |
296 // Since we'd return pending tree now tiles before the eventually tiles on | |
297 // the active tree, update the value. | |
298 ++correct_order_tiles; | |
299 skip_updating_last_tile = true; | |
300 } | |
301 | |
302 if (tile->priority(ACTIVE_TREE).priority_bin == TilePriority::NOW && | |
303 last_tile->priority(ACTIVE_TREE).resolution != | |
304 tile->priority(ACTIVE_TREE).resolution) { | |
305 // Low resolution should come first. | |
306 EXPECT_EQ(LOW_RESOLUTION, last_tile->priority(ACTIVE_TREE).resolution); | |
307 } | |
308 | |
309 if (!skip_updating_last_tile) | |
310 last_tile = tile; | |
311 ++tile_count; | |
312 smoothness_tiles.insert(tile); | |
313 if (tile->required_for_draw()) | |
314 expected_required_for_draw_tiles.insert(tile); | |
315 if (tile->required_for_activation()) | |
316 expected_required_for_activation_tiles.insert(tile); | |
317 queue->Pop(); | |
318 } | |
319 | |
320 EXPECT_EQ(tile_count, smoothness_tiles.size()); | |
321 EXPECT_EQ(all_tiles, smoothness_tiles); | |
322 // Since we don't guarantee increasing distance due to spiral iterator, we | |
323 // should check that we're _mostly_ right. | |
324 EXPECT_GT(correct_order_tiles, 3 * tile_count / 4); | |
325 | |
326 // Check that we have consistent required_for_activation tiles. | |
327 queue = host_impl_.BuildRasterQueue( | |
328 SMOOTHNESS_TAKES_PRIORITY, | |
329 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); | |
330 required_for_activation_tiles.clear(); | |
331 while (!queue->IsEmpty()) { | |
332 Tile* tile = queue->Top(); | |
333 EXPECT_TRUE(tile->required_for_activation()); | |
334 required_for_activation_tiles.insert(tile); | |
335 queue->Pop(); | |
336 } | |
337 EXPECT_EQ(expected_required_for_activation_tiles, | |
338 required_for_activation_tiles); | |
339 EXPECT_NE(all_tiles, required_for_activation_tiles); | |
340 | |
341 // Check that we have consistent required_for_draw tiles. | |
342 queue = host_impl_.BuildRasterQueue( | |
343 SMOOTHNESS_TAKES_PRIORITY, | |
344 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); | |
345 required_for_draw_tiles.clear(); | |
346 while (!queue->IsEmpty()) { | |
347 Tile* tile = queue->Top(); | |
348 EXPECT_TRUE(tile->required_for_draw()); | |
349 required_for_draw_tiles.insert(tile); | |
350 queue->Pop(); | |
351 } | |
352 EXPECT_EQ(expected_required_for_draw_tiles, required_for_draw_tiles); | |
353 EXPECT_NE(all_tiles, required_for_draw_tiles); | |
354 | |
355 std::set<Tile*> new_content_tiles; | |
356 last_tile = NULL; | |
357 size_t increasing_distance_tiles = 0u; | |
358 // Here we expect to get increasing PENDING_TREE priority_bin. | |
359 queue = host_impl_.BuildRasterQueue(NEW_CONTENT_TAKES_PRIORITY, | |
360 RasterTilePriorityQueue::Type::ALL); | |
361 tile_count = 0; | |
362 while (!queue->IsEmpty()) { | |
363 Tile* tile = queue->Top(); | |
364 EXPECT_TRUE(tile); | |
365 | |
366 if (!last_tile) | |
367 last_tile = tile; | |
368 | |
369 EXPECT_LE(last_tile->priority(PENDING_TREE).priority_bin, | |
370 tile->priority(PENDING_TREE).priority_bin); | |
371 if (last_tile->priority(PENDING_TREE).priority_bin == | |
372 tile->priority(PENDING_TREE).priority_bin) { | |
373 increasing_distance_tiles += | |
374 last_tile->priority(PENDING_TREE).distance_to_visible <= | |
375 tile->priority(PENDING_TREE).distance_to_visible; | |
376 } | |
377 | |
378 if (tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW && | |
379 last_tile->priority(PENDING_TREE).resolution != | |
380 tile->priority(PENDING_TREE).resolution) { | |
381 // High resolution should come first. | |
382 EXPECT_EQ(HIGH_RESOLUTION, last_tile->priority(PENDING_TREE).resolution); | |
383 } | |
384 | |
385 last_tile = tile; | |
386 new_content_tiles.insert(tile); | |
387 ++tile_count; | |
388 queue->Pop(); | |
389 } | |
390 | |
391 EXPECT_EQ(tile_count, new_content_tiles.size()); | |
392 EXPECT_EQ(high_res_tiles, new_content_tiles); | |
393 // Since we don't guarantee increasing distance due to spiral iterator, we | |
394 // should check that we're _mostly_ right. | |
395 EXPECT_GE(increasing_distance_tiles, 3 * tile_count / 4); | |
396 | |
397 // Check that we have consistent required_for_activation tiles. | |
398 queue = host_impl_.BuildRasterQueue( | |
399 NEW_CONTENT_TAKES_PRIORITY, | |
400 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); | |
401 required_for_activation_tiles.clear(); | |
402 while (!queue->IsEmpty()) { | |
403 Tile* tile = queue->Top(); | |
404 EXPECT_TRUE(tile->required_for_activation()); | |
405 required_for_activation_tiles.insert(tile); | |
406 queue->Pop(); | |
407 } | |
408 EXPECT_EQ(expected_required_for_activation_tiles, | |
409 required_for_activation_tiles); | |
410 EXPECT_NE(new_content_tiles, required_for_activation_tiles); | |
411 | |
412 // Check that we have consistent required_for_draw tiles. | |
413 queue = host_impl_.BuildRasterQueue( | |
414 NEW_CONTENT_TAKES_PRIORITY, | |
415 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); | |
416 required_for_draw_tiles.clear(); | |
417 while (!queue->IsEmpty()) { | |
418 Tile* tile = queue->Top(); | |
419 EXPECT_TRUE(tile->required_for_draw()); | |
420 required_for_draw_tiles.insert(tile); | |
421 queue->Pop(); | |
422 } | |
423 EXPECT_EQ(expected_required_for_draw_tiles, required_for_draw_tiles); | |
424 EXPECT_NE(new_content_tiles, required_for_draw_tiles); | |
425 } | |
426 | |
427 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) { | |
428 const gfx::Size layer_bounds(1000, 1000); | |
429 host_impl_.SetViewportSize(gfx::Size(500, 500)); | |
430 SetupDefaultTrees(layer_bounds); | |
431 | |
432 // Use a tile's content rect as an invalidation. We should inset it a bit to | |
433 // ensure that border math doesn't invalidate neighbouring tiles. | |
434 gfx::Rect invalidation = | |
435 pending_layer_->HighResTiling()->TileAt(1, 0)->content_rect(); | |
436 invalidation.Inset(2, 2); | |
437 | |
438 pending_layer_->set_invalidation(invalidation); | |
439 pending_layer_->HighResTiling()->Invalidate(invalidation); | |
440 pending_layer_->LowResTiling()->Invalidate(invalidation); | |
441 | |
442 // Sanity checks: Tile at 0, 0 should be the same on both trees, tile at 1, 0 | |
443 // should be different. | |
444 EXPECT_TRUE(pending_layer_->HighResTiling()->TileAt(0, 0)); | |
445 EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(0, 0)); | |
446 EXPECT_EQ(pending_layer_->HighResTiling()->TileAt(0, 0), | |
447 active_layer_->HighResTiling()->TileAt(0, 0)); | |
448 EXPECT_TRUE(pending_layer_->HighResTiling()->TileAt(1, 0)); | |
449 EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(1, 0)); | |
450 EXPECT_NE(pending_layer_->HighResTiling()->TileAt(1, 0), | |
451 active_layer_->HighResTiling()->TileAt(1, 0)); | |
452 | |
453 std::set<Tile*> expected_now_tiles; | |
454 std::set<Tile*> expected_required_for_draw_tiles; | |
455 std::set<Tile*> expected_required_for_activation_tiles; | |
456 for (int i = 0; i <= 1; ++i) { | |
457 for (int j = 0; j <= 1; ++j) { | |
458 expected_now_tiles.insert(pending_layer_->HighResTiling()->TileAt(i, j)); | |
459 expected_now_tiles.insert(active_layer_->HighResTiling()->TileAt(i, j)); | |
460 | |
461 expected_required_for_activation_tiles.insert( | |
462 pending_layer_->HighResTiling()->TileAt(i, j)); | |
463 expected_required_for_draw_tiles.insert( | |
464 active_layer_->HighResTiling()->TileAt(i, j)); | |
465 } | |
466 } | |
467 // Expect 3 shared tiles and 1 unshared tile in total. | |
468 EXPECT_EQ(5u, expected_now_tiles.size()); | |
469 // Expect 4 tiles for each draw and activation, but not all the same. | |
470 EXPECT_EQ(4u, expected_required_for_activation_tiles.size()); | |
471 EXPECT_EQ(4u, expected_required_for_draw_tiles.size()); | |
472 EXPECT_NE(expected_required_for_draw_tiles, | |
473 expected_required_for_activation_tiles); | |
474 | |
475 std::set<Tile*> expected_all_tiles; | |
476 for (int i = 0; i <= 3; ++i) { | |
477 for (int j = 0; j <= 3; ++j) { | |
478 expected_all_tiles.insert(pending_layer_->HighResTiling()->TileAt(i, j)); | |
479 expected_all_tiles.insert(active_layer_->HighResTiling()->TileAt(i, j)); | |
480 } | |
481 } | |
482 // Expect 15 shared tiles and 1 unshared tile. | |
483 EXPECT_EQ(17u, expected_all_tiles.size()); | |
484 | |
485 // The actual test will now build different queues and verify that the queues | |
486 // return the same information as computed manually above. | |
487 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( | |
488 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
489 std::set<Tile*> actual_now_tiles; | |
490 std::set<Tile*> actual_all_tiles; | |
491 while (!queue->IsEmpty()) { | |
492 Tile* tile = queue->Top(); | |
493 queue->Pop(); | |
494 if (tile->combined_priority().priority_bin == TilePriority::NOW) | |
495 actual_now_tiles.insert(tile); | |
496 actual_all_tiles.insert(tile); | |
497 } | |
498 EXPECT_EQ(expected_now_tiles, actual_now_tiles); | |
499 EXPECT_EQ(expected_all_tiles, actual_all_tiles); | |
500 | |
501 queue = host_impl_.BuildRasterQueue( | |
502 SAME_PRIORITY_FOR_BOTH_TREES, | |
503 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); | |
504 std::set<Tile*> actual_required_for_draw_tiles; | |
505 while (!queue->IsEmpty()) { | |
506 Tile* tile = queue->Top(); | |
507 queue->Pop(); | |
508 actual_required_for_draw_tiles.insert(tile); | |
509 } | |
510 EXPECT_EQ(expected_required_for_draw_tiles, actual_required_for_draw_tiles); | |
511 | |
512 queue = host_impl_.BuildRasterQueue( | |
513 SAME_PRIORITY_FOR_BOTH_TREES, | |
514 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); | |
515 std::set<Tile*> actual_required_for_activation_tiles; | |
516 while (!queue->IsEmpty()) { | |
517 Tile* tile = queue->Top(); | |
518 queue->Pop(); | |
519 actual_required_for_activation_tiles.insert(tile); | |
520 } | |
521 EXPECT_EQ(expected_required_for_activation_tiles, | |
522 actual_required_for_activation_tiles); | |
523 } | |
524 | |
525 TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) { | |
526 base::TimeTicks time_ticks; | |
527 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
528 host_impl_.SetCurrentBeginFrameArgs( | |
529 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
530 | |
531 gfx::Size layer_bounds(1000, 1000); | |
532 SetupDefaultTrees(layer_bounds); | |
533 | |
534 // Create a pending child layer. | |
535 gfx::Size tile_size(256, 256); | |
536 scoped_refptr<FakePicturePileImpl> pending_pile = | |
537 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
538 scoped_ptr<FakePictureLayerImpl> pending_child = | |
539 FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), | |
540 id_ + 1, pending_pile); | |
541 FakePictureLayerImpl* pending_child_raw = pending_child.get(); | |
542 pending_child_raw->SetDrawsContent(true); | |
543 pending_layer_->AddChild(pending_child.Pass()); | |
544 | |
545 // Set a small viewport, so we have soon and eventually tiles. | |
546 host_impl_.SetViewportSize(gfx::Size(200, 200)); | |
547 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
548 host_impl_.SetCurrentBeginFrameArgs( | |
549 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
550 bool update_lcd_text = false; | |
551 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); | |
552 | |
553 host_impl_.SetRequiresHighResToDraw(); | |
554 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( | |
555 SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL)); | |
556 EXPECT_FALSE(queue->IsEmpty()); | |
557 | |
558 // Get all the tiles that are NOW or SOON and make sure they are ready to | |
559 // draw. | |
560 std::vector<Tile*> all_tiles; | |
561 while (!queue->IsEmpty()) { | |
562 Tile* tile = queue->Top(); | |
563 if (tile->combined_priority().priority_bin >= TilePriority::EVENTUALLY) | |
564 break; | |
565 | |
566 all_tiles.push_back(tile); | |
567 queue->Pop(); | |
568 } | |
569 | |
570 tile_manager()->InitializeTilesWithResourcesForTesting( | |
571 std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); | |
572 | |
573 // Ensure we can activate. | |
574 EXPECT_TRUE(tile_manager()->IsReadyToActivate()); | |
575 } | |
576 | |
577 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) { | |
578 const gfx::Size layer_bounds(1000, 1000); | |
579 host_impl_.SetViewportSize(layer_bounds); | |
580 SetupDefaultTrees(layer_bounds); | |
581 | |
582 scoped_ptr<EvictionTilePriorityQueue> empty_queue( | |
583 host_impl_.BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); | |
584 EXPECT_TRUE(empty_queue->IsEmpty()); | |
585 std::set<Tile*> all_tiles; | |
586 size_t tile_count = 0; | |
587 | |
588 scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue( | |
589 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
590 while (!raster_queue->IsEmpty()) { | |
591 ++tile_count; | |
592 EXPECT_TRUE(raster_queue->Top()); | |
593 all_tiles.insert(raster_queue->Top()); | |
594 raster_queue->Pop(); | |
595 } | |
596 | |
597 EXPECT_EQ(tile_count, all_tiles.size()); | |
598 EXPECT_EQ(16u, tile_count); | |
599 | |
600 tile_manager()->InitializeTilesWithResourcesForTesting( | |
601 std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); | |
602 | |
603 scoped_ptr<EvictionTilePriorityQueue> queue( | |
604 host_impl_.BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY)); | |
605 EXPECT_FALSE(queue->IsEmpty()); | |
606 | |
607 // Sanity check, all tiles should be visible. | |
608 std::set<Tile*> smoothness_tiles; | |
609 while (!queue->IsEmpty()) { | |
610 Tile* tile = queue->Top(); | |
611 EXPECT_TRUE(tile); | |
612 EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin); | |
613 EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin); | |
614 EXPECT_TRUE(tile->HasResource()); | |
615 smoothness_tiles.insert(tile); | |
616 queue->Pop(); | |
617 } | |
618 EXPECT_EQ(all_tiles, smoothness_tiles); | |
619 | |
620 tile_manager()->ReleaseTileResourcesForTesting( | |
621 std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); | |
622 | |
623 Region invalidation(gfx::Rect(0, 0, 500, 500)); | |
624 | |
625 // Invalidate the pending tree. | |
626 pending_layer_->set_invalidation(invalidation); | |
627 pending_layer_->HighResTiling()->Invalidate(invalidation); | |
628 pending_layer_->LowResTiling()->Invalidate(invalidation); | |
629 | |
630 active_layer_->ResetAllTilesPriorities(); | |
631 pending_layer_->ResetAllTilesPriorities(); | |
632 | |
633 // Renew all of the tile priorities. | |
634 gfx::Rect viewport(50, 50, 100, 100); | |
635 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
636 Occlusion()); | |
637 pending_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
638 Occlusion()); | |
639 active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
640 Occlusion()); | |
641 active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
642 Occlusion()); | |
643 | |
644 // Populate all tiles directly from the tilings. | |
645 all_tiles.clear(); | |
646 std::vector<Tile*> pending_high_res_tiles = | |
647 pending_layer_->HighResTiling()->AllTilesForTesting(); | |
648 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) | |
649 all_tiles.insert(pending_high_res_tiles[i]); | |
650 | |
651 std::vector<Tile*> pending_low_res_tiles = | |
652 pending_layer_->LowResTiling()->AllTilesForTesting(); | |
653 for (size_t i = 0; i < pending_low_res_tiles.size(); ++i) | |
654 all_tiles.insert(pending_low_res_tiles[i]); | |
655 | |
656 std::vector<Tile*> active_high_res_tiles = | |
657 active_layer_->HighResTiling()->AllTilesForTesting(); | |
658 for (size_t i = 0; i < active_high_res_tiles.size(); ++i) | |
659 all_tiles.insert(active_high_res_tiles[i]); | |
660 | |
661 std::vector<Tile*> active_low_res_tiles = | |
662 active_layer_->LowResTiling()->AllTilesForTesting(); | |
663 for (size_t i = 0; i < active_low_res_tiles.size(); ++i) | |
664 all_tiles.insert(active_low_res_tiles[i]); | |
665 | |
666 tile_manager()->InitializeTilesWithResourcesForTesting( | |
667 std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); | |
668 | |
669 Tile* last_tile = NULL; | |
670 smoothness_tiles.clear(); | |
671 tile_count = 0; | |
672 // Here we expect to get increasing combined priority_bin. | |
673 queue = host_impl_.BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY); | |
674 int distance_increasing = 0; | |
675 int distance_decreasing = 0; | |
676 while (!queue->IsEmpty()) { | |
677 Tile* tile = queue->Top(); | |
678 EXPECT_TRUE(tile); | |
679 EXPECT_TRUE(tile->HasResource()); | |
680 | |
681 if (!last_tile) | |
682 last_tile = tile; | |
683 | |
684 const TilePriority& last_priority = last_tile->combined_priority(); | |
685 const TilePriority& priority = tile->combined_priority(); | |
686 | |
687 EXPECT_GE(last_priority.priority_bin, priority.priority_bin); | |
688 if (last_priority.priority_bin == priority.priority_bin) { | |
689 EXPECT_LE(last_tile->required_for_activation(), | |
690 tile->required_for_activation()); | |
691 if (last_tile->required_for_activation() == | |
692 tile->required_for_activation()) { | |
693 if (last_priority.distance_to_visible >= priority.distance_to_visible) | |
694 ++distance_decreasing; | |
695 else | |
696 ++distance_increasing; | |
697 } | |
698 } | |
699 | |
700 last_tile = tile; | |
701 ++tile_count; | |
702 smoothness_tiles.insert(tile); | |
703 queue->Pop(); | |
704 } | |
705 | |
706 // Ensure that the distance is decreasing many more times than increasing. | |
707 EXPECT_EQ(3, distance_increasing); | |
708 EXPECT_EQ(17, distance_decreasing); | |
709 EXPECT_EQ(tile_count, smoothness_tiles.size()); | |
710 EXPECT_EQ(all_tiles, smoothness_tiles); | |
711 | |
712 std::set<Tile*> new_content_tiles; | |
713 last_tile = NULL; | |
714 // Again, we expect to get increasing combined priority_bin. | |
715 queue = host_impl_.BuildEvictionQueue(NEW_CONTENT_TAKES_PRIORITY); | |
716 distance_decreasing = 0; | |
717 distance_increasing = 0; | |
718 while (!queue->IsEmpty()) { | |
719 Tile* tile = queue->Top(); | |
720 EXPECT_TRUE(tile); | |
721 | |
722 if (!last_tile) | |
723 last_tile = tile; | |
724 | |
725 const TilePriority& last_priority = last_tile->combined_priority(); | |
726 const TilePriority& priority = tile->combined_priority(); | |
727 | |
728 EXPECT_GE(last_priority.priority_bin, priority.priority_bin); | |
729 if (last_priority.priority_bin == priority.priority_bin) { | |
730 EXPECT_LE(last_tile->required_for_activation(), | |
731 tile->required_for_activation()); | |
732 if (last_tile->required_for_activation() == | |
733 tile->required_for_activation()) { | |
734 if (last_priority.distance_to_visible >= priority.distance_to_visible) | |
735 ++distance_decreasing; | |
736 else | |
737 ++distance_increasing; | |
738 } | |
739 } | |
740 | |
741 last_tile = tile; | |
742 new_content_tiles.insert(tile); | |
743 queue->Pop(); | |
744 } | |
745 | |
746 // Ensure that the distance is decreasing many more times than increasing. | |
747 EXPECT_EQ(3, distance_increasing); | |
748 EXPECT_EQ(17, distance_decreasing); | |
749 EXPECT_EQ(tile_count, new_content_tiles.size()); | |
750 EXPECT_EQ(all_tiles, new_content_tiles); | |
751 } | |
752 | |
753 TEST_F(TileManagerTilePriorityQueueTest, | |
754 EvictionTilePriorityQueueWithOcclusion) { | |
755 base::TimeTicks time_ticks; | |
756 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
757 host_impl_.SetCurrentBeginFrameArgs( | |
758 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
759 | |
760 gfx::Size tile_size(102, 102); | |
761 gfx::Size layer_bounds(1000, 1000); | |
762 | |
763 host_impl_.SetViewportSize(layer_bounds); | |
764 | |
765 scoped_refptr<FakePicturePileImpl> pending_pile = | |
766 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
767 SetupPendingTree(pending_pile); | |
768 | |
769 scoped_ptr<FakePictureLayerImpl> pending_child = | |
770 FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 2, | |
771 pending_pile); | |
772 pending_layer_->AddChild(pending_child.Pass()); | |
773 | |
774 FakePictureLayerImpl* pending_child_layer = | |
775 static_cast<FakePictureLayerImpl*>(pending_layer_->children()[0]); | |
776 pending_child_layer->SetDrawsContent(true); | |
777 | |
778 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
779 host_impl_.SetCurrentBeginFrameArgs( | |
780 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
781 bool update_lcd_text = false; | |
782 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); | |
783 | |
784 ActivateTree(); | |
785 SetupPendingTree(pending_pile); | |
786 | |
787 FakePictureLayerImpl* active_child_layer = | |
788 static_cast<FakePictureLayerImpl*>(active_layer_->children()[0]); | |
789 | |
790 std::set<Tile*> all_tiles; | |
791 size_t tile_count = 0; | |
792 scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue( | |
793 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
794 while (!raster_queue->IsEmpty()) { | |
795 ++tile_count; | |
796 EXPECT_TRUE(raster_queue->Top()); | |
797 all_tiles.insert(raster_queue->Top()); | |
798 raster_queue->Pop(); | |
799 } | |
800 EXPECT_EQ(tile_count, all_tiles.size()); | |
801 EXPECT_EQ(32u, tile_count); | |
802 | |
803 pending_layer_->ResetAllTilesPriorities(); | |
804 | |
805 // Renew all of the tile priorities. | |
806 gfx::Rect viewport(layer_bounds); | |
807 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
808 Occlusion()); | |
809 pending_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
810 Occlusion()); | |
811 pending_child_layer->HighResTiling()->ComputeTilePriorityRects( | |
812 viewport, 1.0f, 1.0, Occlusion()); | |
813 pending_child_layer->LowResTiling()->ComputeTilePriorityRects( | |
814 viewport, 1.0f, 1.0, Occlusion()); | |
815 | |
816 active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
817 Occlusion()); | |
818 active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
819 Occlusion()); | |
820 active_child_layer->HighResTiling()->ComputeTilePriorityRects( | |
821 viewport, 1.0f, 1.0, Occlusion()); | |
822 active_child_layer->LowResTiling()->ComputeTilePriorityRects( | |
823 viewport, 1.0f, 1.0, Occlusion()); | |
824 | |
825 // Populate all tiles directly from the tilings. | |
826 all_tiles.clear(); | |
827 std::vector<Tile*> pending_high_res_tiles = | |
828 pending_layer_->HighResTiling()->AllTilesForTesting(); | |
829 all_tiles.insert(pending_high_res_tiles.begin(), | |
830 pending_high_res_tiles.end()); | |
831 | |
832 std::vector<Tile*> pending_low_res_tiles = | |
833 pending_layer_->LowResTiling()->AllTilesForTesting(); | |
834 all_tiles.insert(pending_low_res_tiles.begin(), pending_low_res_tiles.end()); | |
835 | |
836 // Set all tiles on the pending_child_layer as occluded on the pending tree. | |
837 std::vector<Tile*> pending_child_high_res_tiles = | |
838 pending_child_layer->HighResTiling()->AllTilesForTesting(); | |
839 pending_child_layer->HighResTiling()->SetAllTilesOccludedForTesting(); | |
840 active_child_layer->HighResTiling()->SetAllTilesOccludedForTesting(); | |
841 all_tiles.insert(pending_child_high_res_tiles.begin(), | |
842 pending_child_high_res_tiles.end()); | |
843 | |
844 std::vector<Tile*> pending_child_low_res_tiles = | |
845 pending_child_layer->LowResTiling()->AllTilesForTesting(); | |
846 pending_child_layer->LowResTiling()->SetAllTilesOccludedForTesting(); | |
847 active_child_layer->LowResTiling()->SetAllTilesOccludedForTesting(); | |
848 all_tiles.insert(pending_child_low_res_tiles.begin(), | |
849 pending_child_low_res_tiles.end()); | |
850 | |
851 tile_manager()->InitializeTilesWithResourcesForTesting( | |
852 std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); | |
853 | |
854 // Verify occlusion is considered by EvictionTilePriorityQueue. | |
855 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY; | |
856 size_t occluded_count = 0u; | |
857 Tile* last_tile = NULL; | |
858 scoped_ptr<EvictionTilePriorityQueue> queue( | |
859 host_impl_.BuildEvictionQueue(tree_priority)); | |
860 while (!queue->IsEmpty()) { | |
861 Tile* tile = queue->Top(); | |
862 if (!last_tile) | |
863 last_tile = tile; | |
864 | |
865 bool tile_is_occluded = tile->is_occluded_combined(); | |
866 | |
867 // The only way we will encounter an occluded tile after an unoccluded | |
868 // tile is if the priorty bin decreased, the tile is required for | |
869 // activation, or the scale changed. | |
870 if (tile_is_occluded) { | |
871 occluded_count++; | |
872 | |
873 bool last_tile_is_occluded = last_tile->is_occluded_combined(); | |
874 if (!last_tile_is_occluded) { | |
875 TilePriority::PriorityBin tile_priority_bin = | |
876 tile->priority_for_tree_priority(tree_priority).priority_bin; | |
877 TilePriority::PriorityBin last_tile_priority_bin = | |
878 last_tile->priority_for_tree_priority(tree_priority).priority_bin; | |
879 | |
880 EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) || | |
881 tile->required_for_activation() || | |
882 (tile->contents_scale() != last_tile->contents_scale())); | |
883 } | |
884 } | |
885 last_tile = tile; | |
886 queue->Pop(); | |
887 } | |
888 size_t expected_occluded_count = | |
889 pending_child_high_res_tiles.size() + pending_child_low_res_tiles.size(); | |
890 EXPECT_EQ(expected_occluded_count, occluded_count); | |
891 } | |
892 | |
893 TEST_F(TileManagerTilePriorityQueueTest, | |
894 EvictionTilePriorityQueueWithTransparentLayer) { | |
895 base::TimeTicks time_ticks; | |
896 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
897 host_impl_.SetCurrentBeginFrameArgs( | |
898 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
899 | |
900 gfx::Size tile_size(102, 102); | |
901 gfx::Size layer_bounds(1000, 1000); | |
902 | |
903 scoped_refptr<FakePicturePileImpl> pending_pile = | |
904 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); | |
905 SetupPendingTree(pending_pile); | |
906 | |
907 scoped_ptr<FakePictureLayerImpl> pending_child = | |
908 FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 2, | |
909 pending_pile); | |
910 FakePictureLayerImpl* pending_child_layer = pending_child.get(); | |
911 pending_layer_->AddChild(pending_child.Pass()); | |
912 | |
913 // Create a fully transparent child layer so that its tile priorities are not | |
914 // considered to be valid. | |
915 pending_child_layer->SetDrawsContent(true); | |
916 | |
917 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
918 host_impl_.SetCurrentBeginFrameArgs( | |
919 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
920 bool update_lcd_text = false; | |
921 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); | |
922 | |
923 pending_child_layer->SetOpacity(0.0); | |
924 | |
925 time_ticks += base::TimeDelta::FromMilliseconds(1); | |
926 host_impl_.SetCurrentBeginFrameArgs( | |
927 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks)); | |
928 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text); | |
929 | |
930 // Renew all of the tile priorities. | |
931 gfx::Rect viewport(layer_bounds); | |
932 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
933 Occlusion()); | |
934 pending_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0, | |
935 Occlusion()); | |
936 pending_child_layer->HighResTiling()->ComputeTilePriorityRects( | |
937 viewport, 1.0f, 1.0, Occlusion()); | |
938 pending_child_layer->LowResTiling()->ComputeTilePriorityRects( | |
939 viewport, 1.0f, 1.0, Occlusion()); | |
940 | |
941 // Populate all tiles directly from the tilings. | |
942 std::set<Tile*> all_pending_tiles; | |
943 std::vector<Tile*> pending_high_res_tiles = | |
944 pending_layer_->HighResTiling()->AllTilesForTesting(); | |
945 all_pending_tiles.insert(pending_high_res_tiles.begin(), | |
946 pending_high_res_tiles.end()); | |
947 EXPECT_EQ(16u, pending_high_res_tiles.size()); | |
948 | |
949 std::vector<Tile*> pending_low_res_tiles = | |
950 pending_layer_->LowResTiling()->AllTilesForTesting(); | |
951 all_pending_tiles.insert(pending_low_res_tiles.begin(), | |
952 pending_low_res_tiles.end()); | |
953 EXPECT_EQ(1u, pending_low_res_tiles.size()); | |
954 | |
955 std::set<Tile*> all_pending_child_tiles; | |
956 std::vector<Tile*> pending_child_high_res_tiles = | |
957 pending_child_layer->HighResTiling()->AllTilesForTesting(); | |
958 all_pending_child_tiles.insert(pending_child_high_res_tiles.begin(), | |
959 pending_child_high_res_tiles.end()); | |
960 EXPECT_EQ(16u, pending_child_high_res_tiles.size()); | |
961 | |
962 std::vector<Tile*> pending_child_low_res_tiles = | |
963 pending_child_layer->LowResTiling()->AllTilesForTesting(); | |
964 all_pending_child_tiles.insert(pending_child_low_res_tiles.begin(), | |
965 pending_child_low_res_tiles.end()); | |
966 EXPECT_EQ(1u, pending_child_low_res_tiles.size()); | |
967 | |
968 std::set<Tile*> all_tiles = all_pending_tiles; | |
969 all_tiles.insert(all_pending_child_tiles.begin(), | |
970 all_pending_child_tiles.end()); | |
971 | |
972 tile_manager()->InitializeTilesWithResourcesForTesting( | |
973 std::vector<Tile*>(all_tiles.begin(), all_tiles.end())); | |
974 | |
975 EXPECT_TRUE(pending_layer_->HasValidTilePriorities()); | |
976 EXPECT_FALSE(pending_child_layer->HasValidTilePriorities()); | |
977 | |
978 // Verify that eviction queue returns tiles also from layers without valid | |
979 // tile priorities and that the tile priority bin of those tiles is (at most) | |
980 // EVENTUALLY. | |
981 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY; | |
982 std::set<Tile*> new_content_tiles; | |
983 size_t tile_count = 0; | |
984 scoped_ptr<EvictionTilePriorityQueue> queue( | |
985 host_impl_.BuildEvictionQueue(tree_priority)); | |
986 while (!queue->IsEmpty()) { | |
987 Tile* tile = queue->Top(); | |
988 const TilePriority& pending_priority = tile->priority(PENDING_TREE); | |
989 EXPECT_NE(std::numeric_limits<float>::infinity(), | |
990 pending_priority.distance_to_visible); | |
991 if (all_pending_child_tiles.find(tile) != all_pending_child_tiles.end()) | |
992 EXPECT_EQ(TilePriority::EVENTUALLY, pending_priority.priority_bin); | |
993 else | |
994 EXPECT_EQ(TilePriority::NOW, pending_priority.priority_bin); | |
995 new_content_tiles.insert(tile); | |
996 ++tile_count; | |
997 queue->Pop(); | |
998 } | |
999 EXPECT_EQ(tile_count, new_content_tiles.size()); | |
1000 EXPECT_EQ(all_tiles, new_content_tiles); | |
1001 } | |
1002 | |
1003 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) { | |
1004 const gfx::Size layer_bounds(1000, 1000); | |
1005 host_impl_.SetViewportSize(layer_bounds); | |
1006 SetupDefaultTrees(layer_bounds); | |
1007 | |
1008 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( | |
1009 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
1010 EXPECT_FALSE(queue->IsEmpty()); | |
1011 | |
1012 size_t tile_count = 0; | |
1013 std::set<Tile*> all_tiles; | |
1014 while (!queue->IsEmpty()) { | |
1015 EXPECT_TRUE(queue->Top()); | |
1016 all_tiles.insert(queue->Top()); | |
1017 ++tile_count; | |
1018 queue->Pop(); | |
1019 } | |
1020 | |
1021 EXPECT_EQ(tile_count, all_tiles.size()); | |
1022 EXPECT_EQ(16u, tile_count); | |
1023 | |
1024 for (int i = 1; i < 10; ++i) { | |
1025 scoped_ptr<FakePictureLayerImpl> pending_layer = | |
1026 FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i); | |
1027 pending_layer->SetDrawsContent(true); | |
1028 pending_layer->set_has_valid_tile_priorities(true); | |
1029 pending_layer_->AddChild(pending_layer.Pass()); | |
1030 } | |
1031 | |
1032 queue = host_impl_.BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, | |
1033 RasterTilePriorityQueue::Type::ALL); | |
1034 EXPECT_FALSE(queue->IsEmpty()); | |
1035 | |
1036 tile_count = 0; | |
1037 all_tiles.clear(); | |
1038 while (!queue->IsEmpty()) { | |
1039 EXPECT_TRUE(queue->Top()); | |
1040 all_tiles.insert(queue->Top()); | |
1041 ++tile_count; | |
1042 queue->Pop(); | |
1043 } | |
1044 EXPECT_EQ(tile_count, all_tiles.size()); | |
1045 EXPECT_EQ(16u, tile_count); | |
1046 } | |
1047 | |
1048 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) { | |
1049 const gfx::Size layer_bounds(1000, 1000); | |
1050 host_impl_.SetViewportSize(layer_bounds); | |
1051 SetupDefaultTrees(layer_bounds); | |
1052 | |
1053 scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue( | |
1054 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
1055 EXPECT_FALSE(raster_queue->IsEmpty()); | |
1056 | |
1057 size_t tile_count = 0; | |
1058 std::set<Tile*> all_tiles; | |
1059 while (!raster_queue->IsEmpty()) { | |
1060 EXPECT_TRUE(raster_queue->Top()); | |
1061 all_tiles.insert(raster_queue->Top()); | |
1062 ++tile_count; | |
1063 raster_queue->Pop(); | |
1064 } | |
1065 EXPECT_EQ(tile_count, all_tiles.size()); | |
1066 EXPECT_EQ(16u, tile_count); | |
1067 | |
1068 std::vector<Tile*> tiles(all_tiles.begin(), all_tiles.end()); | |
1069 host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles); | |
1070 | |
1071 for (int i = 1; i < 10; ++i) { | |
1072 scoped_ptr<FakePictureLayerImpl> pending_layer = | |
1073 FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i); | |
1074 pending_layer->SetDrawsContent(true); | |
1075 pending_layer->set_has_valid_tile_priorities(true); | |
1076 pending_layer_->AddChild(pending_layer.Pass()); | |
1077 } | |
1078 | |
1079 scoped_ptr<EvictionTilePriorityQueue> queue( | |
1080 host_impl_.BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); | |
1081 EXPECT_FALSE(queue->IsEmpty()); | |
1082 | |
1083 tile_count = 0; | |
1084 all_tiles.clear(); | |
1085 while (!queue->IsEmpty()) { | |
1086 EXPECT_TRUE(queue->Top()); | |
1087 all_tiles.insert(queue->Top()); | |
1088 ++tile_count; | |
1089 queue->Pop(); | |
1090 } | |
1091 EXPECT_EQ(tile_count, all_tiles.size()); | |
1092 EXPECT_EQ(16u, tile_count); | |
1093 } | |
1094 | |
1095 TEST_F(TileManagerTilePriorityQueueTest, | |
1096 RasterTilePriorityQueueStaticViewport) { | |
1097 FakePictureLayerTilingClient client; | |
1098 | |
1099 gfx::Rect viewport(50, 50, 500, 500); | |
1100 gfx::Size layer_bounds(1600, 1600); | |
1101 | |
1102 float inset = PictureLayerTiling::CalculateSoonBorderDistance(viewport, 1.0f); | |
1103 gfx::Rect soon_rect = viewport; | |
1104 soon_rect.Inset(-inset, -inset); | |
1105 | |
1106 client.SetTileSize(gfx::Size(30, 30)); | |
1107 client.set_tree(ACTIVE_TREE); | |
1108 LayerTreeSettings settings; | |
1109 settings.max_tiles_for_interest_area = 10000; | |
1110 | |
1111 scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( | |
1112 &client, settings.max_tiles_for_interest_area, | |
1113 settings.skewport_target_time_in_seconds, | |
1114 settings.skewport_extrapolation_limit_in_content_pixels); | |
1115 | |
1116 scoped_refptr<FakePicturePileImpl> pile = | |
1117 FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds); | |
1118 PictureLayerTiling* tiling = tiling_set->AddTiling(1.0f, pile); | |
1119 tiling->set_resolution(HIGH_RESOLUTION); | |
1120 | |
1121 tiling_set->UpdateTilePriorities(viewport, 1.0f, 1.0, Occlusion(), true); | |
1122 std::vector<Tile*> all_tiles = tiling->AllTilesForTesting(); | |
1123 // Sanity check. | |
1124 EXPECT_EQ(3364u, all_tiles.size()); | |
1125 | |
1126 // The explanation of each iteration is as follows: | |
1127 // 1. First iteration tests that we can get all of the tiles correctly. | |
1128 // 2. Second iteration ensures that we can get all of the tiles again (first | |
1129 // iteration didn't change any tiles), as well set all tiles to be ready to | |
1130 // draw. | |
1131 // 3. Third iteration ensures that no tiles are returned, since they were all | |
1132 // marked as ready to draw. | |
1133 for (int i = 0; i < 3; ++i) { | |
1134 scoped_ptr<TilingSetRasterQueueAll> queue( | |
1135 new TilingSetRasterQueueAll(tiling_set.get(), false)); | |
1136 | |
1137 // There are 3 bins in TilePriority. | |
1138 bool have_tiles[3] = {}; | |
1139 | |
1140 // On the third iteration, we should get no tiles since everything was | |
1141 // marked as ready to draw. | |
1142 if (i == 2) { | |
1143 EXPECT_TRUE(queue->IsEmpty()); | |
1144 continue; | |
1145 } | |
1146 | |
1147 EXPECT_FALSE(queue->IsEmpty()); | |
1148 std::set<Tile*> unique_tiles; | |
1149 unique_tiles.insert(queue->Top()); | |
1150 Tile* last_tile = queue->Top(); | |
1151 have_tiles[last_tile->priority(ACTIVE_TREE).priority_bin] = true; | |
1152 | |
1153 // On the second iteration, mark everything as ready to draw (solid color). | |
1154 if (i == 1) { | |
1155 TileDrawInfo& draw_info = last_tile->draw_info(); | |
1156 draw_info.SetSolidColorForTesting(SK_ColorRED); | |
1157 } | |
1158 queue->Pop(); | |
1159 int eventually_bin_order_correct_count = 0; | |
1160 int eventually_bin_order_incorrect_count = 0; | |
1161 while (!queue->IsEmpty()) { | |
1162 Tile* new_tile = queue->Top(); | |
1163 queue->Pop(); | |
1164 unique_tiles.insert(new_tile); | |
1165 | |
1166 TilePriority last_priority = last_tile->priority(ACTIVE_TREE); | |
1167 TilePriority new_priority = new_tile->priority(ACTIVE_TREE); | |
1168 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin); | |
1169 if (last_priority.priority_bin == new_priority.priority_bin) { | |
1170 if (last_priority.priority_bin == TilePriority::EVENTUALLY) { | |
1171 bool order_correct = last_priority.distance_to_visible <= | |
1172 new_priority.distance_to_visible; | |
1173 eventually_bin_order_correct_count += order_correct; | |
1174 eventually_bin_order_incorrect_count += !order_correct; | |
1175 } else if (!soon_rect.Intersects(new_tile->content_rect()) && | |
1176 !soon_rect.Intersects(last_tile->content_rect())) { | |
1177 EXPECT_LE(last_priority.distance_to_visible, | |
1178 new_priority.distance_to_visible); | |
1179 EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin); | |
1180 } else if (new_priority.distance_to_visible > 0.f) { | |
1181 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin); | |
1182 } | |
1183 } | |
1184 have_tiles[new_priority.priority_bin] = true; | |
1185 | |
1186 last_tile = new_tile; | |
1187 | |
1188 // On the second iteration, mark everything as ready to draw (solid | |
1189 // color). | |
1190 if (i == 1) { | |
1191 TileDrawInfo& draw_info = last_tile->draw_info(); | |
1192 draw_info.SetSolidColorForTesting(SK_ColorRED); | |
1193 } | |
1194 } | |
1195 | |
1196 EXPECT_GT(eventually_bin_order_correct_count, | |
1197 eventually_bin_order_incorrect_count); | |
1198 | |
1199 // We should have now and eventually tiles, as well as soon tiles from | |
1200 // the border region. | |
1201 EXPECT_TRUE(have_tiles[TilePriority::NOW]); | |
1202 EXPECT_TRUE(have_tiles[TilePriority::SOON]); | |
1203 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]); | |
1204 | |
1205 EXPECT_EQ(unique_tiles.size(), all_tiles.size()); | |
1206 } | |
1207 } | |
1208 | |
1209 TEST_F(TileManagerTilePriorityQueueTest, | |
1210 RasterTilePriorityQueueMovingViewport) { | |
1211 FakePictureLayerTilingClient client; | |
1212 | |
1213 gfx::Rect viewport(50, 0, 100, 100); | |
1214 gfx::Rect moved_viewport(50, 0, 100, 500); | |
1215 gfx::Size layer_bounds(1000, 1000); | |
1216 | |
1217 client.SetTileSize(gfx::Size(30, 30)); | |
1218 client.set_tree(ACTIVE_TREE); | |
1219 LayerTreeSettings settings; | |
1220 settings.max_tiles_for_interest_area = 10000; | |
1221 | |
1222 scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( | |
1223 &client, settings.max_tiles_for_interest_area, | |
1224 settings.skewport_target_time_in_seconds, | |
1225 settings.skewport_extrapolation_limit_in_content_pixels); | |
1226 | |
1227 scoped_refptr<FakePicturePileImpl> pile = | |
1228 FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds); | |
1229 PictureLayerTiling* tiling = tiling_set->AddTiling(1.0f, pile); | |
1230 tiling->set_resolution(HIGH_RESOLUTION); | |
1231 | |
1232 tiling_set->UpdateTilePriorities(viewport, 1.0f, 1.0, Occlusion(), true); | |
1233 tiling_set->UpdateTilePriorities(moved_viewport, 1.0f, 2.0, Occlusion(), | |
1234 true); | |
1235 | |
1236 float inset = | |
1237 PictureLayerTiling::CalculateSoonBorderDistance(moved_viewport, 1.0f); | |
1238 gfx::Rect soon_rect = moved_viewport; | |
1239 soon_rect.Inset(-inset, -inset); | |
1240 | |
1241 // There are 3 bins in TilePriority. | |
1242 bool have_tiles[3] = {}; | |
1243 Tile* last_tile = NULL; | |
1244 int eventually_bin_order_correct_count = 0; | |
1245 int eventually_bin_order_incorrect_count = 0; | |
1246 scoped_ptr<TilingSetRasterQueueAll> queue( | |
1247 new TilingSetRasterQueueAll(tiling_set.get(), false)); | |
1248 for (; !queue->IsEmpty(); queue->Pop()) { | |
1249 if (!last_tile) | |
1250 last_tile = queue->Top(); | |
1251 | |
1252 Tile* new_tile = queue->Top(); | |
1253 | |
1254 TilePriority last_priority = last_tile->priority(ACTIVE_TREE); | |
1255 TilePriority new_priority = new_tile->priority(ACTIVE_TREE); | |
1256 | |
1257 have_tiles[new_priority.priority_bin] = true; | |
1258 | |
1259 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin); | |
1260 if (last_priority.priority_bin == new_priority.priority_bin) { | |
1261 if (last_priority.priority_bin == TilePriority::EVENTUALLY) { | |
1262 bool order_correct = last_priority.distance_to_visible <= | |
1263 new_priority.distance_to_visible; | |
1264 eventually_bin_order_correct_count += order_correct; | |
1265 eventually_bin_order_incorrect_count += !order_correct; | |
1266 } else if (!soon_rect.Intersects(new_tile->content_rect()) && | |
1267 !soon_rect.Intersects(last_tile->content_rect())) { | |
1268 EXPECT_LE(last_priority.distance_to_visible, | |
1269 new_priority.distance_to_visible); | |
1270 } else if (new_priority.distance_to_visible > 0.f) { | |
1271 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin); | |
1272 } | |
1273 } | |
1274 last_tile = new_tile; | |
1275 } | |
1276 | |
1277 EXPECT_GT(eventually_bin_order_correct_count, | |
1278 eventually_bin_order_incorrect_count); | |
1279 | |
1280 EXPECT_TRUE(have_tiles[TilePriority::NOW]); | |
1281 EXPECT_TRUE(have_tiles[TilePriority::SOON]); | |
1282 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]); | |
1283 } | |
1284 | |
1285 TEST_F(TileManagerTilePriorityQueueTest, SetIsLikelyToRequireADraw) { | |
1286 const gfx::Size layer_bounds(1000, 1000); | |
1287 host_impl_.SetViewportSize(layer_bounds); | |
1288 SetupDefaultTrees(layer_bounds); | |
1289 | |
1290 // Verify that the queue has a required for draw tile at Top. | |
1291 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( | |
1292 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
1293 EXPECT_FALSE(queue->IsEmpty()); | |
1294 EXPECT_TRUE(queue->Top()->required_for_draw()); | |
1295 | |
1296 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); | |
1297 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); | |
1298 EXPECT_TRUE(host_impl_.is_likely_to_require_a_draw()); | |
1299 } | |
1300 | |
1301 TEST_F(TileManagerTilePriorityQueueTest, | |
1302 NoSetIsLikelyToRequireADrawOnZeroMemoryBudget) { | |
1303 const gfx::Size layer_bounds(1000, 1000); | |
1304 host_impl_.SetViewportSize(layer_bounds); | |
1305 SetupDefaultTrees(layer_bounds); | |
1306 | |
1307 // Verify that the queue has a required for draw tile at Top. | |
1308 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue( | |
1309 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL)); | |
1310 EXPECT_FALSE(queue->IsEmpty()); | |
1311 EXPECT_TRUE(queue->Top()->required_for_draw()); | |
1312 | |
1313 ManagedMemoryPolicy policy = host_impl_.ActualManagedMemoryPolicy(); | |
1314 policy.bytes_limit_when_visible = 0; | |
1315 host_impl_.SetMemoryPolicy(policy); | |
1316 | |
1317 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); | |
1318 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state()); | |
1319 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw()); | |
1320 } | |
1321 | |
1322 } // namespace | |
1323 } // namespace cc | |
OLD | NEW |