Add ICU message format support
[chromium-blink-merge.git] / cc / trees / layer_tree_host_perftest.cc
blob845b1305e59a86be0bc4d7488fbb0736eddc44f5
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/trees/layer_tree_host.h"
7 #include <sstream>
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/path_service.h"
12 #include "base/strings/string_piece.h"
13 #include "base/time/time.h"
14 #include "cc/debug/lap_timer.h"
15 #include "cc/layers/nine_patch_layer.h"
16 #include "cc/layers/solid_color_layer.h"
17 #include "cc/layers/texture_layer.h"
18 #include "cc/resources/single_release_callback.h"
19 #include "cc/resources/texture_mailbox.h"
20 #include "cc/test/fake_content_layer_client.h"
21 #include "cc/test/layer_tree_json_parser.h"
22 #include "cc/test/layer_tree_test.h"
23 #include "cc/test/paths.h"
24 #include "cc/trees/layer_tree_impl.h"
25 #include "testing/perf/perf_test.h"
27 namespace cc {
28 namespace {
30 static const int kTimeLimitMillis = 2000;
31 static const int kWarmupRuns = 5;
32 static const int kTimeCheckInterval = 10;
34 class LayerTreeHostPerfTest : public LayerTreeTest {
35 public:
36 LayerTreeHostPerfTest()
37 : draw_timer_(kWarmupRuns,
38 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
39 kTimeCheckInterval),
40 commit_timer_(0, base::TimeDelta(), 1),
41 full_damage_each_frame_(false),
42 begin_frame_driven_drawing_(false),
43 measure_commit_cost_(false) {
46 void InitializeSettings(LayerTreeSettings* settings) override {
47 settings->wait_for_beginframe_interval = false;
48 settings->renderer_settings.disable_display_vsync = true;
51 void BeginTest() override {
52 BuildTree();
53 PostSetNeedsCommitToMainThread();
56 void BeginMainFrame(const BeginFrameArgs& args) override {
57 if (begin_frame_driven_drawing_ && !TestEnded()) {
58 layer_tree_host()->SetNeedsAnimate();
59 layer_tree_host()->SetNextCommitForcesRedraw();
63 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
64 if (measure_commit_cost_)
65 commit_timer_.Start();
68 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
69 if (measure_commit_cost_ && draw_timer_.IsWarmedUp()) {
70 commit_timer_.NextLap();
74 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
75 if (TestEnded() || CleanUpStarted())
76 return;
77 draw_timer_.NextLap();
78 if (draw_timer_.HasTimeLimitExpired()) {
79 CleanUpAndEndTest(impl);
80 return;
82 if (!begin_frame_driven_drawing_)
83 impl->SetNeedsRedraw();
84 if (full_damage_each_frame_)
85 impl->SetFullRootLayerDamage();
88 virtual void CleanUpAndEndTest(LayerTreeHostImpl* host_impl) { EndTest(); }
90 virtual bool CleanUpStarted() { return false; }
92 virtual void BuildTree() {}
94 void AfterTest() override {
95 CHECK(!test_name_.empty()) << "Must SetTestName() before AfterTest().";
96 perf_test::PrintResult("layer_tree_host_frame_time", "", test_name_,
97 1000 * draw_timer_.MsPerLap(), "us", true);
98 if (measure_commit_cost_) {
99 perf_test::PrintResult("layer_tree_host_commit_time", "", test_name_,
100 1000 * commit_timer_.MsPerLap(), "us", true);
104 protected:
105 LapTimer draw_timer_;
106 LapTimer commit_timer_;
108 std::string test_name_;
109 FakeContentLayerClient fake_content_layer_client_;
110 bool full_damage_each_frame_;
111 bool begin_frame_driven_drawing_;
113 bool measure_commit_cost_;
117 class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest {
118 public:
119 LayerTreeHostPerfTestJsonReader()
120 : LayerTreeHostPerfTest() {
123 void SetTestName(const std::string& name) {
124 test_name_ = name;
127 void ReadTestFile(const std::string& name) {
128 base::FilePath test_data_dir;
129 ASSERT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
130 base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
131 ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
134 void BuildTree() override {
135 gfx::Size viewport = gfx::Size(720, 1038);
136 layer_tree_host()->SetViewportSize(viewport);
137 scoped_refptr<Layer> root = ParseTreeFromJson(json_,
138 &fake_content_layer_client_);
139 ASSERT_TRUE(root.get());
140 layer_tree_host()->SetRootLayer(root);
143 private:
144 std::string json_;
147 // Simulates a tab switcher scene with two stacks of 10 tabs each.
148 TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread) {
149 SetTestName("10_10_single_thread");
150 ReadTestFile("10_10_layer_tree");
151 RunTest(false, false);
154 TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded) {
155 SetTestName("10_10_threaded_impl_side");
156 ReadTestFile("10_10_layer_tree");
157 RunTest(true, false);
160 // Simulates a tab switcher scene with two stacks of 10 tabs each.
161 TEST_F(LayerTreeHostPerfTestJsonReader,
162 TenTenSingleThread_FullDamageEachFrame) {
163 full_damage_each_frame_ = true;
164 SetTestName("10_10_single_thread_full_damage_each_frame");
165 ReadTestFile("10_10_layer_tree");
166 RunTest(false, false);
169 TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded_FullDamageEachFrame) {
170 full_damage_each_frame_ = true;
171 SetTestName("10_10_threaded_impl_side_full_damage_each_frame");
172 ReadTestFile("10_10_layer_tree");
173 RunTest(true, false);
176 // Invalidates a leaf layer in the tree on the main thread after every commit.
177 class LayerTreeHostPerfTestLeafInvalidates
178 : public LayerTreeHostPerfTestJsonReader {
179 public:
180 void BuildTree() override {
181 LayerTreeHostPerfTestJsonReader::BuildTree();
183 // Find a leaf layer.
184 for (layer_to_invalidate_ = layer_tree_host()->root_layer();
185 layer_to_invalidate_->children().size();
186 layer_to_invalidate_ = layer_to_invalidate_->children()[0].get()) {
190 void DidCommitAndDrawFrame() override {
191 if (TestEnded())
192 return;
194 layer_to_invalidate_->SetOpacity(
195 layer_to_invalidate_->opacity() != 1.f ? 1.f : 0.5f);
198 protected:
199 Layer* layer_to_invalidate_;
202 // Simulates a tab switcher scene with two stacks of 10 tabs each. Invalidate a
203 // property on a leaf layer in the tree every commit.
204 TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenSingleThread) {
205 SetTestName("10_10_single_thread_leaf_invalidates");
206 ReadTestFile("10_10_layer_tree");
207 RunTest(false, false);
210 TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenThreaded) {
211 SetTestName("10_10_threaded_impl_side_leaf_invalidates");
212 ReadTestFile("10_10_layer_tree");
213 RunTest(true, false);
216 // Simulates main-thread scrolling on each frame.
217 class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader {
218 public:
219 ScrollingLayerTreePerfTest()
220 : LayerTreeHostPerfTestJsonReader() {
223 void BuildTree() override {
224 LayerTreeHostPerfTestJsonReader::BuildTree();
225 scrollable_ = layer_tree_host()->root_layer()->children()[1];
226 ASSERT_TRUE(scrollable_.get());
229 void Layout() override {
230 if (TestEnded())
231 return;
232 static const gfx::Vector2d delta = gfx::Vector2d(0, 10);
233 scrollable_->SetScrollOffset(
234 gfx::ScrollOffsetWithDelta(scrollable_->scroll_offset(), delta));
237 private:
238 scoped_refptr<Layer> scrollable_;
241 TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageSingleThread) {
242 SetTestName("long_scrollable_page");
243 ReadTestFile("long_scrollable_page");
244 // TODO(vollick): Remove verify_property_trees setting after
245 // crbug.com/444219 is fixed.
246 bool old_verify_property_trees = verify_property_trees();
247 set_verify_property_trees(false);
248 RunTest(false, false);
249 set_verify_property_trees(old_verify_property_trees);
252 TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageThreaded) {
253 SetTestName("long_scrollable_page_threaded_impl_side");
254 ReadTestFile("long_scrollable_page");
255 // TODO(vollick): Remove verify_property_trees setting after
256 // crbug.com/444219 is fixed.
257 bool old_verify_property_trees = verify_property_trees();
258 set_verify_property_trees(false);
259 RunTest(true, false);
260 set_verify_property_trees(old_verify_property_trees);
263 static void EmptyReleaseCallback(uint32 sync_point, bool lost_resource) {}
265 // Simulates main-thread scrolling on each frame.
266 class BrowserCompositorInvalidateLayerTreePerfTest
267 : public LayerTreeHostPerfTestJsonReader {
268 public:
269 BrowserCompositorInvalidateLayerTreePerfTest()
270 : LayerTreeHostPerfTestJsonReader(),
271 next_sync_point_(1),
272 clean_up_started_(false) {}
274 void BuildTree() override {
275 LayerTreeHostPerfTestJsonReader::BuildTree();
276 tab_contents_ =
277 static_cast<TextureLayer*>(
278 layer_tree_host()->root_layer()->children()[0]->
279 children()[0]->
280 children()[0]->
281 children()[0].get());
282 ASSERT_TRUE(tab_contents_.get());
285 void WillCommit() override {
286 if (CleanUpStarted())
287 return;
288 gpu::Mailbox gpu_mailbox;
289 std::ostringstream name_stream;
290 name_stream << "name" << next_sync_point_;
291 gpu_mailbox.SetName(
292 reinterpret_cast<const int8*>(name_stream.str().c_str()));
293 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
294 base::Bind(&EmptyReleaseCallback));
295 TextureMailbox mailbox(gpu_mailbox, GL_TEXTURE_2D, next_sync_point_);
296 next_sync_point_++;
298 tab_contents_->SetTextureMailbox(mailbox, callback.Pass());
301 void DidCommit() override {
302 if (CleanUpStarted())
303 return;
304 layer_tree_host()->SetNeedsCommit();
307 void CleanUpAndEndTest(LayerTreeHostImpl* host_impl) override {
308 clean_up_started_ = true;
309 MainThreadTaskRunner()->PostTask(
310 FROM_HERE,
311 base::Bind(&BrowserCompositorInvalidateLayerTreePerfTest::
312 CleanUpAndEndTestOnMainThread,
313 base::Unretained(this)));
316 void CleanUpAndEndTestOnMainThread() {
317 tab_contents_->SetTextureMailbox(TextureMailbox(), nullptr);
318 EndTest();
321 bool CleanUpStarted() override { return clean_up_started_; }
323 private:
324 scoped_refptr<TextureLayer> tab_contents_;
325 unsigned next_sync_point_;
326 bool clean_up_started_;
329 TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) {
330 measure_commit_cost_ = true;
331 SetTestName("dense_layer_tree");
332 ReadTestFile("dense_layer_tree");
333 RunTest(true, false);
336 // Simulates a page with several large, transformed and animated layers.
337 TEST_F(LayerTreeHostPerfTestJsonReader, HeavyPageThreaded) {
338 begin_frame_driven_drawing_ = true;
339 measure_commit_cost_ = true;
340 SetTestName("heavy_page");
341 ReadTestFile("heavy_layer_tree");
342 RunTest(true, false);
345 } // namespace
346 } // namespace cc