Chromium Code Reviews| 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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 bool use_cheapness_estimator) | 187 bool use_cheapness_estimator) |
| 188 : client_(client), | 188 : client_(client), |
| 189 resource_pool_(ResourcePool::Create(resource_provider)), | 189 resource_pool_(ResourcePool::Create(resource_provider)), |
| 190 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 190 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
| 191 manage_tiles_pending_(false), | 191 manage_tiles_pending_(false), |
| 192 manage_tiles_call_count_(0), | 192 manage_tiles_call_count_(0), |
| 193 bytes_pending_set_pixels_(0), | 193 bytes_pending_set_pixels_(0), |
| 194 has_performed_uploads_since_last_flush_(false), | 194 has_performed_uploads_since_last_flush_(false), |
| 195 ever_exceeded_memory_budget_(false), | 195 ever_exceeded_memory_budget_(false), |
| 196 record_rendering_stats_(false), | 196 record_rendering_stats_(false), |
| 197 use_cheapness_estimator_(use_cheapness_estimator) { | 197 use_cheapness_estimator_(use_cheapness_estimator), |
| 198 allow_cheap_tasks_(true), | |
| 199 did_schedule_cheap_tasks_(false) { | |
| 198 for (int i = 0; i < NUM_STATES; ++i) { | 200 for (int i = 0; i < NUM_STATES; ++i) { |
| 199 for (int j = 0; j < NUM_TREES; ++j) { | 201 for (int j = 0; j < NUM_TREES; ++j) { |
| 200 for (int k = 0; k < NUM_BINS; ++k) | 202 for (int k = 0; k < NUM_BINS; ++k) |
| 201 raster_state_count_[i][j][k] = 0; | 203 raster_state_count_[i][j][k] = 0; |
| 202 } | 204 } |
| 203 } | 205 } |
| 204 } | 206 } |
| 205 | 207 |
| 206 TileManager::~TileManager() { | 208 TileManager::~TileManager() { |
| 207 // Reset global state and manage. This should cause | 209 // Reset global state and manage. This should cause |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 managed_tile_state.can_be_freed = true; | 449 managed_tile_state.can_be_freed = true; |
| 448 managed_tile_state.can_use_gpu_memory = false; | 450 managed_tile_state.can_use_gpu_memory = false; |
| 449 FreeResourcesForTile(tile); | 451 FreeResourcesForTile(tile); |
| 450 | 452 |
| 451 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 453 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); |
| 452 DidTileRasterStateChange(tile, IDLE_STATE); | 454 DidTileRasterStateChange(tile, IDLE_STATE); |
| 453 tiles_with_pending_set_pixels_.pop(); | 455 tiles_with_pending_set_pixels_.pop(); |
| 454 } | 456 } |
| 455 } | 457 } |
| 456 | 458 |
| 459 void TileManager::DidCompleteFrame() { | |
| 460 allow_cheap_tasks_ = true; | |
| 461 did_schedule_cheap_tasks_ = false; | |
| 462 } | |
| 463 | |
| 457 void TileManager::GetMemoryStats( | 464 void TileManager::GetMemoryStats( |
| 458 size_t* memoryRequiredBytes, | 465 size_t* memoryRequiredBytes, |
| 459 size_t* memoryNiceToHaveBytes, | 466 size_t* memoryNiceToHaveBytes, |
| 460 size_t* memoryUsedBytes) const { | 467 size_t* memoryUsedBytes) const { |
| 461 *memoryRequiredBytes = 0; | 468 *memoryRequiredBytes = 0; |
| 462 *memoryNiceToHaveBytes = 0; | 469 *memoryNiceToHaveBytes = 0; |
| 463 *memoryUsedBytes = 0; | 470 *memoryUsedBytes = 0; |
| 464 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 471 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
| 465 const Tile* tile = live_or_allocated_tiles_[i]; | 472 const Tile* tile = live_or_allocated_tiles_[i]; |
| 466 const ManagedTileState& mts = tile->managed_state(); | 473 const ManagedTileState& mts = tile->managed_state(); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 tiles_that_need_to_be_rasterized_.end()); | 651 tiles_that_need_to_be_rasterized_.end()); |
| 645 } | 652 } |
| 646 | 653 |
| 647 void TileManager::FreeResourcesForTile(Tile* tile) { | 654 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 648 ManagedTileState& managed_tile_state = tile->managed_state(); | 655 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 649 DCHECK(managed_tile_state.can_be_freed); | 656 DCHECK(managed_tile_state.can_be_freed); |
| 650 if (managed_tile_state.resource) | 657 if (managed_tile_state.resource) |
| 651 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 658 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
| 652 } | 659 } |
| 653 | 660 |
| 654 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 661 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
| 655 if (raster_worker_pool_->IsBusy()) | 662 if (raster_worker_pool_->IsBusy()) |
| 656 return false; | 663 return false; |
| 657 size_t new_bytes_pending = bytes_pending_set_pixels_; | 664 size_t new_bytes_pending = bytes_pending_set_pixels_; |
| 658 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 665 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
| 659 return new_bytes_pending <= kMaxPendingUploadBytes && | 666 return new_bytes_pending <= kMaxPendingUploadBytes && |
| 660 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; | 667 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; |
| 661 } | 668 } |
| 662 | 669 |
| 663 void TileManager::DispatchMoreTasks() { | 670 void TileManager::DispatchMoreTasks() { |
| 664 // Because tiles in the image decoding list have higher priorities, we | 671 // Because tiles in the image decoding list have higher priorities, we |
| 665 // need to process those tiles first before we start to handle the tiles | 672 // need to process those tiles first before we start to handle the tiles |
| 666 // in the need_to_be_rasterized queue. | 673 // in the need_to_be_rasterized queue. |
| 667 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 674 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| 668 it != tiles_with_image_decoding_tasks_.end(); ) { | 675 it != tiles_with_image_decoding_tasks_.end(); ) { |
| 669 DispatchImageDecodeTasksForTile(*it); | 676 DispatchImageDecodeTasksForTile(*it); |
| 670 ManagedTileState& managed_state = (*it)->managed_state(); | 677 ManagedTileState& managed_state = (*it)->managed_state(); |
| 671 if (managed_state.pending_pixel_refs.empty()) { | 678 if (managed_state.pending_pixel_refs.empty()) { |
| 672 if (!CanDispatchRasterTask(*it)) | 679 if (!CanDispatchRasterTask(*it)) |
| 673 return; | 680 break; |
|
reveman
2013/02/19 18:05:23
hm, this makes us enter the loop below in cases wh
Sami
2013/02/19 22:24:38
You're right. We only need to make sure the allow_
| |
| 674 DispatchOneRasterTask(*it); | 681 DispatchOneRasterTask(*it); |
| 675 tiles_with_image_decoding_tasks_.erase(it++); | 682 tiles_with_image_decoding_tasks_.erase(it++); |
| 676 } else { | 683 } else { |
| 677 ++it; | 684 ++it; |
| 678 } | 685 } |
| 679 } | 686 } |
| 680 | 687 |
| 681 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 688 // Process all tiles in the need_to_be_rasterized queue. If a tile has |
| 682 // image decoding tasks, put it to the back of the image decoding list. | 689 // image decoding tasks, put it to the back of the image decoding list. |
| 683 while (!tiles_that_need_to_be_rasterized_.empty()) { | 690 while (!tiles_that_need_to_be_rasterized_.empty()) { |
| 684 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 691 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
| 685 DispatchImageDecodeTasksForTile(tile); | 692 DispatchImageDecodeTasksForTile(tile); |
| 686 ManagedTileState& managed_state = tile->managed_state(); | 693 ManagedTileState& managed_state = tile->managed_state(); |
| 687 if (!managed_state.pending_pixel_refs.empty()) { | 694 if (!managed_state.pending_pixel_refs.empty()) { |
| 688 tiles_with_image_decoding_tasks_.push_back(tile); | 695 tiles_with_image_decoding_tasks_.push_back(tile); |
| 689 } else { | 696 } else { |
| 690 if (!CanDispatchRasterTask(tile)) | 697 if (!CanDispatchRasterTask(tile)) |
| 691 return; | 698 break; |
| 692 DispatchOneRasterTask(tile); | 699 DispatchOneRasterTask(tile); |
| 693 } | 700 } |
| 694 tiles_that_need_to_be_rasterized_.pop_back(); | 701 tiles_that_need_to_be_rasterized_.pop_back(); |
| 695 } | 702 } |
| 703 | |
| 704 if (did_schedule_cheap_tasks_) | |
| 705 allow_cheap_tasks_ = false; | |
| 696 } | 706 } |
| 697 | 707 |
| 698 void TileManager::GatherPixelRefsForTile(Tile* tile) { | 708 void TileManager::GatherPixelRefsForTile(Tile* tile) { |
| 699 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); | 709 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); |
| 700 ManagedTileState& managed_state = tile->managed_state(); | 710 ManagedTileState& managed_state = tile->managed_state(); |
| 701 if (managed_state.need_to_gather_pixel_refs) { | 711 if (managed_state.need_to_gather_pixel_refs) { |
| 702 base::TimeTicks gather_begin_time; | 712 base::TimeTicks gather_begin_time; |
| 703 if (record_rendering_stats_) | 713 if (record_rendering_stats_) |
| 704 gather_begin_time = base::TimeTicks::HighResNow(); | 714 gather_begin_time = base::TimeTicks::HighResNow(); |
| 705 tile->picture_pile()->GatherPixelRefs( | 715 tile->picture_pile()->GatherPixelRefs( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 741 | 751 |
| 742 void TileManager::DispatchOneImageDecodeTask( | 752 void TileManager::DispatchOneImageDecodeTask( |
| 743 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | 753 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
| 744 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | 754 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); |
| 745 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | 755 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
| 746 DCHECK(pending_decode_tasks_.end() == | 756 DCHECK(pending_decode_tasks_.end() == |
| 747 pending_decode_tasks_.find(pixel_ref_id)); | 757 pending_decode_tasks_.find(pixel_ref_id)); |
| 748 pending_decode_tasks_[pixel_ref_id] = pixel_ref; | 758 pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
| 749 | 759 |
| 750 raster_worker_pool_->PostTaskAndReply( | 760 raster_worker_pool_->PostTaskAndReply( |
| 751 base::Bind(&TileManager::RunImageDecodeTask, pixel_ref), | 761 base::Bind(&TileManager::PerformImageDecode, pixel_ref), |
| 752 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 762 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
| 753 base::Unretained(this), | 763 base::Unretained(this), |
| 754 tile, | 764 tile, |
| 755 pixel_ref_id)); | 765 pixel_ref_id)); |
| 756 } | 766 } |
| 757 | 767 |
| 758 void TileManager::OnImageDecodeTaskCompleted( | 768 void TileManager::OnImageDecodeTaskCompleted( |
| 759 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 769 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
| 760 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 770 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
| 761 pending_decode_tasks_.erase(pixel_ref_id); | 771 pending_decode_tasks_.erase(pixel_ref_id); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 787 | 797 |
| 788 DidTileRasterStateChange(tile, RASTER_STATE); | 798 DidTileRasterStateChange(tile, RASTER_STATE); |
| 789 return resource.Pass(); | 799 return resource.Pass(); |
| 790 } | 800 } |
| 791 | 801 |
| 792 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 802 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
| 793 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 803 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
| 794 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 804 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
| 795 ResourceProvider::ResourceId resource_id = resource->id(); | 805 ResourceProvider::ResourceId resource_id = resource->id(); |
| 796 | 806 |
| 807 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && | |
| 808 tile->picture_pile()->IsCheapInRect(tile->content_rect_, | |
| 809 tile->contents_scale()); | |
| 797 raster_worker_pool_->PostRasterTaskAndReply( | 810 raster_worker_pool_->PostRasterTaskAndReply( |
| 798 tile->picture_pile(), | 811 tile->picture_pile(), |
| 812 is_cheap, | |
| 799 base::Bind(&TileManager::PerformRaster, | 813 base::Bind(&TileManager::PerformRaster, |
| 800 resource_pool_->resource_provider()->mapPixelBuffer( | 814 resource_pool_->resource_provider()->mapPixelBuffer( |
| 801 resource_id), | 815 resource_id), |
| 802 tile->content_rect_, | 816 tile->content_rect_, |
| 803 tile->contents_scale(), | 817 tile->contents_scale(), |
| 804 use_cheapness_estimator_, | 818 use_cheapness_estimator_, |
| 805 GetRasterTaskMetadata(tile->managed_state())), | 819 GetRasterTaskMetadata(tile->managed_state())), |
| 806 base::Bind(&TileManager::OnRasterTaskCompleted, | 820 base::Bind(&TileManager::OnRasterTaskCompleted, |
| 807 base::Unretained(this), | 821 base::Unretained(this), |
| 808 tile, | 822 tile, |
| 809 base::Passed(&resource), | 823 base::Passed(&resource), |
| 810 manage_tiles_call_count_)); | 824 manage_tiles_call_count_)); |
| 811 } | 825 did_schedule_cheap_tasks_ |= is_cheap; |
| 812 | |
| 813 void TileManager::PerformOneRaster(Tile* tile) { | |
| 814 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
| 815 ResourceProvider::ResourceId resource_id = resource->id(); | |
| 816 | |
| 817 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | |
| 818 resource_id), | |
| 819 tile->content_rect_, | |
| 820 tile->contents_scale(), | |
| 821 use_cheapness_estimator_, | |
| 822 GetRasterTaskMetadata(tile->managed_state()), | |
| 823 tile->picture_pile(), | |
| 824 &rendering_stats_); | |
| 825 | |
| 826 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | |
| 827 } | 826 } |
| 828 | 827 |
| 829 void TileManager::OnRasterCompleted( | 828 void TileManager::OnRasterCompleted( |
| 830 scoped_refptr<Tile> tile, | 829 scoped_refptr<Tile> tile, |
| 831 scoped_ptr<ResourcePool::Resource> resource, | 830 scoped_ptr<ResourcePool::Resource> resource, |
| 832 int manage_tiles_call_count_when_dispatched) { | 831 int manage_tiles_call_count_when_dispatched) { |
| 833 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 832 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); |
| 834 | 833 |
| 835 // Release raster resources. | 834 // Release raster resources. |
| 836 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 835 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) | 959 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) |
| 961 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 960 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
| 962 | 961 |
| 963 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 962 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
| 964 duration.InMilliseconds(), | 963 duration.InMilliseconds(), |
| 965 0, | 964 0, |
| 966 10, | 965 10, |
| 967 10); | 966 10); |
| 968 | 967 |
| 969 if (use_cheapness_estimator) { | 968 if (use_cheapness_estimator) { |
| 970 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal e); | 969 bool is_predicted_cheap = picture_pile->IsCheapInRect(rect, contents_scale ); |
|
reveman
2013/02/19 18:05:23
nit: make this line <= 80 characters long
Sami
2013/02/19 22:24:38
Whoops, done.
| |
| 971 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 970 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
| 972 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 971 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
| 973 } | 972 } |
| 974 } | 973 } |
| 975 } | 974 } |
| 976 | 975 |
| 977 // static | 976 // static |
| 978 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 977 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
| 979 bool is_actually_cheap) { | 978 bool is_actually_cheap) { |
| 980 if (is_predicted_cheap && !is_actually_cheap) | 979 if (is_predicted_cheap && !is_actually_cheap) |
| 981 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 980 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
| 982 else if (!is_predicted_cheap && is_actually_cheap) | 981 else if (!is_predicted_cheap && is_actually_cheap) |
| 983 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 982 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
| 984 | 983 |
| 985 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 984 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
| 986 is_predicted_cheap == is_actually_cheap); | 985 is_predicted_cheap == is_actually_cheap); |
| 987 } | 986 } |
| 988 | 987 |
| 989 // static | 988 // static |
| 990 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 989 void TileManager::PerformImageDecode(skia::LazyPixelRef* pixel_ref, |
| 991 RenderingStats* stats) { | 990 RenderingStats* stats) { |
| 992 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 991 TRACE_EVENT0("cc", "TileManager::PerformImageDecode"); |
| 993 base::TimeTicks decode_begin_time; | 992 base::TimeTicks decode_begin_time; |
| 994 if (stats) | 993 if (stats) |
| 995 decode_begin_time = base::TimeTicks::HighResNow(); | 994 decode_begin_time = base::TimeTicks::HighResNow(); |
| 996 pixel_ref->Decode(); | 995 pixel_ref->Decode(); |
| 997 if (stats) { | 996 if (stats) { |
| 998 stats->totalDeferredImageDecodeCount++; | 997 stats->totalDeferredImageDecodeCount++; |
| 999 stats->totalDeferredImageDecodeTime += | 998 stats->totalDeferredImageDecodeTime += |
| 1000 base::TimeTicks::HighResNow() - decode_begin_time; | 999 base::TimeTicks::HighResNow() - decode_begin_time; |
| 1001 } | 1000 } |
| 1002 } | 1001 } |
| 1003 | 1002 |
| 1004 } // namespace cc | 1003 } // namespace cc |
| OLD | NEW |