1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/debug/rasterize_and_record_benchmark.h" 6 7 #include <algorithm> 8 #include <limits> 9 10 #include "base/basictypes.h" 11 #include "base/values.h" 12 #include "cc/debug/rasterize_and_record_benchmark_impl.h" 13 #include "cc/layers/layer.h" 14 #include "cc/layers/picture_layer.h" 15 #include "cc/trees/layer_tree_host.h" 16 #include "cc/trees/layer_tree_host_common.h" 17 #include "ui/gfx/rect.h" 18 19 namespace cc { 20 21 namespace { 22 23 const int kDefaultRecordRepeatCount = 100; 24 25 base::TimeTicks Now() { 26 return base::TimeTicks::IsThreadNowSupported() 27 ? base::TimeTicks::ThreadNow() 28 : base::TimeTicks::HighResNow(); 29 } 30 31 } // namespace 32 33 RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark( 34 scoped_ptr<base::Value> value, 35 const MicroBenchmark::DoneCallback& callback) 36 : MicroBenchmark(callback), 37 record_repeat_count_(kDefaultRecordRepeatCount), 38 settings_(value.Pass()), 39 main_thread_benchmark_done_(false), 40 host_(NULL), 41 weak_ptr_factory_(this) { 42 base::DictionaryValue* settings = NULL; 43 settings_->GetAsDictionary(&settings); 44 if (!settings) 45 return; 46 47 if (settings->HasKey("record_repeat_count")) 48 settings->GetInteger("record_repeat_count", &record_repeat_count_); 49 } 50 51 RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() { 52 weak_ptr_factory_.InvalidateWeakPtrs(); 53 } 54 55 void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) { 56 host_ = host; 57 LayerTreeHostCommon::CallFunctionForSubtree( 58 host->root_layer(), 59 base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this))); 60 61 DCHECK(!results_.get()); 62 results_ = make_scoped_ptr(new base::DictionaryValue); 63 results_->SetInteger("pixels_recorded", record_results_.pixels_recorded); 64 results_->SetDouble("record_time_ms", 65 record_results_.total_best_time.InMillisecondsF()); 66 main_thread_benchmark_done_ = true; 67 } 68 69 void RasterizeAndRecordBenchmark::RecordRasterResults( 70 scoped_ptr<base::Value> results_value) { 71 DCHECK(main_thread_benchmark_done_); 72 73 base::DictionaryValue* results = NULL; 74 results_value->GetAsDictionary(&results); 75 76 DCHECK(results); 77 DCHECK(results->HasKey("pixels_rasterized")); 78 DCHECK(results->HasKey("rasterize_time_ms")); 79 80 int pixels_rasterized; 81 results->GetInteger("pixels_rasterized", &pixels_rasterized); 82 double rasterize_time_ms; 83 results->GetDouble("rasterize_time_ms", &rasterize_time_ms); 84 85 results_->SetInteger("pixels_rasterized", pixels_rasterized); 86 results_->SetDouble("rasterize_time_ms", rasterize_time_ms); 87 88 NotifyDone(results_.PassAs<base::Value>()); 89 } 90 91 scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl( 92 scoped_refptr<base::MessageLoopProxy> origin_loop) { 93 return scoped_ptr<MicroBenchmarkImpl>(new RasterizeAndRecordBenchmarkImpl( 94 origin_loop, 95 settings_.get(), 96 base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults, 97 weak_ptr_factory_.GetWeakPtr()))); 98 } 99 100 void RasterizeAndRecordBenchmark::Run(Layer* layer) { 101 layer->RunMicroBenchmark(this); 102 } 103 104 void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) { 105 ContentLayerClient* painter = layer->client(); 106 gfx::Size content_bounds = layer->content_bounds(); 107 108 DCHECK(host_); 109 gfx::Size tile_grid_size = host_->settings().default_tile_size; 110 111 SkTileGridPicture::TileGridInfo tile_grid_info; 112 PicturePileBase::ComputeTileGridInfo(tile_grid_size, &tile_grid_info); 113 114 gfx::Rect visible_content_rect = gfx::ScaleToEnclosingRect( 115 layer->visible_content_rect(), 1.f / layer->contents_scale_x()); 116 if (visible_content_rect.IsEmpty()) 117 return; 118 119 scoped_refptr<Picture> picture = Picture::Create(visible_content_rect); 120 121 base::TimeDelta min_time = 122 base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max()); 123 for (int i = 0; i < record_repeat_count_; ++i) { 124 base::TimeTicks start = Now(); 125 picture->Record(painter, tile_grid_info); 126 base::TimeTicks end = Now(); 127 base::TimeDelta duration = end - start; 128 if (duration < min_time) 129 min_time = duration; 130 } 131 132 record_results_.pixels_recorded += 133 visible_content_rect.width() * visible_content_rect.height(); 134 record_results_.total_best_time += min_time; 135 } 136 137 RasterizeAndRecordBenchmark::RecordResults::RecordResults() 138 : pixels_recorded(0) {} 139 140 RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {} 141 142 } // namespace cc 143