| 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 |