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() { |
| 671 if (did_schedule_cheap_tasks_) |
| 672 allow_cheap_tasks_ = false; |
| 673 |
664 // Because tiles in the image decoding list have higher priorities, we | 674 // 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 | 675 // need to process those tiles first before we start to handle the tiles |
666 // in the need_to_be_rasterized queue. | 676 // in the need_to_be_rasterized queue. |
667 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 677 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
668 it != tiles_with_image_decoding_tasks_.end(); ) { | 678 it != tiles_with_image_decoding_tasks_.end(); ) { |
669 DispatchImageDecodeTasksForTile(*it); | 679 DispatchImageDecodeTasksForTile(*it); |
670 ManagedTileState& managed_state = (*it)->managed_state(); | 680 ManagedTileState& managed_state = (*it)->managed_state(); |
671 if (managed_state.pending_pixel_refs.empty()) { | 681 if (managed_state.pending_pixel_refs.empty()) { |
672 if (!CanDispatchRasterTask(*it)) | 682 if (!CanDispatchRasterTask(*it)) |
673 return; | 683 return; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after 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(), |
799 base::Bind(&TileManager::PerformRaster, | 812 is_cheap, |
| 813 base::Bind(&TileManager::RunRasterTask, |
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_)); |
| 825 did_schedule_cheap_tasks_ |= is_cheap; |
811 } | 826 } |
812 | 827 |
813 void TileManager::PerformOneRaster(Tile* tile) { | 828 void TileManager::OnRasterTaskCompleted( |
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 } | |
828 | |
829 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::OnRasterTaskCompleted"); |
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()); |
837 | 836 |
838 ManagedTileState& managed_tile_state = tile->managed_state(); | 837 ManagedTileState& managed_tile_state = tile->managed_state(); |
839 managed_tile_state.can_be_freed = true; | 838 managed_tile_state.can_be_freed = true; |
840 | 839 |
841 // Tile can be freed after the completion of the raster task. Call | 840 // Tile can be freed after the completion of the raster task. Call |
842 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 841 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority |
843 // tiles if ManageTiles() was called since task was dispatched. The result | 842 // tiles if ManageTiles() was called since task was dispatched. The result |
(...skipping 23 matching lines...) Expand all Loading... |
867 DidTileRasterStateChange(tile, SET_PIXELS_STATE); | 866 DidTileRasterStateChange(tile, SET_PIXELS_STATE); |
868 tiles_with_pending_set_pixels_.push(tile); | 867 tiles_with_pending_set_pixels_.push(tile); |
869 } else { | 868 } else { |
870 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); | 869 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); |
871 resource_pool_->ReleaseResource(resource.Pass()); | 870 resource_pool_->ReleaseResource(resource.Pass()); |
872 managed_tile_state.resource_is_being_initialized = false; | 871 managed_tile_state.resource_is_being_initialized = false; |
873 DidTileRasterStateChange(tile, IDLE_STATE); | 872 DidTileRasterStateChange(tile, IDLE_STATE); |
874 } | 873 } |
875 } | 874 } |
876 | 875 |
877 void TileManager::OnRasterTaskCompleted( | |
878 scoped_refptr<Tile> tile, | |
879 scoped_ptr<ResourcePool::Resource> resource, | |
880 int manage_tiles_call_count_when_dispatched) { | |
881 OnRasterCompleted(tile, resource.Pass(), | |
882 manage_tiles_call_count_when_dispatched); | |
883 } | |
884 | |
885 void TileManager::DidFinishTileInitialization(Tile* tile) { | 876 void TileManager::DidFinishTileInitialization(Tile* tile) { |
886 ManagedTileState& managed_tile_state = tile->managed_state(); | 877 ManagedTileState& managed_tile_state = tile->managed_state(); |
887 DCHECK(managed_tile_state.resource); | 878 DCHECK(managed_tile_state.resource); |
888 managed_tile_state.resource_is_being_initialized = false; | 879 managed_tile_state.resource_is_being_initialized = false; |
889 managed_tile_state.can_be_freed = true; | 880 managed_tile_state.can_be_freed = true; |
890 } | 881 } |
891 | 882 |
892 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { | 883 void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { |
893 ManagedTileState& mts = tile->managed_state(); | 884 ManagedTileState& mts = tile->managed_state(); |
894 DCHECK_LT(state, NUM_STATES); | 885 DCHECK_LT(state, NUM_STATES); |
(...skipping 19 matching lines...) Expand all Loading... |
914 --raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]]; | 905 --raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]]; |
915 DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); | 906 DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); |
916 | 907 |
917 // Increment count for new bin. | 908 // Increment count for new bin. |
918 ++raster_state_count_[mts.raster_state][tree][new_tree_bin]; | 909 ++raster_state_count_[mts.raster_state][tree][new_tree_bin]; |
919 | 910 |
920 mts.tree_bin[tree] = new_tree_bin; | 911 mts.tree_bin[tree] = new_tree_bin; |
921 } | 912 } |
922 | 913 |
923 // static | 914 // static |
924 void TileManager::PerformRaster(uint8* buffer, | 915 void TileManager::RunRasterTask(uint8* buffer, |
925 const gfx::Rect& rect, | 916 const gfx::Rect& rect, |
926 float contents_scale, | 917 float contents_scale, |
927 bool use_cheapness_estimator, | 918 bool use_cheapness_estimator, |
928 const RasterTaskMetadata& raster_task_metadata, | 919 const RasterTaskMetadata& raster_task_metadata, |
929 PicturePileImpl* picture_pile, | 920 PicturePileImpl* picture_pile, |
930 RenderingStats* stats) { | 921 RenderingStats* stats) { |
931 TRACE_EVENT2( | 922 TRACE_EVENT2( |
932 "cc", "TileManager::PerformRaster", | 923 "cc", "TileManager::RunRasterTask", |
933 "is_on_pending_tree", | 924 "is_on_pending_tree", |
934 raster_task_metadata.is_tile_in_pending_tree_now_bin, | 925 raster_task_metadata.is_tile_in_pending_tree_now_bin, |
935 "is_low_res", | 926 "is_low_res", |
936 raster_task_metadata.tile_resolution == LOW_RESOLUTION); | 927 raster_task_metadata.tile_resolution == LOW_RESOLUTION); |
937 | 928 |
938 DCHECK(picture_pile); | 929 DCHECK(picture_pile); |
939 DCHECK(buffer); | 930 DCHECK(buffer); |
940 SkBitmap bitmap; | 931 SkBitmap bitmap; |
941 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); | 932 bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); |
942 bitmap.setPixels(buffer); | 933 bitmap.setPixels(buffer); |
(...skipping 17 matching lines...) Expand all Loading... |
960 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) | 951 if (raster_task_metadata.is_tile_in_pending_tree_now_bin) |
961 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 952 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
962 | 953 |
963 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 954 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
964 duration.InMilliseconds(), | 955 duration.InMilliseconds(), |
965 0, | 956 0, |
966 10, | 957 10, |
967 10); | 958 10); |
968 | 959 |
969 if (use_cheapness_estimator) { | 960 if (use_cheapness_estimator) { |
970 bool is_predicted_cheap = picture_pile->IsCheapInRect (rect, contents_scal
e); | 961 bool is_predicted_cheap = |
| 962 picture_pile->IsCheapInRect(rect, contents_scale); |
971 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 963 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
972 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 964 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
973 } | 965 } |
974 } | 966 } |
975 } | 967 } |
976 | 968 |
977 // static | 969 // static |
978 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 970 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
979 bool is_actually_cheap) { | 971 bool is_actually_cheap) { |
980 if (is_predicted_cheap && !is_actually_cheap) | 972 if (is_predicted_cheap && !is_actually_cheap) |
(...skipping 14 matching lines...) Expand all Loading... |
995 decode_begin_time = base::TimeTicks::HighResNow(); | 987 decode_begin_time = base::TimeTicks::HighResNow(); |
996 pixel_ref->Decode(); | 988 pixel_ref->Decode(); |
997 if (stats) { | 989 if (stats) { |
998 stats->totalDeferredImageDecodeCount++; | 990 stats->totalDeferredImageDecodeCount++; |
999 stats->totalDeferredImageDecodeTime += | 991 stats->totalDeferredImageDecodeTime += |
1000 base::TimeTicks::HighResNow() - decode_begin_time; | 992 base::TimeTicks::HighResNow() - decode_begin_time; |
1001 } | 993 } |
1002 } | 994 } |
1003 | 995 |
1004 } // namespace cc | 996 } // namespace cc |
OLD | NEW |