Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: cc/resources/tile_manager.cc

Issue 246673005: cc: Start using raster/eviction iterators in tile manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/resources/tile_manager.h" 5 #include "cc/resources/tile_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 10
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 skia::RefPtr<SkPixelRef> pixel_ref_; 239 skia::RefPtr<SkPixelRef> pixel_ref_;
240 int layer_id_; 240 int layer_id_;
241 RenderingStatsInstrumentation* rendering_stats_; 241 RenderingStatsInstrumentation* rendering_stats_;
242 const base::Callback<void(bool was_canceled)> reply_; 242 const base::Callback<void(bool was_canceled)> reply_;
243 243
244 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 244 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
245 }; 245 };
246 246
247 const size_t kScheduledRasterTasksLimit = 32u; 247 const size_t kScheduledRasterTasksLimit = 32u;
248 248
249 // Memory limit policy works by mapping some bin states to the NEVER bin.
250 const ManagedTileBin kBinPolicyMap[NUM_TILE_MEMORY_LIMIT_POLICIES][NUM_BINS] = {
251 // [ALLOW_NOTHING]
252 {NEVER_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
253 NEVER_BIN, // [NOW_BIN]
254 NEVER_BIN, // [SOON_BIN]
255 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
256 NEVER_BIN, // [EVENTUALLY_BIN]
257 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN]
258 NEVER_BIN, // [AT_LAST_BIN]
259 NEVER_BIN // [NEVER_BIN]
260 },
261 // [ALLOW_ABSOLUTE_MINIMUM]
262 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
263 NOW_BIN, // [NOW_BIN]
264 NEVER_BIN, // [SOON_BIN]
265 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
266 NEVER_BIN, // [EVENTUALLY_BIN]
267 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN]
268 NEVER_BIN, // [AT_LAST_BIN]
269 NEVER_BIN // [NEVER_BIN]
270 },
271 // [ALLOW_PREPAINT_ONLY]
272 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
273 NOW_BIN, // [NOW_BIN]
274 SOON_BIN, // [SOON_BIN]
275 NEVER_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
276 NEVER_BIN, // [EVENTUALLY_BIN]
277 NEVER_BIN, // [AT_LAST_AND_ACTIVE_BIN]
278 NEVER_BIN, // [AT_LAST_BIN]
279 NEVER_BIN // [NEVER_BIN]
280 },
281 // [ALLOW_ANYTHING]
282 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
283 NOW_BIN, // [NOW_BIN]
284 SOON_BIN, // [SOON_BIN]
285 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
286 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
287 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
288 AT_LAST_BIN, // [AT_LAST_BIN]
289 NEVER_BIN // [NEVER_BIN]
290 }};
291
292 // Ready to draw works by mapping NOW_BIN to NOW_AND_READY_TO_DRAW_BIN.
293 const ManagedTileBin kBinReadyToDrawMap[2][NUM_BINS] = {
294 // Not ready
295 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
296 NOW_BIN, // [NOW_BIN]
297 SOON_BIN, // [SOON_BIN]
298 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
299 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
300 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
301 AT_LAST_BIN, // [AT_LAST_BIN]
302 NEVER_BIN // [NEVER_BIN]
303 },
304 // Ready
305 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
306 NOW_AND_READY_TO_DRAW_BIN, // [NOW_BIN]
307 SOON_BIN, // [SOON_BIN]
308 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
309 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
310 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
311 AT_LAST_BIN, // [AT_LAST_BIN]
312 NEVER_BIN // [NEVER_BIN]
313 }};
314
315 // Active works by mapping some bin stats to equivalent _ACTIVE_BIN state.
316 const ManagedTileBin kBinIsActiveMap[2][NUM_BINS] = {
317 // Inactive
318 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
319 NOW_BIN, // [NOW_BIN]
320 SOON_BIN, // [SOON_BIN]
321 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
322 EVENTUALLY_BIN, // [EVENTUALLY_BIN]
323 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
324 AT_LAST_BIN, // [AT_LAST_BIN]
325 NEVER_BIN // [NEVER_BIN]
326 },
327 // Active
328 {NOW_AND_READY_TO_DRAW_BIN, // [NOW_AND_READY_TO_DRAW_BIN]
329 NOW_BIN, // [NOW_BIN]
330 SOON_BIN, // [SOON_BIN]
331 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_AND_ACTIVE_BIN]
332 EVENTUALLY_AND_ACTIVE_BIN, // [EVENTUALLY_BIN]
333 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_AND_ACTIVE_BIN]
334 AT_LAST_AND_ACTIVE_BIN, // [AT_LAST_BIN]
335 NEVER_BIN // [NEVER_BIN]
336 }};
337
338 // Determine bin based on three categories of tiles: things we need now,
339 // things we need soon, and eventually.
340 inline ManagedTileBin BinFromTilePriority(const TilePriority& prio) {
341 const float kBackflingGuardDistancePixels = 314.0f;
342
343 if (prio.priority_bin == TilePriority::NOW)
344 return NOW_BIN;
345
346 if (prio.priority_bin == TilePriority::SOON ||
347 prio.distance_to_visible < kBackflingGuardDistancePixels)
348 return SOON_BIN;
349
350 if (prio.distance_to_visible == std::numeric_limits<float>::infinity())
351 return NEVER_BIN;
352
353 return EVENTUALLY_BIN;
354 }
355
356 } // namespace 249 } // namespace
357 250
358 RasterTaskCompletionStats::RasterTaskCompletionStats() 251 RasterTaskCompletionStats::RasterTaskCompletionStats()
359 : completed_count(0u), canceled_count(0u) {} 252 : completed_count(0u), canceled_count(0u) {}
360 253
361 scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue( 254 scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue(
362 const RasterTaskCompletionStats& stats) { 255 const RasterTaskCompletionStats& stats) {
363 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 256 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
364 state->SetInteger("completed_count", stats.completed_count); 257 state->SetInteger("completed_count", stats.completed_count);
365 state->SetInteger("canceled_count", stats.canceled_count); 258 state->SetInteger("canceled_count", stats.canceled_count);
(...skipping 21 matching lines...) Expand all
387 TileManager::TileManager( 280 TileManager::TileManager(
388 TileManagerClient* client, 281 TileManagerClient* client,
389 ResourcePool* resource_pool, 282 ResourcePool* resource_pool,
390 Rasterizer* rasterizer, 283 Rasterizer* rasterizer,
391 Rasterizer* gpu_rasterizer, 284 Rasterizer* gpu_rasterizer,
392 size_t max_raster_usage_bytes, 285 size_t max_raster_usage_bytes,
393 bool use_rasterize_on_demand, 286 bool use_rasterize_on_demand,
394 RenderingStatsInstrumentation* rendering_stats_instrumentation) 287 RenderingStatsInstrumentation* rendering_stats_instrumentation)
395 : client_(client), 288 : client_(client),
396 resource_pool_(resource_pool), 289 resource_pool_(resource_pool),
397 prioritized_tiles_dirty_(false),
398 all_tiles_that_need_to_be_rasterized_have_memory_(true), 290 all_tiles_that_need_to_be_rasterized_have_memory_(true),
399 all_tiles_required_for_activation_have_memory_(true), 291 all_tiles_required_for_activation_have_memory_(true),
400 memory_required_bytes_(0),
401 memory_nice_to_have_bytes_(0),
402 bytes_releasable_(0), 292 bytes_releasable_(0),
403 resources_releasable_(0), 293 resources_releasable_(0),
404 max_raster_usage_bytes_(max_raster_usage_bytes), 294 max_raster_usage_bytes_(max_raster_usage_bytes),
405 ever_exceeded_memory_budget_(false), 295 ever_exceeded_memory_budget_(false),
406 rendering_stats_instrumentation_(rendering_stats_instrumentation), 296 rendering_stats_instrumentation_(rendering_stats_instrumentation),
407 did_initialize_visible_tile_(false), 297 did_initialize_visible_tile_(false),
408 did_check_for_completed_tasks_since_last_schedule_tasks_(true), 298 did_check_for_completed_tasks_since_last_schedule_tasks_(true),
409 use_rasterize_on_demand_(use_rasterize_on_demand) { 299 use_rasterize_on_demand_(use_rasterize_on_demand) {
410 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = { 300 Rasterizer* rasterizers[NUM_RASTERIZER_TYPES] = {
411 rasterizer, // RASTERIZER_TYPE_DEFAULT 301 rasterizer, // RASTERIZER_TYPE_DEFAULT
(...skipping 25 matching lines...) Expand all
437 327
438 for (std::vector<PictureLayerImpl*>::iterator it = layers_.begin(); 328 for (std::vector<PictureLayerImpl*>::iterator it = layers_.begin();
439 it != layers_.end(); 329 it != layers_.end();
440 ++it) { 330 ++it) {
441 (*it)->DidUnregisterLayer(); 331 (*it)->DidUnregisterLayer();
442 } 332 }
443 layers_.clear(); 333 layers_.clear();
444 } 334 }
445 335
446 void TileManager::Release(Tile* tile) { 336 void TileManager::Release(Tile* tile) {
447 prioritized_tiles_dirty_ = true;
448 released_tiles_.push_back(tile); 337 released_tiles_.push_back(tile);
449 } 338 }
450 339
451 void TileManager::DidChangeTilePriority(Tile* tile) {
452 prioritized_tiles_dirty_ = true;
453 }
454
455 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { 340 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const {
456 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; 341 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY;
457 } 342 }
458 343
459 void TileManager::CleanUpReleasedTiles() { 344 void TileManager::CleanUpReleasedTiles() {
460 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); 345 for (std::vector<Tile*>::iterator it = released_tiles_.begin();
461 it != released_tiles_.end(); 346 it != released_tiles_.end();
462 ++it) { 347 ++it) {
463 Tile* tile = *it; 348 Tile* tile = *it;
464 ManagedTileState& mts = tile->managed_state(); 349 ManagedTileState& mts = tile->managed_state();
(...skipping 13 matching lines...) Expand all
478 used_layer_counts_.erase(layer_it); 363 used_layer_counts_.erase(layer_it);
479 image_decode_tasks_.erase(tile->layer_id()); 364 image_decode_tasks_.erase(tile->layer_id());
480 } 365 }
481 366
482 delete tile; 367 delete tile;
483 } 368 }
484 369
485 released_tiles_.clear(); 370 released_tiles_.clear();
486 } 371 }
487 372
488 void TileManager::UpdatePrioritizedTileSetIfNeeded() {
489 if (!prioritized_tiles_dirty_)
490 return;
491
492 CleanUpReleasedTiles();
493
494 prioritized_tiles_.Clear();
495 GetTilesWithAssignedBins(&prioritized_tiles_);
496 prioritized_tiles_dirty_ = false;
497 }
498
499 void TileManager::DidFinishRunningTasks() { 373 void TileManager::DidFinishRunningTasks() {
500 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); 374 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks");
501 375
502 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > 376 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() >
503 global_state_.soft_memory_limit_in_bytes; 377 global_state_.soft_memory_limit_in_bytes;
504 378
505 // When OOM, keep re-assigning memory until we reach a steady state 379 // When OOM, keep re-assigning memory until we reach a steady state
506 // where top-priority tiles are initialized. 380 // where top-priority tiles are initialized.
507 if (all_tiles_that_need_to_be_rasterized_have_memory_ && 381 if (all_tiles_that_need_to_be_rasterized_have_memory_ &&
508 !memory_usage_above_limit) 382 !memory_usage_above_limit)
509 return; 383 return;
510 384
511 rasterizer_delegate_->CheckForCompletedTasks(); 385 rasterizer_delegate_->CheckForCompletedTasks();
512 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 386 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
513 387
514 TileVector tiles_that_need_to_be_rasterized; 388 TileVector tiles_that_need_to_be_rasterized;
515 AssignGpuMemoryToTiles(&prioritized_tiles_, 389 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
516 &tiles_that_need_to_be_rasterized);
517 390
518 // |tiles_that_need_to_be_rasterized| will be empty when we reach a 391 // |tiles_that_need_to_be_rasterized| will be empty when we reach a
519 // steady memory state. Keep scheduling tasks until we reach this state. 392 // steady memory state. Keep scheduling tasks until we reach this state.
520 if (!tiles_that_need_to_be_rasterized.empty()) { 393 if (!tiles_that_need_to_be_rasterized.empty()) {
521 ScheduleTasks(tiles_that_need_to_be_rasterized); 394 ScheduleTasks(tiles_that_need_to_be_rasterized);
522 return; 395 return;
523 } 396 }
524 397
525 resource_pool_->ReduceResourceUsage(); 398 resource_pool_->ReduceResourceUsage();
526 399
(...skipping 29 matching lines...) Expand all
556 // activation are initialized when no tiles are OOM. We need to 429 // activation are initialized when no tiles are OOM. We need to
557 // wait for DidFinishRunningTasks() to be called, try to re-assign 430 // wait for DidFinishRunningTasks() to be called, try to re-assign
558 // memory and in worst case use on-demand raster when tiles 431 // memory and in worst case use on-demand raster when tiles
559 // required for activation are OOM. 432 // required for activation are OOM.
560 if (!all_tiles_required_for_activation_have_memory_) 433 if (!all_tiles_required_for_activation_have_memory_)
561 return; 434 return;
562 435
563 client_->NotifyReadyToActivate(); 436 client_->NotifyReadyToActivate();
564 } 437 }
565 438
566 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
567 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins");
568
569 // Compute new stats to be return by GetMemoryStats().
570 memory_required_bytes_ = 0;
571 memory_nice_to_have_bytes_ = 0;
572
573 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy;
574 const TreePriority tree_priority = global_state_.tree_priority;
575
576 // For each tree, bin into different categories of tiles.
577 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
578 Tile* tile = it->second;
579 ManagedTileState& mts = tile->managed_state();
580
581 const ManagedTileState::TileVersion& tile_version =
582 tile->GetTileVersionForDrawing();
583 bool tile_is_ready_to_draw = tile_version.IsReadyToDraw();
584 bool tile_is_active = tile_is_ready_to_draw ||
585 mts.tile_versions[mts.raster_mode].raster_task_;
586
587 // Get the active priority and bin.
588 TilePriority active_priority = tile->priority(ACTIVE_TREE);
589 ManagedTileBin active_bin = BinFromTilePriority(active_priority);
590
591 // Get the pending priority and bin.
592 TilePriority pending_priority = tile->priority(PENDING_TREE);
593 ManagedTileBin pending_bin = BinFromTilePriority(pending_priority);
594
595 bool pending_is_low_res = pending_priority.resolution == LOW_RESOLUTION;
596 bool pending_is_non_ideal =
597 pending_priority.resolution == NON_IDEAL_RESOLUTION;
598 bool active_is_non_ideal =
599 active_priority.resolution == NON_IDEAL_RESOLUTION;
600
601 // Adjust pending bin state for low res tiles. This prevents
602 // pending tree low-res tiles from being initialized before
603 // high-res tiles.
604 if (pending_is_low_res)
605 pending_bin = std::max(pending_bin, EVENTUALLY_BIN);
606
607 // Adjust bin state based on if ready to draw.
608 active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin];
609 pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin];
610
611 // Adjust bin state based on if active.
612 active_bin = kBinIsActiveMap[tile_is_active][active_bin];
613 pending_bin = kBinIsActiveMap[tile_is_active][pending_bin];
614
615 // We never want to paint new non-ideal tiles, as we always have
616 // a high-res tile covering that content (paint that instead).
617 if (!tile_is_ready_to_draw && active_is_non_ideal)
618 active_bin = NEVER_BIN;
619 if (!tile_is_ready_to_draw && pending_is_non_ideal)
620 pending_bin = NEVER_BIN;
621
622 // Compute combined bin.
623 ManagedTileBin combined_bin = std::min(active_bin, pending_bin);
624
625 if (!tile_is_ready_to_draw || tile_version.requires_resource()) {
626 // The bin that the tile would have if the GPU memory manager had
627 // a maximally permissive policy, send to the GPU memory manager
628 // to determine policy.
629 ManagedTileBin gpu_memmgr_stats_bin = combined_bin;
630 if ((gpu_memmgr_stats_bin == NOW_BIN) ||
631 (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN))
632 memory_required_bytes_ += BytesConsumedIfAllocated(tile);
633 if (gpu_memmgr_stats_bin != NEVER_BIN)
634 memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile);
635 }
636
637 ManagedTileBin tree_bin[NUM_TREES];
638 tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
639 tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
640
641 TilePriority tile_priority;
642 switch (tree_priority) {
643 case SAME_PRIORITY_FOR_BOTH_TREES:
644 mts.bin = kBinPolicyMap[memory_policy][combined_bin];
645 tile_priority = tile->combined_priority();
646 break;
647 case SMOOTHNESS_TAKES_PRIORITY:
648 mts.bin = tree_bin[ACTIVE_TREE];
649 tile_priority = active_priority;
650 break;
651 case NEW_CONTENT_TAKES_PRIORITY:
652 mts.bin = tree_bin[PENDING_TREE];
653 tile_priority = pending_priority;
654 break;
655 }
656
657 // Bump up the priority if we determined it's NEVER_BIN on one tree,
658 // but is still required on the other tree.
659 bool is_in_never_bin_on_both_trees = tree_bin[ACTIVE_TREE] == NEVER_BIN &&
660 tree_bin[PENDING_TREE] == NEVER_BIN;
661
662 if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
663 mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
664
665 mts.resolution = tile_priority.resolution;
666 mts.priority_bin = tile_priority.priority_bin;
667 mts.distance_to_visible = tile_priority.distance_to_visible;
668 mts.required_for_activation = tile_priority.required_for_activation;
669
670 mts.visible_and_ready_to_draw =
671 tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
672
673 // If the tile is in NEVER_BIN and it does not have an active task, then we
674 // can release the resources early. If it does have the task however, we
675 // should keep it in the prioritized tile set to ensure that AssignGpuMemory
676 // can visit it.
677 if (mts.bin == NEVER_BIN &&
678 !mts.tile_versions[mts.raster_mode].raster_task_) {
679 FreeResourcesForTile(tile);
680 continue;
681 }
682
683 // Insert the tile into a priority set.
684 tiles->InsertTile(tile, mts.bin);
685 }
686 }
687
688 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { 439 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
689 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 440 TRACE_EVENT0("cc", "TileManager::ManageTiles");
690 441
691 // Update internal state. 442 // Update internal state.
692 if (state != global_state_) { 443 global_state_ = state;
693 global_state_ = state; 444
694 prioritized_tiles_dirty_ = true; 445 // TODO(vmpstr): See if we still need to keep tiles alive when layers release
695 } 446 // them.
447 CleanUpReleasedTiles();
696 448
697 // We need to call CheckForCompletedTasks() once in-between each call 449 // We need to call CheckForCompletedTasks() once in-between each call
698 // to ScheduleTasks() to prevent canceled tasks from being scheduled. 450 // to ScheduleTasks() to prevent canceled tasks from being scheduled.
699 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { 451 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
700 rasterizer_delegate_->CheckForCompletedTasks(); 452 rasterizer_delegate_->CheckForCompletedTasks();
701 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 453 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
702 } 454 }
703 455
704 UpdatePrioritizedTileSetIfNeeded();
705
706 TileVector tiles_that_need_to_be_rasterized; 456 TileVector tiles_that_need_to_be_rasterized;
707 AssignGpuMemoryToTiles(&prioritized_tiles_, 457 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
708 &tiles_that_need_to_be_rasterized);
709 458
710 // Finally, schedule rasterizer tasks. 459 // Finally, schedule rasterizer tasks.
711 ScheduleTasks(tiles_that_need_to_be_rasterized); 460 ScheduleTasks(tiles_that_need_to_be_rasterized);
712 461
713 TRACE_EVENT_INSTANT1("cc", 462 TRACE_EVENT_INSTANT1("cc",
714 "DidManage", 463 "DidManage",
715 TRACE_EVENT_SCOPE_THREAD, 464 TRACE_EVENT_SCOPE_THREAD,
716 "state", 465 "state",
717 TracedValue::FromValue(BasicStateAsValue().release())); 466 TracedValue::FromValue(BasicStateAsValue().release()));
718 467
(...skipping 21 matching lines...) Expand all
740 489
741 bool did_initialize_visible_tile = did_initialize_visible_tile_; 490 bool did_initialize_visible_tile = did_initialize_visible_tile_;
742 did_initialize_visible_tile_ = false; 491 did_initialize_visible_tile_ = false;
743 return did_initialize_visible_tile; 492 return did_initialize_visible_tile;
744 } 493 }
745 494
746 void TileManager::GetMemoryStats(size_t* memory_required_bytes, 495 void TileManager::GetMemoryStats(size_t* memory_required_bytes,
747 size_t* memory_nice_to_have_bytes, 496 size_t* memory_nice_to_have_bytes,
748 size_t* memory_allocated_bytes, 497 size_t* memory_allocated_bytes,
749 size_t* memory_used_bytes) const { 498 size_t* memory_used_bytes) const {
750 *memory_required_bytes = memory_required_bytes_; 499 *memory_required_bytes = resource_pool_->total_memory_usage_bytes();
751 *memory_nice_to_have_bytes = memory_nice_to_have_bytes_; 500 *memory_nice_to_have_bytes = resource_pool_->total_memory_usage_bytes();
reveman 2014/04/28 19:39:18 what's our plan for computing these properly?
vmpstr 2014/04/28 20:56:42 That's a good question. There's no good way for us
reveman 2014/04/28 21:43:15 The end result is that these values are used by th
vmpstr 2014/04/28 22:44:38 Yeah that's the thing that always made me a bit he
reveman 2014/05/20 23:01:00 Doesn't have to be precise. I don't think memory_r
752 *memory_allocated_bytes = resource_pool_->total_memory_usage_bytes(); 501 *memory_allocated_bytes = resource_pool_->total_memory_usage_bytes();
753 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); 502 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes();
754 } 503 }
755 504
756 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { 505 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const {
757 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 506 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
758 state->SetInteger("tile_count", tiles_.size()); 507 state->SetInteger("tile_count", tiles_.size());
759 state->Set("global_state", global_state_.AsValue().release()); 508 state->Set("global_state", global_state_.AsValue().release());
760 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); 509 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release());
761 return state.PassAs<base::Value>(); 510 return state.PassAs<base::Value>();
(...skipping 20 matching lines...) Expand all
782 &memory_used_bytes); 531 &memory_used_bytes);
783 requirements->SetInteger("memory_required_bytes", memory_required_bytes); 532 requirements->SetInteger("memory_required_bytes", memory_required_bytes);
784 requirements->SetInteger("memory_nice_to_have_bytes", 533 requirements->SetInteger("memory_nice_to_have_bytes",
785 memory_nice_to_have_bytes); 534 memory_nice_to_have_bytes);
786 requirements->SetInteger("memory_allocated_bytes", memory_allocated_bytes); 535 requirements->SetInteger("memory_allocated_bytes", memory_allocated_bytes);
787 requirements->SetInteger("memory_used_bytes", memory_used_bytes); 536 requirements->SetInteger("memory_used_bytes", memory_used_bytes);
788 return requirements.PassAs<base::Value>(); 537 return requirements.PassAs<base::Value>();
789 } 538 }
790 539
791 void TileManager::AssignGpuMemoryToTiles( 540 void TileManager::AssignGpuMemoryToTiles(
792 PrioritizedTileSet* tiles,
793 TileVector* tiles_that_need_to_be_rasterized) { 541 TileVector* tiles_that_need_to_be_rasterized) {
794 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 542 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
795 543
796 // Maintain the list of released resources that can potentially be re-used 544 // Maintain the list of released resources that can potentially be re-used
797 // or deleted. 545 // or deleted.
798 // If this operation becomes expensive too, only do this after some 546 // If this operation becomes expensive too, only do this after some
799 // resource(s) was returned. Note that in that case, one also need to 547 // resource(s) was returned. Note that in that case, one also need to
800 // invalidate when releasing some resource from the pool. 548 // invalidate when releasing some resource from the pool.
801 resource_pool_->CheckBusyResources(); 549 resource_pool_->CheckBusyResources();
802 550
803 // Now give memory out to the tiles until we're out, and build 551 // Now give memory out to the tiles until we're out, and build
804 // the needs-to-be-rasterized queue. 552 // the needs-to-be-rasterized queue.
805 all_tiles_that_need_to_be_rasterized_have_memory_ = true; 553 all_tiles_that_need_to_be_rasterized_have_memory_ = true;
806 all_tiles_required_for_activation_have_memory_ = true; 554 all_tiles_required_for_activation_have_memory_ = true;
807 555
808 // Cast to prevent overflow. 556 // Cast to prevent overflow.
809 int64 soft_bytes_available = 557 int64 soft_bytes_available =
810 static_cast<int64>(bytes_releasable_) +
811 static_cast<int64>(global_state_.soft_memory_limit_in_bytes) - 558 static_cast<int64>(global_state_.soft_memory_limit_in_bytes) -
812 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); 559 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
813 int64 hard_bytes_available = 560 int64 hard_bytes_available =
814 static_cast<int64>(bytes_releasable_) +
815 static_cast<int64>(global_state_.hard_memory_limit_in_bytes) - 561 static_cast<int64>(global_state_.hard_memory_limit_in_bytes) -
816 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); 562 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
817 int resources_available = resources_releasable_ + 563 int resources_available = global_state_.num_resources_limit -
818 global_state_.num_resources_limit -
819 resource_pool_->acquired_resource_count(); 564 resource_pool_->acquired_resource_count();
820 size_t soft_bytes_allocatable = 565
821 std::max(static_cast<int64>(0), soft_bytes_available); 566 EvictionTileIterator eviction_it(this, global_state_.tree_priority);
822 size_t hard_bytes_allocatable = 567 bool evicted_tiles_required_for_activation = false;
823 std::max(static_cast<int64>(0), hard_bytes_available); 568
824 size_t resources_allocatable = std::max(0, resources_available); 569 // Evict resources if we're OOM before processing any tiles.
570 while (hard_bytes_available < 0 || resources_available < 0) {
reveman 2014/04/28 19:39:18 can you fold this into the loop below instead of d
vmpstr 2014/04/28 20:56:42 It has to be outside of the loop since the raster
reveman 2014/04/28 21:43:15 It's not clear to me why these eviction cases need
vmpstr 2014/04/28 22:44:38 I kind of reworked this a bit (I put the memory li
571 if (!eviction_it)
572 break;
573
574 Tile* eviction_tile = *eviction_it;
575 const TilePriority& eviction_priority =
576 eviction_tile->priority_for_tree_priority(global_state_.tree_priority);
577 size_t eviction_bytes_if_allocated =
578 BytesConsumedIfAllocated(eviction_tile);
579 ManagedTileState& eviction_mts = eviction_tile->managed_state();
580 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
581 if (eviction_mts.tile_versions[mode].resource_) {
582 hard_bytes_available += eviction_bytes_if_allocated;
583 if (eviction_priority.priority_bin != TilePriority::NOW)
584 soft_bytes_available += eviction_bytes_if_allocated;
585 resources_available++;
586 }
587 }
588 FreeResourcesForTile(eviction_tile);
589 ++eviction_it;
590
591 evicted_tiles_required_for_activation |=
592 eviction_tile->required_for_activation();
593 }
594
595 int64 soft_bytes_allocatable = soft_bytes_available;
596 int64 hard_bytes_allocatable = hard_bytes_available;
597 int resources_allocatable = resources_available;
825 598
826 size_t bytes_that_exceeded_memory_budget = 0; 599 size_t bytes_that_exceeded_memory_budget = 0;
827 size_t soft_bytes_left = soft_bytes_allocatable; 600 int64 soft_bytes_left = soft_bytes_allocatable;
828 size_t hard_bytes_left = hard_bytes_allocatable; 601 int64 hard_bytes_left = hard_bytes_allocatable;
829 602
830 size_t resources_left = resources_allocatable; 603 int* resources_left = &resources_allocatable;
831 bool oomed_soft = false; 604 bool oomed_soft = false;
832 bool oomed_hard = false; 605 bool oomed_hard = false;
833 bool have_hit_soft_memory = false; // Soft memory comes after hard. 606 bool have_hit_soft_memory = false; // Soft memory comes after hard.
834 607
835 // Memory we assign to raster tasks now will be deducted from our memory 608 // Memory we assign to raster tasks now will be deducted from our memory
836 // in future iterations if priorities change. By assigning at most half 609 // in future iterations if priorities change. By assigning at most half
837 // the raster limit, we will always have another 50% left even if priorities 610 // the raster limit, we will always have another 50% left even if priorities
838 // change completely (assuming we check for completed/cancelled rasters 611 // change completely (assuming we check for completed/cancelled rasters
839 // between each call to this function). 612 // between each call to this function).
840 size_t max_raster_bytes = max_raster_usage_bytes_ / 2; 613 size_t max_raster_bytes = max_raster_usage_bytes_ / 2;
841 size_t raster_bytes = 0; 614 size_t raster_bytes = 0;
842 615
843 unsigned schedule_priority = 1u; 616 unsigned schedule_priority = 1u;
844 for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) { 617 for (RasterTileIterator it(this, global_state_.tree_priority); it; ++it) {
845 Tile* tile = *it; 618 Tile* tile = *it;
619 TilePriority priority =
620 tile->priority_for_tree_priority(global_state_.tree_priority);
621
622 bool tile_violates_memory_policy = false;
623 switch (global_state_.memory_limit_policy) {
624 case ALLOW_NOTHING:
625 tile_violates_memory_policy = true;
626 break;
627 case ALLOW_ABSOLUTE_MINIMUM:
628 tile_violates_memory_policy = priority.priority_bin > TilePriority::NOW;
629 break;
630 case ALLOW_PREPAINT_ONLY:
631 tile_violates_memory_policy =
632 priority.priority_bin > TilePriority::SOON;
633 break;
634 case ALLOW_ANYTHING:
635 case NUM_TILE_MEMORY_LIMIT_POLICIES:
636 break;
637 }
638
639 if (tile_violates_memory_policy)
640 break;
641
846 ManagedTileState& mts = tile->managed_state(); 642 ManagedTileState& mts = tile->managed_state();
847 643
848 mts.scheduled_priority = schedule_priority++; 644 mts.scheduled_priority = schedule_priority++;
849 645
850 mts.raster_mode = tile->DetermineOverallRasterMode(); 646 mts.raster_mode = tile->DetermineOverallRasterMode();
851 647
852 ManagedTileState::TileVersion& tile_version = 648 ManagedTileState::TileVersion& tile_version =
853 mts.tile_versions[mts.raster_mode]; 649 mts.tile_versions[mts.raster_mode];
854 650
855 // If this tile doesn't need a resource, then nothing to do. 651 // If this version is ready to draw, then nothing to do.
856 if (!tile_version.requires_resource()) 652 if (tile_version.IsReadyToDraw())
857 continue; 653 continue;
858 654
859 // If the tile is not needed, free it up. 655 const bool tile_uses_hard_limit =
860 if (mts.bin == NEVER_BIN) { 656 priority.priority_bin == TilePriority::NOW;
861 FreeResourcesForTile(tile);
862 continue;
863 }
864 657
865 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN;
866 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); 658 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile);
867 const size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated; 659 const size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated;
868 const size_t tile_bytes_left = 660 int64* tile_bytes_left =
869 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left; 661 (tile_uses_hard_limit) ? &hard_bytes_left : &soft_bytes_left;
870 662
871 // Hard-limit is reserved for tiles that would cause a calamity 663 // Hard-limit is reserved for tiles that would cause a calamity
872 // if they were to go away, so by definition they are the highest 664 // if they were to go away, so by definition they are the highest
873 // priority memory, and must be at the front of the list. 665 // priority memory, and must be at the front of the list.
874 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit)); 666 DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit));
875 have_hit_soft_memory |= !tile_uses_hard_limit; 667 have_hit_soft_memory |= !tile_uses_hard_limit;
876 668
877 size_t tile_bytes = 0; 669 int64 tile_bytes = 0;
878 size_t tile_resources = 0; 670 int tile_resources = 0;
879 671
880 // It costs to maintain a resource. 672 // It costs to maintain a resource.
881 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { 673 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
882 if (mts.tile_versions[mode].resource_) { 674 if (mts.tile_versions[mode].resource_) {
883 tile_bytes += bytes_if_allocated; 675 tile_bytes += bytes_if_allocated;
884 tile_resources++; 676 tile_resources++;
885 } 677 }
886 } 678 }
887 679
888 // Allow lower priority tiles with initialized resources to keep 680 // If we don't have the required version, and it's not in flight
889 // their memory by only assigning memory to new raster tasks if 681 // then we'll have to pay to create a new task.
890 // they can be scheduled. 682 if (!tile_version.resource_ && !tile_version.raster_task_) {
891 if (raster_bytes_if_rastered <= max_raster_bytes) { 683 tile_bytes += bytes_if_allocated;
892 // If we don't have the required version, and it's not in flight 684 tile_resources++;
893 // then we'll have to pay to create a new task.
894 if (!tile_version.resource_ && !tile_version.raster_task_) {
895 tile_bytes += bytes_if_allocated;
896 tile_resources++;
897 }
898 } 685 }
899 686
900 // Tile is OOM. 687 // Handle OOM tiles.
901 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) { 688 while (tile_bytes > *tile_bytes_left || tile_resources > *resources_left) {
902 FreeResourcesForTile(tile); 689 if (!eviction_it)
690 break;
903 691
692 Tile* eviction_tile = *eviction_it;
693 DCHECK(eviction_tile);
694
695 TilePriority eviction_priority =
696 eviction_tile->priority_for_tree_priority(
697 global_state_.tree_priority);
698
699 if (!priority.IsHigherPriorityThan(eviction_priority))
700 break;
701
702 size_t eviction_tile_bytes = 0;
703 size_t eviction_tile_resources = 0;
704 size_t eviction_bytes_if_allocated = BytesConsumedIfAllocated(tile);
705 ManagedTileState& eviction_mts = eviction_tile->managed_state();
706 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
707 if (eviction_mts.tile_versions[mode].resource_) {
708 eviction_tile_bytes += eviction_bytes_if_allocated;
709 eviction_tile_resources++;
710 }
711 }
712
713 FreeResourcesForTile(eviction_tile);
714 ++eviction_it;
715
716 evicted_tiles_required_for_activation |=
717 eviction_tile->required_for_activation();
718
719 *tile_bytes_left += eviction_tile_bytes;
720 *resources_left += eviction_tile_resources;
721 }
722
723 // Tile is still OOM.
724 if (tile_bytes > *tile_bytes_left || tile_resources > *resources_left) {
904 // This tile was already on screen and now its resources have been 725 // This tile was already on screen and now its resources have been
905 // released. In order to prevent checkerboarding, set this tile as 726 // released. In order to prevent checkerboarding, set this tile as
906 // rasterize on demand immediately. 727 // rasterize on demand immediately.
907 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) 728 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_)
908 tile_version.set_rasterize_on_demand(); 729 tile_version.set_rasterize_on_demand();
909 730
910 oomed_soft = true; 731 oomed_soft = true;
911 if (tile_uses_hard_limit) { 732 if (tile_uses_hard_limit) {
912 oomed_hard = true; 733 oomed_hard = true;
913 bytes_that_exceeded_memory_budget += tile_bytes; 734 bytes_that_exceeded_memory_budget += tile_bytes;
914 } 735 }
915 } else { 736 } else {
916 resources_left -= tile_resources; 737 *resources_left -= tile_resources;
917 hard_bytes_left -= tile_bytes; 738 hard_bytes_left -= tile_bytes;
918 soft_bytes_left = 739 soft_bytes_left =
919 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0; 740 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0;
920 if (tile_version.resource_) 741 if (tile_version.resource_)
921 continue; 742 continue;
922 } 743 }
923 744
924 DCHECK(!tile_version.resource_); 745 DCHECK(!tile_version.resource_);
925 746
926 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| 747 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized|
927 // has reached it's limit or we've failed to assign gpu memory to this 748 // has reached it's limit or we've failed to assign gpu memory to this
928 // or any higher priority tile. Preventing tiles that fit into memory 749 // or any higher priority tile. Preventing tiles that fit into memory
929 // budget to be rasterized when higher priority tile is oom is 750 // budget to be rasterized when higher priority tile is oom is
930 // important for two reasons: 751 // important for two reasons:
931 // 1. Tile size should not impact raster priority. 752 // 1. Tile size should not impact raster priority.
932 // 2. Tiles with existing raster task could otherwise incorrectly 753 // 2. Tiles with existing raster task could otherwise incorrectly
933 // be added as they are not affected by |bytes_allocatable|. 754 // be added as they are not affected by |bytes_allocatable|.
934 bool can_schedule_tile = 755 bool can_schedule_tile =
935 !oomed_soft && raster_bytes_if_rastered <= max_raster_bytes && 756 !oomed_soft && raster_bytes_if_rastered <= max_raster_bytes &&
936 tiles_that_need_to_be_rasterized->size() < kScheduledRasterTasksLimit; 757 tiles_that_need_to_be_rasterized->size() < kScheduledRasterTasksLimit;
937 758
938 if (!can_schedule_tile) { 759 if (!can_schedule_tile) {
939 all_tiles_that_need_to_be_rasterized_have_memory_ = false; 760 all_tiles_that_need_to_be_rasterized_have_memory_ = false;
940 if (tile->required_for_activation()) 761 all_tiles_required_for_activation_have_memory_ =
941 all_tiles_required_for_activation_have_memory_ = false; 762 !it.HasTilesRequiredForActivation() &&
942 it.DisablePriorityOrdering(); 763 !evicted_tiles_required_for_activation;
943 continue; 764 break;
944 } 765 }
945 766
946 raster_bytes = raster_bytes_if_rastered; 767 raster_bytes = raster_bytes_if_rastered;
947 tiles_that_need_to_be_rasterized->push_back(tile); 768 tiles_that_need_to_be_rasterized->push_back(tile);
948 } 769 }
949 770
950 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit. 771 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit.
951 ever_exceeded_memory_budget_ |= oomed_hard; 772 ever_exceeded_memory_budget_ |= oomed_hard;
952 if (ever_exceeded_memory_budget_) { 773 if (ever_exceeded_memory_budget_) {
953 TRACE_COUNTER_ID2("cc", 774 TRACE_COUNTER_ID2("cc",
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 content_rect, 1039 content_rect,
1219 opaque_rect, 1040 opaque_rect,
1220 contents_scale, 1041 contents_scale,
1221 layer_id, 1042 layer_id,
1222 source_frame_number, 1043 source_frame_number,
1223 flags)); 1044 flags));
1224 DCHECK(tiles_.find(tile->id()) == tiles_.end()); 1045 DCHECK(tiles_.find(tile->id()) == tiles_.end());
1225 1046
1226 tiles_[tile->id()] = tile; 1047 tiles_[tile->id()] = tile;
1227 used_layer_counts_[tile->layer_id()]++; 1048 used_layer_counts_[tile->layer_id()]++;
1228 prioritized_tiles_dirty_ = true;
1229 return tile; 1049 return tile;
1230 } 1050 }
1231 1051
1232 void TileManager::RegisterPictureLayerImpl(PictureLayerImpl* layer) { 1052 void TileManager::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1233 DCHECK(std::find(layers_.begin(), layers_.end(), layer) == layers_.end()); 1053 DCHECK(std::find(layers_.begin(), layers_.end(), layer) == layers_.end());
1234 layers_.push_back(layer); 1054 layers_.push_back(layer);
1235 } 1055 }
1236 1056
1237 void TileManager::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { 1057 void TileManager::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1238 std::vector<PictureLayerImpl*>::iterator it = 1058 std::vector<PictureLayerImpl*>::iterator it =
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 1135
1316 if (paired_iterator.PeekTile(tree_priority_) != NULL) { 1136 if (paired_iterator.PeekTile(tree_priority_) != NULL) {
1317 paired_iterators_.push_back(paired_iterator); 1137 paired_iterators_.push_back(paired_iterator);
1318 iterator_heap_.push_back(&paired_iterators_.back()); 1138 iterator_heap_.push_back(&paired_iterators_.back());
1319 } 1139 }
1320 } 1140 }
1321 1141
1322 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); 1142 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1323 } 1143 }
1324 1144
1145 TileManager::RasterTileIterator::RasterTileIterator(
1146 const RasterTileIterator& other)
1147 : comparator_(other.comparator_) {
1148 *this = other;
1149 }
1150
1151 TileManager::RasterTileIterator& TileManager::RasterTileIterator::operator=(
1152 const RasterTileIterator& other) {
1153 paired_iterators_ = other.paired_iterators_;
1154 tree_priority_ = other.tree_priority_;
1155 comparator_ = other.comparator_;
1156
1157 iterator_heap_.reserve(paired_iterators_.size());
1158 for (size_t i = 0; i < paired_iterators_.size(); ++i) {
1159 if (paired_iterators_[i].PeekTile(tree_priority_) != NULL)
1160 iterator_heap_.push_back(&paired_iterators_[i]);
1161 }
1162 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1163 return *this;
1164 }
1165
1325 TileManager::RasterTileIterator::~RasterTileIterator() {} 1166 TileManager::RasterTileIterator::~RasterTileIterator() {}
1326 1167
1168 bool TileManager::RasterTileIterator::HasTilesRequiredForActivation() const {
1169 for (std::vector<PairedPictureLayerIterator*>::const_iterator it =
1170 iterator_heap_.begin();
1171 it != iterator_heap_.end();
1172 ++it) {
1173 const PairedPictureLayerIterator* pair = *it;
1174
1175 // Tiles required for activation can only come from pending layers.
1176 if (pair->pending_iterator.HasTilesRequiredForActivation())
1177 return true;
1178 }
1179 return false;
1180 }
1181
1327 TileManager::RasterTileIterator& TileManager::RasterTileIterator::operator++() { 1182 TileManager::RasterTileIterator& TileManager::RasterTileIterator::operator++() {
1328 DCHECK(*this); 1183 DCHECK(*this);
1329 1184
1330 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); 1185 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1331 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); 1186 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back();
1332 iterator_heap_.pop_back(); 1187 iterator_heap_.pop_back();
1333 1188
1334 paired_iterator->PopTile(tree_priority_); 1189 paired_iterator->PopTile(tree_priority_);
1335 if (paired_iterator->PeekTile(tree_priority_) != NULL) { 1190 if (paired_iterator->PeekTile(tree_priority_) != NULL) {
1336 iterator_heap_.push_back(paired_iterator); 1191 iterator_heap_.push_back(paired_iterator);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 1304
1450 Tile* a_tile = **a_pair.first; 1305 Tile* a_tile = **a_pair.first;
1451 Tile* b_tile = **b_pair.first; 1306 Tile* b_tile = **b_pair.first;
1452 1307
1453 const TilePriority& a_priority = 1308 const TilePriority& a_priority =
1454 a_tile->priority_for_tree_priority(tree_priority_); 1309 a_tile->priority_for_tree_priority(tree_priority_);
1455 const TilePriority& b_priority = 1310 const TilePriority& b_priority =
1456 b_tile->priority_for_tree_priority(tree_priority_); 1311 b_tile->priority_for_tree_priority(tree_priority_);
1457 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; 1312 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY;
1458 1313
1459 if (b_priority.resolution != a_priority.resolution) { 1314 if (b_priority.priority_bin == a_priority.priority_bin &&
1315 b_priority.resolution != a_priority.resolution) {
1460 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || 1316 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) ||
1461 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || 1317 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) ||
1462 (a_priority.resolution == NON_IDEAL_RESOLUTION); 1318 (a_priority.resolution == NON_IDEAL_RESOLUTION);
1463 } 1319 }
1464 1320
1465 return b_priority.IsHigherPriorityThan(a_priority); 1321 return b_priority.IsHigherPriorityThan(a_priority);
1466 } 1322 }
1467 1323
1468 TileManager::EvictionTileIterator::EvictionTileIterator() 1324 TileManager::EvictionTileIterator::EvictionTileIterator()
1469 : comparator_(SAME_PRIORITY_FOR_BOTH_TREES) {} 1325 : initialized_(true),
1326 tile_manager_(NULL),
1327 comparator_(SAME_PRIORITY_FOR_BOTH_TREES) {
1328 }
1329
1330 TileManager::EvictionTileIterator::EvictionTileIterator(
1331 const EvictionTileIterator& other)
1332 : comparator_(other.comparator_) {
1333 *this = other;
1334 }
1335
1336 TileManager::EvictionTileIterator& TileManager::EvictionTileIterator::operator=(
1337 const EvictionTileIterator& other) {
1338 paired_iterators_ = other.paired_iterators_;
1339 tree_priority_ = other.tree_priority_;
1340 comparator_ = other.comparator_;
1341 initialized_ = other.initialized_;
1342 tile_manager_ = other.tile_manager_;
1343
1344 iterator_heap_.reserve(paired_iterators_.size());
1345 for (size_t i = 0; i < paired_iterators_.size(); ++i) {
1346 if (paired_iterators_[i].PeekTile(tree_priority_) != NULL)
1347 iterator_heap_.push_back(&paired_iterators_[i]);
1348 }
1349 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1350 return *this;
1351 }
1470 1352
1471 TileManager::EvictionTileIterator::EvictionTileIterator( 1353 TileManager::EvictionTileIterator::EvictionTileIterator(
1472 TileManager* tile_manager, 1354 TileManager* tile_manager,
1473 TreePriority tree_priority) 1355 TreePriority tree_priority)
1474 : tree_priority_(tree_priority), comparator_(tree_priority) { 1356 : initialized_(false),
1357 tile_manager_(tile_manager),
1358 tree_priority_(tree_priority),
1359 comparator_(tree_priority) {
1360 }
1361
1362 void TileManager::EvictionTileIterator::Initialize() {
1475 std::vector<TileManager::PairedPictureLayer> paired_layers; 1363 std::vector<TileManager::PairedPictureLayer> paired_layers;
1476 1364
1477 tile_manager->GetPairedPictureLayers(&paired_layers); 1365 tile_manager_->GetPairedPictureLayers(&paired_layers);
1478 1366
1479 paired_iterators_.reserve(paired_layers.size()); 1367 paired_iterators_.reserve(paired_layers.size());
1480 iterator_heap_.reserve(paired_layers.size()); 1368 iterator_heap_.reserve(paired_layers.size());
1481 for (std::vector<TileManager::PairedPictureLayer>::iterator it = 1369 for (std::vector<TileManager::PairedPictureLayer>::iterator it =
1482 paired_layers.begin(); 1370 paired_layers.begin();
1483 it != paired_layers.end(); 1371 it != paired_layers.end();
1484 ++it) { 1372 ++it) {
1485 PairedPictureLayerIterator paired_iterator; 1373 PairedPictureLayerIterator paired_iterator;
1486 if (it->active_layer) { 1374 if (it->active_layer) {
1487 paired_iterator.active_iterator = 1375 paired_iterator.active_iterator =
1488 PictureLayerImpl::LayerEvictionTileIterator(it->active_layer, 1376 PictureLayerImpl::LayerEvictionTileIterator(it->active_layer,
1489 tree_priority_); 1377 tree_priority_);
1490 } 1378 }
1491 1379
1492 if (it->pending_layer) { 1380 if (it->pending_layer) {
1493 paired_iterator.pending_iterator = 1381 paired_iterator.pending_iterator =
1494 PictureLayerImpl::LayerEvictionTileIterator(it->pending_layer, 1382 PictureLayerImpl::LayerEvictionTileIterator(it->pending_layer,
1495 tree_priority_); 1383 tree_priority_);
1496 } 1384 }
1497 1385
1498 if (paired_iterator.PeekTile(tree_priority_) != NULL) { 1386 if (paired_iterator.PeekTile(tree_priority_) != NULL) {
1499 paired_iterators_.push_back(paired_iterator); 1387 paired_iterators_.push_back(paired_iterator);
1500 iterator_heap_.push_back(&paired_iterators_.back()); 1388 iterator_heap_.push_back(&paired_iterators_.back());
1501 } 1389 }
1502 } 1390 }
1503 1391
1504 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); 1392 std::make_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1393 initialized_ = true;
1505 } 1394 }
1506 1395
1507 TileManager::EvictionTileIterator::~EvictionTileIterator() {} 1396 TileManager::EvictionTileIterator::~EvictionTileIterator() {}
1508 1397
1509 TileManager::EvictionTileIterator& TileManager::EvictionTileIterator:: 1398 TileManager::EvictionTileIterator& TileManager::EvictionTileIterator::
1510 operator++() { 1399 operator++() {
1400 DCHECK(initialized_);
1401
1511 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); 1402 std::pop_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1512 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back(); 1403 PairedPictureLayerIterator* paired_iterator = iterator_heap_.back();
1513 iterator_heap_.pop_back(); 1404 iterator_heap_.pop_back();
1514 1405
1515 paired_iterator->PopTile(tree_priority_); 1406 paired_iterator->PopTile(tree_priority_);
1516 if (paired_iterator->PeekTile(tree_priority_) != NULL) { 1407 if (paired_iterator->PeekTile(tree_priority_) != NULL) {
1517 iterator_heap_.push_back(paired_iterator); 1408 iterator_heap_.push_back(paired_iterator);
1518 std::push_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_); 1409 std::push_heap(iterator_heap_.begin(), iterator_heap_.end(), comparator_);
1519 } 1410 }
1520 return *this; 1411 return *this;
1521 } 1412 }
1522 1413
1523 TileManager::EvictionTileIterator::operator bool() const { 1414 TileManager::EvictionTileIterator::operator bool() {
1415 if (!initialized_)
1416 Initialize();
1417
1524 return !iterator_heap_.empty(); 1418 return !iterator_heap_.empty();
1525 } 1419 }
1526 1420
1527 Tile* TileManager::EvictionTileIterator::operator*() { 1421 Tile* TileManager::EvictionTileIterator::operator*() {
1422 DCHECK(initialized_);
1528 DCHECK(*this); 1423 DCHECK(*this);
1529 return iterator_heap_.front()->PeekTile(tree_priority_); 1424 return iterator_heap_.front()->PeekTile(tree_priority_);
1530 } 1425 }
1531 1426
1532 TileManager::EvictionTileIterator::PairedPictureLayerIterator:: 1427 TileManager::EvictionTileIterator::PairedPictureLayerIterator::
1533 PairedPictureLayerIterator() {} 1428 PairedPictureLayerIterator() {}
1534 1429
1535 TileManager::EvictionTileIterator::PairedPictureLayerIterator:: 1430 TileManager::EvictionTileIterator::PairedPictureLayerIterator::
1536 ~PairedPictureLayerIterator() {} 1431 ~PairedPictureLayerIterator() {}
1537 1432
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 1519
1625 if (b_priority.resolution != a_priority.resolution) { 1520 if (b_priority.resolution != a_priority.resolution) {
1626 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) || 1521 return (prioritize_low_res && b_priority.resolution == LOW_RESOLUTION) ||
1627 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) || 1522 (!prioritize_low_res && b_priority.resolution == HIGH_RESOLUTION) ||
1628 (a_priority.resolution == NON_IDEAL_RESOLUTION); 1523 (a_priority.resolution == NON_IDEAL_RESOLUTION);
1629 } 1524 }
1630 return a_priority.IsHigherPriorityThan(b_priority); 1525 return a_priority.IsHigherPriorityThan(b_priority);
1631 } 1526 }
1632 1527
1633 } // namespace cc 1528 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698