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

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

Issue 862263004: cc: Make eviction queue building consistent with raster. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 11 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
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 task_runner_.get(), 233 task_runner_.get(),
234 base::Bind(&TileManager::CheckIfReadyToActivate, 234 base::Bind(&TileManager::CheckIfReadyToActivate,
235 base::Unretained(this))), 235 base::Unretained(this))),
236 ready_to_draw_check_notifier_( 236 ready_to_draw_check_notifier_(
237 task_runner_.get(), 237 task_runner_.get(),
238 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))), 238 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))),
239 more_tiles_need_prepare_check_notifier_( 239 more_tiles_need_prepare_check_notifier_(
240 task_runner_.get(), 240 task_runner_.get(),
241 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, 241 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared,
242 base::Unretained(this))), 242 base::Unretained(this))),
243 eviction_priority_queue_is_up_to_date_(false),
244 did_notify_ready_to_activate_(false), 243 did_notify_ready_to_activate_(false),
245 did_notify_ready_to_draw_(false) { 244 did_notify_ready_to_draw_(false) {
246 tile_task_runner_->SetClient(this); 245 tile_task_runner_->SetClient(this);
247 } 246 }
248 247
249 TileManager::~TileManager() { 248 TileManager::~TileManager() {
250 // Reset global state and manage. This should cause 249 // Reset global state and manage. This should cause
251 // our memory usage to drop to zero. 250 // our memory usage to drop to zero.
252 global_state_ = GlobalStateThatImpactsTilePriority(); 251 global_state_ = GlobalStateThatImpactsTilePriority();
253 252
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 scheduled_raster_task_limit_, 366 scheduled_raster_task_limit_,
368 &tiles_that_need_to_be_rasterized); 367 &tiles_that_need_to_be_rasterized);
369 368
370 // Schedule tile tasks. 369 // Schedule tile tasks.
371 ScheduleTasks(tiles_that_need_to_be_rasterized); 370 ScheduleTasks(tiles_that_need_to_be_rasterized);
372 371
373 did_notify_ready_to_activate_ = false; 372 did_notify_ready_to_activate_ = false;
374 did_notify_ready_to_draw_ = false; 373 did_notify_ready_to_draw_ = false;
375 } else { 374 } else {
376 if (global_state_.hard_memory_limit_in_bytes == 0) { 375 if (global_state_.hard_memory_limit_in_bytes == 0) {
377 // TODO(vmpstr): Add a function to unconditionally create an eviction
378 // queue and guard the rest of the calls sites with this flag, instead of
379 // clearing here and building, which is a bit awkward.
380 eviction_priority_queue_is_up_to_date_ = false;
381 resource_pool_->CheckBusyResources(false); 376 resource_pool_->CheckBusyResources(false);
382 MemoryUsage memory_limit(0, 0); 377 MemoryUsage memory_limit(0, 0);
383 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), 378 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(),
384 resource_pool_->acquired_resource_count()); 379 resource_pool_->acquired_resource_count());
385 FreeTileResourcesUntilUsageIsWithinLimit(memory_limit, &memory_usage); 380 FreeTileResourcesUntilUsageIsWithinLimit(nullptr, memory_limit,
381 &memory_usage);
386 } 382 }
387 383
388 did_notify_ready_to_activate_ = false; 384 did_notify_ready_to_activate_ = false;
389 did_notify_ready_to_draw_ = false; 385 did_notify_ready_to_draw_ = false;
390 ready_to_activate_notifier_.Schedule(); 386 ready_to_activate_notifier_.Schedule();
391 ready_to_draw_notifier_.Schedule(); 387 ready_to_draw_notifier_.Schedule();
392 } 388 }
393 389
394 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD, 390 TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
395 "state", BasicStateAsValue()); 391 "state", BasicStateAsValue());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 } 480 }
485 481
486 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const { 482 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const {
487 state->SetInteger("tile_count", tiles_.size()); 483 state->SetInteger("tile_count", tiles_.size());
488 state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_); 484 state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_);
489 state->BeginDictionary("global_state"); 485 state->BeginDictionary("global_state");
490 global_state_.AsValueInto(state); 486 global_state_.AsValueInto(state);
491 state->EndDictionary(); 487 state->EndDictionary();
492 } 488 }
493 489
494 void TileManager::RebuildEvictionQueueIfNeeded() { 490 scoped_ptr<EvictionTilePriorityQueue>
495 TRACE_EVENT1("cc", 491 TileManager::FreeTileResourcesUntilUsageIsWithinLimit(
496 "TileManager::RebuildEvictionQueueIfNeeded", 492 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
497 "eviction_priority_queue_is_up_to_date",
498 eviction_priority_queue_is_up_to_date_);
499 if (eviction_priority_queue_is_up_to_date_)
500 return;
501
502 eviction_priority_queue_.Reset();
503 client_->BuildEvictionQueue(&eviction_priority_queue_,
504 global_state_.tree_priority);
505 eviction_priority_queue_is_up_to_date_ = true;
506 }
507
508 bool TileManager::FreeTileResourcesUntilUsageIsWithinLimit(
509 const MemoryUsage& limit, 493 const MemoryUsage& limit,
510 MemoryUsage* usage) { 494 MemoryUsage* usage) {
511 while (usage->Exceeds(limit)) { 495 while (usage->Exceeds(limit)) {
512 RebuildEvictionQueueIfNeeded(); 496 if (!eviction_priority_queue) {
513 if (eviction_priority_queue_.IsEmpty()) 497 eviction_priority_queue =
514 return false; 498 client_->BuildEvictionQueue(global_state_.tree_priority);
499 }
500 if (eviction_priority_queue->IsEmpty())
501 break;
515 502
516 Tile* tile = eviction_priority_queue_.Top(); 503 Tile* tile = eviction_priority_queue->Top();
517 *usage -= MemoryUsage::FromTile(tile); 504 *usage -= MemoryUsage::FromTile(tile);
518 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); 505 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
519 eviction_priority_queue_.Pop(); 506 eviction_priority_queue->Pop();
520 } 507 }
521 return true; 508 return eviction_priority_queue;
522 } 509 }
523 510
524 bool TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( 511 scoped_ptr<EvictionTilePriorityQueue>
512 TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
513 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
525 const MemoryUsage& limit, 514 const MemoryUsage& limit,
526 const TilePriority& other_priority, 515 const TilePriority& other_priority,
527 MemoryUsage* usage) { 516 MemoryUsage* usage) {
528 while (usage->Exceeds(limit)) { 517 while (usage->Exceeds(limit)) {
529 RebuildEvictionQueueIfNeeded(); 518 if (!eviction_priority_queue) {
530 if (eviction_priority_queue_.IsEmpty()) 519 eviction_priority_queue =
531 return false; 520 client_->BuildEvictionQueue(global_state_.tree_priority);
521 }
522 if (eviction_priority_queue->IsEmpty())
523 break;
532 524
533 Tile* tile = eviction_priority_queue_.Top(); 525 Tile* tile = eviction_priority_queue->Top();
534 if (!other_priority.IsHigherPriorityThan(tile->combined_priority())) 526 if (!other_priority.IsHigherPriorityThan(tile->combined_priority()))
535 return false; 527 break;
536 528
537 *usage -= MemoryUsage::FromTile(tile); 529 *usage -= MemoryUsage::FromTile(tile);
538 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); 530 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
539 eviction_priority_queue_.Pop(); 531 eviction_priority_queue->Pop();
540 } 532 }
541 return true; 533 return eviction_priority_queue;
542 } 534 }
543 535
544 bool TileManager::TilePriorityViolatesMemoryPolicy( 536 bool TileManager::TilePriorityViolatesMemoryPolicy(
545 const TilePriority& priority) { 537 const TilePriority& priority) {
546 switch (global_state_.memory_limit_policy) { 538 switch (global_state_.memory_limit_policy) {
547 case ALLOW_NOTHING: 539 case ALLOW_NOTHING:
548 return true; 540 return true;
549 case ALLOW_ABSOLUTE_MINIMUM: 541 case ALLOW_ABSOLUTE_MINIMUM:
550 return priority.priority_bin > TilePriority::NOW; 542 return priority.priority_bin > TilePriority::NOW;
551 case ALLOW_PREPAINT_ONLY: 543 case ALLOW_PREPAINT_ONLY:
(...skipping 24 matching lines...) Expand all
576 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; 568 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true;
577 bool had_enough_memory_to_schedule_tiles_needed_now = true; 569 bool had_enough_memory_to_schedule_tiles_needed_now = true;
578 570
579 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, 571 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes,
580 global_state_.num_resources_limit); 572 global_state_.num_resources_limit);
581 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, 573 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes,
582 global_state_.num_resources_limit); 574 global_state_.num_resources_limit);
583 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), 575 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(),
584 resource_pool_->acquired_resource_count()); 576 resource_pool_->acquired_resource_count());
585 577
586 eviction_priority_queue_is_up_to_date_ = false; 578 scoped_ptr<EvictionTilePriorityQueue> eviction_priority_queue;
587 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { 579 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
588 Tile* tile = raster_priority_queue->Top(); 580 Tile* tile = raster_priority_queue->Top();
589 TilePriority priority = tile->combined_priority(); 581 TilePriority priority = tile->combined_priority();
590 582
591 if (TilePriorityViolatesMemoryPolicy(priority)) { 583 if (TilePriorityViolatesMemoryPolicy(priority)) {
592 TRACE_EVENT_INSTANT0( 584 TRACE_EVENT_INSTANT0(
593 "cc", "TileManager::AssignGpuMemory tile violates memory policy", 585 "cc", "TileManager::AssignGpuMemory tile violates memory policy",
594 TRACE_EVENT_SCOPE_THREAD); 586 TRACE_EVENT_SCOPE_THREAD);
595 break; 587 break;
596 } 588 }
(...skipping 21 matching lines...) Expand all
618 } 610 }
619 611
620 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW; 612 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW;
621 613
622 // This is the memory limit that will be used by this tile. Depending on 614 // This is the memory limit that will be used by this tile. Depending on
623 // the tile priority, it will be one of hard_memory_limit or 615 // the tile priority, it will be one of hard_memory_limit or
624 // soft_memory_limit. 616 // soft_memory_limit.
625 MemoryUsage& tile_memory_limit = 617 MemoryUsage& tile_memory_limit =
626 tile_is_needed_now ? hard_memory_limit : soft_memory_limit; 618 tile_is_needed_now ? hard_memory_limit : soft_memory_limit;
627 619
620 const MemoryUsage& scheduled_tile_memory_limit =
621 tile_memory_limit - memory_required_by_tile_to_be_scheduled;
622 eviction_priority_queue =
623 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
624 eviction_priority_queue.Pass(), scheduled_tile_memory_limit,
625 priority, &memory_usage);
628 bool memory_usage_is_within_limit = 626 bool memory_usage_is_within_limit =
629 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( 627 !memory_usage.Exceeds(scheduled_tile_memory_limit);
630 tile_memory_limit - memory_required_by_tile_to_be_scheduled,
631 priority, &memory_usage);
632 628
633 // If we couldn't fit the tile into our current memory limit, then we're 629 // If we couldn't fit the tile into our current memory limit, then we're
634 // done. 630 // done.
635 if (!memory_usage_is_within_limit) { 631 if (!memory_usage_is_within_limit) {
636 if (tile_is_needed_now) 632 if (tile_is_needed_now)
637 had_enough_memory_to_schedule_tiles_needed_now = false; 633 had_enough_memory_to_schedule_tiles_needed_now = false;
638 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; 634 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
639 break; 635 break;
640 } 636 }
641 637
642 memory_usage += memory_required_by_tile_to_be_scheduled; 638 memory_usage += memory_required_by_tile_to_be_scheduled;
643 tiles_that_need_to_be_rasterized->push_back(tile); 639 tiles_that_need_to_be_rasterized->push_back(tile);
644 } 640 }
645 641
646 // Note that we should try and further reduce memory in case the above loop 642 // Note that we should try and further reduce memory in case the above loop
647 // didn't reduce memory. This ensures that we always release as many resources 643 // didn't reduce memory. This ensures that we always release as many resources
648 // as possible to stay within the memory limit. 644 // as possible to stay within the memory limit.
649 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage); 645 eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit(
646 eviction_priority_queue.Pass(), hard_memory_limit, &memory_usage);
650 647
651 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", 648 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget",
652 !had_enough_memory_to_schedule_tiles_needed_now); 649 !had_enough_memory_to_schedule_tiles_needed_now);
653 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; 650 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now;
654 651
655 memory_stats_from_last_assign_.total_budget_in_bytes = 652 memory_stats_from_last_assign_.total_budget_in_bytes =
656 global_state_.hard_memory_limit_in_bytes; 653 global_state_.hard_memory_limit_in_bytes;
657 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); 654 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes();
658 memory_stats_from_last_assign_.had_enough_memory = 655 memory_stats_from_last_assign_.had_enough_memory =
659 had_enough_memory_to_schedule_tiles_needed_now; 656 had_enough_memory_to_schedule_tiles_needed_now;
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 result -= other; 1040 result -= other;
1044 return result; 1041 return result;
1045 } 1042 }
1046 1043
1047 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { 1044 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const {
1048 return memory_bytes_ > limit.memory_bytes_ || 1045 return memory_bytes_ > limit.memory_bytes_ ||
1049 resource_count_ > limit.resource_count_; 1046 resource_count_ > limit.resource_count_;
1050 } 1047 }
1051 1048
1052 } // namespace cc 1049 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/tile_manager.h ('k') | cc/resources/tile_manager_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698