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/picture_record_benchmark.h"
9 #include "base/basictypes.h"
10 #include "base/values.h"
11 #include "cc/layers/layer.h"
12 #include "cc/layers/picture_layer.h"
13 #include "cc/trees/layer_tree_host.h"
14 #include "cc/trees/layer_tree_host_common.h"
15 #include "ui/gfx/rect.h"
21 const int kPositionIncrement
= 100;
22 const int kTileGridSize
= 512;
23 const int kTileGridBorder
= 1;
27 PictureRecordBenchmark::PictureRecordBenchmark(
28 scoped_ptr
<base::Value
> value
,
29 const MicroBenchmark::DoneCallback
& callback
)
30 : MicroBenchmark(callback
) {
34 base::ListValue
* list
= NULL
;
35 value
->GetAsList(&list
);
39 for (base::ListValue::iterator it
= list
->begin(); it
!= list
->end(); ++it
) {
40 base::DictionaryValue
* dictionary
= NULL
;
41 (*it
)->GetAsDictionary(&dictionary
);
43 !dictionary
->HasKey("width") ||
44 !dictionary
->HasKey("height"))
48 dictionary
->GetInteger("width", &width
);
49 dictionary
->GetInteger("height", &height
);
51 dimensions_
.push_back(std::make_pair(width
, height
));
55 PictureRecordBenchmark::~PictureRecordBenchmark() {}
57 void PictureRecordBenchmark::DidUpdateLayers(LayerTreeHost
* host
) {
58 LayerTreeHostCommon::CallFunctionForSubtree(
60 base::Bind(&PictureRecordBenchmark::Run
, base::Unretained(this)));
62 scoped_ptr
<base::ListValue
> results(new base::ListValue());
63 for (std::map
<std::pair
<int, int>, TotalTime
>::iterator it
= times_
.begin();
66 std::pair
<int, int> dimensions
= it
->first
;
67 base::TimeDelta total_time
= it
->second
.first
;
68 unsigned total_count
= it
->second
.second
;
70 double average_time
= 0.0;
72 average_time
= total_time
.InMillisecondsF() / total_count
;
74 scoped_ptr
<base::DictionaryValue
> result(new base::DictionaryValue());
75 result
->SetInteger("width", dimensions
.first
);
76 result
->SetInteger("height", dimensions
.second
);
77 result
->SetInteger("samples_count", total_count
);
78 result
->SetDouble("time_ms", average_time
);
80 results
->Append(result
.release());
83 NotifyDone(results
.PassAs
<base::Value
>());
86 void PictureRecordBenchmark::Run(Layer
* layer
) {
87 layer
->RunMicroBenchmark(this);
90 void PictureRecordBenchmark::RunOnLayer(PictureLayer
* layer
) {
91 ContentLayerClient
* painter
= layer
->client();
92 gfx::Size content_bounds
= layer
->content_bounds();
94 SkTileGridFactory::TileGridInfo tile_grid_info
;
95 tile_grid_info
.fTileInterval
.set(kTileGridSize
- 2 * kTileGridBorder
,
96 kTileGridSize
- 2 * kTileGridBorder
);
97 tile_grid_info
.fMargin
.set(kTileGridBorder
, kTileGridBorder
);
98 tile_grid_info
.fOffset
.set(-kTileGridBorder
, -kTileGridBorder
);
100 for (size_t i
= 0; i
< dimensions_
.size(); ++i
) {
101 std::pair
<int, int> dimensions
= dimensions_
[i
];
102 int width
= dimensions
.first
;
103 int height
= dimensions
.second
;
105 int y_limit
= std::max(1, content_bounds
.height() - height
);
106 int x_limit
= std::max(1, content_bounds
.width() - width
);
107 for (int y
= 0; y
< y_limit
; y
+= kPositionIncrement
) {
108 for (int x
= 0; x
< x_limit
; x
+= kPositionIncrement
) {
109 gfx::Rect rect
= gfx::Rect(x
, y
, width
, height
);
111 base::TimeTicks start
= base::TimeTicks::HighResNow();
113 scoped_refptr
<Picture
> picture
= Picture::Create(
114 rect
, painter
, tile_grid_info
, false, 0, Picture::RECORD_NORMALLY
);
116 base::TimeTicks end
= base::TimeTicks::HighResNow();
117 base::TimeDelta duration
= end
- start
;
118 TotalTime
& total_time
= times_
[dimensions
];
119 total_time
.first
+= duration
;