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/resources/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 const size_t kMaxPendingUploadBytes = 100 * 1024 * 1024; | 37 const size_t kMaxPendingUploadBytes = 100 * 1024 * 1024; |
38 const size_t kMaxPendingUploads = 1000; | 38 const size_t kMaxPendingUploads = 1000; |
39 #endif | 39 #endif |
40 | 40 |
41 #if defined(OS_ANDROID) | 41 #if defined(OS_ANDROID) |
42 const int kMaxNumPendingTasksPerThread = 8; | 42 const int kMaxNumPendingTasksPerThread = 8; |
43 #else | 43 #else |
44 const int kMaxNumPendingTasksPerThread = 40; | 44 const int kMaxNumPendingTasksPerThread = 40; |
45 #endif | 45 #endif |
46 | 46 |
47 // Limit for time spent running cheap tasks during a single frame. | |
48 // TODO(skyostil): Determine this limit more dynamically. | |
49 const int kRunCheapTasksTimeMs = 6; | |
50 | |
51 // Determine bin based on three categories of tiles: things we need now, | 47 // Determine bin based on three categories of tiles: things we need now, |
52 // things we need soon, and eventually. | 48 // things we need soon, and eventually. |
53 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { | 49 inline TileManagerBin BinFromTilePriority(const TilePriority& prio) { |
54 if (!prio.is_live) | 50 if (!prio.is_live) |
55 return NEVER_BIN; | 51 return NEVER_BIN; |
56 | 52 |
57 // The amount of time for which we want to have prepainting coverage. | 53 // The amount of time for which we want to have prepainting coverage. |
58 const float kPrepaintingWindowTimeSeconds = 1.0f; | 54 const float kPrepaintingWindowTimeSeconds = 1.0f; |
59 const float kBackflingGuardDistancePixels = 314.0f; | 55 const float kBackflingGuardDistancePixels = 314.0f; |
60 | 56 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 DCHECK(false) << "Unrecognized TileManagerBinPriority value"; | 109 DCHECK(false) << "Unrecognized TileManagerBinPriority value"; |
114 return scoped_ptr<base::Value>(base::Value::CreateStringValue( | 110 return scoped_ptr<base::Value>(base::Value::CreateStringValue( |
115 "<unknown TileManagerBinPriority value>")); | 111 "<unknown TileManagerBinPriority value>")); |
116 } | 112 } |
117 } | 113 } |
118 | 114 |
119 TileManager::TileManager( | 115 TileManager::TileManager( |
120 TileManagerClient* client, | 116 TileManagerClient* client, |
121 ResourceProvider* resource_provider, | 117 ResourceProvider* resource_provider, |
122 size_t num_raster_threads, | 118 size_t num_raster_threads, |
123 bool use_cheapness_estimator, | |
124 bool use_color_estimator, | 119 bool use_color_estimator, |
125 bool prediction_benchmarking, | 120 bool prediction_benchmarking, |
126 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 121 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
127 : client_(client), | 122 : client_(client), |
128 resource_pool_(ResourcePool::Create(resource_provider)), | 123 resource_pool_(ResourcePool::Create(resource_provider)), |
129 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 124 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
130 manage_tiles_pending_(false), | 125 manage_tiles_pending_(false), |
131 manage_tiles_call_count_(0), | 126 manage_tiles_call_count_(0), |
132 bytes_pending_upload_(0), | 127 bytes_pending_upload_(0), |
133 has_performed_uploads_since_last_flush_(false), | 128 has_performed_uploads_since_last_flush_(false), |
134 ever_exceeded_memory_budget_(false), | 129 ever_exceeded_memory_budget_(false), |
135 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 130 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
136 use_cheapness_estimator_(use_cheapness_estimator), | |
137 use_color_estimator_(use_color_estimator), | 131 use_color_estimator_(use_color_estimator), |
138 prediction_benchmarking_(prediction_benchmarking), | 132 prediction_benchmarking_(prediction_benchmarking), |
139 did_initialize_visible_tile_(false), | 133 did_initialize_visible_tile_(false), |
140 pending_tasks_(0), | 134 pending_tasks_(0), |
141 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { | 135 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { |
142 } | 136 } |
143 | 137 |
144 TileManager::~TileManager() { | 138 TileManager::~TileManager() { |
145 // Reset global state and manage. This should cause | 139 // Reset global state and manage. This should cause |
146 // our memory usage to drop to zero. | 140 // our memory usage to drop to zero. |
147 global_state_ = GlobalStateThatImpactsTilePriority(); | 141 global_state_ = GlobalStateThatImpactsTilePriority(); |
148 AssignGpuMemoryToTiles(); | 142 AssignGpuMemoryToTiles(); |
149 // This should finish all pending tasks and release any uninitialized | 143 // This should finish all pending tasks and release any uninitialized |
150 // resources. | 144 // resources. |
151 raster_worker_pool_.reset(); | 145 raster_worker_pool_.reset(); |
152 AbortPendingTileUploads(); | 146 AbortPendingTileUploads(); |
153 DCHECK_EQ(0u, tiles_with_pending_upload_.size()); | 147 DCHECK_EQ(0u, tiles_with_pending_upload_.size()); |
154 DCHECK_EQ(0u, all_tiles_.size()); | 148 DCHECK_EQ(0u, all_tiles_.size()); |
155 DCHECK_EQ(0u, live_or_allocated_tiles_.size()); | 149 DCHECK_EQ(0u, live_or_allocated_tiles_.size()); |
156 } | 150 } |
157 | 151 |
158 void TileManager::SetGlobalState( | 152 void TileManager::SetGlobalState( |
159 const GlobalStateThatImpactsTilePriority& global_state) { | 153 const GlobalStateThatImpactsTilePriority& global_state) { |
160 global_state_ = global_state; | 154 global_state_ = global_state; |
161 resource_pool_->SetMaxMemoryUsageBytes( | 155 resource_pool_->SetMaxMemoryUsageBytes( |
162 global_state_.memory_limit_in_bytes, | 156 global_state_.memory_limit_in_bytes, |
163 global_state_.unused_memory_limit_in_bytes); | 157 global_state_.unused_memory_limit_in_bytes); |
164 ScheduleManageTiles(); | 158 ScheduleManageTiles(); |
165 UpdateCheapTasksTimeLimit(); | |
166 } | 159 } |
167 | 160 |
168 void TileManager::RegisterTile(Tile* tile) { | 161 void TileManager::RegisterTile(Tile* tile) { |
169 all_tiles_.insert(tile); | 162 all_tiles_.insert(tile); |
170 ScheduleManageTiles(); | 163 ScheduleManageTiles(); |
171 } | 164 } |
172 | 165 |
173 void TileManager::UnregisterTile(Tile* tile) { | 166 void TileManager::UnregisterTile(Tile* tile) { |
174 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 167 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
175 it != tiles_that_need_to_be_rasterized_.end(); it++) { | 168 it != tiles_that_need_to_be_rasterized_.end(); it++) { |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 tiles_with_image_decoding_tasks.rend()); | 643 tiles_with_image_decoding_tasks.rend()); |
651 | 644 |
652 if (did_initialize_visible_tile_) { | 645 if (did_initialize_visible_tile_) { |
653 did_initialize_visible_tile_ = false; | 646 did_initialize_visible_tile_ = false; |
654 client_->DidInitializeVisibleTile(); | 647 client_->DidInitializeVisibleTile(); |
655 } | 648 } |
656 } | 649 } |
657 | 650 |
658 void TileManager::AnalyzeTile(Tile* tile) { | 651 void TileManager::AnalyzeTile(Tile* tile) { |
659 ManagedTileState& managed_tile_state = tile->managed_state(); | 652 ManagedTileState& managed_tile_state = tile->managed_state(); |
660 if ((use_cheapness_estimator_ || use_color_estimator_) && | 653 if (use_color_estimator_ && !managed_tile_state.picture_pile_analyzed) { |
661 !managed_tile_state.picture_pile_analyzed) { | |
662 tile->picture_pile()->AnalyzeInRect( | 654 tile->picture_pile()->AnalyzeInRect( |
663 tile->content_rect(), | 655 tile->content_rect(), |
664 tile->contents_scale(), | 656 tile->contents_scale(), |
665 &managed_tile_state.picture_pile_analysis); | 657 &managed_tile_state.picture_pile_analysis); |
666 managed_tile_state.picture_pile_analysis.is_cheap_to_raster &= | |
667 use_cheapness_estimator_; | |
668 managed_tile_state.picture_pile_analysis.is_solid_color &= | 658 managed_tile_state.picture_pile_analysis.is_solid_color &= |
669 use_color_estimator_; | 659 use_color_estimator_; |
670 managed_tile_state.picture_pile_analysis.is_transparent &= | 660 managed_tile_state.picture_pile_analysis.is_transparent &= |
671 use_color_estimator_; | 661 use_color_estimator_; |
672 managed_tile_state.picture_pile_analyzed = true; | 662 managed_tile_state.picture_pile_analyzed = true; |
673 managed_tile_state.need_to_gather_pixel_refs = false; | 663 managed_tile_state.need_to_gather_pixel_refs = false; |
674 managed_tile_state.pending_pixel_refs.swap( | 664 managed_tile_state.pending_pixel_refs.swap( |
675 managed_tile_state.picture_pile_analysis.lazy_pixel_refs); | 665 managed_tile_state.picture_pile_analysis.lazy_pixel_refs); |
676 | 666 |
677 if (managed_tile_state.picture_pile_analysis.is_solid_color) { | 667 if (managed_tile_state.picture_pile_analysis.is_solid_color) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 tile->tile_size_.size(), | 769 tile->tile_size_.size(), |
780 tile->drawing_info().resource_format_); | 770 tile->drawing_info().resource_format_); |
781 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); | 771 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); |
782 | 772 |
783 tile->drawing_info().resource_is_being_initialized_ = true; | 773 tile->drawing_info().resource_is_being_initialized_ = true; |
784 tile->drawing_info().can_be_freed_ = false; | 774 tile->drawing_info().can_be_freed_ = false; |
785 | 775 |
786 return resource.Pass(); | 776 return resource.Pass(); |
787 } | 777 } |
788 | 778 |
789 void TileManager::SetAnticipatedDrawTime(base::TimeTicks time) { | |
790 anticipated_draw_time_ = time; | |
791 UpdateCheapTasksTimeLimit(); | |
792 } | |
793 | |
794 void TileManager::UpdateCheapTasksTimeLimit() { | |
795 base::TimeTicks limit; | |
796 if (use_cheapness_estimator_ && | |
797 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) { | |
798 limit = std::min( | |
799 base::TimeTicks::Now() + | |
800 base::TimeDelta::FromMilliseconds(kRunCheapTasksTimeMs), | |
801 anticipated_draw_time_); | |
802 } | |
803 raster_worker_pool_->SetRunCheapTasksTimeLimit(limit); | |
804 } | |
805 | |
806 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 779 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
807 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 780 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
808 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 781 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
809 ResourceProvider::ResourceId resource_id = resource->id(); | 782 ResourceProvider::ResourceId resource_id = resource->id(); |
810 uint8* buffer = | 783 uint8* buffer = |
811 resource_pool_->resource_provider()->MapPixelBuffer(resource_id); | 784 resource_pool_->resource_provider()->MapPixelBuffer(resource_id); |
812 | 785 |
813 CHECK(buffer); | 786 CHECK(buffer); |
814 // skia requires that our buffer be 4-byte aligned | 787 // skia requires that our buffer be 4-byte aligned |
815 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3)); | 788 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3)); |
816 | 789 |
817 ManagedTileState& managed_tile_state = tile->managed_state(); | |
818 raster_worker_pool_->PostRasterTaskAndReply( | 790 raster_worker_pool_->PostRasterTaskAndReply( |
819 tile->picture_pile(), | 791 tile->picture_pile(), |
820 managed_tile_state.picture_pile_analysis.is_cheap_to_raster, | |
821 base::Bind(&TileManager::RunRasterTask, | 792 base::Bind(&TileManager::RunRasterTask, |
822 buffer, | 793 buffer, |
823 tile->content_rect(), | 794 tile->content_rect(), |
824 tile->contents_scale(), | 795 tile->contents_scale(), |
825 GetRasterTaskMetadata(*tile), | 796 GetRasterTaskMetadata(*tile), |
826 rendering_stats_instrumentation_), | 797 rendering_stats_instrumentation_), |
827 base::Bind(&TileManager::OnRasterTaskCompleted, | 798 base::Bind(&TileManager::OnRasterTaskCompleted, |
828 base::Unretained(this), | 799 base::Unretained(this), |
829 tile, | 800 tile, |
830 base::Passed(&resource), | 801 base::Passed(&resource), |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 | 906 |
936 HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeUS", | 907 HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeUS", |
937 raster_stats.total_rasterize_time.InMicroseconds(), | 908 raster_stats.total_rasterize_time.InMicroseconds(), |
938 0, | 909 0, |
939 100000, | 910 100000, |
940 100); | 911 100); |
941 | 912 |
942 if (metadata.prediction_benchmarking) { | 913 if (metadata.prediction_benchmarking) { |
943 PicturePileImpl::Analysis analysis; | 914 PicturePileImpl::Analysis analysis; |
944 picture_pile->AnalyzeInRect(rect, contents_scale, &analysis); | 915 picture_pile->AnalyzeInRect(rect, contents_scale, &analysis); |
945 bool is_predicted_cheap = analysis.is_cheap_to_raster; | |
946 bool is_actually_cheap = | |
947 raster_stats.best_rasterize_time.InMillisecondsF() <= 1.0f; | |
948 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | |
949 | 916 |
950 DCHECK_EQ(bitmap.rowBytes(), | 917 DCHECK_EQ(bitmap.rowBytes(), |
951 static_cast<size_t>(bitmap.width() * bitmap.bytesPerPixel())); | 918 static_cast<size_t>(bitmap.width() * bitmap.bytesPerPixel())); |
952 | 919 |
953 RecordSolidColorPredictorResults( | 920 RecordSolidColorPredictorResults( |
954 reinterpret_cast<SkColor*>(bitmap.getPixels()), | 921 reinterpret_cast<SkColor*>(bitmap.getPixels()), |
955 bitmap.getSize() / bitmap.bytesPerPixel(), | 922 bitmap.getSize() / bitmap.bytesPerPixel(), |
956 analysis.is_solid_color, | 923 analysis.is_solid_color, |
957 analysis.solid_color, | 924 analysis.solid_color, |
958 analysis.is_transparent); | 925 analysis.is_transparent); |
959 } | 926 } |
960 } else { | 927 } else { |
961 picture_pile->Raster(&canvas, rect, contents_scale, NULL); | 928 picture_pile->Raster(&canvas, rect, contents_scale, NULL); |
962 } | 929 } |
963 } | 930 } |
964 | 931 |
965 // static | 932 // static |
966 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | |
967 bool is_actually_cheap) { | |
968 if (is_predicted_cheap && !is_actually_cheap) | |
969 HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | |
970 else if (!is_predicted_cheap && is_actually_cheap) | |
971 HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | |
972 | |
973 HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | |
974 is_predicted_cheap == is_actually_cheap); | |
975 } | |
976 | |
977 // static | |
978 void TileManager::RecordSolidColorPredictorResults( | 933 void TileManager::RecordSolidColorPredictorResults( |
979 const SkColor* actual_colors, | 934 const SkColor* actual_colors, |
980 size_t color_count, | 935 size_t color_count, |
981 bool is_predicted_solid, | 936 bool is_predicted_solid, |
982 SkColor predicted_color, | 937 SkColor predicted_color, |
983 bool is_predicted_transparent) { | 938 bool is_predicted_transparent) { |
984 DCHECK_GT(color_count, 0u); | 939 DCHECK_GT(color_count, 0u); |
985 | 940 |
986 bool is_actually_solid = true; | 941 bool is_actually_solid = true; |
987 bool is_transparent = true; | 942 bool is_transparent = true; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 skia::LazyPixelRef* pixel_ref, | 985 skia::LazyPixelRef* pixel_ref, |
1031 RenderingStatsInstrumentation* stats_instrumentation) { | 986 RenderingStatsInstrumentation* stats_instrumentation) { |
1032 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 987 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); |
1033 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | 988 base::TimeTicks start_time = stats_instrumentation->StartRecording(); |
1034 pixel_ref->Decode(); | 989 pixel_ref->Decode(); |
1035 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); | 990 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); |
1036 stats_instrumentation->AddDeferredImageDecode(duration); | 991 stats_instrumentation->AddDeferredImageDecode(duration); |
1037 } | 992 } |
1038 | 993 |
1039 } // namespace cc | 994 } // namespace cc |
OLD | NEW |