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.h"
11 #include "base/basictypes.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/values.h"
14 #include "cc/debug/lap_timer.h"
15 #include "cc/debug/rasterize_and_record_benchmark_impl.h"
16 #include "cc/layers/layer.h"
17 #include "cc/layers/picture_layer.h"
18 #include "cc/trees/layer_tree_host.h"
19 #include "cc/trees/layer_tree_host_common.h"
20 #include "ui/gfx/rect.h"
26 const int kDefaultRecordRepeatCount
= 100;
28 const char* kModeSuffixes
[Picture::RECORDING_MODE_COUNT
] = {
29 "", "_sk_null_canvas", "_painting_disabled", "_skrecord"};
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),
41 weak_ptr_factory_(this) {
42 base::DictionaryValue
* settings
= NULL
;
43 settings_
->GetAsDictionary(&settings
);
47 if (settings
->HasKey("record_repeat_count"))
48 settings
->GetInteger("record_repeat_count", &record_repeat_count_
);
51 RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() {
52 weak_ptr_factory_
.InvalidateWeakPtrs();
55 void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost
* host
) {
57 LayerTreeHostCommon::CallFunctionForSubtree(
59 base::Bind(&RasterizeAndRecordBenchmark::Run
, base::Unretained(this)));
61 DCHECK(!results_
.get());
62 results_
= make_scoped_ptr(new base::DictionaryValue
);
63 results_
->SetInteger("pixels_recorded", record_results_
.pixels_recorded
);
65 for (int i
= 0; i
< Picture::RECORDING_MODE_COUNT
; i
++) {
66 std::string name
= base::StringPrintf("record_time%s_ms", kModeSuffixes
[i
]);
67 results_
->SetDouble(name
,
68 record_results_
.total_best_time
[i
].InMillisecondsF());
70 main_thread_benchmark_done_
= true;
73 void RasterizeAndRecordBenchmark::RecordRasterResults(
74 scoped_ptr
<base::Value
> results_value
) {
75 DCHECK(main_thread_benchmark_done_
);
77 base::DictionaryValue
* results
= NULL
;
78 results_value
->GetAsDictionary(&results
);
81 results_
->MergeDictionary(results
);
83 NotifyDone(results_
.PassAs
<base::Value
>());
86 scoped_ptr
<MicroBenchmarkImpl
> RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
87 scoped_refptr
<base::MessageLoopProxy
> origin_loop
) {
88 return scoped_ptr
<MicroBenchmarkImpl
>(new RasterizeAndRecordBenchmarkImpl(
91 base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults
,
92 weak_ptr_factory_
.GetWeakPtr())));
95 void RasterizeAndRecordBenchmark::Run(Layer
* layer
) {
96 layer
->RunMicroBenchmark(this);
99 void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer
* layer
) {
100 ContentLayerClient
* painter
= layer
->client();
101 gfx::Size content_bounds
= layer
->content_bounds();
104 gfx::Size tile_grid_size
= host_
->settings().default_tile_size
;
106 SkTileGridFactory::TileGridInfo tile_grid_info
;
107 PicturePileBase::ComputeTileGridInfo(tile_grid_size
, &tile_grid_info
);
109 gfx::Rect visible_content_rect
= gfx::ScaleToEnclosingRect(
110 layer
->visible_content_rect(), 1.f
/ layer
->contents_scale_x());
111 if (visible_content_rect
.IsEmpty())
114 for (int mode_index
= 0; mode_index
< Picture::RECORDING_MODE_COUNT
;
116 Picture::RecordingMode mode
=
117 static_cast<Picture::RecordingMode
>(mode_index
);
118 base::TimeDelta min_time
= base::TimeDelta::Max();
120 // Parameters for LapTimer.
121 const int kTimeLimitMillis
= 1;
122 const int kWarmupRuns
= 0;
123 const int kTimeCheckInterval
= 1;
125 for (int i
= 0; i
< record_repeat_count_
; ++i
) {
126 // Run for a minimum amount of time to avoid problems with timer
127 // quantization when the layer is very small.
128 LapTimer
timer(kWarmupRuns
,
129 base::TimeDelta::FromMilliseconds(kTimeLimitMillis
),
132 scoped_refptr
<Picture
> picture
= Picture::Create(
133 visible_content_rect
, painter
, tile_grid_info
, false, 0, mode
);
135 } while (!timer
.HasTimeLimitExpired());
136 base::TimeDelta duration
=
137 base::TimeDelta::FromMillisecondsD(timer
.MsPerLap());
138 if (duration
< min_time
)
142 if (mode
== Picture::RECORD_NORMALLY
) {
143 record_results_
.pixels_recorded
+=
144 visible_content_rect
.width() * visible_content_rect
.height();
146 record_results_
.total_best_time
[mode_index
] += min_time
;
150 RasterizeAndRecordBenchmark::RecordResults::RecordResults()
151 : pixels_recorded(0) {}
153 RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {}