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

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

Issue 140673009: CC/GPU: Add a soft limit to the compositor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 6 years, 10 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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 } 454 }
455 } 455 }
456 456
457 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) { 457 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
458 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 458 TRACE_EVENT0("cc", "TileManager::ManageTiles");
459 459
460 // Update internal state. 460 // Update internal state.
461 if (state != global_state_) { 461 if (state != global_state_) {
462 global_state_ = state; 462 global_state_ = state;
463 prioritized_tiles_dirty_ = true; 463 prioritized_tiles_dirty_ = true;
464 // Soft limit is used for resource pool such that
465 // memory returns to soft limit after going over.
464 resource_pool_->SetResourceUsageLimits( 466 resource_pool_->SetResourceUsageLimits(
465 global_state_.memory_limit_in_bytes, 467 global_state_.soft_memory_limit_in_bytes,
466 global_state_.unused_memory_limit_in_bytes, 468 global_state_.unused_memory_limit_in_bytes,
467 global_state_.num_resources_limit); 469 global_state_.num_resources_limit);
468 } 470 }
469 471
470 // We need to call CheckForCompletedTasks() once in-between each call 472 // We need to call CheckForCompletedTasks() once in-between each call
471 // to ScheduleTasks() to prevent canceled tasks from being scheduled. 473 // to ScheduleTasks() to prevent canceled tasks from being scheduled.
472 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { 474 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
473 raster_worker_pool_->CheckForCompletedTasks(); 475 raster_worker_pool_->CheckForCompletedTasks();
474 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; 476 did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
475 } 477 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 // resource(s) was returned. Note that in that case, one also need to 593 // resource(s) was returned. Note that in that case, one also need to
592 // invalidate when releasing some resource from the pool. 594 // invalidate when releasing some resource from the pool.
593 resource_pool_->CheckBusyResources(); 595 resource_pool_->CheckBusyResources();
594 596
595 // Now give memory out to the tiles until we're out, and build 597 // Now give memory out to the tiles until we're out, and build
596 // the needs-to-be-rasterized queue. 598 // the needs-to-be-rasterized queue.
597 all_tiles_that_need_to_be_rasterized_have_memory_ = true; 599 all_tiles_that_need_to_be_rasterized_have_memory_ = true;
598 all_tiles_required_for_activation_have_memory_ = true; 600 all_tiles_required_for_activation_have_memory_ = true;
599 601
600 // Cast to prevent overflow. 602 // Cast to prevent overflow.
601 int64 bytes_available = 603 int64 soft_bytes_available =
602 static_cast<int64>(bytes_releasable_) + 604 static_cast<int64>(bytes_releasable_) +
603 static_cast<int64>(global_state_.memory_limit_in_bytes) - 605 static_cast<int64>(global_state_.soft_memory_limit_in_bytes) -
606 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
607 int64 hard_bytes_available =
608 static_cast<int64>(bytes_releasable_) +
609 static_cast<int64>(global_state_.hard_memory_limit_in_bytes) -
604 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); 610 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
605 int resources_available = resources_releasable_ + 611 int resources_available = resources_releasable_ +
606 global_state_.num_resources_limit - 612 global_state_.num_resources_limit -
607 resource_pool_->acquired_resource_count(); 613 resource_pool_->acquired_resource_count();
608 614 size_t soft_bytes_allocatable =
609 size_t bytes_allocatable = std::max(static_cast<int64>(0), bytes_available); 615 std::max(static_cast<int64>(0), soft_bytes_available);
616 size_t hard_bytes_allocatable =
617 std::max(static_cast<int64>(0), hard_bytes_available);
610 size_t resources_allocatable = std::max(0, resources_available); 618 size_t resources_allocatable = std::max(0, resources_available);
611 619
612 size_t bytes_that_exceeded_memory_budget = 0; 620 size_t bytes_that_exceeded_memory_budget = 0;
613 size_t bytes_left = bytes_allocatable; 621 size_t soft_bytes_left = soft_bytes_allocatable;
622 size_t hard_bytes_left = hard_bytes_allocatable;
623
614 size_t resources_left = resources_allocatable; 624 size_t resources_left = resources_allocatable;
615 bool oomed = false; 625 bool oomed_soft = false;
626 bool oomed_hard = false;
616 627
617 // Memory we assign to raster tasks now will be deducted from our memory 628 // Memory we assign to raster tasks now will be deducted from our memory
618 // in future iterations if priorities change. By assigning at most half 629 // in future iterations if priorities change. By assigning at most half
619 // the raster limit, we will always have another 50% left even if priorities 630 // the raster limit, we will always have another 50% left even if priorities
620 // change completely (assuming we check for completed/cancelled rasters 631 // change completely (assuming we check for completed/cancelled rasters
621 // between each call to this function). 632 // between each call to this function).
622 size_t max_raster_bytes = max_raster_usage_bytes_ / 2; 633 size_t max_raster_bytes = max_raster_usage_bytes_ / 2;
623 size_t raster_bytes = 0; 634 size_t raster_bytes = 0;
624 635
625 unsigned schedule_priority = 1u; 636 unsigned schedule_priority = 1u;
(...skipping 11 matching lines...) Expand all
637 // If this tile doesn't need a resource, then nothing to do. 648 // If this tile doesn't need a resource, then nothing to do.
638 if (!tile_version.requires_resource()) 649 if (!tile_version.requires_resource())
639 continue; 650 continue;
640 651
641 // If the tile is not needed, free it up. 652 // If the tile is not needed, free it up.
642 if (mts.bin == NEVER_BIN) { 653 if (mts.bin == NEVER_BIN) {
643 FreeResourcesForTile(tile); 654 FreeResourcesForTile(tile);
644 continue; 655 continue;
645 } 656 }
646 657
647 size_t bytes_if_allocated = BytesConsumedIfAllocated(tile); 658 const bool tile_uses_hard_limit = mts.bin <= NOW_BIN;
648 size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated; 659 const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile);
660 const size_t raster_bytes_if_rastered = raster_bytes + bytes_if_allocated;
661 const size_t tile_bytes_left =
662 (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left;
649 663
650 size_t tile_bytes = 0; 664 size_t tile_bytes = 0;
651 size_t tile_resources = 0; 665 size_t tile_resources = 0;
652 666
653 // It costs to maintain a resource. 667 // It costs to maintain a resource.
654 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { 668 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
655 if (mts.tile_versions[mode].resource_) { 669 if (mts.tile_versions[mode].resource_) {
656 tile_bytes += bytes_if_allocated; 670 tile_bytes += bytes_if_allocated;
657 tile_resources++; 671 tile_resources++;
658 } 672 }
659 } 673 }
660 674
661 // Allow lower priority tiles with initialized resources to keep 675 // Allow lower priority tiles with initialized resources to keep
662 // their memory by only assigning memory to new raster tasks if 676 // their memory by only assigning memory to new raster tasks if
663 // they can be scheduled. 677 // they can be scheduled.
664 if (raster_bytes_if_rastered <= max_raster_bytes) { 678 if (raster_bytes_if_rastered <= max_raster_bytes) {
665 // If we don't have the required version, and it's not in flight 679 // If we don't have the required version, and it's not in flight
666 // then we'll have to pay to create a new task. 680 // then we'll have to pay to create a new task.
667 if (!tile_version.resource_ && tile_version.raster_task_.is_null()) { 681 if (!tile_version.resource_ && tile_version.raster_task_.is_null()) {
668 tile_bytes += bytes_if_allocated; 682 tile_bytes += bytes_if_allocated;
669 tile_resources++; 683 tile_resources++;
670 } 684 }
671 } 685 }
672 686
673 // Tile is OOM. 687 // Tile is OOM.
674 if (tile_bytes > bytes_left || tile_resources > resources_left) { 688 if (tile_bytes > tile_bytes_left || tile_resources > resources_left) {
675 FreeResourcesForTile(tile); 689 FreeResourcesForTile(tile);
676 690
677 // This tile was already on screen and now its resources have been 691 // This tile was already on screen and now its resources have been
678 // released. In order to prevent checkerboarding, set this tile as 692 // released. In order to prevent checkerboarding, set this tile as
679 // rasterize on demand immediately. 693 // rasterize on demand immediately.
680 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_) 694 if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_)
681 tile_version.set_rasterize_on_demand(); 695 tile_version.set_rasterize_on_demand();
682 696
683 oomed = true; 697 oomed_soft = true;
684 bytes_that_exceeded_memory_budget += tile_bytes; 698 if (tile_uses_hard_limit) {
699 oomed_hard = true;
700 bytes_that_exceeded_memory_budget += tile_bytes;
701 }
685 } else { 702 } else {
686 bytes_left -= tile_bytes;
687 resources_left -= tile_resources; 703 resources_left -= tile_resources;
688 704 hard_bytes_left -= tile_bytes;
705 soft_bytes_left =
706 (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0;
689 if (tile_version.resource_) 707 if (tile_version.resource_)
690 continue; 708 continue;
691 } 709 }
692 710
693 DCHECK(!tile_version.resource_); 711 DCHECK(!tile_version.resource_);
694 712
695 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized| 713 // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized|
696 // has reached it's limit or we've failed to assign gpu memory to this 714 // has reached it's limit or we've failed to assign gpu memory to this
697 // or any higher priority tile. Preventing tiles that fit into memory 715 // or any higher priority tile. Preventing tiles that fit into memory
698 // budget to be rasterized when higher priority tile is oom is 716 // budget to be rasterized when higher priority tile is oom is
699 // important for two reasons: 717 // important for two reasons:
700 // 1. Tile size should not impact raster priority. 718 // 1. Tile size should not impact raster priority.
701 // 2. Tiles with existing raster task could otherwise incorrectly 719 // 2. Tiles with existing raster task could otherwise incorrectly
702 // be added as they are not affected by |bytes_allocatable|. 720 // be added as they are not affected by |bytes_allocatable|.
703 if (oomed || raster_bytes_if_rastered > max_raster_bytes) { 721 if (oomed_soft || raster_bytes_if_rastered > max_raster_bytes) {
704 all_tiles_that_need_to_be_rasterized_have_memory_ = false; 722 all_tiles_that_need_to_be_rasterized_have_memory_ = false;
705 if (tile->required_for_activation()) 723 if (tile->required_for_activation())
706 all_tiles_required_for_activation_have_memory_ = false; 724 all_tiles_required_for_activation_have_memory_ = false;
707 it.DisablePriorityOrdering(); 725 it.DisablePriorityOrdering();
708 continue; 726 continue;
709 } 727 }
710 728
711 raster_bytes = raster_bytes_if_rastered; 729 raster_bytes = raster_bytes_if_rastered;
712 tiles_that_need_to_be_rasterized->push_back(tile); 730 tiles_that_need_to_be_rasterized->push_back(tile);
713 } 731 }
714 732
715 ever_exceeded_memory_budget_ |= bytes_that_exceeded_memory_budget > 0; 733 // OOM reporting uses hard-limit, soft-OOM is normal depending on limit.
734 ever_exceeded_memory_budget_ |= oomed_hard;
716 if (ever_exceeded_memory_budget_) { 735 if (ever_exceeded_memory_budget_) {
717 TRACE_COUNTER_ID2("cc", 736 TRACE_COUNTER_ID2("cc",
718 "over_memory_budget", 737 "over_memory_budget",
719 this, 738 this,
720 "budget", 739 "budget",
721 global_state_.memory_limit_in_bytes, 740 global_state_.hard_memory_limit_in_bytes,
722 "over", 741 "over",
723 bytes_that_exceeded_memory_budget); 742 bytes_that_exceeded_memory_budget);
724 } 743 }
725 memory_stats_from_last_assign_.total_budget_in_bytes = 744 memory_stats_from_last_assign_.total_budget_in_bytes =
726 global_state_.memory_limit_in_bytes; 745 global_state_.hard_memory_limit_in_bytes;
727 memory_stats_from_last_assign_.bytes_allocated = 746 memory_stats_from_last_assign_.bytes_allocated =
728 bytes_allocatable - bytes_left; 747 hard_bytes_allocatable - hard_bytes_left;
729 memory_stats_from_last_assign_.bytes_unreleasable = 748 memory_stats_from_last_assign_.bytes_unreleasable =
730 bytes_allocatable - bytes_releasable_; 749 hard_bytes_allocatable - bytes_releasable_;
731 memory_stats_from_last_assign_.bytes_over = bytes_that_exceeded_memory_budget; 750 memory_stats_from_last_assign_.bytes_over = bytes_that_exceeded_memory_budget;
732 } 751 }
733 752
734 void TileManager::FreeResourceForTile(Tile* tile, RasterMode mode) { 753 void TileManager::FreeResourceForTile(Tile* tile, RasterMode mode) {
735 ManagedTileState& mts = tile->managed_state(); 754 ManagedTileState& mts = tile->managed_state();
736 if (mts.tile_versions[mode].resource_) { 755 if (mts.tile_versions[mode].resource_) {
737 resource_pool_->ReleaseResource(mts.tile_versions[mode].resource_.Pass()); 756 resource_pool_->ReleaseResource(mts.tile_versions[mode].resource_.Pass());
738 757
739 DCHECK_GE(bytes_releasable_, BytesConsumedIfAllocated(tile)); 758 DCHECK_GE(bytes_releasable_, BytesConsumedIfAllocated(tile));
740 DCHECK_GE(resources_releasable_, 1u); 759 DCHECK_GE(resources_releasable_, 1u);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 flags)); 976 flags));
958 DCHECK(tiles_.find(tile->id()) == tiles_.end()); 977 DCHECK(tiles_.find(tile->id()) == tiles_.end());
959 978
960 tiles_[tile->id()] = tile; 979 tiles_[tile->id()] = tile;
961 used_layer_counts_[tile->layer_id()]++; 980 used_layer_counts_[tile->layer_id()]++;
962 prioritized_tiles_dirty_ = true; 981 prioritized_tiles_dirty_ = true;
963 return tile; 982 return tile;
964 } 983 }
965 984
966 } // namespace cc 985 } // 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