Fix redundant flushes in CommandBufferHelper::WaitForToken().
[chromium-blink-merge.git] / cc / debug / rasterize_and_record_benchmark_impl.cc
blob48d7c34f112a74569cb3b4a1d92d7a5fe40e4a87
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/layers/layer_impl.h"
13 #include "cc/layers/picture_layer_impl.h"
14 #include "cc/resources/raster_worker_pool.h"
15 #include "cc/trees/layer_tree_host_common.h"
16 #include "cc/trees/layer_tree_host_impl.h"
17 #include "ui/gfx/rect.h"
19 namespace cc {
21 namespace {
23 const int kDefaultRasterizeRepeatCount = 100;
25 base::TimeTicks Now() {
26 return base::TimeTicks::IsThreadNowSupported()
27 ? base::TimeTicks::ThreadNow()
28 : base::TimeTicks::HighResNow();
31 class BenchmarkRasterTask : public Task {
32 public:
33 BenchmarkRasterTask(PicturePileImpl* picture_pile,
34 const gfx::Rect& content_rect,
35 float contents_scale,
36 size_t repeat_count)
37 : picture_pile_(picture_pile),
38 content_rect_(content_rect),
39 contents_scale_(contents_scale),
40 repeat_count_(repeat_count),
41 is_solid_color_(false),
42 best_time_(base::TimeDelta::Max()) {}
44 // Overridden from Task:
45 virtual void RunOnWorkerThread() OVERRIDE {
46 PicturePileImpl* picture_pile = picture_pile_->GetCloneForDrawingOnThread(
47 RasterWorkerPool::GetPictureCloneIndexForCurrentThread());
49 for (size_t i = 0; i < repeat_count_; ++i) {
50 SkBitmap bitmap;
51 bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect_.width(),
52 content_rect_.height()));
53 SkCanvas canvas(bitmap);
54 PicturePileImpl::Analysis analysis;
56 base::TimeTicks start = Now();
57 picture_pile->AnalyzeInRect(
58 content_rect_, contents_scale_, &analysis, NULL);
59 picture_pile->RasterToBitmap(
60 &canvas, content_rect_, contents_scale_, NULL);
61 base::TimeTicks end = Now();
62 base::TimeDelta duration = end - start;
63 if (duration < best_time_)
64 best_time_ = duration;
66 is_solid_color_ = analysis.is_solid_color;
70 bool IsSolidColor() const { return is_solid_color_; }
71 base::TimeDelta GetBestTime() const { return best_time_; }
73 private:
74 virtual ~BenchmarkRasterTask() {}
76 PicturePileImpl* picture_pile_;
77 gfx::Rect content_rect_;
78 float contents_scale_;
79 size_t repeat_count_;
80 bool is_solid_color_;
81 base::TimeDelta best_time_;
84 } // namespace
86 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
87 scoped_refptr<base::MessageLoopProxy> origin_loop,
88 base::Value* value,
89 const MicroBenchmarkImpl::DoneCallback& callback)
90 : MicroBenchmarkImpl(callback, origin_loop),
91 rasterize_repeat_count_(kDefaultRasterizeRepeatCount) {
92 base::DictionaryValue* settings = NULL;
93 value->GetAsDictionary(&settings);
94 if (!settings)
95 return;
97 if (settings->HasKey("rasterize_repeat_count"))
98 settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_);
101 RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
103 void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
104 LayerTreeHostImpl* host) {
105 LayerTreeHostCommon::CallFunctionForSubtree(
106 host->RootLayer(),
107 base::Bind(&RasterizeAndRecordBenchmarkImpl::Run,
108 base::Unretained(this)));
110 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
111 result->SetDouble("rasterize_time_ms",
112 rasterize_results_.total_best_time.InMillisecondsF());
113 result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
114 result->SetInteger("pixels_rasterized_with_non_solid_color",
115 rasterize_results_.pixels_rasterized_with_non_solid_color);
116 result->SetInteger("pixels_rasterized_as_opaque",
117 rasterize_results_.pixels_rasterized_as_opaque);
118 result->SetInteger("total_layers", rasterize_results_.total_layers);
119 result->SetInteger("total_picture_layers",
120 rasterize_results_.total_picture_layers);
121 result->SetInteger("total_picture_layers_with_no_content",
122 rasterize_results_.total_picture_layers_with_no_content);
123 result->SetInteger("total_picture_layers_off_screen",
124 rasterize_results_.total_picture_layers_off_screen);
126 NotifyDone(result.PassAs<base::Value>());
129 void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) {
130 rasterize_results_.total_layers++;
131 layer->RunMicroBenchmark(this);
134 void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
135 rasterize_results_.total_picture_layers++;
136 if (!layer->DrawsContent()) {
137 rasterize_results_.total_picture_layers_with_no_content++;
138 return;
140 if (layer->visible_content_rect().IsEmpty()) {
141 rasterize_results_.total_picture_layers_off_screen++;
142 return;
145 TaskGraphRunner* task_graph_runner = RasterWorkerPool::GetTaskGraphRunner();
146 DCHECK(task_graph_runner);
148 if (!task_namespace_.IsValid())
149 task_namespace_ = task_graph_runner->GetNamespaceToken();
151 PictureLayerTilingSet tiling_set(layer, layer->content_bounds());
153 PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x());
154 tiling->CreateAllTilesForTesting();
155 for (PictureLayerTiling::CoverageIterator it(
156 tiling, layer->contents_scale_x(), layer->visible_content_rect());
158 ++it) {
159 DCHECK(*it);
161 PicturePileImpl* picture_pile = (*it)->picture_pile();
162 gfx::Rect content_rect = (*it)->content_rect();
163 float contents_scale = (*it)->contents_scale();
165 scoped_refptr<BenchmarkRasterTask> benchmark_raster_task(
166 new BenchmarkRasterTask(picture_pile,
167 content_rect,
168 contents_scale,
169 rasterize_repeat_count_));
171 TaskGraph graph;
173 graph.nodes.push_back(
174 TaskGraph::Node(benchmark_raster_task,
175 RasterWorkerPool::kBenchmarkRasterTaskPriority,
176 0u));
178 task_graph_runner->ScheduleTasks(task_namespace_, &graph);
179 task_graph_runner->WaitForTasksToFinishRunning(task_namespace_);
181 Task::Vector completed_tasks;
182 task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks);
183 DCHECK_EQ(1u, completed_tasks.size());
184 DCHECK_EQ(completed_tasks[0], benchmark_raster_task);
186 int tile_size = content_rect.width() * content_rect.height();
187 base::TimeDelta min_time = benchmark_raster_task->GetBestTime();
188 bool is_solid_color = benchmark_raster_task->IsSolidColor();
190 if (layer->contents_opaque())
191 rasterize_results_.pixels_rasterized_as_opaque += tile_size;
193 if (!is_solid_color) {
194 rasterize_results_.pixels_rasterized_with_non_solid_color += tile_size;
197 rasterize_results_.pixels_rasterized += tile_size;
198 rasterize_results_.total_best_time += min_time;
202 RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
203 : pixels_rasterized(0),
204 pixels_rasterized_with_non_solid_color(0),
205 pixels_rasterized_as_opaque(0),
206 total_layers(0),
207 total_picture_layers(0),
208 total_picture_layers_with_no_content(0),
209 total_picture_layers_off_screen(0) {}
211 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}
213 } // namespace cc