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"
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"
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
{
33 BenchmarkRasterTask(PicturePileImpl
* picture_pile
,
34 const gfx::Rect
& content_rect
,
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
) {
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_
; }
74 virtual ~BenchmarkRasterTask() {}
76 PicturePileImpl
* picture_pile_
;
77 gfx::Rect content_rect_
;
78 float contents_scale_
;
81 base::TimeDelta best_time_
;
86 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
87 scoped_refptr
<base::MessageLoopProxy
> origin_loop
,
89 const MicroBenchmarkImpl::DoneCallback
& callback
)
90 : MicroBenchmarkImpl(callback
, origin_loop
),
91 rasterize_repeat_count_(kDefaultRasterizeRepeatCount
) {
92 base::DictionaryValue
* settings
= NULL
;
93 value
->GetAsDictionary(&settings
);
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(
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
++;
140 if (layer
->visible_content_rect().IsEmpty()) {
141 rasterize_results_
.total_picture_layers_off_screen
++;
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());
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
,
169 rasterize_repeat_count_
));
173 graph
.nodes
.push_back(
174 TaskGraph::Node(benchmark_raster_task
,
175 RasterWorkerPool::kBenchmarkRasterTaskPriority
,
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),
207 total_picture_layers(0),
208 total_picture_layers_with_no_content(0),
209 total_picture_layers_off_screen(0) {}
211 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}