| OLD | NEW |
| 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/tile_manager.h" | 5 #include "cc/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 bool use_cheapness_estimator) | 180 bool use_cheapness_estimator) |
| 181 : client_(client), | 181 : client_(client), |
| 182 resource_pool_(ResourcePool::Create(resource_provider)), | 182 resource_pool_(ResourcePool::Create(resource_provider)), |
| 183 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 183 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
| 184 manage_tiles_pending_(false), | 184 manage_tiles_pending_(false), |
| 185 manage_tiles_call_count_(0), | 185 manage_tiles_call_count_(0), |
| 186 bytes_pending_set_pixels_(0), | 186 bytes_pending_set_pixels_(0), |
| 187 has_performed_uploads_since_last_flush_(false), | 187 has_performed_uploads_since_last_flush_(false), |
| 188 ever_exceeded_memory_budget_(false), | 188 ever_exceeded_memory_budget_(false), |
| 189 record_rendering_stats_(false), | 189 record_rendering_stats_(false), |
| 190 use_cheapness_estimator_(use_cheapness_estimator) { | 190 use_cheapness_estimator_(use_cheapness_estimator), |
| 191 allow_cheap_tasks_(true), |
| 192 did_schedule_cheap_tasks_(false) { |
| 191 for (int i = 0; i < NUM_STATES; ++i) { | 193 for (int i = 0; i < NUM_STATES; ++i) { |
| 192 for (int j = 0; j < NUM_TREES; ++j) { | 194 for (int j = 0; j < NUM_TREES; ++j) { |
| 193 for (int k = 0; k < NUM_BINS; ++k) | 195 for (int k = 0; k < NUM_BINS; ++k) |
| 194 raster_state_count_[i][j][k] = 0; | 196 raster_state_count_[i][j][k] = 0; |
| 195 } | 197 } |
| 196 } | 198 } |
| 197 } | 199 } |
| 198 | 200 |
| 199 TileManager::~TileManager() { | 201 TileManager::~TileManager() { |
| 200 // Reset global state and manage. This should cause | 202 // Reset global state and manage. This should cause |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 managed_tile_state.can_be_freed = true; | 437 managed_tile_state.can_be_freed = true; |
| 436 managed_tile_state.can_use_gpu_memory = false; | 438 managed_tile_state.can_use_gpu_memory = false; |
| 437 FreeResourcesForTile(tile); | 439 FreeResourcesForTile(tile); |
| 438 | 440 |
| 439 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 441 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); |
| 440 DidTileRasterStateChange(tile, IDLE_STATE); | 442 DidTileRasterStateChange(tile, IDLE_STATE); |
| 441 tiles_with_pending_set_pixels_.pop(); | 443 tiles_with_pending_set_pixels_.pop(); |
| 442 } | 444 } |
| 443 } | 445 } |
| 444 | 446 |
| 447 void TileManager::DidCompleteFrame() { |
| 448 allow_cheap_tasks_ = true; |
| 449 did_schedule_cheap_tasks_ = false; |
| 450 } |
| 451 |
| 445 void TileManager::GetMemoryStats( | 452 void TileManager::GetMemoryStats( |
| 446 size_t* memoryRequiredBytes, | 453 size_t* memoryRequiredBytes, |
| 447 size_t* memoryNiceToHaveBytes, | 454 size_t* memoryNiceToHaveBytes, |
| 448 size_t* memoryUsedBytes) const { | 455 size_t* memoryUsedBytes) const { |
| 449 *memoryRequiredBytes = 0; | 456 *memoryRequiredBytes = 0; |
| 450 *memoryNiceToHaveBytes = 0; | 457 *memoryNiceToHaveBytes = 0; |
| 451 *memoryUsedBytes = 0; | 458 *memoryUsedBytes = 0; |
| 452 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 459 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
| 453 const Tile* tile = live_or_allocated_tiles_[i]; | 460 const Tile* tile = live_or_allocated_tiles_[i]; |
| 454 const ManagedTileState& mts = tile->managed_state(); | 461 const ManagedTileState& mts = tile->managed_state(); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 tiles_that_need_to_be_rasterized_.end()); | 639 tiles_that_need_to_be_rasterized_.end()); |
| 633 } | 640 } |
| 634 | 641 |
| 635 void TileManager::FreeResourcesForTile(Tile* tile) { | 642 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 636 ManagedTileState& managed_tile_state = tile->managed_state(); | 643 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 637 DCHECK(managed_tile_state.can_be_freed); | 644 DCHECK(managed_tile_state.can_be_freed); |
| 638 if (managed_tile_state.resource) | 645 if (managed_tile_state.resource) |
| 639 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 646 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
| 640 } | 647 } |
| 641 | 648 |
| 642 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 649 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
| 643 if (raster_worker_pool_->IsBusy()) | 650 if (raster_worker_pool_->IsBusy()) |
| 644 return false; | 651 return false; |
| 645 size_t new_bytes_pending = bytes_pending_set_pixels_; | 652 size_t new_bytes_pending = bytes_pending_set_pixels_; |
| 646 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 653 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
| 647 return new_bytes_pending <= kMaxPendingUploadBytes && | 654 return new_bytes_pending <= kMaxPendingUploadBytes && |
| 648 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; | 655 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; |
| 649 } | 656 } |
| 650 | 657 |
| 651 void TileManager::DispatchMoreTasks() { | 658 void TileManager::DispatchMoreTasks() { |
| 652 // Because tiles in the image decoding list have higher priorities, we | 659 // Because tiles in the image decoding list have higher priorities, we |
| 653 // need to process those tiles first before we start to handle the tiles | 660 // need to process those tiles first before we start to handle the tiles |
| 654 // in the need_to_be_rasterized queue. | 661 // in the need_to_be_rasterized queue. |
| 655 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 662 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| 656 it != tiles_with_image_decoding_tasks_.end(); ) { | 663 it != tiles_with_image_decoding_tasks_.end(); ) { |
| 657 DispatchImageDecodeTasksForTile(*it); | 664 DispatchImageDecodeTasksForTile(*it); |
| 658 ManagedTileState& managed_state = (*it)->managed_state(); | 665 ManagedTileState& managed_state = (*it)->managed_state(); |
| 659 if (managed_state.pending_pixel_refs.empty()) { | 666 if (managed_state.pending_pixel_refs.empty()) { |
| 660 if (!CanDispatchRasterTask(*it)) | 667 if (!CanDispatchRasterTask(*it)) |
| 661 return; | 668 break; |
| 662 DispatchOneRasterTask(*it); | 669 DispatchOneRasterTask(*it); |
| 663 tiles_with_image_decoding_tasks_.erase(it++); | 670 tiles_with_image_decoding_tasks_.erase(it++); |
| 664 } else { | 671 } else { |
| 665 ++it; | 672 ++it; |
| 666 } | 673 } |
| 667 } | 674 } |
| 668 | 675 |
| 669 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 676 // Process all tiles in the need_to_be_rasterized queue. If a tile has |
| 670 // image decoding tasks, put it to the back of the image decoding list. | 677 // image decoding tasks, put it to the back of the image decoding list. |
| 671 while (!tiles_that_need_to_be_rasterized_.empty()) { | 678 while (!tiles_that_need_to_be_rasterized_.empty()) { |
| 672 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 679 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
| 673 DispatchImageDecodeTasksForTile(tile); | 680 DispatchImageDecodeTasksForTile(tile); |
| 674 ManagedTileState& managed_state = tile->managed_state(); | 681 ManagedTileState& managed_state = tile->managed_state(); |
| 675 if (!managed_state.pending_pixel_refs.empty()) { | 682 if (!managed_state.pending_pixel_refs.empty()) { |
| 676 tiles_with_image_decoding_tasks_.push_back(tile); | 683 tiles_with_image_decoding_tasks_.push_back(tile); |
| 677 } else { | 684 } else { |
| 678 if (!CanDispatchRasterTask(tile)) | 685 if (!CanDispatchRasterTask(tile)) |
| 679 return; | 686 break; |
| 680 DispatchOneRasterTask(tile); | 687 DispatchOneRasterTask(tile); |
| 681 } | 688 } |
| 682 tiles_that_need_to_be_rasterized_.pop_back(); | 689 tiles_that_need_to_be_rasterized_.pop_back(); |
| 683 } | 690 } |
| 691 |
| 692 if (did_schedule_cheap_tasks_) |
| 693 allow_cheap_tasks_ = false; |
| 684 } | 694 } |
| 685 | 695 |
| 686 void TileManager::GatherPixelRefsForTile(Tile* tile) { | 696 void TileManager::GatherPixelRefsForTile(Tile* tile) { |
| 687 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); | 697 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); |
| 688 ManagedTileState& managed_state = tile->managed_state(); | 698 ManagedTileState& managed_state = tile->managed_state(); |
| 689 if (managed_state.need_to_gather_pixel_refs) { | 699 if (managed_state.need_to_gather_pixel_refs) { |
| 690 base::TimeTicks gather_begin_time; | 700 base::TimeTicks gather_begin_time; |
| 691 if (record_rendering_stats_) | 701 if (record_rendering_stats_) |
| 692 gather_begin_time = base::TimeTicks::Now(); | 702 gather_begin_time = base::TimeTicks::Now(); |
| 693 tile->picture_pile()->GatherPixelRefs( | 703 tile->picture_pile()->GatherPixelRefs( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 | 739 |
| 730 void TileManager::DispatchOneImageDecodeTask( | 740 void TileManager::DispatchOneImageDecodeTask( |
| 731 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | 741 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
| 732 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | 742 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); |
| 733 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | 743 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
| 734 DCHECK(pending_decode_tasks_.end() == | 744 DCHECK(pending_decode_tasks_.end() == |
| 735 pending_decode_tasks_.find(pixel_ref_id)); | 745 pending_decode_tasks_.find(pixel_ref_id)); |
| 736 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | 746 pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
| 737 | 747 |
| 738 raster_worker_pool_->PostTaskAndReply( | 748 raster_worker_pool_->PostTaskAndReply( |
| 739 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), | 749 base::Bind(&TileManager::PerformImageDecode, pixel_ref), |
| 740 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 750 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
| 741 base::Unretained(this), | 751 base::Unretained(this), |
| 742 tile, | 752 tile, |
| 743 pixel_ref_id)); | 753 pixel_ref_id)); |
| 744 } | 754 } |
| 745 | 755 |
| 746 void TileManager::OnImageDecodeTaskCompleted( | 756 void TileManager::OnImageDecodeTaskCompleted( |
| 747 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 757 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
| 748 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 758 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
| 749 pending_decode_tasks_.erase(pixel_ref_id); | 759 pending_decode_tasks_.erase(pixel_ref_id); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 775 | 785 |
| 776 DidTileRasterStateChange(tile, RASTER_STATE); | 786 DidTileRasterStateChange(tile, RASTER_STATE); |
| 777 return resource.Pass(); | 787 return resource.Pass(); |
| 778 } | 788 } |
| 779 | 789 |
| 780 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 790 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
| 781 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 791 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
| 782 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 792 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
| 783 ResourceProvider::ResourceId resource_id = resource->id(); | 793 ResourceProvider::ResourceId resource_id = resource->id(); |
| 784 | 794 |
| 795 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && |
| 796 tile->picture_pile()->IsCheapInRect(tile->content_rect_, |
| 797 tile->contents_scale()); |
| 785 raster_worker_pool_->PostRasterTaskAndReply( | 798 raster_worker_pool_->PostRasterTaskAndReply( |
| 786 tile->picture_pile(), | 799 tile->picture_pile(), |
| 800 is_cheap, |
| 787 base::Bind(&TileManager::PerformRaster, | 801 base::Bind(&TileManager::PerformRaster, |
| 788 resource_pool_->resource_provider()->mapPixelBuffer( | 802 resource_pool_->resource_provider()->mapPixelBuffer( |
| 789 resource_id), | 803 resource_id), |
| 790 tile->content_rect_, | 804 tile->content_rect_, |
| 791 tile->contents_scale(), | 805 tile->contents_scale(), |
| 792 use_cheapness_estimator_, | 806 use_cheapness_estimator_, |
| 793 GetRasterTaskMetadata(tile->managed_state())), | 807 GetRasterTaskMetadata(tile->managed_state())), |
| 794 base::Bind(&TileManager::OnRasterTaskCompleted, | 808 base::Bind(&TileManager::OnRasterTaskCompleted, |
| 795 base::Unretained(this), | 809 base::Unretained(this), |
| 796 tile, | 810 tile, |
| 797 base::Passed(&resource), | 811 base::Passed(&resource), |
| 798 manage_tiles_call_count_)); | 812 manage_tiles_call_count_)); |
| 799 } | 813 did_schedule_cheap_tasks_ |= is_cheap; |
| 800 | |
| 801 void TileManager::PerformOneRaster(Tile* tile) { | |
| 802 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
| 803 ResourceProvider::ResourceId resource_id = resource->id(); | |
| 804 | |
| 805 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | |
| 806 resource_id), | |
| 807 tile->content_rect_, | |
| 808 tile->contents_scale(), | |
| 809 use_cheapness_estimator_, | |
| 810 GetRasterTaskMetadata(tile->managed_state()), | |
| 811 tile->picture_pile(), | |
| 812 &rendering_stats_); | |
| 813 | |
| 814 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | |
| 815 } | 814 } |
| 816 | 815 |
| 817 void TileManager::OnRasterCompleted( | 816 void TileManager::OnRasterCompleted( |
| 818 scoped_refptr<Tile> tile, | 817 scoped_refptr<Tile> tile, |
| 819 scoped_ptr<ResourcePool::Resource> resource, | 818 scoped_ptr<ResourcePool::Resource> resource, |
| 820 int manage_tiles_call_count_when_dispatched) { | 819 int manage_tiles_call_count_when_dispatched) { |
| 821 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 820 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); |
| 822 | 821 |
| 823 // Release raster resources. | 822 // Release raster resources. |
| 824 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 823 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 base::TimeTicks end_time = base::TimeTicks::Now(); | 944 base::TimeTicks end_time = base::TimeTicks::Now(); |
| 946 base::TimeDelta duration = end_time - begin_time; | 945 base::TimeDelta duration = end_time - begin_time; |
| 947 stats->totalRasterizeTime += duration; | 946 stats->totalRasterizeTime += duration; |
| 948 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 947 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
| 949 duration.InMilliseconds(), | 948 duration.InMilliseconds(), |
| 950 0, | 949 0, |
| 951 10, | 950 10, |
| 952 10); | 951 10); |
| 953 | 952 |
| 954 if (use_cheapness_estimator) { | 953 if (use_cheapness_estimator) { |
| 955 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal
e); | 954 bool is_predicted_cheap = picture_pile->IsCheapInRect(rect, contents_scale
); |
| 956 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 955 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
| 957 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 956 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
| 958 } | 957 } |
| 959 } | 958 } |
| 960 } | 959 } |
| 961 | 960 |
| 962 // static | 961 // static |
| 963 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 962 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
| 964 bool is_actually_cheap) { | 963 bool is_actually_cheap) { |
| 965 if (is_predicted_cheap && !is_actually_cheap) | 964 if (is_predicted_cheap && !is_actually_cheap) |
| 966 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 965 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
| 967 else if (!is_predicted_cheap && is_actually_cheap) | 966 else if (!is_predicted_cheap && is_actually_cheap) |
| 968 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 967 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
| 969 | 968 |
| 970 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 969 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
| 971 is_predicted_cheap == is_actually_cheap); | 970 is_predicted_cheap == is_actually_cheap); |
| 972 } | 971 } |
| 973 | 972 |
| 974 // static | 973 // static |
| 975 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 974 void TileManager::PerformImageDecode(skia::LazyPixelRef* pixel_ref, |
| 976 RenderingStats* stats) { | 975 RenderingStats* stats) { |
| 977 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 976 TRACE_EVENT0("cc", "TileManager::PerformImageDecode"); |
| 978 base::TimeTicks decode_begin_time; | 977 base::TimeTicks decode_begin_time; |
| 979 if (stats) | 978 if (stats) |
| 980 decode_begin_time = base::TimeTicks::Now(); | 979 decode_begin_time = base::TimeTicks::Now(); |
| 981 pixel_ref->Decode(); | 980 pixel_ref->Decode(); |
| 982 if (stats) { | 981 if (stats) { |
| 983 stats->totalDeferredImageDecodeCount++; | 982 stats->totalDeferredImageDecodeCount++; |
| 984 stats->totalDeferredImageDecodeTime += | 983 stats->totalDeferredImageDecodeTime += |
| 985 base::TimeTicks::Now() - decode_begin_time; | 984 base::TimeTicks::Now() - decode_begin_time; |
| 986 } | 985 } |
| 987 } | 986 } |
| 988 | 987 |
| 989 } // namespace cc | 988 } // namespace cc |
| OLD | NEW |