1 // Copyright 2012 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/layer_tree_host.h"
7 #include "base/file_path.h"
8 #include "base/file_util.h"
9 #include "base/json/json_reader.h"
10 #include "base/path_service.h"
11 #include "base/string_piece.h"
12 #include "cc/content_layer.h"
13 #include "cc/nine_patch_layer.h"
14 #include "cc/solid_color_layer.h"
15 #include "cc/test/fake_content_layer_client.h"
16 #include "cc/test/layer_tree_test_common.h"
17 #include "cc/test/paths.h"
22 static const int kTimeLimitMillis
= 2000;
24 class LayerTreeHostPerfTest
: public ThreadedTest
{
26 LayerTreeHostPerfTest()
28 fake_delegate_
.setPaintAllOpaque(true);
31 virtual void beginTest() OVERRIDE
{
33 start_time_
= base::TimeTicks::HighResNow();
34 postSetNeedsCommitToMainThread();
37 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
39 if ((base::TimeTicks::HighResNow() - start_time_
) >=
40 base::TimeDelta::FromMilliseconds(kTimeLimitMillis
))
43 impl
->setNeedsRedraw();
46 virtual void buildTree() {}
48 virtual void afterTest() OVERRIDE
{
49 base::TimeDelta elapsed
= base::TimeTicks::HighResNow() - start_time_
;
50 // Format matches chrome/test/perf/perf_test.h:PrintResult
51 printf("*RESULT %s: frames= %.2f runs/s\n",
53 num_draws_
/ elapsed
.InSecondsF());
56 scoped_refptr
<Layer
> CreateLayer(float x
, float y
, int width
, int height
) {
57 scoped_refptr
<Layer
> layer
= Layer::create();
58 layer
->setAnchorPoint(gfx::Point());
59 layer
->setPosition(gfx::PointF(x
, y
));
60 layer
->setBounds(gfx::Size(width
, height
));
64 scoped_refptr
<ContentLayer
> CreateContentLayer(float x
, float y
, int width
, int height
, bool drawable
=true) {
65 scoped_refptr
<ContentLayer
> layer
= ContentLayer::create(&fake_delegate_
);
66 layer
->setAnchorPoint(gfx::Point());
67 layer
->setPosition(gfx::PointF(x
, y
));
68 layer
->setBounds(gfx::Size(width
, height
));
69 layer
->setIsDrawable(drawable
);
73 scoped_refptr
<SolidColorLayer
> CreateColorLayer(float x
, float y
, int width
, int height
, bool drawable
=true) {
74 scoped_refptr
<SolidColorLayer
> layer
= SolidColorLayer::create();
75 layer
->setAnchorPoint(gfx::Point());
76 layer
->setPosition(gfx::PointF(x
, y
));
77 layer
->setBounds(gfx::Size(width
, height
));
78 layer
->setIsDrawable(drawable
);
82 scoped_refptr
<NinePatchLayer
> CreateDecorationLayer(float x
, float y
, int width
, int height
) {
83 return CreateDecorationLayer(x
, y
, width
, height
, gfx::Rect(0, 0, width
, height
));
86 scoped_refptr
<NinePatchLayer
> CreateDecorationLayer(float x
, float y
, int width
, int height
, gfx::Rect aperture
, bool drawable
=true) {
87 scoped_refptr
<NinePatchLayer
> layer
= NinePatchLayer::create();
88 layer
->setAnchorPoint(gfx::Point());
89 layer
->setPosition(gfx::PointF(x
, y
));
90 layer
->setBounds(gfx::Size(width
, height
));
91 layer
->setIsDrawable(drawable
);
94 bitmap
.setConfig(SkBitmap::kARGB_8888_Config
, 1, 1);
95 bitmap
.allocPixels(NULL
, NULL
);
96 layer
->setBitmap(bitmap
, aperture
);
101 scoped_refptr
<Layer
> addChild(scoped_refptr
<Layer
> parent
, scoped_refptr
<Layer
> child
) {
102 parent
->addChild(child
);
107 base::TimeTicks start_time_
;
109 std::string test_name_
;
110 FakeContentLayerClient fake_delegate_
;
113 class LayerTreeHostPerfTestSevenTabSwitcher
: public LayerTreeHostPerfTest
{
115 LayerTreeHostPerfTestSevenTabSwitcher()
116 : LayerTreeHostPerfTest() {
117 test_name_
= "SevenTabSwitcher";
120 virtual void buildTree() OVERRIDE
{
121 scoped_refptr
<Layer
> root
= CreateLayer(0, 0, 720, 1038); // 1
122 scoped_refptr
<Layer
> layer
;
124 gfx::Transform down_scale_matrix
;
125 down_scale_matrix
.Scale(0.747, 0.747);
127 layer
= addChild(root
, CreateLayer(0, 0, 0, 0)); // 2
129 layer
= addChild(root
, CreateLayer(628, 15, 0, 0)); // 5
130 layer
= addChild(root
, CreateDecorationLayer(564, -49, 665, 274)); // 13
131 layer
= addChild(root
, CreateDecorationLayer(-16, -16, 569, 807)); // 12
132 layer
= addChild(root
, CreateColorLayer(628, 15, 720, 1038)); // 11
133 layer
->setTransform(down_scale_matrix
);
134 layer
= addChild(root
, CreateContentLayer(628, 16, 720, 1038)); // 34
135 layer
->setTransform(down_scale_matrix
);
137 layer
= addChild(root
, CreateLayer(628, 15, 0, 0)); // 6
138 layer
= addChild(root
, CreateDecorationLayer(612, -1, 569, 807)); // 10
139 layer
= addChild(root
, CreateDecorationLayer(827.135986f
, -1, 354, 96)); // 9
140 layer
= addChild(root
, CreateContentLayer(628, 15, 0, 0)); // 8
141 layer
= addChild(root
, CreateContentLayer(627.418f
, 15, 0, 0)); // 7
143 layer
= addChild(root
, CreateLayer(628, 161, 0, 0)); // 74
144 layer
= addChild(root
, CreateDecorationLayer(564, 97, 665, 383)); // 82
145 layer
= addChild(root
, CreateDecorationLayer(0, 0, 569, 807)); // 81
146 layer
= addChild(root
, CreateColorLayer(628, 161, 720, 1038)); // 80
147 layer
->setTransform(down_scale_matrix
);
148 layer
= addChild(root
, CreateContentLayer(628, 161, 720, 1038)); // 44
149 layer
->setTransform(down_scale_matrix
);
151 layer
= addChild(root
, CreateLayer(628, 161, 0, 0)); // 75
152 layer
= addChild(root
, CreateDecorationLayer(612, 145, 569, 807)); // 79
153 layer
= addChild(root
, CreateDecorationLayer(827.135986f
, 145, 354, 96)); // 78
154 layer
= addChild(root
, CreateContentLayer(628, 161, 0, 0)); // 77
155 layer
= addChild(root
, CreateContentLayer(627.418f
, 161, 0, 0)); // 76
157 layer
= addChild(root
, CreateLayer(628, 417, 0, 0)); // 83
158 layer
= addChild(root
, CreateDecorationLayer(564, 353, 665, 445)); // 91
159 layer
= addChild(root
, CreateDecorationLayer(0, 0, 569, 807)); // 90
160 layer
= addChild(root
, CreateColorLayer(628, 417, 720, 1038)); // 89
161 layer
->setTransform(down_scale_matrix
);
162 layer
= addChild(root
, CreateContentLayer(628, 417, 720, 1038)); // 54
163 layer
->setTransform(down_scale_matrix
);
165 layer
= addChild(root
, CreateLayer(628, 417, 0, 0)); // 84
166 layer
= addChild(root
, CreateDecorationLayer(612, 401, 569, 807)); // 88
167 layer
= addChild(root
, CreateDecorationLayer(827.135986f
, 401, 354, 96)); // 87
168 layer
= addChild(root
, CreateContentLayer(628, 417, 0, 0)); // 86
169 layer
= addChild(root
, CreateContentLayer(627.418f
, 417, 0, 0)); // 85
171 layer
= addChild(root
, CreateLayer(628, 735, 0, 0)); // 92
172 layer
= addChild(root
, CreateDecorationLayer(564, 671, 665, 439)); // 100
173 layer
= addChild(root
, CreateDecorationLayer(0, 0, 569, 807)); // 99
174 layer
= addChild(root
, CreateColorLayer(628, 735, 720, 1038)); // 98
175 layer
->setTransform(down_scale_matrix
);
176 layer
= addChild(root
, CreateContentLayer(628, 735, 720, 1038)); // 64
177 layer
->setTransform(down_scale_matrix
);
179 layer
= addChild(root
, CreateLayer(628, 735, 0, 0)); // 93
180 layer
= addChild(root
, CreateDecorationLayer(612, 719, 569, 807)); // 97
181 layer
= addChild(root
, CreateDecorationLayer(827.135986f
, 719, 354, 96)); // 96
182 layer
= addChild(root
, CreateContentLayer(628, 735, 0, 0)); // 95
183 layer
= addChild(root
, CreateContentLayer(627.418f
, 735, 0, 0)); // 94
185 layer
= addChild(root
, CreateLayer(30, 15, 0, 0)); // 101
186 layer
= addChild(root
, CreateDecorationLayer(-34, -49, 665, 337)); // 109
187 layer
= addChild(root
, CreateDecorationLayer(0, 0, 569, 807)); // 108
188 layer
= addChild(root
, CreateColorLayer(30, 15, 720, 1038)); // 107
189 layer
->setTransform(down_scale_matrix
);
190 layer
= addChild(root
, CreateContentLayer(30, 15, 0, 0)); // 3
191 layer
->setTransform(down_scale_matrix
);
193 layer
= addChild(root
, CreateLayer(30, 15, 0, 0)); // 102
194 layer
= addChild(root
, CreateDecorationLayer(14, -1, 569, 807)); // 106
195 layer
= addChild(root
, CreateDecorationLayer(229.135986f
, -1, 354, 96)); // 105
196 layer
= addChild(root
, CreateContentLayer(30, 15, 0, 0)); // 104
197 layer
= addChild(root
, CreateContentLayer(30, 15, 0, 0)); // 103
199 layer
= addChild(root
, CreateLayer(30, 227, 0, 0)); // 110
200 layer
= addChild(root
, CreateDecorationLayer(-34, 163, 665, 517)); // 118
201 layer
= addChild(root
, CreateDecorationLayer(0, 0, 569, 807)); // 117
202 layer
= addChild(root
, CreateColorLayer(30, 227, 720, 1038)); // 116
203 layer
->setTransform(down_scale_matrix
);
204 layer
= addChild(root
, CreateContentLayer(30, 227, 720, 1038)); // 4
205 layer
->setTransform(down_scale_matrix
);
207 layer
= addChild(root
, CreateLayer(30, 227, 0, 0)); // 111
208 layer
= addChild(root
, CreateDecorationLayer(14, 211, 569, 807)); // 115
209 layer
= addChild(root
, CreateDecorationLayer(229.135986f
, 211, 354, 96)); // 114
210 layer
= addChild(root
, CreateContentLayer(30, 227, 0, 0)); // 113
211 layer
= addChild(root
, CreateContentLayer(30, 227, 0, 0)); // 112
213 layer
= addChild(root
, CreateLayer(30, 617, 0, 0)); // 119
214 layer
= addChild(root
, CreateDecorationLayer(-34, 553, 665, 559)); // 127
215 layer
= addChild(root
, CreateDecorationLayer(136.349190f
, 566.524940f
, 569, 807)); // 126
216 layer
= addChild(root
, CreateColorLayer(30, 617, 720, 1038)); // 125
217 layer
->setTransform(down_scale_matrix
);
218 layer
= addChild(root
, CreateContentLayer(30, 617, 720, 1038)); // 14
219 layer
->setTransform(down_scale_matrix
);
221 layer
= addChild(root
, CreateLayer(30, 617, 0, 0)); // 120
222 layer
= addChild(root
, CreateDecorationLayer(14, 601, 569, 807)); // 124
223 layer
= addChild(root
, CreateDecorationLayer(229.135986f
, 601, 354, 96)); // 123
224 layer
= addChild(root
, CreateContentLayer(30, 617, 0, 0)); // 122
225 layer
= addChild(root
, CreateContentLayer(30, 617, 0, 0)); // 121
227 m_layerTreeHost
->setViewportSize(gfx::Size(720, 1038), gfx::Size(720, 1038));
228 m_layerTreeHost
->setRootLayer(root
);
232 TEST_F(LayerTreeHostPerfTestSevenTabSwitcher
, runSingleThread
) {
236 class LayerTreeHostPerfTestJsonReader
: public LayerTreeHostPerfTest
{
238 LayerTreeHostPerfTestJsonReader()
239 : LayerTreeHostPerfTest() {
242 void readTestFile(std::string name
) {
244 FilePath test_data_dir
;
245 ASSERT_TRUE(PathService::Get(cc::DIR_TEST_DATA
, &test_data_dir
));
246 FilePath json_file
= test_data_dir
.AppendASCII(name
+ ".json");
248 ASSERT_TRUE(file_util::ReadFileToString(json_file
, &json
));
249 tree_
.reset(base::JSONReader::Read(json
));
253 scoped_refptr
<Layer
> parseLayer(base::Value
* val
) {
254 DictionaryValue
* dict
;
256 success
&= val
->GetAsDictionary(&dict
);
257 std::string layer_type
;
258 success
&= dict
->GetString("LayerType", &layer_type
);
260 success
&= dict
->GetList("Bounds", &list
);
262 success
&= list
->GetInteger(0, &width
);
263 success
&= list
->GetInteger(1, &height
);
264 success
&= dict
->GetList("Position", &list
);
265 double position_x
, position_y
;
266 success
&= list
->GetDouble(0, &position_x
);
267 success
&= list
->GetDouble(1, &position_y
);
270 success
&= dict
->GetBoolean("DrawsContent", &draws_content
);
272 scoped_refptr
<Layer
> new_layer
;
273 if (layer_type
== "SolidColorLayer") {
274 new_layer
= CreateColorLayer(position_x
, position_y
, width
, height
, draws_content
);
275 } else if (layer_type
== "ContentLayer") {
276 new_layer
= CreateContentLayer(position_x
, position_y
, width
, height
, draws_content
);
277 } else if (layer_type
== "NinePatchLayer") {
278 success
&= dict
->GetList("ImageAperture", &list
);
279 int aperture_x
, aperture_y
, aperture_width
, aperture_height
;
280 success
&= list
->GetInteger(0, &aperture_x
);
281 success
&= list
->GetInteger(1, &aperture_y
);
282 success
&= list
->GetInteger(2, &aperture_width
);
283 success
&= list
->GetInteger(3, &aperture_height
);
285 new_layer
= CreateDecorationLayer(
286 position_x
, position_y
, width
, height
,
287 gfx::Rect(aperture_x
, aperture_y
, aperture_width
, aperture_height
),
290 } else { // Type "Layer" or "unknown"
291 new_layer
= CreateLayer(position_x
, position_y
, width
, height
);
295 if (dict
->GetDouble("Opacity", &opacity
))
296 new_layer
->setOpacity(opacity
);
298 success
&= dict
->GetList("DrawTransform", &list
);
299 double transform
[16];
300 for (int i
= 0; i
< 16; ++i
)
301 success
&= list
->GetDouble(i
, &transform
[i
]);
303 gfx::Transform gfxTransform
;
304 gfxTransform
.matrix().setColMajord(transform
);
305 new_layer
->setTransform(gfxTransform
);
307 success
&= dict
->GetList("Children", &list
);
308 for (ListValue::const_iterator it
= list
->begin();
309 it
!= list
->end(); ++it
) {
310 new_layer
->addChild(parseLayer(*it
));
314 ADD_FAILURE() << "Could not parse json data";
319 virtual void buildTree() OVERRIDE
{
320 gfx::Size viewport
= gfx::Size(720, 1038);
321 m_layerTreeHost
->setViewportSize(viewport
, viewport
);
322 m_layerTreeHost
->setRootLayer(parseLayer(tree_
.get()));
326 scoped_ptr
<base::Value
> tree_
;
329 TEST_F(LayerTreeHostPerfTestJsonReader
, tenTenSingleThread
) {
330 readTestFile("10_10_layer_tree");