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" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "cc/math_util.h" | 14 #include "cc/math_util.h" |
15 #include "cc/platform_color.h" | 15 #include "cc/platform_color.h" |
16 #include "cc/raster_worker_pool.h" | 16 #include "cc/raster_worker_pool.h" |
17 #include "cc/resource_pool.h" | 17 #include "cc/resource_pool.h" |
18 #include "cc/tile.h" | 18 #include "cc/tile.h" |
19 #include "third_party/skia/include/core/SkDevice.h" | 19 #include "third_party/skia/include/core/SkDevice.h" |
| 20 #include "ui/gfx/rect_conversions.h" |
20 | 21 |
21 namespace cc { | 22 namespace cc { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 // If we raster too fast we become upload bound, and pending | 26 // If we raster too fast we become upload bound, and pending |
26 // uploads consume memory. For maximum upload throughput, we would | 27 // uploads consume memory. For maximum upload throughput, we would |
27 // want to allow for upload_throughput * pipeline_time of pending | 28 // want to allow for upload_throughput * pipeline_time of pending |
28 // uploads, after which we are just wasting memory. Since we don't | 29 // uploads, after which we are just wasting memory. Since we don't |
29 // know our upload throughput yet, this just caps our memory usage. | 30 // know our upload throughput yet, this just caps our memory usage. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 state->Set("resolution", TileResolutionAsValue(resolution).release()); | 170 state->Set("resolution", TileResolutionAsValue(resolution).release()); |
170 state->Set("time_to_needed_in_seconds", MathUtil::asValueSafely(time_to_needed
_in_seconds).release()); | 171 state->Set("time_to_needed_in_seconds", MathUtil::asValueSafely(time_to_needed
_in_seconds).release()); |
171 state->Set("distance_to_visible_in_pixels", MathUtil::asValueSafely(distance_t
o_visible_in_pixels).release()); | 172 state->Set("distance_to_visible_in_pixels", MathUtil::asValueSafely(distance_t
o_visible_in_pixels).release()); |
172 return state.PassAs<base::Value>(); | 173 return state.PassAs<base::Value>(); |
173 } | 174 } |
174 | 175 |
175 TileManager::TileManager( | 176 TileManager::TileManager( |
176 TileManagerClient* client, | 177 TileManagerClient* client, |
177 ResourceProvider* resource_provider, | 178 ResourceProvider* resource_provider, |
178 size_t num_raster_threads, | 179 size_t num_raster_threads, |
179 bool use_cheapness_estimator) | 180 bool use_cheapness_estimator, |
| 181 bool solid_color_benchmarking) |
180 : client_(client), | 182 : client_(client), |
181 resource_pool_(ResourcePool::Create(resource_provider)), | 183 resource_pool_(ResourcePool::Create(resource_provider)), |
182 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 184 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
183 manage_tiles_pending_(false), | 185 manage_tiles_pending_(false), |
184 manage_tiles_call_count_(0), | 186 manage_tiles_call_count_(0), |
185 bytes_pending_upload_(0), | 187 bytes_pending_upload_(0), |
186 has_performed_uploads_since_last_flush_(false), | 188 has_performed_uploads_since_last_flush_(false), |
187 ever_exceeded_memory_budget_(false), | 189 ever_exceeded_memory_budget_(false), |
188 record_rendering_stats_(false), | 190 record_rendering_stats_(false), |
189 use_cheapness_estimator_(use_cheapness_estimator), | 191 use_cheapness_estimator_(use_cheapness_estimator), |
190 allow_cheap_tasks_(true), | 192 allow_cheap_tasks_(true), |
191 did_schedule_cheap_tasks_(false) { | 193 did_schedule_cheap_tasks_(false), |
| 194 solid_color_benchmarking_(solid_color_benchmarking) { |
192 for (int i = 0; i < NUM_STATES; ++i) { | 195 for (int i = 0; i < NUM_STATES; ++i) { |
193 for (int j = 0; j < NUM_TREES; ++j) { | 196 for (int j = 0; j < NUM_TREES; ++j) { |
194 for (int k = 0; k < NUM_BINS; ++k) | 197 for (int k = 0; k < NUM_BINS; ++k) |
195 raster_state_count_[i][j][k] = 0; | 198 raster_state_count_[i][j][k] = 0; |
196 } | 199 } |
197 } | 200 } |
198 } | 201 } |
199 | 202 |
200 TileManager::~TileManager() { | 203 TileManager::~TileManager() { |
201 // Reset global state and manage. This should cause | 204 // Reset global state and manage. This should cause |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 base::Passed(&resource), | 813 base::Passed(&resource), |
811 manage_tiles_call_count_)); | 814 manage_tiles_call_count_)); |
812 did_schedule_cheap_tasks_ |= is_cheap; | 815 did_schedule_cheap_tasks_ |= is_cheap; |
813 } | 816 } |
814 | 817 |
815 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 818 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
816 const Tile& tile) const { | 819 const Tile& tile) const { |
817 RasterTaskMetadata metadata; | 820 RasterTaskMetadata metadata; |
818 const ManagedTileState& mts = tile.managed_state(); | 821 const ManagedTileState& mts = tile.managed_state(); |
819 metadata.use_cheapness_estimator = use_cheapness_estimator_; | 822 metadata.use_cheapness_estimator = use_cheapness_estimator_; |
| 823 metadata.solid_color_benchmarking = solid_color_benchmarking_; |
820 metadata.is_tile_in_pending_tree_now_bin = | 824 metadata.is_tile_in_pending_tree_now_bin = |
821 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 825 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
822 metadata.tile_resolution = mts.resolution; | 826 metadata.tile_resolution = mts.resolution; |
823 return metadata; | 827 return metadata; |
824 } | 828 } |
825 | 829 |
826 void TileManager::OnRasterTaskCompleted( | 830 void TileManager::OnRasterTaskCompleted( |
827 scoped_refptr<Tile> tile, | 831 scoped_refptr<Tile> tile, |
828 scoped_ptr<ResourcePool::Resource> resource, | 832 scoped_ptr<ResourcePool::Resource> resource, |
829 int manage_tiles_call_count_when_dispatched) { | 833 int manage_tiles_call_count_when_dispatched) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 SkDevice device(bitmap); | 936 SkDevice device(bitmap); |
933 SkCanvas canvas(&device); | 937 SkCanvas canvas(&device); |
934 | 938 |
935 base::TimeTicks begin_time; | 939 base::TimeTicks begin_time; |
936 if (stats) | 940 if (stats) |
937 begin_time = base::TimeTicks::HighResNow(); | 941 begin_time = base::TimeTicks::HighResNow(); |
938 | 942 |
939 int64 total_pixels_rasterized = 0; | 943 int64 total_pixels_rasterized = 0; |
940 picture_pile->Raster(&canvas, rect, contents_scale, | 944 picture_pile->Raster(&canvas, rect, contents_scale, |
941 &total_pixels_rasterized); | 945 &total_pixels_rasterized); |
942 | |
943 if (stats) { | 946 if (stats) { |
944 stats->totalPixelsRasterized += total_pixels_rasterized; | 947 stats->totalPixelsRasterized += total_pixels_rasterized; |
945 | 948 |
946 base::TimeTicks end_time = base::TimeTicks::HighResNow(); | 949 base::TimeTicks end_time = base::TimeTicks::HighResNow(); |
947 base::TimeDelta duration = end_time - begin_time; | 950 base::TimeDelta duration = end_time - begin_time; |
948 stats->totalRasterizeTime += duration; | 951 stats->totalRasterizeTime += duration; |
949 if (metadata.is_tile_in_pending_tree_now_bin) | 952 if (metadata.is_tile_in_pending_tree_now_bin) |
950 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 953 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
951 | 954 |
952 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 955 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
953 duration.InMilliseconds(), | 956 duration.InMilliseconds(), |
954 0, | 957 0, |
955 10, | 958 10, |
956 10); | 959 10); |
957 | 960 |
958 if (metadata.use_cheapness_estimator) { | 961 if (metadata.use_cheapness_estimator) { |
959 bool is_predicted_cheap = | 962 bool is_predicted_cheap = |
960 picture_pile->IsCheapInRect(rect, contents_scale); | 963 picture_pile->IsCheapInRect(rect, contents_scale); |
961 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 964 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
962 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 965 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
963 } | 966 } |
964 } | 967 } |
| 968 |
| 969 if (metadata.solid_color_benchmarking) { |
| 970 SkColor solid_color; |
| 971 bool is_predicted_solid = |
| 972 picture_pile->GetColorIfSolidInRect(rect, contents_scale, &solid_color); |
| 973 bool is_predicted_transparent = |
| 974 picture_pile->IsTransparentInRect(rect, contents_scale); |
| 975 |
| 976 RecordSolidColorPredictorResults(buffer, |
| 977 rect.width() * rect.height(), |
| 978 is_predicted_solid, |
| 979 solid_color, |
| 980 is_predicted_transparent); |
| 981 } |
965 } | 982 } |
966 | 983 |
967 // static | 984 // static |
968 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 985 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
969 bool is_actually_cheap) { | 986 bool is_actually_cheap) { |
970 if (is_predicted_cheap && !is_actually_cheap) | 987 if (is_predicted_cheap && !is_actually_cheap) |
971 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 988 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
972 else if (!is_predicted_cheap && is_actually_cheap) | 989 else if (!is_predicted_cheap && is_actually_cheap) |
973 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 990 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
974 | 991 |
975 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 992 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
976 is_predicted_cheap == is_actually_cheap); | 993 is_predicted_cheap == is_actually_cheap); |
977 } | 994 } |
978 | 995 |
| 996 //static |
| 997 void TileManager::RecordSolidColorPredictorResults(const uint8* actual_bytes, |
| 998 size_t pixel_count, |
| 999 bool is_predicted_solid, |
| 1000 SkColor predicted_color, |
| 1001 bool is_predicted_transparent
) { |
| 1002 CHECK(pixel_count > 0); |
| 1003 |
| 1004 bool is_actually_solid = true; |
| 1005 bool is_transparent = true; |
| 1006 SkColor actual_color = SkColorSetARGB(actual_bytes[3], |
| 1007 actual_bytes[2], |
| 1008 actual_bytes[1], |
| 1009 actual_bytes[0]); |
| 1010 for (int i = (pixel_count-1)*4; i >= 0; i -= 4) { |
| 1011 SkColor current_color = SkColorSetARGB(actual_bytes[i+3], |
| 1012 actual_bytes[i+2], |
| 1013 actual_bytes[i+1], |
| 1014 actual_bytes[i]); |
| 1015 if (current_color != actual_color || |
| 1016 SkColorGetA(current_color) != 255) |
| 1017 is_actually_solid = false; |
| 1018 |
| 1019 if (SkColorGetA(current_color) != 0) |
| 1020 is_transparent = false; |
| 1021 } |
| 1022 |
| 1023 if (is_predicted_solid && !is_actually_solid) |
| 1024 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualNotSolid", true); |
| 1025 else if (is_predicted_solid && |
| 1026 is_actually_solid && |
| 1027 predicted_color != actual_color) |
| 1028 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongColor", true); |
| 1029 else if(!is_predicted_solid && is_actually_solid) |
| 1030 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualSolid", true); |
| 1031 |
| 1032 bool correct_guess = (is_predicted_solid && is_actually_solid && |
| 1033 predicted_color == actual_color) || |
| 1034 (!is_predicted_solid && !is_actually_solid); |
| 1035 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.Accuracy", correct_guess); |
| 1036 |
| 1037 if (correct_guess) |
| 1038 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsCorrectSolid", |
| 1039 is_predicted_solid); |
| 1040 |
| 1041 if (is_predicted_transparent) |
| 1042 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.PredictedTransparentIsActual
ly", is_transparent); |
| 1043 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsActuallyTransparent", is_tra
nsparent); |
| 1044 } |
| 1045 |
979 // static | 1046 // static |
980 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 1047 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, |
981 RenderingStats* stats) { | 1048 RenderingStats* stats) { |
982 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 1049 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); |
983 base::TimeTicks decode_begin_time; | 1050 base::TimeTicks decode_begin_time; |
984 if (stats) | 1051 if (stats) |
985 decode_begin_time = base::TimeTicks::HighResNow(); | 1052 decode_begin_time = base::TimeTicks::HighResNow(); |
986 pixel_ref->Decode(); | 1053 pixel_ref->Decode(); |
987 if (stats) { | 1054 if (stats) { |
988 stats->totalDeferredImageDecodeCount++; | 1055 stats->totalDeferredImageDecodeCount++; |
989 stats->totalDeferredImageDecodeTime += | 1056 stats->totalDeferredImageDecodeTime += |
990 base::TimeTicks::HighResNow() - decode_begin_time; | 1057 base::TimeTicks::HighResNow() - decode_begin_time; |
991 } | 1058 } |
992 } | 1059 } |
993 | 1060 |
994 } // namespace cc | 1061 } // namespace cc |
OLD | NEW |