Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / cc / debug / rasterize_and_record_benchmark_impl.cc
bloba22c2cd4d286dd06fa4998d2538a0944f0de5a63
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/raster_worker_pool.h"
16 #include "cc/trees/layer_tree_host_common.h"
17 #include "cc/trees/layer_tree_host_impl.h"
18 #include "ui/gfx/rect.h"
20 namespace cc {
22 namespace {
24 const int kDefaultRasterizeRepeatCount = 100;
26 class BenchmarkRasterTask : public Task {
27 public:
28 BenchmarkRasterTask(PicturePileImpl* picture_pile,
29 const gfx::Rect& content_rect,
30 float contents_scale,
31 size_t repeat_count)
32 : picture_pile_(picture_pile),
33 content_rect_(content_rect),
34 contents_scale_(contents_scale),
35 repeat_count_(repeat_count),
36 is_solid_color_(false),
37 best_time_(base::TimeDelta::Max()) {}
39 // Overridden from Task:
40 virtual void RunOnWorkerThread() OVERRIDE {
41 PicturePileImpl* picture_pile = picture_pile_->GetCloneForDrawingOnThread(
42 RasterWorkerPool::GetPictureCloneIndexForCurrentThread());
44 // Parameters for LapTimer.
45 const int kTimeLimitMillis = 1;
46 const int kWarmupRuns = 0;
47 const int kTimeCheckInterval = 1;
49 for (size_t i = 0; i < repeat_count_; ++i) {
50 // Run for a minimum amount of time to avoid problems with timer
51 // quantization when the layer is very small.
52 LapTimer timer(kWarmupRuns,
53 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
54 kTimeCheckInterval);
55 do {
56 SkBitmap bitmap;
57 bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect_.width(),
58 content_rect_.height()));
59 SkCanvas canvas(bitmap);
60 PicturePileImpl::Analysis analysis;
62 picture_pile->AnalyzeInRect(
63 content_rect_, contents_scale_, &analysis, NULL);
64 picture_pile->RasterToBitmap(
65 &canvas, content_rect_, contents_scale_, NULL);
67 is_solid_color_ = analysis.is_solid_color;
69 timer.NextLap();
70 } while (!timer.HasTimeLimitExpired());
71 base::TimeDelta duration =
72 base::TimeDelta::FromMillisecondsD(timer.MsPerLap());
73 if (duration < best_time_)
74 best_time_ = duration;
79 bool IsSolidColor() const { return is_solid_color_; }
80 base::TimeDelta GetBestTime() const { return best_time_; }
82 private:
83 virtual ~BenchmarkRasterTask() {}
85 PicturePileImpl* picture_pile_;
86 gfx::Rect content_rect_;
87 float contents_scale_;
88 size_t repeat_count_;
89 bool is_solid_color_;
90 base::TimeDelta best_time_;
93 } // namespace
95 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
96 scoped_refptr<base::MessageLoopProxy> origin_loop,
97 base::Value* value,
98 const MicroBenchmarkImpl::DoneCallback& callback)
99 : MicroBenchmarkImpl(callback, origin_loop),
100 rasterize_repeat_count_(kDefaultRasterizeRepeatCount) {
101 base::DictionaryValue* settings = NULL;
102 value->GetAsDictionary(&settings);
103 if (!settings)
104 return;
106 if (settings->HasKey("rasterize_repeat_count"))
107 settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_);
110 RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
112 void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
113 LayerTreeHostImpl* host) {
114 LayerTreeHostCommon::CallFunctionForSubtree(
115 host->RootLayer(),
116 base::Bind(&RasterizeAndRecordBenchmarkImpl::Run,
117 base::Unretained(this)));
119 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
120 result->SetDouble("rasterize_time_ms",
121 rasterize_results_.total_best_time.InMillisecondsF());
122 result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
123 result->SetInteger("pixels_rasterized_with_non_solid_color",
124 rasterize_results_.pixels_rasterized_with_non_solid_color);
125 result->SetInteger("pixels_rasterized_as_opaque",
126 rasterize_results_.pixels_rasterized_as_opaque);
127 result->SetInteger("total_layers", rasterize_results_.total_layers);
128 result->SetInteger("total_picture_layers",
129 rasterize_results_.total_picture_layers);
130 result->SetInteger("total_picture_layers_with_no_content",
131 rasterize_results_.total_picture_layers_with_no_content);
132 result->SetInteger("total_picture_layers_off_screen",
133 rasterize_results_.total_picture_layers_off_screen);
135 NotifyDone(result.PassAs<base::Value>());
138 void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) {
139 rasterize_results_.total_layers++;
140 layer->RunMicroBenchmark(this);
143 void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
144 rasterize_results_.total_picture_layers++;
145 if (!layer->DrawsContent()) {
146 rasterize_results_.total_picture_layers_with_no_content++;
147 return;
149 if (layer->visible_content_rect().IsEmpty()) {
150 rasterize_results_.total_picture_layers_off_screen++;
151 return;
154 TaskGraphRunner* task_graph_runner = RasterWorkerPool::GetTaskGraphRunner();
155 DCHECK(task_graph_runner);
157 if (!task_namespace_.IsValid())
158 task_namespace_ = task_graph_runner->GetNamespaceToken();
160 PictureLayerTilingSet tiling_set(layer, layer->content_bounds());
162 PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x());
163 tiling->CreateAllTilesForTesting();
164 for (PictureLayerTiling::CoverageIterator it(
165 tiling, layer->contents_scale_x(), layer->visible_content_rect());
167 ++it) {
168 DCHECK(*it);
170 PicturePileImpl* picture_pile = (*it)->picture_pile();
171 gfx::Rect content_rect = (*it)->content_rect();
172 float contents_scale = (*it)->contents_scale();
174 scoped_refptr<BenchmarkRasterTask> benchmark_raster_task(
175 new BenchmarkRasterTask(picture_pile,
176 content_rect,
177 contents_scale,
178 rasterize_repeat_count_));
180 TaskGraph graph;
182 graph.nodes.push_back(
183 TaskGraph::Node(benchmark_raster_task,
184 RasterWorkerPool::kBenchmarkRasterTaskPriority,
185 0u));
187 task_graph_runner->ScheduleTasks(task_namespace_, &graph);
188 task_graph_runner->WaitForTasksToFinishRunning(task_namespace_);
190 Task::Vector completed_tasks;
191 task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks);
192 DCHECK_EQ(1u, completed_tasks.size());
193 DCHECK_EQ(completed_tasks[0], benchmark_raster_task);
195 int tile_size = content_rect.width() * content_rect.height();
196 base::TimeDelta min_time = benchmark_raster_task->GetBestTime();
197 bool is_solid_color = benchmark_raster_task->IsSolidColor();
199 if (layer->contents_opaque())
200 rasterize_results_.pixels_rasterized_as_opaque += tile_size;
202 if (!is_solid_color) {
203 rasterize_results_.pixels_rasterized_with_non_solid_color += tile_size;
206 rasterize_results_.pixels_rasterized += tile_size;
207 rasterize_results_.total_best_time += min_time;
211 RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
212 : pixels_rasterized(0),
213 pixels_rasterized_with_non_solid_color(0),
214 pixels_rasterized_as_opaque(0),
215 total_layers(0),
216 total_picture_layers(0),
217 total_picture_layers_with_no_content(0),
218 total_picture_layers_off_screen(0) {}
220 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}
222 } // namespace cc