Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / cc / tiles / tile_manager_unittest.cc
blobacae67d07f9e9fc066b6cc5de9bda5d8038579d9
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.
5 #include "base/run_loop.h"
6 #include "base/thread_task_runner_handle.h"
7 #include "cc/playback/display_list_raster_source.h"
8 #include "cc/playback/display_list_recording_source.h"
9 #include "cc/resources/resource_pool.h"
10 #include "cc/test/begin_frame_args_test.h"
11 #include "cc/test/fake_display_list_recording_source.h"
12 #include "cc/test/fake_impl_proxy.h"
13 #include "cc/test/fake_layer_tree_host_impl.h"
14 #include "cc/test/fake_output_surface.h"
15 #include "cc/test/fake_output_surface_client.h"
16 #include "cc/test/fake_picture_layer_impl.h"
17 #include "cc/test/fake_picture_layer_tiling_client.h"
18 #include "cc/test/fake_picture_pile_impl.h"
19 #include "cc/test/fake_tile_manager.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/tiles/eviction_tile_priority_queue.h"
24 #include "cc/tiles/raster_tile_priority_queue.h"
25 #include "cc/tiles/tile.h"
26 #include "cc/tiles/tile_priority.h"
27 #include "cc/tiles/tiling_set_raster_queue_all.h"
28 #include "cc/trees/layer_tree_impl.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
32 namespace cc {
33 namespace {
35 class LowResTilingsSettings : public LayerTreeSettings {
36 public:
37 LowResTilingsSettings() { create_low_res_tiling = true; }
40 class TileManagerTilePriorityQueueTest : public testing::Test {
41 public:
42 TileManagerTilePriorityQueueTest()
43 : memory_limit_policy_(ALLOW_ANYTHING),
44 max_tiles_(10000),
45 ready_to_activate_(false),
46 id_(7),
47 proxy_(base::ThreadTaskRunnerHandle::Get()),
48 host_impl_(LowResTilingsSettings(),
49 &proxy_,
50 &shared_bitmap_manager_,
51 &task_graph_runner_) {}
53 void SetTreePriority(TreePriority tree_priority) {
54 GlobalStateThatImpactsTilePriority state;
55 gfx::Size tile_size(256, 256);
57 state.soft_memory_limit_in_bytes = 100 * 1000 * 1000;
58 state.num_resources_limit = max_tiles_;
59 state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2;
60 state.memory_limit_policy = memory_limit_policy_;
61 state.tree_priority = tree_priority;
63 global_state_ = state;
64 host_impl_.resource_pool()->SetResourceUsageLimits(
65 state.soft_memory_limit_in_bytes,
66 state.num_resources_limit);
67 host_impl_.tile_manager()->SetGlobalStateForTesting(state);
70 void SetUp() override {
71 InitializeRenderer();
72 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
75 virtual void InitializeRenderer() {
76 host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
79 void SetupDefaultTrees(const gfx::Size& layer_bounds) {
80 gfx::Size tile_size(100, 100);
82 scoped_refptr<FakePicturePileImpl> pending_pile =
83 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
84 scoped_refptr<FakePicturePileImpl> active_pile =
85 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
87 SetupTrees(pending_pile, active_pile);
90 // This matches picture_layer_impl_unittest's ActivateTree.
91 void ActivateTree() {
92 host_impl_.ActivateSyncTree();
93 CHECK(!host_impl_.pending_tree());
94 pending_layer_ = NULL;
95 active_layer_ = static_cast<FakePictureLayerImpl*>(
96 host_impl_.active_tree()->LayerById(id_));
97 bool update_lcd_text = false;
98 host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text);
101 void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds,
102 const gfx::Size& tile_size) {
103 SetupDefaultTrees(layer_bounds);
104 pending_layer_->set_fixed_tile_size(tile_size);
105 active_layer_->set_fixed_tile_size(tile_size);
108 void SetupTrees(scoped_refptr<PicturePileImpl> pending_pile,
109 scoped_refptr<PicturePileImpl> active_pile) {
110 SetupPendingTree(active_pile);
111 ActivateTree();
112 SetupPendingTree(pending_pile);
115 void SetupPendingTree(scoped_refptr<RasterSource> pile) {
116 host_impl_.CreatePendingTree();
117 LayerTreeImpl* pending_tree = host_impl_.pending_tree();
119 // Steal from the recycled tree.
120 scoped_ptr<LayerImpl> old_pending_root = pending_tree->DetachLayerTree();
121 DCHECK_IMPLIES(old_pending_root, old_pending_root->id() == id_);
123 scoped_ptr<FakePictureLayerImpl> pending_layer;
124 if (old_pending_root) {
125 pending_layer.reset(
126 static_cast<FakePictureLayerImpl*>(old_pending_root.release()));
127 pending_layer->SetRasterSourceOnPending(pile, Region());
128 } else {
129 pending_layer =
130 FakePictureLayerImpl::CreateWithRasterSource(pending_tree, id_, pile);
131 pending_layer->SetDrawsContent(true);
132 pending_layer->SetHasRenderSurface(true);
134 // The bounds() just mirror the pile size.
135 pending_layer->SetBounds(pending_layer->raster_source()->GetSize());
136 pending_tree->SetRootLayer(pending_layer.Pass());
138 pending_layer_ = static_cast<FakePictureLayerImpl*>(
139 host_impl_.pending_tree()->LayerById(id_));
141 // Add tilings/tiles for the layer.
142 bool update_lcd_text = false;
143 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
146 TileManager* tile_manager() { return host_impl_.tile_manager(); }
148 protected:
149 GlobalStateThatImpactsTilePriority global_state_;
151 TestSharedBitmapManager shared_bitmap_manager_;
152 TestTaskGraphRunner task_graph_runner_;
153 TileMemoryLimitPolicy memory_limit_policy_;
154 int max_tiles_;
155 bool ready_to_activate_;
156 int id_;
157 FakeImplProxy proxy_;
158 FakeLayerTreeHostImpl host_impl_;
159 FakePictureLayerImpl* pending_layer_;
160 FakePictureLayerImpl* active_layer_;
163 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) {
164 const gfx::Size layer_bounds(1000, 1000);
165 host_impl_.SetViewportSize(layer_bounds);
166 SetupDefaultTrees(layer_bounds);
168 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
169 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
170 EXPECT_FALSE(queue->IsEmpty());
172 size_t tile_count = 0;
173 std::set<Tile*> all_tiles;
174 while (!queue->IsEmpty()) {
175 EXPECT_TRUE(queue->Top().tile());
176 all_tiles.insert(queue->Top().tile());
177 ++tile_count;
178 queue->Pop();
181 EXPECT_EQ(tile_count, all_tiles.size());
182 EXPECT_EQ(16u, tile_count);
184 // Sanity check, all tiles should be visible.
185 std::set<Tile*> smoothness_tiles;
186 queue = host_impl_.BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY,
187 RasterTilePriorityQueue::Type::ALL);
188 bool had_low_res = false;
189 while (!queue->IsEmpty()) {
190 PrioritizedTile prioritized_tile = queue->Top();
191 EXPECT_TRUE(prioritized_tile.tile());
192 EXPECT_EQ(TilePriority::NOW, prioritized_tile.priority().priority_bin);
193 if (prioritized_tile.priority().resolution == LOW_RESOLUTION)
194 had_low_res = true;
195 else
196 smoothness_tiles.insert(prioritized_tile.tile());
197 queue->Pop();
199 EXPECT_EQ(all_tiles, smoothness_tiles);
200 EXPECT_TRUE(had_low_res);
202 // Check that everything is required for activation.
203 queue = host_impl_.BuildRasterQueue(
204 SMOOTHNESS_TAKES_PRIORITY,
205 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
206 std::set<Tile*> required_for_activation_tiles;
207 while (!queue->IsEmpty()) {
208 PrioritizedTile prioritized_tile = queue->Top();
209 EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
210 required_for_activation_tiles.insert(prioritized_tile.tile());
211 queue->Pop();
213 EXPECT_EQ(all_tiles, required_for_activation_tiles);
215 // Check that everything is required for draw.
216 queue = host_impl_.BuildRasterQueue(
217 SMOOTHNESS_TAKES_PRIORITY,
218 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
219 std::set<Tile*> required_for_draw_tiles;
220 while (!queue->IsEmpty()) {
221 PrioritizedTile prioritized_tile = queue->Top();
222 EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
223 required_for_draw_tiles.insert(prioritized_tile.tile());
224 queue->Pop();
226 EXPECT_EQ(all_tiles, required_for_draw_tiles);
228 Region invalidation(gfx::Rect(0, 0, 500, 500));
230 // Invalidate the pending tree.
231 pending_layer_->set_invalidation(invalidation);
232 pending_layer_->HighResTiling()->Invalidate(invalidation);
234 // Renew all of the tile priorities.
235 gfx::Rect viewport(50, 50, 100, 100);
236 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
237 Occlusion());
238 active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
239 Occlusion());
240 active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
241 Occlusion());
243 // Populate all tiles directly from the tilings.
244 all_tiles.clear();
245 std::set<Tile*> high_res_tiles;
246 std::vector<Tile*> pending_high_res_tiles =
247 pending_layer_->HighResTiling()->AllTilesForTesting();
248 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) {
249 all_tiles.insert(pending_high_res_tiles[i]);
250 high_res_tiles.insert(pending_high_res_tiles[i]);
253 std::vector<Tile*> active_high_res_tiles =
254 active_layer_->HighResTiling()->AllTilesForTesting();
255 for (size_t i = 0; i < active_high_res_tiles.size(); ++i) {
256 all_tiles.insert(active_high_res_tiles[i]);
257 high_res_tiles.insert(active_high_res_tiles[i]);
260 std::vector<Tile*> active_low_res_tiles =
261 active_layer_->LowResTiling()->AllTilesForTesting();
262 for (size_t i = 0; i < active_low_res_tiles.size(); ++i)
263 all_tiles.insert(active_low_res_tiles[i]);
265 PrioritizedTile last_tile;
266 smoothness_tiles.clear();
267 tile_count = 0;
268 size_t correct_order_tiles = 0u;
269 // Here we expect to get increasing ACTIVE_TREE priority_bin.
270 queue = host_impl_.BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY,
271 RasterTilePriorityQueue::Type::ALL);
272 std::set<Tile*> expected_required_for_draw_tiles;
273 std::set<Tile*> expected_required_for_activation_tiles;
274 while (!queue->IsEmpty()) {
275 PrioritizedTile prioritized_tile = queue->Top();
276 EXPECT_TRUE(prioritized_tile.tile());
278 if (!last_tile.tile())
279 last_tile = prioritized_tile;
281 EXPECT_LE(last_tile.priority().priority_bin,
282 prioritized_tile.priority().priority_bin);
283 bool skip_updating_last_tile = false;
284 if (last_tile.priority().priority_bin ==
285 prioritized_tile.priority().priority_bin) {
286 correct_order_tiles += last_tile.priority().distance_to_visible <=
287 prioritized_tile.priority().distance_to_visible;
288 } else if (prioritized_tile.priority().priority_bin == TilePriority::NOW) {
289 // Since we'd return pending tree now tiles before the eventually tiles on
290 // the active tree, update the value.
291 ++correct_order_tiles;
292 skip_updating_last_tile = true;
295 if (prioritized_tile.priority().priority_bin == TilePriority::NOW &&
296 last_tile.priority().resolution !=
297 prioritized_tile.priority().resolution) {
298 // Low resolution should come first.
299 EXPECT_EQ(LOW_RESOLUTION, last_tile.priority().resolution);
302 if (!skip_updating_last_tile)
303 last_tile = prioritized_tile;
304 ++tile_count;
305 smoothness_tiles.insert(prioritized_tile.tile());
306 if (prioritized_tile.tile()->required_for_draw())
307 expected_required_for_draw_tiles.insert(prioritized_tile.tile());
308 if (prioritized_tile.tile()->required_for_activation())
309 expected_required_for_activation_tiles.insert(prioritized_tile.tile());
310 queue->Pop();
313 EXPECT_EQ(tile_count, smoothness_tiles.size());
314 EXPECT_EQ(all_tiles, smoothness_tiles);
315 // Since we don't guarantee increasing distance due to spiral iterator, we
316 // should check that we're _mostly_ right.
317 EXPECT_GT(correct_order_tiles, 3 * tile_count / 4);
319 // Check that we have consistent required_for_activation tiles.
320 queue = host_impl_.BuildRasterQueue(
321 SMOOTHNESS_TAKES_PRIORITY,
322 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
323 required_for_activation_tiles.clear();
324 while (!queue->IsEmpty()) {
325 PrioritizedTile prioritized_tile = queue->Top();
326 EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
327 required_for_activation_tiles.insert(prioritized_tile.tile());
328 queue->Pop();
330 EXPECT_EQ(expected_required_for_activation_tiles,
331 required_for_activation_tiles);
332 EXPECT_NE(all_tiles, required_for_activation_tiles);
334 // Check that we have consistent required_for_draw tiles.
335 queue = host_impl_.BuildRasterQueue(
336 SMOOTHNESS_TAKES_PRIORITY,
337 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
338 required_for_draw_tiles.clear();
339 while (!queue->IsEmpty()) {
340 PrioritizedTile prioritized_tile = queue->Top();
341 EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
342 required_for_draw_tiles.insert(prioritized_tile.tile());
343 queue->Pop();
345 EXPECT_EQ(expected_required_for_draw_tiles, required_for_draw_tiles);
346 EXPECT_NE(all_tiles, required_for_draw_tiles);
348 std::set<Tile*> new_content_tiles;
349 last_tile = PrioritizedTile();
350 size_t increasing_distance_tiles = 0u;
351 // Here we expect to get increasing PENDING_TREE priority_bin.
352 queue = host_impl_.BuildRasterQueue(NEW_CONTENT_TAKES_PRIORITY,
353 RasterTilePriorityQueue::Type::ALL);
354 tile_count = 0;
355 while (!queue->IsEmpty()) {
356 PrioritizedTile prioritized_tile = queue->Top();
357 EXPECT_TRUE(prioritized_tile.tile());
359 if (!last_tile.tile())
360 last_tile = prioritized_tile;
362 EXPECT_LE(last_tile.priority().priority_bin,
363 prioritized_tile.priority().priority_bin);
364 if (last_tile.priority().priority_bin ==
365 prioritized_tile.priority().priority_bin) {
366 increasing_distance_tiles +=
367 last_tile.priority().distance_to_visible <=
368 prioritized_tile.priority().distance_to_visible;
371 if (prioritized_tile.priority().priority_bin == TilePriority::NOW &&
372 last_tile.priority().resolution !=
373 prioritized_tile.priority().resolution) {
374 // High resolution should come first.
375 EXPECT_EQ(HIGH_RESOLUTION, last_tile.priority().resolution);
378 last_tile = prioritized_tile;
379 new_content_tiles.insert(prioritized_tile.tile());
380 ++tile_count;
381 queue->Pop();
384 EXPECT_EQ(tile_count, new_content_tiles.size());
385 EXPECT_EQ(high_res_tiles, new_content_tiles);
386 // Since we don't guarantee increasing distance due to spiral iterator, we
387 // should check that we're _mostly_ right.
388 EXPECT_GE(increasing_distance_tiles, 3 * tile_count / 4);
390 // Check that we have consistent required_for_activation tiles.
391 queue = host_impl_.BuildRasterQueue(
392 NEW_CONTENT_TAKES_PRIORITY,
393 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
394 required_for_activation_tiles.clear();
395 while (!queue->IsEmpty()) {
396 PrioritizedTile prioritized_tile = queue->Top();
397 EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
398 required_for_activation_tiles.insert(prioritized_tile.tile());
399 queue->Pop();
401 EXPECT_EQ(expected_required_for_activation_tiles,
402 required_for_activation_tiles);
403 EXPECT_NE(new_content_tiles, required_for_activation_tiles);
405 // Check that we have consistent required_for_draw tiles.
406 queue = host_impl_.BuildRasterQueue(
407 NEW_CONTENT_TAKES_PRIORITY,
408 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
409 required_for_draw_tiles.clear();
410 while (!queue->IsEmpty()) {
411 PrioritizedTile prioritized_tile = queue->Top();
412 EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
413 required_for_draw_tiles.insert(prioritized_tile.tile());
414 queue->Pop();
416 EXPECT_EQ(expected_required_for_draw_tiles, required_for_draw_tiles);
417 EXPECT_NE(new_content_tiles, required_for_draw_tiles);
420 TEST_F(TileManagerTilePriorityQueueTest,
421 RasterTilePriorityQueueHighNonIdealTilings) {
422 const gfx::Size layer_bounds(1000, 1000);
423 const gfx::Size viewport(800, 800);
424 host_impl_.SetViewportSize(viewport);
425 SetupDefaultTrees(layer_bounds);
427 pending_layer_->tilings()->AddTiling(1.5f, pending_layer_->raster_source());
428 active_layer_->tilings()->AddTiling(1.5f, active_layer_->raster_source());
429 pending_layer_->tilings()->AddTiling(1.7f, pending_layer_->raster_source());
430 active_layer_->tilings()->AddTiling(1.7f, active_layer_->raster_source());
432 pending_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0,
433 Occlusion(), true);
434 active_layer_->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0,
435 Occlusion(), true);
437 std::set<Tile*> all_expected_tiles;
438 for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
439 PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
440 if (tiling->contents_scale() == 1.f) {
441 tiling->set_resolution(HIGH_RESOLUTION);
442 const auto& all_tiles = tiling->AllTilesForTesting();
443 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
444 } else {
445 tiling->set_resolution(NON_IDEAL_RESOLUTION);
449 for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
450 PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i);
451 if (tiling->contents_scale() == 1.5f) {
452 tiling->set_resolution(HIGH_RESOLUTION);
453 const auto& all_tiles = tiling->AllTilesForTesting();
454 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
455 } else {
456 tiling->set_resolution(NON_IDEAL_RESOLUTION);
457 // Non ideal tilings with a high res pending twin have to be processed
458 // because of possible activation tiles.
459 if (tiling->contents_scale() == 1.f) {
460 tiling->UpdateAndGetAllPrioritizedTilesForTesting();
461 const auto& all_tiles = tiling->AllTilesForTesting();
462 for (auto* tile : all_tiles)
463 EXPECT_TRUE(tile->required_for_activation());
464 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
469 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
470 SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL));
471 EXPECT_FALSE(queue->IsEmpty());
473 size_t tile_count = 0;
474 std::set<Tile*> all_actual_tiles;
475 while (!queue->IsEmpty()) {
476 EXPECT_TRUE(queue->Top().tile());
477 all_actual_tiles.insert(queue->Top().tile());
478 ++tile_count;
479 queue->Pop();
482 EXPECT_EQ(tile_count, all_actual_tiles.size());
483 EXPECT_EQ(all_expected_tiles.size(), all_actual_tiles.size());
484 EXPECT_EQ(all_expected_tiles, all_actual_tiles);
487 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) {
488 const gfx::Size layer_bounds(1000, 1000);
489 host_impl_.SetViewportSize(gfx::Size(500, 500));
490 SetupDefaultTrees(layer_bounds);
492 // Use a tile's content rect as an invalidation. We should inset it a bit to
493 // ensure that border math doesn't invalidate neighbouring tiles.
494 gfx::Rect invalidation =
495 active_layer_->HighResTiling()->TileAt(1, 0)->content_rect();
496 invalidation.Inset(2, 2);
498 pending_layer_->set_invalidation(invalidation);
499 pending_layer_->HighResTiling()->Invalidate(invalidation);
500 pending_layer_->HighResTiling()->CreateMissingTilesInLiveTilesRect();
502 // Sanity checks: Tile at 0, 0 not exist on the pending tree (it's not
503 // invalidated). Tile 1, 0 should exist on both.
504 EXPECT_FALSE(pending_layer_->HighResTiling()->TileAt(0, 0));
505 EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(0, 0));
506 EXPECT_TRUE(pending_layer_->HighResTiling()->TileAt(1, 0));
507 EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(1, 0));
508 EXPECT_NE(pending_layer_->HighResTiling()->TileAt(1, 0),
509 active_layer_->HighResTiling()->TileAt(1, 0));
511 std::set<Tile*> expected_now_tiles;
512 std::set<Tile*> expected_required_for_draw_tiles;
513 std::set<Tile*> expected_required_for_activation_tiles;
514 for (int i = 0; i <= 1; ++i) {
515 for (int j = 0; j <= 1; ++j) {
516 bool have_pending_tile = false;
517 if (pending_layer_->HighResTiling()->TileAt(i, j)) {
518 expected_now_tiles.insert(
519 pending_layer_->HighResTiling()->TileAt(i, j));
520 expected_required_for_activation_tiles.insert(
521 pending_layer_->HighResTiling()->TileAt(i, j));
522 have_pending_tile = true;
524 Tile* active_tile = active_layer_->HighResTiling()->TileAt(i, j);
525 EXPECT_TRUE(active_tile);
526 expected_now_tiles.insert(active_tile);
527 expected_required_for_draw_tiles.insert(active_tile);
528 if (!have_pending_tile)
529 expected_required_for_activation_tiles.insert(active_tile);
532 // Expect 3 shared tiles and 1 unshared tile in total.
533 EXPECT_EQ(5u, expected_now_tiles.size());
534 // Expect 4 tiles for each draw and activation, but not all the same.
535 EXPECT_EQ(4u, expected_required_for_activation_tiles.size());
536 EXPECT_EQ(4u, expected_required_for_draw_tiles.size());
537 EXPECT_NE(expected_required_for_draw_tiles,
538 expected_required_for_activation_tiles);
540 std::set<Tile*> expected_all_tiles;
541 for (int i = 0; i <= 3; ++i) {
542 for (int j = 0; j <= 3; ++j) {
543 if (pending_layer_->HighResTiling()->TileAt(i, j))
544 expected_all_tiles.insert(
545 pending_layer_->HighResTiling()->TileAt(i, j));
546 EXPECT_TRUE(active_layer_->HighResTiling()->TileAt(i, j));
547 expected_all_tiles.insert(active_layer_->HighResTiling()->TileAt(i, j));
550 // Expect 15 shared tiles and 1 unshared tile.
551 EXPECT_EQ(17u, expected_all_tiles.size());
553 // The actual test will now build different queues and verify that the queues
554 // return the same information as computed manually above.
555 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
556 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
557 std::set<Tile*> actual_now_tiles;
558 std::set<Tile*> actual_all_tiles;
559 while (!queue->IsEmpty()) {
560 PrioritizedTile prioritized_tile = queue->Top();
561 queue->Pop();
562 if (prioritized_tile.priority().priority_bin == TilePriority::NOW)
563 actual_now_tiles.insert(prioritized_tile.tile());
564 actual_all_tiles.insert(prioritized_tile.tile());
566 EXPECT_EQ(expected_now_tiles, actual_now_tiles);
567 EXPECT_EQ(expected_all_tiles, actual_all_tiles);
569 queue = host_impl_.BuildRasterQueue(
570 SAME_PRIORITY_FOR_BOTH_TREES,
571 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
572 std::set<Tile*> actual_required_for_draw_tiles;
573 while (!queue->IsEmpty()) {
574 PrioritizedTile prioritized_tile = queue->Top();
575 queue->Pop();
576 actual_required_for_draw_tiles.insert(prioritized_tile.tile());
578 EXPECT_EQ(expected_required_for_draw_tiles, actual_required_for_draw_tiles);
580 queue = host_impl_.BuildRasterQueue(
581 SAME_PRIORITY_FOR_BOTH_TREES,
582 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
583 std::set<Tile*> actual_required_for_activation_tiles;
584 while (!queue->IsEmpty()) {
585 Tile* tile = queue->Top().tile();
586 queue->Pop();
587 actual_required_for_activation_tiles.insert(tile);
589 EXPECT_EQ(expected_required_for_activation_tiles,
590 actual_required_for_activation_tiles);
593 TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) {
594 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
596 gfx::Size layer_bounds(1000, 1000);
597 SetupDefaultTrees(layer_bounds);
599 // Create a pending child layer.
600 gfx::Size tile_size(256, 256);
601 scoped_refptr<FakePicturePileImpl> pending_pile =
602 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
603 scoped_ptr<FakePictureLayerImpl> pending_child =
604 FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(),
605 id_ + 1, pending_pile);
606 FakePictureLayerImpl* pending_child_raw = pending_child.get();
607 pending_child_raw->SetDrawsContent(true);
608 pending_layer_->AddChild(pending_child.Pass());
610 // Set a small viewport, so we have soon and eventually tiles.
611 host_impl_.SetViewportSize(gfx::Size(200, 200));
612 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
613 bool update_lcd_text = false;
614 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
616 host_impl_.SetRequiresHighResToDraw();
617 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
618 SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL));
619 EXPECT_FALSE(queue->IsEmpty());
621 // Get all the tiles that are NOW or SOON and make sure they are ready to
622 // draw.
623 std::vector<Tile*> all_tiles;
624 while (!queue->IsEmpty()) {
625 PrioritizedTile prioritized_tile = queue->Top();
626 if (prioritized_tile.priority().priority_bin >= TilePriority::EVENTUALLY)
627 break;
629 all_tiles.push_back(prioritized_tile.tile());
630 queue->Pop();
633 tile_manager()->InitializeTilesWithResourcesForTesting(
634 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
636 // Ensure we can activate.
637 EXPECT_TRUE(tile_manager()->IsReadyToActivate());
640 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
641 const gfx::Size layer_bounds(1000, 1000);
642 host_impl_.SetViewportSize(layer_bounds);
643 SetupDefaultTrees(layer_bounds);
644 ASSERT_TRUE(active_layer_->HighResTiling());
645 ASSERT_TRUE(active_layer_->LowResTiling());
646 ASSERT_TRUE(pending_layer_->HighResTiling());
647 EXPECT_FALSE(pending_layer_->LowResTiling());
649 scoped_ptr<EvictionTilePriorityQueue> empty_queue(
650 host_impl_.BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
651 EXPECT_TRUE(empty_queue->IsEmpty());
652 std::set<Tile*> all_tiles;
653 size_t tile_count = 0;
655 scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue(
656 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
657 while (!raster_queue->IsEmpty()) {
658 ++tile_count;
659 EXPECT_TRUE(raster_queue->Top().tile());
660 all_tiles.insert(raster_queue->Top().tile());
661 raster_queue->Pop();
664 EXPECT_EQ(tile_count, all_tiles.size());
665 EXPECT_EQ(16u, tile_count);
667 tile_manager()->InitializeTilesWithResourcesForTesting(
668 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
670 scoped_ptr<EvictionTilePriorityQueue> queue(
671 host_impl_.BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY));
672 EXPECT_FALSE(queue->IsEmpty());
674 // Sanity check, all tiles should be visible.
675 std::set<Tile*> smoothness_tiles;
676 while (!queue->IsEmpty()) {
677 PrioritizedTile prioritized_tile = queue->Top();
678 EXPECT_TRUE(prioritized_tile.tile());
679 EXPECT_EQ(TilePriority::NOW, prioritized_tile.priority().priority_bin);
680 EXPECT_TRUE(prioritized_tile.tile()->draw_info().has_resource());
681 smoothness_tiles.insert(prioritized_tile.tile());
682 queue->Pop();
684 EXPECT_EQ(all_tiles, smoothness_tiles);
686 tile_manager()->ReleaseTileResourcesForTesting(
687 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
689 Region invalidation(gfx::Rect(0, 0, 500, 500));
691 // Invalidate the pending tree.
692 pending_layer_->set_invalidation(invalidation);
693 pending_layer_->HighResTiling()->Invalidate(invalidation);
694 pending_layer_->HighResTiling()->CreateMissingTilesInLiveTilesRect();
695 EXPECT_FALSE(pending_layer_->LowResTiling());
697 // Renew all of the tile priorities.
698 gfx::Rect viewport(50, 50, 100, 100);
699 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
700 Occlusion());
701 active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
702 Occlusion());
703 active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
704 Occlusion());
706 // Populate all tiles directly from the tilings.
707 all_tiles.clear();
708 std::vector<Tile*> pending_high_res_tiles =
709 pending_layer_->HighResTiling()->AllTilesForTesting();
710 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
711 all_tiles.insert(pending_high_res_tiles[i]);
713 std::vector<Tile*> active_high_res_tiles =
714 active_layer_->HighResTiling()->AllTilesForTesting();
715 for (size_t i = 0; i < active_high_res_tiles.size(); ++i)
716 all_tiles.insert(active_high_res_tiles[i]);
718 std::vector<Tile*> active_low_res_tiles =
719 active_layer_->LowResTiling()->AllTilesForTesting();
720 for (size_t i = 0; i < active_low_res_tiles.size(); ++i)
721 all_tiles.insert(active_low_res_tiles[i]);
723 tile_manager()->InitializeTilesWithResourcesForTesting(
724 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
726 PrioritizedTile last_tile;
727 smoothness_tiles.clear();
728 tile_count = 0;
729 // Here we expect to get increasing combined priority_bin.
730 queue = host_impl_.BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY);
731 int distance_increasing = 0;
732 int distance_decreasing = 0;
733 while (!queue->IsEmpty()) {
734 PrioritizedTile prioritized_tile = queue->Top();
735 Tile* tile = prioritized_tile.tile();
736 EXPECT_TRUE(tile);
737 EXPECT_TRUE(tile->draw_info().has_resource());
739 if (!last_tile.tile())
740 last_tile = prioritized_tile;
742 const TilePriority& last_priority = last_tile.priority();
743 const TilePriority& priority = prioritized_tile.priority();
745 EXPECT_GE(last_priority.priority_bin, priority.priority_bin);
746 if (last_priority.priority_bin == priority.priority_bin) {
747 EXPECT_LE(last_tile.tile()->required_for_activation(),
748 tile->required_for_activation());
749 if (last_tile.tile()->required_for_activation() ==
750 tile->required_for_activation()) {
751 if (last_priority.distance_to_visible >= priority.distance_to_visible)
752 ++distance_decreasing;
753 else
754 ++distance_increasing;
758 last_tile = prioritized_tile;
759 ++tile_count;
760 smoothness_tiles.insert(tile);
761 queue->Pop();
764 // Ensure that the distance is decreasing many more times than increasing.
765 EXPECT_EQ(3, distance_increasing);
766 EXPECT_EQ(16, distance_decreasing);
767 EXPECT_EQ(tile_count, smoothness_tiles.size());
768 EXPECT_EQ(all_tiles, smoothness_tiles);
770 std::set<Tile*> new_content_tiles;
771 last_tile = PrioritizedTile();
772 // Again, we expect to get increasing combined priority_bin.
773 queue = host_impl_.BuildEvictionQueue(NEW_CONTENT_TAKES_PRIORITY);
774 distance_decreasing = 0;
775 distance_increasing = 0;
776 while (!queue->IsEmpty()) {
777 PrioritizedTile prioritized_tile = queue->Top();
778 Tile* tile = prioritized_tile.tile();
779 EXPECT_TRUE(tile);
781 if (!last_tile.tile())
782 last_tile = prioritized_tile;
784 const TilePriority& last_priority = last_tile.priority();
785 const TilePriority& priority = prioritized_tile.priority();
787 EXPECT_GE(last_priority.priority_bin, priority.priority_bin);
788 if (last_priority.priority_bin == priority.priority_bin) {
789 EXPECT_LE(last_tile.tile()->required_for_activation(),
790 tile->required_for_activation());
791 if (last_tile.tile()->required_for_activation() ==
792 tile->required_for_activation()) {
793 if (last_priority.distance_to_visible >= priority.distance_to_visible)
794 ++distance_decreasing;
795 else
796 ++distance_increasing;
800 last_tile = prioritized_tile;
801 new_content_tiles.insert(tile);
802 queue->Pop();
805 // Ensure that the distance is decreasing many more times than increasing.
806 EXPECT_EQ(3, distance_increasing);
807 EXPECT_EQ(16, distance_decreasing);
808 EXPECT_EQ(tile_count, new_content_tiles.size());
809 EXPECT_EQ(all_tiles, new_content_tiles);
812 TEST_F(TileManagerTilePriorityQueueTest,
813 EvictionTilePriorityQueueWithOcclusion) {
814 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
816 gfx::Size tile_size(102, 102);
817 gfx::Size layer_bounds(1000, 1000);
819 host_impl_.SetViewportSize(layer_bounds);
821 scoped_refptr<FakePicturePileImpl> pending_pile =
822 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
823 SetupPendingTree(pending_pile);
825 scoped_ptr<FakePictureLayerImpl> pending_child =
826 FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 2,
827 pending_pile);
828 pending_layer_->AddChild(pending_child.Pass());
830 FakePictureLayerImpl* pending_child_layer =
831 static_cast<FakePictureLayerImpl*>(pending_layer_->children()[0]);
832 pending_child_layer->SetDrawsContent(true);
834 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
835 bool update_lcd_text = false;
836 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
838 ActivateTree();
839 SetupPendingTree(pending_pile);
841 FakePictureLayerImpl* active_child_layer =
842 static_cast<FakePictureLayerImpl*>(active_layer_->children()[0]);
844 std::set<Tile*> all_tiles;
845 size_t tile_count = 0;
846 scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue(
847 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
848 while (!raster_queue->IsEmpty()) {
849 ++tile_count;
850 EXPECT_TRUE(raster_queue->Top().tile());
851 all_tiles.insert(raster_queue->Top().tile());
852 raster_queue->Pop();
854 EXPECT_EQ(tile_count, all_tiles.size());
855 EXPECT_EQ(32u, tile_count);
857 // Renew all of the tile priorities.
858 gfx::Rect viewport(layer_bounds);
859 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
860 Occlusion());
861 pending_child_layer->HighResTiling()->ComputeTilePriorityRects(
862 viewport, 1.0f, 1.0, Occlusion());
864 active_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
865 Occlusion());
866 active_layer_->LowResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
867 Occlusion());
868 active_child_layer->HighResTiling()->ComputeTilePriorityRects(
869 viewport, 1.0f, 1.0, Occlusion());
870 active_child_layer->LowResTiling()->ComputeTilePriorityRects(
871 viewport, 1.0f, 1.0, Occlusion());
873 // Populate all tiles directly from the tilings.
874 all_tiles.clear();
875 std::vector<Tile*> pending_high_res_tiles =
876 pending_layer_->HighResTiling()->AllTilesForTesting();
877 all_tiles.insert(pending_high_res_tiles.begin(),
878 pending_high_res_tiles.end());
880 // Set all tiles on the pending_child_layer as occluded on the pending tree.
881 std::vector<Tile*> pending_child_high_res_tiles =
882 pending_child_layer->HighResTiling()->AllTilesForTesting();
883 pending_child_layer->HighResTiling()->SetAllTilesOccludedForTesting();
884 active_child_layer->HighResTiling()->SetAllTilesOccludedForTesting();
885 active_child_layer->LowResTiling()->SetAllTilesOccludedForTesting();
887 tile_manager()->InitializeTilesWithResourcesForTesting(
888 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
890 // Verify occlusion is considered by EvictionTilePriorityQueue.
891 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY;
892 size_t occluded_count = 0u;
893 PrioritizedTile last_tile;
894 scoped_ptr<EvictionTilePriorityQueue> queue(
895 host_impl_.BuildEvictionQueue(tree_priority));
896 while (!queue->IsEmpty()) {
897 PrioritizedTile prioritized_tile = queue->Top();
898 if (!last_tile.tile())
899 last_tile = prioritized_tile;
901 bool tile_is_occluded = prioritized_tile.is_occluded();
903 // The only way we will encounter an occluded tile after an unoccluded
904 // tile is if the priorty bin decreased, the tile is required for
905 // activation, or the scale changed.
906 if (tile_is_occluded) {
907 occluded_count++;
909 bool last_tile_is_occluded = last_tile.is_occluded();
910 if (!last_tile_is_occluded) {
911 TilePriority::PriorityBin tile_priority_bin =
912 prioritized_tile.priority().priority_bin;
913 TilePriority::PriorityBin last_tile_priority_bin =
914 last_tile.priority().priority_bin;
916 EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) ||
917 prioritized_tile.tile()->required_for_activation() ||
918 (prioritized_tile.tile()->contents_scale() !=
919 last_tile.tile()->contents_scale()));
922 last_tile = prioritized_tile;
923 queue->Pop();
925 size_t expected_occluded_count = pending_child_high_res_tiles.size();
926 EXPECT_EQ(expected_occluded_count, occluded_count);
929 TEST_F(TileManagerTilePriorityQueueTest,
930 EvictionTilePriorityQueueWithTransparentLayer) {
931 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
933 gfx::Size tile_size(102, 102);
934 gfx::Size layer_bounds(1000, 1000);
936 scoped_refptr<FakePicturePileImpl> pending_pile =
937 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
938 SetupPendingTree(pending_pile);
940 scoped_ptr<FakePictureLayerImpl> pending_child =
941 FakePictureLayerImpl::CreateWithRasterSource(host_impl_.pending_tree(), 2,
942 pending_pile);
943 FakePictureLayerImpl* pending_child_layer = pending_child.get();
944 pending_layer_->AddChild(pending_child.Pass());
946 // Create a fully transparent child layer so that its tile priorities are not
947 // considered to be valid.
948 pending_child_layer->SetDrawsContent(true);
950 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
951 bool update_lcd_text = false;
952 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
954 pending_child_layer->SetOpacity(0.0);
956 host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
957 host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
959 // Renew all of the tile priorities.
960 gfx::Rect viewport(layer_bounds);
961 pending_layer_->HighResTiling()->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
962 Occlusion());
963 pending_child_layer->HighResTiling()->ComputeTilePriorityRects(
964 viewport, 1.0f, 1.0, Occlusion());
966 // Populate all tiles directly from the tilings.
967 std::set<Tile*> all_pending_tiles;
968 std::vector<Tile*> pending_high_res_tiles =
969 pending_layer_->HighResTiling()->AllTilesForTesting();
970 all_pending_tiles.insert(pending_high_res_tiles.begin(),
971 pending_high_res_tiles.end());
972 EXPECT_EQ(16u, pending_high_res_tiles.size());
974 std::set<Tile*> all_pending_child_tiles;
975 std::vector<Tile*> pending_child_high_res_tiles =
976 pending_child_layer->HighResTiling()->AllTilesForTesting();
977 all_pending_child_tiles.insert(pending_child_high_res_tiles.begin(),
978 pending_child_high_res_tiles.end());
979 EXPECT_EQ(16u, pending_child_high_res_tiles.size());
981 std::set<Tile*> all_tiles = all_pending_tiles;
982 all_tiles.insert(all_pending_child_tiles.begin(),
983 all_pending_child_tiles.end());
985 tile_manager()->InitializeTilesWithResourcesForTesting(
986 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
988 EXPECT_TRUE(pending_layer_->HasValidTilePriorities());
989 EXPECT_FALSE(pending_child_layer->HasValidTilePriorities());
991 // Verify that eviction queue returns tiles also from layers without valid
992 // tile priorities and that the tile priority bin of those tiles is (at most)
993 // EVENTUALLY.
994 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY;
995 std::set<Tile*> new_content_tiles;
996 size_t tile_count = 0;
997 scoped_ptr<EvictionTilePriorityQueue> queue(
998 host_impl_.BuildEvictionQueue(tree_priority));
999 while (!queue->IsEmpty()) {
1000 PrioritizedTile prioritized_tile = queue->Top();
1001 Tile* tile = prioritized_tile.tile();
1002 const TilePriority& pending_priority = prioritized_tile.priority();
1003 EXPECT_NE(std::numeric_limits<float>::infinity(),
1004 pending_priority.distance_to_visible);
1005 if (all_pending_child_tiles.find(tile) != all_pending_child_tiles.end())
1006 EXPECT_EQ(TilePriority::EVENTUALLY, pending_priority.priority_bin);
1007 else
1008 EXPECT_EQ(TilePriority::NOW, pending_priority.priority_bin);
1009 new_content_tiles.insert(tile);
1010 ++tile_count;
1011 queue->Pop();
1013 EXPECT_EQ(tile_count, new_content_tiles.size());
1014 EXPECT_EQ(all_tiles, new_content_tiles);
1017 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) {
1018 const gfx::Size layer_bounds(1000, 1000);
1019 host_impl_.SetViewportSize(layer_bounds);
1020 SetupDefaultTrees(layer_bounds);
1022 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
1023 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1024 EXPECT_FALSE(queue->IsEmpty());
1026 size_t tile_count = 0;
1027 std::set<Tile*> all_tiles;
1028 while (!queue->IsEmpty()) {
1029 EXPECT_TRUE(queue->Top().tile());
1030 all_tiles.insert(queue->Top().tile());
1031 ++tile_count;
1032 queue->Pop();
1035 EXPECT_EQ(tile_count, all_tiles.size());
1036 EXPECT_EQ(16u, tile_count);
1038 for (int i = 1; i < 10; ++i) {
1039 scoped_ptr<FakePictureLayerImpl> pending_layer =
1040 FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i);
1041 pending_layer->SetDrawsContent(true);
1042 pending_layer->set_has_valid_tile_priorities(true);
1043 pending_layer_->AddChild(pending_layer.Pass());
1046 queue = host_impl_.BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES,
1047 RasterTilePriorityQueue::Type::ALL);
1048 EXPECT_FALSE(queue->IsEmpty());
1050 tile_count = 0;
1051 all_tiles.clear();
1052 while (!queue->IsEmpty()) {
1053 EXPECT_TRUE(queue->Top().tile());
1054 all_tiles.insert(queue->Top().tile());
1055 ++tile_count;
1056 queue->Pop();
1058 EXPECT_EQ(tile_count, all_tiles.size());
1059 EXPECT_EQ(16u, tile_count);
1062 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) {
1063 const gfx::Size layer_bounds(1000, 1000);
1064 host_impl_.SetViewportSize(layer_bounds);
1065 SetupDefaultTrees(layer_bounds);
1067 scoped_ptr<RasterTilePriorityQueue> raster_queue(host_impl_.BuildRasterQueue(
1068 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1069 EXPECT_FALSE(raster_queue->IsEmpty());
1071 size_t tile_count = 0;
1072 std::set<Tile*> all_tiles;
1073 while (!raster_queue->IsEmpty()) {
1074 EXPECT_TRUE(raster_queue->Top().tile());
1075 all_tiles.insert(raster_queue->Top().tile());
1076 ++tile_count;
1077 raster_queue->Pop();
1079 EXPECT_EQ(tile_count, all_tiles.size());
1080 EXPECT_EQ(16u, tile_count);
1082 std::vector<Tile*> tiles(all_tiles.begin(), all_tiles.end());
1083 host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
1085 for (int i = 1; i < 10; ++i) {
1086 scoped_ptr<FakePictureLayerImpl> pending_layer =
1087 FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i);
1088 pending_layer->SetDrawsContent(true);
1089 pending_layer->set_has_valid_tile_priorities(true);
1090 pending_layer_->AddChild(pending_layer.Pass());
1093 scoped_ptr<EvictionTilePriorityQueue> queue(
1094 host_impl_.BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
1095 EXPECT_FALSE(queue->IsEmpty());
1097 tile_count = 0;
1098 all_tiles.clear();
1099 while (!queue->IsEmpty()) {
1100 EXPECT_TRUE(queue->Top().tile());
1101 all_tiles.insert(queue->Top().tile());
1102 ++tile_count;
1103 queue->Pop();
1105 EXPECT_EQ(tile_count, all_tiles.size());
1106 EXPECT_EQ(16u, tile_count);
1109 TEST_F(TileManagerTilePriorityQueueTest,
1110 RasterTilePriorityQueueStaticViewport) {
1111 FakePictureLayerTilingClient client;
1113 gfx::Rect viewport(50, 50, 500, 500);
1114 gfx::Size layer_bounds(1600, 1600);
1116 float inset = PictureLayerTiling::CalculateSoonBorderDistance(viewport, 1.0f);
1117 gfx::Rect soon_rect = viewport;
1118 soon_rect.Inset(-inset, -inset);
1120 client.SetTileSize(gfx::Size(30, 30));
1121 LayerTreeSettings settings;
1123 scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create(
1124 ACTIVE_TREE, &client, settings.tiling_interest_area_padding,
1125 settings.skewport_target_time_in_seconds,
1126 settings.skewport_extrapolation_limit_in_content_pixels);
1128 scoped_refptr<FakePicturePileImpl> pile =
1129 FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds);
1130 PictureLayerTiling* tiling = tiling_set->AddTiling(1.0f, pile);
1131 tiling->set_resolution(HIGH_RESOLUTION);
1133 tiling_set->UpdateTilePriorities(viewport, 1.0f, 1.0, Occlusion(), true);
1134 std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
1135 // Sanity check.
1136 EXPECT_EQ(3364u, all_tiles.size());
1138 // The explanation of each iteration is as follows:
1139 // 1. First iteration tests that we can get all of the tiles correctly.
1140 // 2. Second iteration ensures that we can get all of the tiles again (first
1141 // iteration didn't change any tiles), as well set all tiles to be ready to
1142 // draw.
1143 // 3. Third iteration ensures that no tiles are returned, since they were all
1144 // marked as ready to draw.
1145 for (int i = 0; i < 3; ++i) {
1146 scoped_ptr<TilingSetRasterQueueAll> queue(
1147 new TilingSetRasterQueueAll(tiling_set.get(), false));
1149 // There are 3 bins in TilePriority.
1150 bool have_tiles[3] = {};
1152 // On the third iteration, we should get no tiles since everything was
1153 // marked as ready to draw.
1154 if (i == 2) {
1155 EXPECT_TRUE(queue->IsEmpty());
1156 continue;
1159 EXPECT_FALSE(queue->IsEmpty());
1160 std::set<Tile*> unique_tiles;
1161 unique_tiles.insert(queue->Top().tile());
1162 PrioritizedTile last_tile = queue->Top();
1163 have_tiles[last_tile.priority().priority_bin] = true;
1165 // On the second iteration, mark everything as ready to draw (solid color).
1166 if (i == 1) {
1167 TileDrawInfo& draw_info = last_tile.tile()->draw_info();
1168 draw_info.SetSolidColorForTesting(SK_ColorRED);
1170 queue->Pop();
1171 int eventually_bin_order_correct_count = 0;
1172 int eventually_bin_order_incorrect_count = 0;
1173 while (!queue->IsEmpty()) {
1174 PrioritizedTile new_tile = queue->Top();
1175 queue->Pop();
1176 unique_tiles.insert(new_tile.tile());
1178 TilePriority last_priority = last_tile.priority();
1179 TilePriority new_priority = new_tile.priority();
1180 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
1181 if (last_priority.priority_bin == new_priority.priority_bin) {
1182 if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
1183 bool order_correct = last_priority.distance_to_visible <=
1184 new_priority.distance_to_visible;
1185 eventually_bin_order_correct_count += order_correct;
1186 eventually_bin_order_incorrect_count += !order_correct;
1187 } else if (!soon_rect.Intersects(new_tile.tile()->content_rect()) &&
1188 !soon_rect.Intersects(last_tile.tile()->content_rect())) {
1189 EXPECT_LE(last_priority.distance_to_visible,
1190 new_priority.distance_to_visible);
1191 EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin);
1192 } else if (new_priority.distance_to_visible > 0.f) {
1193 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1196 have_tiles[new_priority.priority_bin] = true;
1198 last_tile = new_tile;
1200 // On the second iteration, mark everything as ready to draw (solid
1201 // color).
1202 if (i == 1) {
1203 TileDrawInfo& draw_info = last_tile.tile()->draw_info();
1204 draw_info.SetSolidColorForTesting(SK_ColorRED);
1208 EXPECT_GT(eventually_bin_order_correct_count,
1209 eventually_bin_order_incorrect_count);
1211 // We should have now and eventually tiles, as well as soon tiles from
1212 // the border region.
1213 EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1214 EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1215 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1217 EXPECT_EQ(unique_tiles.size(), all_tiles.size());
1221 TEST_F(TileManagerTilePriorityQueueTest,
1222 RasterTilePriorityQueueMovingViewport) {
1223 FakePictureLayerTilingClient client;
1225 gfx::Rect viewport(50, 0, 100, 100);
1226 gfx::Rect moved_viewport(50, 0, 100, 500);
1227 gfx::Size layer_bounds(1000, 1000);
1229 client.SetTileSize(gfx::Size(30, 30));
1230 LayerTreeSettings settings;
1232 scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create(
1233 ACTIVE_TREE, &client, settings.tiling_interest_area_padding,
1234 settings.skewport_target_time_in_seconds,
1235 settings.skewport_extrapolation_limit_in_content_pixels);
1237 scoped_refptr<FakePicturePileImpl> pile =
1238 FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds);
1239 PictureLayerTiling* tiling = tiling_set->AddTiling(1.0f, pile);
1240 tiling->set_resolution(HIGH_RESOLUTION);
1242 tiling_set->UpdateTilePriorities(viewport, 1.0f, 1.0, Occlusion(), true);
1243 tiling_set->UpdateTilePriorities(moved_viewport, 1.0f, 2.0, Occlusion(),
1244 true);
1246 float inset =
1247 PictureLayerTiling::CalculateSoonBorderDistance(moved_viewport, 1.0f);
1248 gfx::Rect soon_rect = moved_viewport;
1249 soon_rect.Inset(-inset, -inset);
1251 // There are 3 bins in TilePriority.
1252 bool have_tiles[3] = {};
1253 PrioritizedTile last_tile;
1254 int eventually_bin_order_correct_count = 0;
1255 int eventually_bin_order_incorrect_count = 0;
1256 scoped_ptr<TilingSetRasterQueueAll> queue(
1257 new TilingSetRasterQueueAll(tiling_set.get(), false));
1258 for (; !queue->IsEmpty(); queue->Pop()) {
1259 if (!last_tile.tile())
1260 last_tile = queue->Top();
1262 const PrioritizedTile& new_tile = queue->Top();
1264 TilePriority last_priority = last_tile.priority();
1265 TilePriority new_priority = new_tile.priority();
1267 have_tiles[new_priority.priority_bin] = true;
1269 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
1270 if (last_priority.priority_bin == new_priority.priority_bin) {
1271 if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
1272 bool order_correct = last_priority.distance_to_visible <=
1273 new_priority.distance_to_visible;
1274 eventually_bin_order_correct_count += order_correct;
1275 eventually_bin_order_incorrect_count += !order_correct;
1276 } else if (!soon_rect.Intersects(new_tile.tile()->content_rect()) &&
1277 !soon_rect.Intersects(last_tile.tile()->content_rect())) {
1278 EXPECT_LE(last_priority.distance_to_visible,
1279 new_priority.distance_to_visible);
1280 } else if (new_priority.distance_to_visible > 0.f) {
1281 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1284 last_tile = new_tile;
1287 EXPECT_GT(eventually_bin_order_correct_count,
1288 eventually_bin_order_incorrect_count);
1290 EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1291 EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1292 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1295 TEST_F(TileManagerTilePriorityQueueTest, SetIsLikelyToRequireADraw) {
1296 const gfx::Size layer_bounds(1000, 1000);
1297 host_impl_.SetViewportSize(layer_bounds);
1298 SetupDefaultTrees(layer_bounds);
1300 // Verify that the queue has a required for draw tile at Top.
1301 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
1302 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1303 EXPECT_FALSE(queue->IsEmpty());
1304 EXPECT_TRUE(queue->Top().tile()->required_for_draw());
1306 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
1307 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
1308 EXPECT_TRUE(host_impl_.is_likely_to_require_a_draw());
1311 TEST_F(TileManagerTilePriorityQueueTest,
1312 SetIsLikelyToRequireADrawOnZeroMemoryBudget) {
1313 const gfx::Size layer_bounds(1000, 1000);
1314 host_impl_.SetViewportSize(layer_bounds);
1315 SetupDefaultTrees(layer_bounds);
1317 // Verify that the queue has a required for draw tile at Top.
1318 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
1319 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1320 EXPECT_FALSE(queue->IsEmpty());
1321 EXPECT_TRUE(queue->Top().tile()->required_for_draw());
1323 ManagedMemoryPolicy policy = host_impl_.ActualManagedMemoryPolicy();
1324 policy.bytes_limit_when_visible = 0;
1325 host_impl_.SetMemoryPolicy(policy);
1327 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
1328 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
1329 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
1332 TEST_F(TileManagerTilePriorityQueueTest,
1333 SetIsLikelyToRequireADrawOnLimitedMemoryBudget) {
1334 const gfx::Size layer_bounds(1000, 1000);
1335 host_impl_.SetViewportSize(layer_bounds);
1336 SetupDefaultTrees(layer_bounds);
1338 // Verify that the queue has a required for draw tile at Top.
1339 scoped_ptr<RasterTilePriorityQueue> queue(host_impl_.BuildRasterQueue(
1340 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1341 EXPECT_FALSE(queue->IsEmpty());
1342 EXPECT_TRUE(queue->Top().tile()->required_for_draw());
1343 EXPECT_EQ(gfx::Size(256, 256), queue->Top().tile()->desired_texture_size());
1344 EXPECT_EQ(RGBA_8888, host_impl_.resource_provider()->best_texture_format());
1346 ManagedMemoryPolicy policy = host_impl_.ActualManagedMemoryPolicy();
1347 policy.bytes_limit_when_visible = ResourceUtil::UncheckedSizeInBytes<size_t>(
1348 gfx::Size(256, 256), RGBA_8888);
1349 host_impl_.SetMemoryPolicy(policy);
1351 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
1352 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
1353 EXPECT_TRUE(host_impl_.is_likely_to_require_a_draw());
1355 Resource* resource = host_impl_.resource_pool()->AcquireResource(
1356 gfx::Size(256, 256), RGBA_8888);
1358 host_impl_.tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting();
1359 EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
1361 host_impl_.resource_pool()->ReleaseResource(resource, 0);
1364 TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) {
1365 // Verify that we use the real tile bounds when advancing phases during the
1366 // tile iteration.
1367 gfx::Size layer_bounds(1, 1);
1369 scoped_refptr<FakePicturePileImpl> pile =
1370 FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds);
1372 FakePictureLayerTilingClient pending_client;
1373 pending_client.SetTileSize(gfx::Size(64, 64));
1375 scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create(
1376 WhichTree::ACTIVE_TREE, &pending_client, 1.0f, 1.0f, 1000);
1377 pending_client.set_twin_tiling_set(tiling_set.get());
1379 auto* tiling = tiling_set->AddTiling(1.0f, pile);
1381 tiling->set_resolution(HIGH_RESOLUTION);
1382 tiling->CreateAllTilesForTesting();
1384 // The tile is (0, 0, 1, 1), create an intersecting and non-intersecting
1385 // rectangle to test the advance phase with. The tile size is (64, 64), so
1386 // both rectangles intersect the tile content size, but only one should
1387 // intersect the actual size.
1388 gfx::Rect non_intersecting_rect(2, 2, 10, 10);
1389 gfx::Rect intersecting_rect(0, 0, 10, 10);
1391 tiling->SetTilePriorityRectsForTesting(
1392 non_intersecting_rect, // Visible rect.
1393 intersecting_rect, // Skewport rect.
1394 intersecting_rect, // Soon rect.
1395 intersecting_rect); // Eventually rect.
1396 scoped_ptr<TilingSetRasterQueueAll> queue(
1397 new TilingSetRasterQueueAll(tiling_set.get(), false));
1398 EXPECT_FALSE(queue->IsEmpty());
1401 tiling->SetTilePriorityRectsForTesting(
1402 non_intersecting_rect, // Visible rect.
1403 non_intersecting_rect, // Skewport rect.
1404 intersecting_rect, // Soon rect.
1405 intersecting_rect); // Eventually rect.
1406 scoped_ptr<TilingSetRasterQueueAll> queue(
1407 new TilingSetRasterQueueAll(tiling_set.get(), false));
1408 EXPECT_FALSE(queue->IsEmpty());
1411 tiling->SetTilePriorityRectsForTesting(
1412 non_intersecting_rect, // Visible rect.
1413 non_intersecting_rect, // Skewport rect.
1414 non_intersecting_rect, // Soon rect.
1415 intersecting_rect); // Eventually rect.
1416 scoped_ptr<TilingSetRasterQueueAll> queue(
1417 new TilingSetRasterQueueAll(tiling_set.get(), false));
1418 EXPECT_FALSE(queue->IsEmpty());
1422 class TileManagerTest : public testing::Test {
1423 public:
1424 TileManagerTest()
1425 : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {}
1427 protected:
1428 // MockLayerTreeHostImpl allows us to intercept tile manager callbacks.
1429 class MockLayerTreeHostImpl : public FakeLayerTreeHostImpl {
1430 public:
1431 MockLayerTreeHostImpl(Proxy* proxy,
1432 SharedBitmapManager* manager,
1433 TaskGraphRunner* task_graph_runner)
1434 : FakeLayerTreeHostImpl(proxy, manager, task_graph_runner) {
1435 InitializeRenderer(FakeOutputSurface::CreateSoftware(
1436 make_scoped_ptr(new SoftwareOutputDevice)));
1439 MOCK_METHOD0(NotifyAllTileTasksCompleted, void());
1442 TestSharedBitmapManager shared_bitmap_manager_;
1443 TestTaskGraphRunner task_graph_runner_;
1444 FakeImplProxy proxy_;
1445 MockLayerTreeHostImpl host_impl_;
1448 // Test to ensure that we call NotifyAllTileTasksCompleted when PrepareTiles is
1449 // called.
1450 TEST_F(TileManagerTest, AllWorkFinishedTest) {
1451 // Check with no tile work enqueued.
1453 base::RunLoop run_loop;
1454 EXPECT_FALSE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
1455 EXPECT_CALL(host_impl_, NotifyAllTileTasksCompleted())
1456 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1457 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
1458 EXPECT_TRUE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
1459 run_loop.Run();
1462 // Check that the "schedule more work" path also triggers the expected
1463 // callback.
1465 base::RunLoop run_loop;
1466 EXPECT_FALSE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
1467 EXPECT_CALL(host_impl_, NotifyAllTileTasksCompleted())
1468 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1469 host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
1470 host_impl_.tile_manager()->SetMoreTilesNeedToBeRasterizedForTesting();
1471 EXPECT_TRUE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
1472 run_loop.Run();
1476 TEST_F(TileManagerTest, LowResHasNoImage) {
1477 gfx::Size size(10, 12);
1478 TileResolution resolutions[] = {HIGH_RESOLUTION, LOW_RESOLUTION};
1480 for (size_t i = 0; i < arraysize(resolutions); ++i) {
1481 SCOPED_TRACE(resolutions[i]);
1483 // Make a RasterSource that will draw a blue bitmap image.
1484 SkBitmap blue_bitmap;
1485 blue_bitmap.allocN32Pixels(size.width(), size.height(), true);
1486 blue_bitmap.eraseColor(SK_ColorBLUE);
1487 scoped_ptr<FakeDisplayListRecordingSource> recording_source =
1488 FakeDisplayListRecordingSource::CreateFilledRecordingSource(size);
1489 recording_source->SetBackgroundColor(SK_ColorTRANSPARENT);
1490 recording_source->SetRequiresClear(true);
1491 recording_source->SetClearCanvasWithDebugColor(false);
1492 SkPaint paint;
1493 paint.setColor(SK_ColorGREEN);
1494 recording_source->add_draw_rect_with_paint(gfx::Rect(size), paint);
1495 recording_source->add_draw_bitmap(blue_bitmap, gfx::Point());
1496 recording_source->Rerecord();
1497 scoped_refptr<DisplayListRasterSource> raster =
1498 DisplayListRasterSource::CreateFromDisplayListRecordingSource(
1499 recording_source.get(), false);
1501 FakePictureLayerTilingClient tiling_client;
1502 tiling_client.SetTileSize(size);
1504 scoped_ptr<PictureLayerImpl> layer =
1505 PictureLayerImpl::Create(host_impl_.active_tree(), 1, false, nullptr);
1506 PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set();
1508 auto* tiling = tiling_set->AddTiling(1.0f, raster);
1509 tiling->set_resolution(resolutions[i]);
1510 tiling->CreateAllTilesForTesting();
1511 tiling->SetTilePriorityRectsForTesting(
1512 gfx::Rect(size), // Visible rect.
1513 gfx::Rect(size), // Skewport rect.
1514 gfx::Rect(size), // Soon rect.
1515 gfx::Rect(size)); // Eventually rect.
1517 // SMOOTHNESS_TAKES_PRIORITY ensures that we will actually raster
1518 // LOW_RESOLUTION tiles, otherwise they are skipped.
1519 host_impl_.SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
1521 // Call PrepareTiles and wait for it to complete.
1522 auto* tile_manager = host_impl_.tile_manager();
1523 base::RunLoop run_loop;
1524 EXPECT_CALL(host_impl_, NotifyAllTileTasksCompleted())
1525 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1526 tile_manager->PrepareTiles(host_impl_.global_tile_state());
1527 run_loop.Run();
1528 tile_manager->Flush();
1530 Tile* tile = tiling->TileAt(0, 0);
1531 // The tile in the tiling was rastered.
1532 EXPECT_EQ(TileDrawInfo::RESOURCE_MODE, tile->draw_info().mode());
1533 EXPECT_TRUE(tile->draw_info().IsReadyToDraw());
1535 ResourceProvider::ScopedReadLockSoftware lock(
1536 host_impl_.resource_provider(), tile->draw_info().resource_id());
1537 const SkBitmap* bitmap = lock.sk_bitmap();
1538 for (int x = 0; x < size.width(); ++x) {
1539 for (int y = 0; y < size.height(); ++y) {
1540 SCOPED_TRACE(y);
1541 SCOPED_TRACE(x);
1542 if (resolutions[i] == LOW_RESOLUTION) {
1543 // Since it's low res, the bitmap was not drawn, and the background
1544 // (green) is visible instead.
1545 ASSERT_EQ(SK_ColorGREEN, bitmap->getColor(x, y));
1546 } else {
1547 EXPECT_EQ(HIGH_RESOLUTION, resolutions[i]);
1548 // Since it's high res, the bitmap (blue) was drawn, and the
1549 // background is not visible.
1550 ASSERT_EQ(SK_ColorBLUE, bitmap->getColor(x, y));
1557 } // namespace
1558 } // namespace cc