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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 managed_tile_state.can_be_freed = true; | 444 managed_tile_state.can_be_freed = true; |
443 managed_tile_state.can_use_gpu_memory = false; | 445 managed_tile_state.can_use_gpu_memory = false; |
444 FreeResourcesForTile(tile); | 446 FreeResourcesForTile(tile); |
445 | 447 |
446 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); | 448 bytes_pending_set_pixels_ -= tile->bytes_consumed_if_allocated(); |
447 DidTileRasterStateChange(tile, IDLE_STATE); | 449 DidTileRasterStateChange(tile, IDLE_STATE); |
448 tiles_with_pending_set_pixels_.pop(); | 450 tiles_with_pending_set_pixels_.pop(); |
449 } | 451 } |
450 } | 452 } |
451 | 453 |
| 454 void TileManager::DidCompleteFrame() { |
| 455 allow_cheap_tasks_ = true; |
| 456 did_schedule_cheap_tasks_ = false; |
| 457 } |
| 458 |
452 void TileManager::GetMemoryStats( | 459 void TileManager::GetMemoryStats( |
453 size_t* memoryRequiredBytes, | 460 size_t* memoryRequiredBytes, |
454 size_t* memoryNiceToHaveBytes, | 461 size_t* memoryNiceToHaveBytes, |
455 size_t* memoryUsedBytes) const { | 462 size_t* memoryUsedBytes) const { |
456 *memoryRequiredBytes = 0; | 463 *memoryRequiredBytes = 0; |
457 *memoryNiceToHaveBytes = 0; | 464 *memoryNiceToHaveBytes = 0; |
458 *memoryUsedBytes = 0; | 465 *memoryUsedBytes = 0; |
459 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 466 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
460 const Tile* tile = live_or_allocated_tiles_[i]; | 467 const Tile* tile = live_or_allocated_tiles_[i]; |
461 const ManagedTileState& mts = tile->managed_state(); | 468 const ManagedTileState& mts = tile->managed_state(); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 tiles_that_need_to_be_rasterized_.end()); | 646 tiles_that_need_to_be_rasterized_.end()); |
640 } | 647 } |
641 | 648 |
642 void TileManager::FreeResourcesForTile(Tile* tile) { | 649 void TileManager::FreeResourcesForTile(Tile* tile) { |
643 ManagedTileState& managed_tile_state = tile->managed_state(); | 650 ManagedTileState& managed_tile_state = tile->managed_state(); |
644 DCHECK(managed_tile_state.can_be_freed); | 651 DCHECK(managed_tile_state.can_be_freed); |
645 if (managed_tile_state.resource) | 652 if (managed_tile_state.resource) |
646 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); | 653 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
647 } | 654 } |
648 | 655 |
649 bool TileManager::CanDispatchRasterTask(Tile* tile) { | 656 bool TileManager::CanDispatchRasterTask(Tile* tile) const { |
650 if (raster_worker_pool_->IsBusy()) | 657 if (raster_worker_pool_->IsBusy()) |
651 return false; | 658 return false; |
652 size_t new_bytes_pending = bytes_pending_set_pixels_; | 659 size_t new_bytes_pending = bytes_pending_set_pixels_; |
653 new_bytes_pending += tile->bytes_consumed_if_allocated(); | 660 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
654 return new_bytes_pending <= kMaxPendingUploadBytes && | 661 return new_bytes_pending <= kMaxPendingUploadBytes && |
655 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; | 662 tiles_with_pending_set_pixels_.size() < kMaxPendingUploads; |
656 } | 663 } |
657 | 664 |
658 void TileManager::DispatchMoreTasks() { | 665 void TileManager::DispatchMoreTasks() { |
| 666 if (did_schedule_cheap_tasks_) |
| 667 allow_cheap_tasks_ = false; |
| 668 |
659 // Because tiles in the image decoding list have higher priorities, we | 669 // Because tiles in the image decoding list have higher priorities, we |
660 // need to process those tiles first before we start to handle the tiles | 670 // need to process those tiles first before we start to handle the tiles |
661 // in the need_to_be_rasterized queue. | 671 // in the need_to_be_rasterized queue. |
662 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 672 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
663 it != tiles_with_image_decoding_tasks_.end(); ) { | 673 it != tiles_with_image_decoding_tasks_.end(); ) { |
664 DispatchImageDecodeTasksForTile(*it); | 674 DispatchImageDecodeTasksForTile(*it); |
665 ManagedTileState& managed_state = (*it)->managed_state(); | 675 ManagedTileState& managed_state = (*it)->managed_state(); |
666 if (managed_state.pending_pixel_refs.empty()) { | 676 if (managed_state.pending_pixel_refs.empty()) { |
667 if (!CanDispatchRasterTask(*it)) | 677 if (!CanDispatchRasterTask(*it)) |
668 return; | 678 return; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 | 792 |
783 DidTileRasterStateChange(tile, RASTER_STATE); | 793 DidTileRasterStateChange(tile, RASTER_STATE); |
784 return resource.Pass(); | 794 return resource.Pass(); |
785 } | 795 } |
786 | 796 |
787 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 797 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
788 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 798 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
789 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 799 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
790 ResourceProvider::ResourceId resource_id = resource->id(); | 800 ResourceProvider::ResourceId resource_id = resource->id(); |
791 | 801 |
| 802 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && |
| 803 tile->picture_pile()->IsCheapInRect(tile->content_rect_, |
| 804 tile->contents_scale()); |
792 raster_worker_pool_->PostRasterTaskAndReply( | 805 raster_worker_pool_->PostRasterTaskAndReply( |
793 tile->picture_pile(), | 806 tile->picture_pile(), |
794 base::Bind(&TileManager::PerformRaster, | 807 is_cheap, |
| 808 base::Bind(&TileManager::RunRasterTask, |
795 resource_pool_->resource_provider()->mapPixelBuffer( | 809 resource_pool_->resource_provider()->mapPixelBuffer( |
796 resource_id), | 810 resource_id), |
797 tile->content_rect_, | 811 tile->content_rect_, |
798 tile->contents_scale(), | 812 tile->contents_scale(), |
799 use_cheapness_estimator_, | 813 use_cheapness_estimator_, |
800 GetRasterTaskMetadata(tile->managed_state())), | 814 GetRasterTaskMetadata(tile->managed_state())), |
801 base::Bind(&TileManager::OnRasterTaskCompleted, | 815 base::Bind(&TileManager::OnRasterTaskCompleted, |
802 base::Unretained(this), | 816 base::Unretained(this), |
803 tile, | 817 tile, |
804 base::Passed(&resource), | 818 base::Passed(&resource), |
805 manage_tiles_call_count_)); | 819 manage_tiles_call_count_)); |
| 820 did_schedule_cheap_tasks_ |= is_cheap; |
806 } | 821 } |
807 | 822 |
808 void TileManager::PerformOneRaster(Tile* tile) { | 823 void TileManager::OnRasterTaskCompleted( |
809 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
810 ResourceProvider::ResourceId resource_id = resource->id(); | |
811 | |
812 PerformRaster(resource_pool_->resource_provider()->mapPixelBuffer( | |
813 resource_id), | |
814 tile->content_rect_, | |
815 tile->contents_scale(), | |
816 use_cheapness_estimator_, | |
817 GetRasterTaskMetadata(tile->managed_state()), | |
818 tile->picture_pile(), | |
819 &rendering_stats_); | |
820 | |
821 OnRasterCompleted(tile, resource.Pass(), manage_tiles_call_count_); | |
822 } | |
823 | |
824 void TileManager::OnRasterCompleted( | |
825 scoped_refptr<Tile> tile, | 824 scoped_refptr<Tile> tile, |
826 scoped_ptr<ResourcePool::Resource> resource, | 825 scoped_ptr<ResourcePool::Resource> resource, |
827 int manage_tiles_call_count_when_dispatched) { | 826 int manage_tiles_call_count_when_dispatched) { |
828 TRACE_EVENT0("cc", "TileManager::OnRasterCompleted"); | 827 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); |
829 | 828 |
830 // Release raster resources. | 829 // Release raster resources. |
831 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); | 830 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
832 | 831 |
833 ManagedTileState& managed_tile_state = tile->managed_state(); | 832 ManagedTileState& managed_tile_state = tile->managed_state(); |
834 managed_tile_state.can_be_freed = true; | 833 managed_tile_state.can_be_freed = true; |
835 | 834 |
836 // Tile can be freed after the completion of the raster task. Call | 835 // Tile can be freed after the completion of the raster task. Call |
837 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 836 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority |
838 // tiles if ManageTiles() was called since task was dispatched. The result | 837 // tiles if ManageTiles() was called since task was dispatched. The result |
(...skipping 23 matching lines...) Expand all Loading... |
862 DidTileRasterStateChange(tile, SET_PIXELS_STATE); | 861 DidTileRasterStateChange(tile, SET_PIXELS_STATE); |
863 tiles_with_pending_set_pixels_.push(tile); | 862 tiles_with_pending_set_pixels_.push(tile); |
864 } else { | 863 } else { |
865 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); | 864 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
866 resource_pool_->ReleaseResource(resource.Pass()); | 865 resource_pool_->ReleaseResource(resource.Pass()); |
867 managed_tile_state.resource_is_being_initialized = false; | 866 managed_tile_state.resource_is_being_initialized = false; |
868 DidTileRasterStateChange(tile, IDLE_STATE); | 867 DidTileRasterStateChange(tile, IDLE_STATE); |
869 } | 868 } |
870 } | 869 } |
871 | 870 |
872 void TileManager::OnRasterTaskCompleted( | |
873 scoped_refptr<Tile> tile, | |
874 scoped_ptr<ResourcePool::Resource> resource, | |
875 int manage_tiles_call_count_when_dispatched) { | |
876 OnRasterCompleted(tile, resource.Pass(), | |
877 manage_tiles_call_count_when_dispatched); | |
878 } | |
879 | |
880 void TileManager::DidFinishTileInitialization(Tile* tile) { | 871 void TileManager::DidFinishTileInitialization(Tile* tile) { |
881 ManagedTileState& managed_tile_state = tile->managed_state(); | 872 ManagedTileState& managed_tile_state = tile->managed_state(); |
882 DCHECK(managed_tile_state.resource); | 873 DCHECK(managed_tile_state.resource); |
883 managed_tile_state.resource_is_being_initialized = false; | 874 managed_tile_state.resource_is_being_initialized = false; |
884 managed_tile_state.can_be_freed = true; | 875 managed_tile_state.can_be_freed = true; |
885 } | 876 } |
886 | 877 |
887 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { | 878 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { |
888 ManagedTileState& mts = tile->managed_state(); | 879 ManagedTileState& mts = tile->managed_state(); |
889 DCHECK_LT(state, NUM_STATES); | 880 DCHECK_LT(state, NUM_STATES); |
(...skipping 19 matching lines...) Expand all Loading... |
909 --raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]]; | 900 --raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]]; |
910 DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); | 901 DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); |
911 | 902 |
912 // Increment count for new bin. | 903 // Increment count for new bin. |
913 ++raster_state_count_[mts.raster_state][tree][new_tree_bin]; | 904 ++raster_state_count_[mts.raster_state][tree][new_tree_bin]; |
914 | 905 |
915 mts.tree_bin[tree] = new_tree_bin; | 906 mts.tree_bin[tree] = new_tree_bin; |
916 } | 907 } |
917 | 908 |
918 // static | 909 // static |
919 void TileManager::PerformRaster(uint8* buffer, | 910 void TileManager::RunRasterTask(uint8* buffer, |
920 const gfx::Rect& rect, | 911 const gfx::Rect& rect, |
921 float contents_scale, | 912 float contents_scale, |
922 bool use_cheapness_estimator, | 913 bool use_cheapness_estimator, |
923 const RasterTaskMetadata& raster_task_metadata, | 914 const RasterTaskMetadata& raster_task_metadata, |
924 PicturePileImpl* picture_pile, | 915 PicturePileImpl* picture_pile, |
925 RenderingStats* stats) { | 916 RenderingStats* stats) { |
926 TRACE_EVENT2( | 917 TRACE_EVENT2( |
927 "cc", "TileManager::PerformRaster", | 918 "cc", "TileManager::RunRasterTask", |
928 "is_on_pending_tree", | 919 "is_on_pending_tree", |
929 raster_task_metadata.is_tile_in_pending_tree_now_bin, | 920 raster_task_metadata.is_tile_in_pending_tree_now_bin, |
930 "is_low_res", | 921 "is_low_res", |
931 raster_task_metadata.tile_resolution == LOW_RESOLUTION); | 922 raster_task_metadata.tile_resolution == LOW_RESOLUTION); |
932 | 923 |
933 DCHECK(picture_pile); | 924 DCHECK(picture_pile); |
934 DCHECK(buffer); | 925 DCHECK(buffer); |
935 SkBitmap bitmap; | 926 SkBitmap bitmap; |
936 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); | 927 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); |
937 bitmap.setPixels(buffer); | 928 bitmap.setPixels(buffer); |
(...skipping 17 matching lines...) Expand all Loading... |
955 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) | 946 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) |
956 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 947 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
957 | 948 |
958 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 949 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
959 duration.InMilliseconds(), | 950 duration.InMilliseconds(), |
960 0, | 951 0, |
961 10, | 952 10, |
962 10); | 953 10); |
963 | 954 |
964 if (use_cheapness_estimator) { | 955 if (use_cheapness_estimator) { |
965 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal
e); | 956 bool is_predicted_cheap = |
| 957 picture_pile->IsCheapInRect(rect, contents_scale); |
966 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 958 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
967 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 959 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
968 } | 960 } |
969 } | 961 } |
970 } | 962 } |
971 | 963 |
972 // static | 964 // static |
973 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 965 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
974 bool is_actually_cheap) { | 966 bool is_actually_cheap) { |
975 if (is_predicted_cheap && !is_actually_cheap) | 967 if (is_predicted_cheap && !is_actually_cheap) |
(...skipping 14 matching lines...) Expand all Loading... |
990 decode_begin_time = base::TimeTicks::HighResNow(); | 982 decode_begin_time = base::TimeTicks::HighResNow(); |
991 pixel_ref->Decode(); | 983 pixel_ref->Decode(); |
992 if (stats) { | 984 if (stats) { |
993 stats->totalDeferredImageDecodeCount++; | 985 stats->totalDeferredImageDecodeCount++; |
994 stats->totalDeferredImageDecodeTime += | 986 stats->totalDeferredImageDecodeTime += |
995 base::TimeTicks::HighResNow() - decode_begin_time; | 987 base::TimeTicks::HighResNow() - decode_begin_time; |
996 } | 988 } |
997 } | 989 } |
998 | 990 |
999 } // namespace cc | 991 } // namespace cc |
OLD | NEW |