cc: Remove auto use with smart pointers.
[chromium-blink-merge.git] / cc / debug / rasterize_and_record_benchmark_impl.cc
blobc638ddcf65bb507ddb2ebeaae0b04827a4045905
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.
5 #include "cc/debug/rasterize_and_record_benchmark_impl.h"
7 #include <algorithm>
8 #include <limits>
10 #include "base/basictypes.h"
11 #include "base/values.h"
12 #include "cc/debug/lap_timer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/layers/picture_layer_impl.h"
15 #include "cc/resources/tile_task_worker_pool.h"
16 #include "cc/trees/layer_tree_host_common.h"
17 #include "cc/trees/layer_tree_host_impl.h"
18 #include "cc/trees/layer_tree_impl.h"
19 #include "ui/gfx/geometry/rect.h"
21 namespace cc {
23 namespace {
25 const int kDefaultRasterizeRepeatCount = 100;
27 class BenchmarkRasterTask : public Task {
28 public:
29 BenchmarkRasterTask(RasterSource* raster_source,
30 const gfx::Rect& content_rect,
31 float contents_scale,
32 size_t repeat_count)
33 : raster_source_(raster_source),
34 content_rect_(content_rect),
35 contents_scale_(contents_scale),
36 repeat_count_(repeat_count),
37 is_solid_color_(false),
38 best_time_(base::TimeDelta::Max()) {}
40 // Overridden from Task:
41 void RunOnWorkerThread() override {
42 // Parameters for LapTimer.
43 const int kTimeLimitMillis = 1;
44 const int kWarmupRuns = 0;
45 const int kTimeCheckInterval = 1;
47 for (size_t i = 0; i < repeat_count_; ++i) {
48 // Run for a minimum amount of time to avoid problems with timer
49 // quantization when the layer is very small.
50 LapTimer timer(kWarmupRuns,
51 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
52 kTimeCheckInterval);
53 do {
54 SkBitmap bitmap;
55 bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect_.width(),
56 content_rect_.height()));
57 SkCanvas canvas(bitmap);
58 RasterSource::SolidColorAnalysis analysis;
60 raster_source_->PerformSolidColorAnalysis(content_rect_,
61 contents_scale_, &analysis);
62 raster_source_->PlaybackToCanvas(&canvas, content_rect_,
63 contents_scale_);
65 is_solid_color_ = analysis.is_solid_color;
67 timer.NextLap();
68 } while (!timer.HasTimeLimitExpired());
69 base::TimeDelta duration =
70 base::TimeDelta::FromMillisecondsD(timer.MsPerLap());
71 if (duration < best_time_)
72 best_time_ = duration;
76 bool IsSolidColor() const { return is_solid_color_; }
77 base::TimeDelta GetBestTime() const { return best_time_; }
79 private:
80 ~BenchmarkRasterTask() override {}
82 RasterSource* raster_source_;
83 gfx::Rect content_rect_;
84 float contents_scale_;
85 size_t repeat_count_;
86 bool is_solid_color_;
87 base::TimeDelta best_time_;
90 class FixedInvalidationPictureLayerTilingClient
91 : public PictureLayerTilingClient {
92 public:
93 FixedInvalidationPictureLayerTilingClient(
94 PictureLayerTilingClient* base_client,
95 const Region invalidation)
96 : base_client_(base_client), invalidation_(invalidation) {}
98 scoped_refptr<Tile> CreateTile(float contents_scale,
99 const gfx::Rect& content_rect) override {
100 return base_client_->CreateTile(contents_scale, content_rect);
103 gfx::Size CalculateTileSize(const gfx::Size& content_bounds) const override {
104 return base_client_->CalculateTileSize(content_bounds);
107 // This is the only function that returns something different from the base
108 // client. Avoids sharing tiles in this area.
109 const Region* GetPendingInvalidation() override { return &invalidation_; }
111 const PictureLayerTiling* GetPendingOrActiveTwinTiling(
112 const PictureLayerTiling* tiling) const override {
113 return base_client_->GetPendingOrActiveTwinTiling(tiling);
116 PictureLayerTiling* GetRecycledTwinTiling(
117 const PictureLayerTiling* tiling) override {
118 return base_client_->GetRecycledTwinTiling(tiling);
121 TilePriority::PriorityBin GetMaxTilePriorityBin() const override {
122 return base_client_->GetMaxTilePriorityBin();
125 WhichTree GetTree() const override { return base_client_->GetTree(); }
127 bool RequiresHighResToDraw() const override {
128 return base_client_->RequiresHighResToDraw();
131 private:
132 PictureLayerTilingClient* base_client_;
133 Region invalidation_;
136 } // namespace
138 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
139 scoped_refptr<base::MessageLoopProxy> origin_loop,
140 base::Value* value,
141 const MicroBenchmarkImpl::DoneCallback& callback)
142 : MicroBenchmarkImpl(callback, origin_loop),
143 rasterize_repeat_count_(kDefaultRasterizeRepeatCount) {
144 base::DictionaryValue* settings = nullptr;
145 value->GetAsDictionary(&settings);
146 if (!settings)
147 return;
149 if (settings->HasKey("rasterize_repeat_count"))
150 settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_);
153 RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
155 void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
156 LayerTreeHostImpl* host) {
157 LayerTreeHostCommon::CallFunctionForSubtree(
158 host->RootLayer(),
159 base::Bind(&RasterizeAndRecordBenchmarkImpl::Run,
160 base::Unretained(this)));
162 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
163 result->SetDouble("rasterize_time_ms",
164 rasterize_results_.total_best_time.InMillisecondsF());
165 result->SetDouble("total_pictures_in_pile_size",
166 rasterize_results_.total_memory_usage);
167 result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
168 result->SetInteger("pixels_rasterized_with_non_solid_color",
169 rasterize_results_.pixels_rasterized_with_non_solid_color);
170 result->SetInteger("pixels_rasterized_as_opaque",
171 rasterize_results_.pixels_rasterized_as_opaque);
172 result->SetInteger("total_layers", rasterize_results_.total_layers);
173 result->SetInteger("total_picture_layers",
174 rasterize_results_.total_picture_layers);
175 result->SetInteger("total_picture_layers_with_no_content",
176 rasterize_results_.total_picture_layers_with_no_content);
177 result->SetInteger("total_picture_layers_off_screen",
178 rasterize_results_.total_picture_layers_off_screen);
180 NotifyDone(result.Pass());
183 void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) {
184 rasterize_results_.total_layers++;
185 layer->RunMicroBenchmark(this);
188 void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
189 rasterize_results_.total_picture_layers++;
190 if (!layer->CanHaveTilings()) {
191 rasterize_results_.total_picture_layers_with_no_content++;
192 return;
194 if (layer->visible_content_rect().IsEmpty()) {
195 rasterize_results_.total_picture_layers_off_screen++;
196 return;
199 TaskGraphRunner* task_graph_runner = TileTaskWorkerPool::GetTaskGraphRunner();
200 DCHECK(task_graph_runner);
202 if (!task_namespace_.IsValid())
203 task_namespace_ = task_graph_runner->GetNamespaceToken();
205 FixedInvalidationPictureLayerTilingClient client(
206 layer, gfx::Rect(layer->content_bounds()));
208 // In this benchmark, we will create a local tiling set and measure how long
209 // it takes to rasterize content. As such, the actual settings used here don't
210 // really matter.
211 const LayerTreeSettings& settings = layer->layer_tree_impl()->settings();
212 scoped_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create(
213 &client, settings.max_tiles_for_interest_area,
214 settings.skewport_target_time_in_seconds,
215 settings.skewport_extrapolation_limit_in_content_pixels);
217 PictureLayerTiling* tiling = tiling_set->AddTiling(layer->contents_scale_x(),
218 layer->GetRasterSource());
219 tiling->CreateAllTilesForTesting();
220 for (PictureLayerTiling::CoverageIterator it(
221 tiling, layer->contents_scale_x(), layer->visible_content_rect());
223 ++it) {
224 DCHECK(*it);
226 RasterSource* raster_source = (*it)->raster_source();
227 gfx::Rect content_rect = (*it)->content_rect();
228 float contents_scale = (*it)->contents_scale();
230 scoped_refptr<BenchmarkRasterTask> benchmark_raster_task(
231 new BenchmarkRasterTask(raster_source,
232 content_rect,
233 contents_scale,
234 rasterize_repeat_count_));
236 TaskGraph graph;
238 graph.nodes.push_back(
239 TaskGraph::Node(benchmark_raster_task.get(),
240 TileTaskWorkerPool::kBenchmarkTaskPriority, 0u));
242 task_graph_runner->ScheduleTasks(task_namespace_, &graph);
243 task_graph_runner->WaitForTasksToFinishRunning(task_namespace_);
245 Task::Vector completed_tasks;
246 task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks);
247 DCHECK_EQ(1u, completed_tasks.size());
248 DCHECK_EQ(completed_tasks[0], benchmark_raster_task);
250 int tile_size = content_rect.width() * content_rect.height();
251 base::TimeDelta min_time = benchmark_raster_task->GetBestTime();
252 bool is_solid_color = benchmark_raster_task->IsSolidColor();
254 if (layer->contents_opaque())
255 rasterize_results_.pixels_rasterized_as_opaque += tile_size;
257 if (!is_solid_color) {
258 rasterize_results_.pixels_rasterized_with_non_solid_color += tile_size;
261 rasterize_results_.pixels_rasterized += tile_size;
262 rasterize_results_.total_best_time += min_time;
265 const RasterSource* layer_raster_source = layer->GetRasterSource();
266 rasterize_results_.total_memory_usage +=
267 layer_raster_source->GetPictureMemoryUsage();
270 RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
271 : pixels_rasterized(0),
272 pixels_rasterized_with_non_solid_color(0),
273 pixels_rasterized_as_opaque(0),
274 total_memory_usage(0),
275 total_layers(0),
276 total_picture_layers(0),
277 total_picture_layers_with_no_content(0),
278 total_picture_layers_off_screen(0) {
281 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}
283 } // namespace cc