blob: b18a88a7865e0f2e4ea6fc61ecc7e095ebcaa77e [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// Copyright 2011 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.
4
5#include "cc/trees/layer_tree_host.h"
6
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007#include <algorithm>
8
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01009#include "base/auto_reset.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include "base/synchronization/lock.h"
11#include "cc/animation/timing_function.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010012#include "cc/debug/frame_rate_counter.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000013#include "cc/layers/content_layer.h"
14#include "cc/layers/content_layer_client.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010015#include "cc/layers/io_surface_layer.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000016#include "cc/layers/layer_impl.h"
17#include "cc/layers/picture_layer.h"
18#include "cc/layers/scrollbar_layer.h"
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010019#include "cc/layers/solid_color_layer.h"
20#include "cc/layers/video_layer.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010021#include "cc/output/begin_frame_args.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010022#include "cc/output/copy_output_request.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010023#include "cc/output/copy_output_result.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000024#include "cc/output/output_surface.h"
25#include "cc/resources/prioritized_resource.h"
26#include "cc/resources/prioritized_resource_manager.h"
27#include "cc/resources/resource_update_queue.h"
28#include "cc/scheduler/frame_rate_controller.h"
29#include "cc/test/fake_content_layer.h"
30#include "cc/test/fake_content_layer_client.h"
31#include "cc/test/fake_layer_tree_host_client.h"
32#include "cc/test/fake_output_surface.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010033#include "cc/test/fake_picture_layer.h"
34#include "cc/test/fake_picture_layer_impl.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000035#include "cc/test/fake_proxy.h"
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010036#include "cc/test/fake_scoped_ui_resource.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000037#include "cc/test/fake_scrollbar_layer.h"
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010038#include "cc/test/fake_video_frame_provider.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000039#include "cc/test/geometry_test_utils.h"
40#include "cc/test/layer_tree_test.h"
41#include "cc/test/occlusion_tracker_test_common.h"
42#include "cc/trees/layer_tree_host_impl.h"
43#include "cc/trees/layer_tree_impl.h"
44#include "cc/trees/single_thread_proxy.h"
45#include "cc/trees/thread_proxy.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010046#include "gpu/GLES2/gl2extchromium.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000047#include "skia/ext/refptr.h"
48#include "testing/gmock/include/gmock/gmock.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000049#include "third_party/khronos/GLES2/gl2.h"
50#include "third_party/khronos/GLES2/gl2ext.h"
51#include "third_party/skia/include/core/SkPicture.h"
52#include "ui/gfx/point_conversions.h"
53#include "ui/gfx/size_conversions.h"
54#include "ui/gfx/vector2d_conversions.h"
55
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010056using testing::_;
57using testing::AnyNumber;
58using testing::AtLeast;
59using testing::Mock;
60
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000061namespace cc {
62namespace {
63
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010064class LayerTreeHostTest : public LayerTreeTest {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000065};
66
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000067// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
68// draw with frame 0.
69class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010070 public:
71 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000072
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010073 virtual void BeginTest() OVERRIDE {
74 PostSetNeedsCommitToMainThread();
75 PostSetNeedsCommitToMainThread();
76 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000077
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010078 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
79 num_draws_++;
80 if (!impl->active_tree()->source_frame_number())
81 EndTest();
82 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000083
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010084 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
85 num_commits_++;
86 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000087
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010088 virtual void AfterTest() OVERRIDE {
89 EXPECT_GE(1, num_commits_);
90 EXPECT_GE(1, num_draws_);
91 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000092
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010093 private:
94 int num_commits_;
95 int num_draws_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000096};
97
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010098SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000099
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100100// A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000101// first committed frame draws should lead to another commit.
102class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100103 public:
104 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000105
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100106 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000107
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100108 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
109 ++num_draws_;
110 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000111
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100112 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
113 ++num_commits_;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100114 switch (num_commits_) {
115 case 1:
116 PostSetNeedsCommitToMainThread();
117 break;
118 case 2:
119 EndTest();
120 break;
121 default:
122 NOTREACHED();
123 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100124 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000125
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100126 virtual void AfterTest() OVERRIDE {
127 EXPECT_EQ(2, num_commits_);
128 EXPECT_LE(1, num_draws_);
129 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000130
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100131 private:
132 int num_commits_;
133 int num_draws_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000134};
135
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100136MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000137
Ben Murdocheb525c52013-07-10 11:40:50 +0100138// Verify that we pass property values in PushPropertiesTo.
139class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
140 protected:
141 virtual void SetupTree() OVERRIDE {
142 scoped_refptr<Layer> root = Layer::Create();
143 root->SetBounds(gfx::Size(10, 10));
144 layer_tree_host()->SetRootLayer(root);
145 LayerTreeHostTest::SetupTree();
146 }
147
148 enum Properties {
149 STARTUP,
150 BOUNDS,
151 HIDE_LAYER_AND_SUBTREE,
152 DRAWS_CONTENT,
153 DONE,
154 };
155
156 virtual void BeginTest() OVERRIDE {
157 index_ = STARTUP;
158 PostSetNeedsCommitToMainThread();
159 }
160
161 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
162 VerifyAfterValues(impl->active_tree()->root_layer());
163 }
164
165 virtual void DidCommitAndDrawFrame() OVERRIDE {
166 SetBeforeValues(layer_tree_host()->root_layer());
167 VerifyBeforeValues(layer_tree_host()->root_layer());
168
169 ++index_;
170 if (index_ == DONE) {
171 EndTest();
172 return;
173 }
174
175 SetAfterValues(layer_tree_host()->root_layer());
176 }
177
178 virtual void AfterTest() OVERRIDE {}
179
180 void VerifyBeforeValues(Layer* layer) {
181 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
182 EXPECT_FALSE(layer->hide_layer_and_subtree());
183 EXPECT_FALSE(layer->DrawsContent());
184 }
185
186 void SetBeforeValues(Layer* layer) {
187 layer->SetBounds(gfx::Size(10, 10));
188 layer->SetHideLayerAndSubtree(false);
189 layer->SetIsDrawable(false);
190 }
191
192 void VerifyAfterValues(LayerImpl* layer) {
193 switch (static_cast<Properties>(index_)) {
194 case STARTUP:
195 case DONE:
196 break;
197 case BOUNDS:
198 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
199 break;
200 case HIDE_LAYER_AND_SUBTREE:
201 EXPECT_TRUE(layer->hide_layer_and_subtree());
202 break;
203 case DRAWS_CONTENT:
204 EXPECT_TRUE(layer->DrawsContent());
205 break;
206 }
207 }
208
209 void SetAfterValues(Layer* layer) {
210 switch (static_cast<Properties>(index_)) {
211 case STARTUP:
212 case DONE:
213 break;
214 case BOUNDS:
215 layer->SetBounds(gfx::Size(20, 20));
216 break;
217 case HIDE_LAYER_AND_SUBTREE:
218 layer->SetHideLayerAndSubtree(true);
219 break;
220 case DRAWS_CONTENT:
221 layer->SetIsDrawable(true);
222 break;
223 }
224 }
225
226 int index_;
227};
228
229SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
230
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000231// 1 setNeedsRedraw after the first commit has completed should lead to 1
232// additional draw.
233class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100234 public:
235 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000236
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100237 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000238
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100239 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
240 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
241 if (!num_draws_) {
242 // Redraw again to verify that the second redraw doesn't commit.
243 PostSetNeedsRedrawToMainThread();
244 } else {
245 EndTest();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000246 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100247 num_draws_++;
248 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000249
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100250 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
251 EXPECT_EQ(0, num_draws_);
252 num_commits_++;
253 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000254
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100255 virtual void AfterTest() OVERRIDE {
256 EXPECT_GE(2, num_draws_);
257 EXPECT_EQ(1, num_commits_);
258 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000259
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100260 private:
261 int num_commits_;
262 int num_draws_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000263};
264
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100265MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
266
267// After setNeedsRedrawRect(invalid_rect) the final damage_rect
268// must contain invalid_rect.
269class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
270 public:
271 LayerTreeHostTestSetNeedsRedrawRect()
272 : num_draws_(0),
273 bounds_(50, 50),
274 invalid_rect_(10, 10, 20, 20),
275 root_layer_(ContentLayer::Create(&client_)) {
276 }
277
278 virtual void BeginTest() OVERRIDE {
279 root_layer_->SetIsDrawable(true);
280 root_layer_->SetBounds(bounds_);
281 layer_tree_host()->SetRootLayer(root_layer_);
282 layer_tree_host()->SetViewportSize(bounds_);
283 PostSetNeedsCommitToMainThread();
284 }
285
286 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
287 LayerTreeHostImpl::FrameData* frame_data,
288 bool result) OVERRIDE {
289 EXPECT_TRUE(result);
290
291 gfx::RectF root_damage_rect;
292 if (!frame_data->render_passes.empty())
293 root_damage_rect = frame_data->render_passes.back()->damage_rect;
294
295 if (!num_draws_) {
296 // If this is the first frame, expect full frame damage.
297 EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
298 } else {
299 // Check that invalid_rect_ is indeed repainted.
300 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
301 }
302
303 return result;
304 }
305
306 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
307 if (!num_draws_) {
308 PostSetNeedsRedrawRectToMainThread(invalid_rect_);
309 } else {
310 EndTest();
311 }
312 num_draws_++;
313 }
314
315 virtual void AfterTest() OVERRIDE {
316 EXPECT_EQ(2, num_draws_);
317 }
318
319 private:
320 int num_draws_;
321 const gfx::Size bounds_;
322 const gfx::Rect invalid_rect_;
323 FakeContentLayerClient client_;
324 scoped_refptr<ContentLayer> root_layer_;
325};
326
327SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000328
329class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100330 public:
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100331 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
332 settings->layer_transforms_should_scale_layer_contents = true;
333 }
334
335 virtual void SetupTree() OVERRIDE {
336 root_layer_ = Layer::Create();
337 root_layer_->SetBounds(gfx::Size(10, 20));
338
339 scaled_layer_ = FakeContentLayer::Create(&client_);
340 scaled_layer_->SetBounds(gfx::Size(1, 1));
341 root_layer_->AddChild(scaled_layer_);
342
343 layer_tree_host()->SetRootLayer(root_layer_);
344 LayerTreeHostTest::SetupTree();
345 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000346
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100347 virtual void BeginTest() OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100348 PostSetNeedsCommitToMainThread();
349 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000350
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100351 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
352 if (host_impl->active_tree()->source_frame_number() == 1)
353 EndTest();
354 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000355
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100356 virtual void DidCommit() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +0100357 switch (layer_tree_host()->source_frame_number()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100358 case 1:
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100359 // Changing the device scale factor causes a commit. It also changes
360 // the content bounds of |scaled_layer_|, which should not generate
361 // a second commit as a result.
362 layer_tree_host()->SetDeviceScaleFactor(4.f);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100363 break;
364 default:
365 // No extra commits.
Ben Murdochbbcdd452013-07-25 10:06:34 +0100366 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000367 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100368 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000369
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100370 virtual void AfterTest() OVERRIDE {
371 EXPECT_EQ(gfx::Size(4, 4).ToString(),
372 scaled_layer_->content_bounds().ToString());
373 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100374
375 private:
376 FakeContentLayerClient client_;
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100377 scoped_refptr<Layer> root_layer_;
378 scoped_refptr<FakeContentLayer> scaled_layer_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000379};
380
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100381SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
382
383class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
384 : public LayerTreeHostTest {
385 public:
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100386 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
387 settings->layer_transforms_should_scale_layer_contents = true;
388 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100389
390 virtual void SetupTree() OVERRIDE {
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100391 root_layer_ = Layer::Create();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100392 root_layer_->SetBounds(gfx::Size(10, 20));
393
394 bool paint_scrollbar = true;
395 bool has_thumb = false;
396 scrollbar_ = FakeScrollbarLayer::Create(paint_scrollbar,
397 has_thumb,
398 root_layer_->id());
399 scrollbar_->SetPosition(gfx::Point(0, 10));
400 scrollbar_->SetBounds(gfx::Size(10, 10));
401
402 root_layer_->AddChild(scrollbar_);
403
404 layer_tree_host()->SetRootLayer(root_layer_);
405 LayerTreeHostTest::SetupTree();
406 }
407
408 virtual void BeginTest() OVERRIDE {
409 PostSetNeedsCommitToMainThread();
410 }
411
412 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
413 if (host_impl->active_tree()->source_frame_number() == 1)
414 EndTest();
415 }
416
417 virtual void DidCommit() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +0100418 switch (layer_tree_host()->source_frame_number()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100419 case 1:
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100420 // Changing the device scale factor causes a commit. It also changes
421 // the content bounds of |scrollbar_|, which should not generate
422 // a second commit as a result.
423 layer_tree_host()->SetDeviceScaleFactor(4.f);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100424 break;
425 default:
426 // No extra commits.
Ben Murdochbbcdd452013-07-25 10:06:34 +0100427 EXPECT_EQ(2, layer_tree_host()->source_frame_number());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100428 }
429 }
430
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100431 virtual void AfterTest() OVERRIDE {
432 EXPECT_EQ(gfx::Size(40, 40).ToString(),
433 scrollbar_->content_bounds().ToString());
434 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100435
436 private:
437 FakeContentLayerClient client_;
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100438 scoped_refptr<Layer> root_layer_;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100439 scoped_refptr<FakeScrollbarLayer> scrollbar_;
440};
441
442SINGLE_AND_MULTI_THREAD_TEST_F(
443 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000444
445class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100446 public:
447 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000448
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100449 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000450
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100451 virtual void DidCommit() OVERRIDE {
452 num_commits_++;
453 if (num_commits_ == 1) {
454 char pixels[4];
455 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
456 } else if (num_commits_ == 2) {
457 // This is inside the readback. We should get another commit after it.
458 } else if (num_commits_ == 3) {
459 EndTest();
460 } else {
461 NOTREACHED();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000462 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100463 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000464
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100465 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000466
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100467 private:
468 int num_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000469};
470
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100471MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000472
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100473class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
474 : public LayerTreeHostTest {
475 public:
476 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
477 : num_commits_(0) {}
478
479 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
480
481 virtual void DidCommit() OVERRIDE {
482 num_commits_++;
483 if (num_commits_ == 1) {
484 layer_tree_host()->SetNeedsCommit();
485 } else if (num_commits_ == 2) {
486 char pixels[4];
487 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
488 } else if (num_commits_ == 3) {
489 // This is inside the readback. We should get another commit after it.
490 } else if (num_commits_ == 4) {
491 EndTest();
492 } else {
493 NOTREACHED();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000494 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100495 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000496
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100497 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000498
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100499 private:
500 int num_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000501};
502
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100503MULTI_THREAD_TEST_F(
504 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000505
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100506// If the layerTreeHost says it can't draw, Then we should not try to draw.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000507class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100508 public:
509 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000510
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100511 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000512
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100513 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
514 if (done_)
515 return;
516 // Only the initial draw should bring us here.
517 EXPECT_TRUE(impl->CanDraw());
518 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
519 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000520
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100521 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
522 if (done_)
523 return;
524 if (num_commits_ >= 1) {
525 // After the first commit, we should not be able to draw.
526 EXPECT_FALSE(impl->CanDraw());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000527 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100528 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000529
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100530 virtual void DidCommit() OVERRIDE {
531 num_commits_++;
532 if (num_commits_ == 1) {
533 // Make the viewport empty so the host says it can't draw.
534 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
535 } else if (num_commits_ == 2) {
536 char pixels[4];
537 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
538 } else if (num_commits_ == 3) {
539 // Let it draw so we go idle and end the test.
540 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
541 done_ = true;
542 EndTest();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000543 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100544 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000545
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100546 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000547
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100548 private:
549 int num_commits_;
550 bool done_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000551};
552
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100553SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000554
555// beginLayerWrite should prevent draws from executing until a commit occurs
556class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100557 public:
558 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000559
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100560 virtual void BeginTest() OVERRIDE {
561 PostAcquireLayerTextures();
562 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
563 PostSetNeedsCommitToMainThread();
564 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000565
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100566 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
567 num_draws_++;
568 EXPECT_EQ(num_draws_, num_commits_);
569 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000570
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100571 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
572 num_commits_++;
573 EndTest();
574 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000575
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100576 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000577
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100578 private:
579 int num_commits_;
580 int num_draws_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000581};
582
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100583MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000584
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100585// Verify that when resuming visibility, Requesting layer write permission
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000586// will not deadlock the main thread even though there are not yet any
587// scheduled redraws. This behavior is critical for reliably surviving tab
588// switching. There are no failure conditions to this test, it just passes
589// by not timing out.
590class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100591 public:
592 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000593
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100594 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000595
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100596 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
597 num_commits_++;
598 if (num_commits_ == 2)
599 EndTest();
600 else if (num_commits_ < 2) {
601 PostSetVisibleToMainThread(false);
602 PostSetVisibleToMainThread(true);
603 PostAcquireLayerTextures();
604 PostSetNeedsCommitToMainThread();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000605 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100606 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000607
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100608 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000609
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100610 private:
611 int num_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000612};
613
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100614MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000615
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100616// A compositeAndReadback while invisible should force a normal commit without
617// assertion.
618class LayerTreeHostTestCompositeAndReadbackWhileInvisible
619 : public LayerTreeHostTest {
620 public:
621 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
622
623 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
624
625 virtual void DidCommitAndDrawFrame() OVERRIDE {
626 num_commits_++;
627 if (num_commits_ == 1) {
628 layer_tree_host()->SetVisible(false);
629 layer_tree_host()->SetNeedsCommit();
630 layer_tree_host()->SetNeedsCommit();
631 char pixels[4];
632 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
633 } else {
634 EndTest();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000635 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100636 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000637
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100638 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000639
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100640 private:
641 int num_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000642};
643
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100644MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000645
646class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100647 public:
648 LayerTreeHostTestAbortFrameWhenInvisible() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000649
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100650 virtual void BeginTest() OVERRIDE {
651 // Request a commit (from the main thread), Which will trigger the commit
652 // flow from the impl side.
653 layer_tree_host()->SetNeedsCommit();
654 // Then mark ourselves as not visible before processing any more messages
655 // on the main thread.
656 layer_tree_host()->SetVisible(false);
657 // If we make it without kicking a frame, we pass!
658 EndTestAfterDelay(1);
659 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000660
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100661 virtual void Layout() OVERRIDE {
662 ASSERT_FALSE(true);
663 EndTest();
664 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000665
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100666 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000667
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100668 private:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000669};
670
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100671MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000672
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100673// This test verifies that properties on the layer tree host are commited
674// to the impl side.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000675class LayerTreeHostTestCommit : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100676 public:
677 LayerTreeHostTestCommit() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000678
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100679 virtual void BeginTest() OVERRIDE {
680 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
681 layer_tree_host()->set_background_color(SK_ColorGRAY);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000682
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100683 PostSetNeedsCommitToMainThread();
684 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000685
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100686 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100687 EXPECT_EQ(gfx::Size(20, 20), impl->device_viewport_size());
688 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000689
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100690 EndTest();
691 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000692
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100693 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000694};
695
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100696MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000697
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100698// This test verifies that LayerTreeHostImpl's current frame time gets
699// updated in consecutive frames when it doesn't draw due to tree
700// activation failure.
701class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
702 : public LayerTreeHostTest {
703 public:
704 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() : frame_(0) {}
705
706 virtual void BeginTest() OVERRIDE {
707 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
708 layer_tree_host()->set_background_color(SK_ColorGRAY);
709
710 PostSetNeedsCommitToMainThread();
711 }
712
713 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
714 if (frame_ >= 1) {
715 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
716 EndTest();
717 return;
718 }
719
720 EXPECT_FALSE(impl->settings().impl_side_painting);
721 EndTest();
722 }
723
724 virtual bool CanActivatePendingTree(LayerTreeHostImpl* impl) OVERRIDE {
Ben Murdocheb525c52013-07-10 11:40:50 +0100725 if (frame_ >= 1)
726 return true;
727
728 return false;
729 }
730
731 virtual bool CanActivatePendingTreeIfNeeded(LayerTreeHostImpl* impl)
732 OVERRIDE {
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100733 frame_++;
734 if (frame_ == 1) {
735 first_frame_time_ = impl->CurrentFrameTimeTicks();
736
737 // Since base::TimeTicks::Now() uses a low-resolution clock on
738 // Windows, we need to make sure that the clock has incremented past
739 // first_frame_time_.
740 while (first_frame_time_ == base::TimeTicks::Now()) {}
741
742 return false;
743 }
744
745 return true;
746 }
747
748 virtual void AfterTest() OVERRIDE {}
749
750 private:
751 int frame_;
752 base::TimeTicks first_frame_time_;
753};
754
755SINGLE_AND_MULTI_THREAD_TEST_F(
756 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
757
758// This test verifies that LayerTreeHostImpl's current frame time gets
759// updated in consecutive frames when it draws in each frame.
760class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
761 public:
762 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
763
764 virtual void BeginTest() OVERRIDE {
765 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
766 layer_tree_host()->set_background_color(SK_ColorGRAY);
767
768 PostSetNeedsCommitToMainThread();
769 }
770
771 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
772 frame_++;
773 if (frame_ == 1) {
774 first_frame_time_ = impl->CurrentFrameTimeTicks();
775 impl->SetNeedsRedraw();
776
777 // Since base::TimeTicks::Now() uses a low-resolution clock on
778 // Windows, we need to make sure that the clock has incremented past
779 // first_frame_time_.
780 while (first_frame_time_ == base::TimeTicks::Now()) {}
781
782 return;
783 }
784
785 EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
786 EndTest();
787 }
788
789 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
790 // Ensure there isn't a commit between the two draws, to ensure that a
791 // commit isn't required for updating the current frame time. We can
792 // only check for this in the multi-threaded case, since in the single-
793 // threaded case there will always be a commit between consecutive draws.
Ben Murdocheb525c52013-07-10 11:40:50 +0100794 if (HasImplThread())
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100795 EXPECT_EQ(0, frame_);
796 }
797
798 virtual void AfterTest() OVERRIDE {}
799
800 private:
801 int frame_;
802 base::TimeTicks first_frame_time_;
803};
804
805SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
806
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100807// Verifies that StartPageScaleAnimation events propagate correctly
808// from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000809class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100810 public:
811 LayerTreeHostTestStartPageScaleAnimation() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000812
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100813 virtual void SetupTree() OVERRIDE {
814 LayerTreeHostTest::SetupTree();
815
816 scroll_layer_ = FakeContentLayer::Create(&client_);
817 scroll_layer_->SetScrollable(true);
818 scroll_layer_->SetScrollOffset(gfx::Vector2d());
819 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
820 }
821
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100822 virtual void BeginTest() OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100823 PostSetNeedsCommitToMainThread();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100824 }
825
826 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
827 OVERRIDE {
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100828 gfx::Vector2d offset = scroll_layer_->scroll_offset();
829 scroll_layer_->SetScrollOffset(offset + scroll_delta);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100830 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
831 }
832
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100833 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100834 impl->ProcessScrollDeltas();
835 // We get one commit before the first draw, and the animation doesn't happen
836 // until the second draw.
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100837 switch (impl->active_tree()->source_frame_number()) {
838 case 0:
839 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
840 // We'll start an animation when we get back to the main thread.
841 break;
842 case 1:
843 EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
844 PostSetNeedsRedrawToMainThread();
845 break;
846 case 2:
847 EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
848 EndTest();
849 break;
850 default:
851 NOTREACHED();
852 }
853 }
854
855 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +0100856 switch (layer_tree_host()->source_frame_number()) {
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100857 case 1:
858 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
859 layer_tree_host()->StartPageScaleAnimation(
860 gfx::Vector2d(), false, 1.25f, base::TimeDelta());
861 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000862 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100863 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000864
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100865 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100866
867 FakeContentLayerClient client_;
868 scoped_refptr<FakeContentLayer> scroll_layer_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000869};
870
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100871MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000872
873class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100874 public:
875 LayerTreeHostTestSetVisible() : num_draws_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000876
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100877 virtual void BeginTest() OVERRIDE {
878 PostSetNeedsCommitToMainThread();
879 PostSetVisibleToMainThread(false);
880 // This is suppressed while we're invisible.
881 PostSetNeedsRedrawToMainThread();
882 // Triggers the redraw.
883 PostSetVisibleToMainThread(true);
884 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000885
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100886 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
887 EXPECT_TRUE(impl->visible());
888 ++num_draws_;
889 EndTest();
890 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000891
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100892 virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000893
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100894 private:
895 int num_draws_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000896};
897
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100898MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000899
900class TestOpacityChangeLayerDelegate : public ContentLayerClient {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100901 public:
902 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000903
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100904 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000905
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100906 virtual void PaintContents(SkCanvas*, gfx::Rect, gfx::RectF*) OVERRIDE {
907 // Set layer opacity to 0.
908 if (test_layer_)
909 test_layer_->SetOpacity(0.f);
910 }
911 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000912
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100913 private:
914 Layer* test_layer_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000915};
916
917class ContentLayerWithUpdateTracking : public ContentLayer {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100918 public:
919 static scoped_refptr<ContentLayerWithUpdateTracking> Create(
920 ContentLayerClient* client) {
921 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
922 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000923
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100924 int PaintContentsCount() { return paint_contents_count_; }
925 void ResetPaintContentsCount() { paint_contents_count_ = 0; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000926
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100927 virtual bool Update(ResourceUpdateQueue* queue,
Ben Murdocheb525c52013-07-10 11:40:50 +0100928 const OcclusionTracker* occlusion) OVERRIDE {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100929 bool updated = ContentLayer::Update(queue, occlusion);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100930 paint_contents_count_++;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100931 return updated;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100932 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000933
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100934 private:
935 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
936 : ContentLayer(client), paint_contents_count_(0) {
937 SetAnchorPoint(gfx::PointF(0.f, 0.f));
938 SetBounds(gfx::Size(10, 10));
939 SetIsDrawable(true);
940 }
941 virtual ~ContentLayerWithUpdateTracking() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000942
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100943 int paint_contents_count_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000944};
945
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100946// Layer opacity change during paint should not prevent compositor resources
947// from being updated during commit.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000948class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100949 public:
950 LayerTreeHostTestOpacityChange()
951 : test_opacity_change_delegate_(),
952 update_check_layer_(ContentLayerWithUpdateTracking::Create(
953 &test_opacity_change_delegate_)) {
954 test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
955 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000956
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100957 virtual void BeginTest() OVERRIDE {
958 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
959 layer_tree_host()->root_layer()->AddChild(update_check_layer_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000960
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100961 PostSetNeedsCommitToMainThread();
962 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000963
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100964 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
965 EndTest();
966 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000967
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100968 virtual void AfterTest() OVERRIDE {
969 // Update() should have been called once.
970 EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
971 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000972
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100973 private:
974 TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
975 scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000976};
977
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100978MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000979
980class NoScaleContentLayer : public ContentLayer {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100981 public:
982 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
983 return make_scoped_refptr(new NoScaleContentLayer(client));
984 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000985
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100986 virtual void CalculateContentsScale(float ideal_contents_scale,
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100987 float device_scale_factor,
988 float page_scale_factor,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100989 bool animating_transform_to_screen,
990 float* contents_scale_x,
991 float* contents_scale_y,
992 gfx::Size* contentBounds) OVERRIDE {
993 // Skip over the ContentLayer's method to the base Layer class.
994 Layer::CalculateContentsScale(ideal_contents_scale,
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100995 device_scale_factor,
996 page_scale_factor,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100997 animating_transform_to_screen,
998 contents_scale_x,
999 contents_scale_y,
1000 contentBounds);
1001 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001002
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001003 private:
1004 explicit NoScaleContentLayer(ContentLayerClient* client)
1005 : ContentLayer(client) {}
1006 virtual ~NoScaleContentLayer() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001007};
1008
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001009class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1010 : public LayerTreeHostTest {
1011 public:
1012 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1013 : root_layer_(NoScaleContentLayer::Create(&client_)),
1014 child_layer_(ContentLayer::Create(&client_)) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001015
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001016 virtual void BeginTest() OVERRIDE {
1017 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1018 layer_tree_host()->SetDeviceScaleFactor(1.5);
1019 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001020
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001021 root_layer_->AddChild(child_layer_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001022
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001023 root_layer_->SetIsDrawable(true);
1024 root_layer_->SetBounds(gfx::Size(30, 30));
1025 root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001026
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001027 child_layer_->SetIsDrawable(true);
1028 child_layer_->SetPosition(gfx::Point(2, 2));
1029 child_layer_->SetBounds(gfx::Size(10, 10));
1030 child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001031
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001032 layer_tree_host()->SetRootLayer(root_layer_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001033
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001034 PostSetNeedsCommitToMainThread();
1035 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001036
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01001037 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001038 // Should only do one commit.
1039 EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1040 // Device scale factor should come over to impl.
1041 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001042
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001043 // Both layers are on impl.
1044 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001045
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001046 // Device viewport is scaled.
1047 EXPECT_EQ(gfx::Size(60, 60), impl->device_viewport_size());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001048
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001049 LayerImpl* root = impl->active_tree()->root_layer();
1050 LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001051
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001052 // Positions remain in layout pixels.
1053 EXPECT_EQ(gfx::Point(0, 0), root->position());
1054 EXPECT_EQ(gfx::Point(2, 2), child->position());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001055
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001056 // Compute all the layer transforms for the frame.
1057 LayerTreeHostImpl::FrameData frame_data;
1058 impl->PrepareToDraw(&frame_data, gfx::Rect());
1059 impl->DidDrawAllLayers(frame_data);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001060
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001061 const LayerImplList& render_surface_layer_list =
1062 *frame_data.render_surface_layer_list;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001063
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001064 // Both layers should be drawing into the root render surface.
1065 ASSERT_EQ(1u, render_surface_layer_list.size());
1066 ASSERT_EQ(root->render_surface(),
1067 render_surface_layer_list[0]->render_surface());
1068 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001069
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001070 // The root render surface is the size of the viewport.
1071 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1072 root->render_surface()->content_rect());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001073
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001074 // The content bounds of the child should be scaled.
1075 gfx::Size child_bounds_scaled =
1076 gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1077 EXPECT_EQ(child_bounds_scaled, child->content_bounds());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001078
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001079 gfx::Transform scale_transform;
1080 scale_transform.Scale(impl->device_scale_factor(),
1081 impl->device_scale_factor());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001082
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001083 // The root layer is scaled by 2x.
1084 gfx::Transform root_screen_space_transform = scale_transform;
1085 gfx::Transform root_draw_transform = scale_transform;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001086
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001087 EXPECT_EQ(root_draw_transform, root->draw_transform());
1088 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001089
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001090 // The child is at position 2,2, which is transformed to 3,3 after the scale
1091 gfx::Transform child_screen_space_transform;
1092 child_screen_space_transform.Translate(3.f, 3.f);
1093 gfx::Transform child_draw_transform = child_screen_space_transform;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001094
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001095 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1096 child->draw_transform());
1097 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1098 child->screen_space_transform());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001099
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001100 EndTest();
1101 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001102
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001103 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001104
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001105 private:
1106 FakeContentLayerClient client_;
1107 scoped_refptr<NoScaleContentLayer> root_layer_;
1108 scoped_refptr<ContentLayer> child_layer_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001109};
1110
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001111MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001112
1113// Verify atomicity of commits and reuse of textures.
1114class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001115 public:
1116 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1117 // Make sure partial texture updates are turned off.
1118 settings->max_partial_texture_updates = 0;
1119 // Linear fade animator prevents scrollbars from drawing immediately.
1120 settings->use_linear_fade_scrollbar_animator = false;
1121 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001122
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001123 virtual void SetupTree() OVERRIDE {
1124 layer_ = FakeContentLayer::Create(&client_);
1125 layer_->SetBounds(gfx::Size(10, 20));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001126
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001127 bool paint_scrollbar = true;
1128 bool has_thumb = false;
1129 scrollbar_ =
1130 FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, layer_->id());
1131 scrollbar_->SetPosition(gfx::Point(0, 10));
1132 scrollbar_->SetBounds(gfx::Size(10, 10));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001133
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001134 layer_->AddChild(scrollbar_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001135
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001136 layer_tree_host()->SetRootLayer(layer_);
1137 LayerTreeHostTest::SetupTree();
1138 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001139
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001140 virtual void BeginTest() OVERRIDE {
1141 drew_frame_ = -1;
1142 PostSetNeedsCommitToMainThread();
1143 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001144
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01001145 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001146 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001147
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001148 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1149 impl->output_surface()->context3d());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001150
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001151 switch (impl->active_tree()->source_frame_number()) {
1152 case 0:
1153 // Number of textures should be one for each layer
1154 ASSERT_EQ(2u, context->NumTextures());
1155 // Number of textures used for commit should be one for each layer.
1156 EXPECT_EQ(2u, context->NumUsedTextures());
1157 // Verify that used texture is correct.
1158 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1159 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001160
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001161 context->ResetUsedTextures();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001162 PostSetNeedsCommitToMainThread();
1163 break;
1164 case 1:
1165 // Number of textures should be doubled as the first textures
1166 // are used by impl thread and cannot by used for update.
1167 ASSERT_EQ(4u, context->NumTextures());
1168 // Number of textures used for commit should still be
1169 // one for each layer.
1170 EXPECT_EQ(2u, context->NumUsedTextures());
1171 // First textures should not have been used.
1172 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1173 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1174 // New textures should have been used.
1175 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1176 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001177
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001178 context->ResetUsedTextures();
1179 PostSetNeedsCommitToMainThread();
1180 break;
1181 case 2:
1182 EndTest();
1183 break;
1184 default:
1185 NOTREACHED();
1186 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001187 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001188 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001189
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001190 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1191 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1192 impl->output_surface()->context3d());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001193
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001194 if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1195 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1196 return;
1197 }
1198 drew_frame_ = impl->active_tree()->source_frame_number();
1199
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01001200 // We draw/ship one texture each frame for each layer.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001201 EXPECT_EQ(2u, context->NumUsedTextures());
1202 context->ResetUsedTextures();
1203 }
1204
1205 virtual void Layout() OVERRIDE {
1206 layer_->SetNeedsDisplay();
1207 scrollbar_->SetNeedsDisplay();
1208 }
1209
1210 virtual void AfterTest() OVERRIDE {}
1211
1212 private:
1213 FakeContentLayerClient client_;
1214 scoped_refptr<FakeContentLayer> layer_;
1215 scoped_refptr<FakeScrollbarLayer> scrollbar_;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001216 int drew_frame_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001217};
1218
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001219MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001220
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001221static void SetLayerPropertiesForTesting(Layer* layer,
1222 Layer* parent,
1223 const gfx::Transform& transform,
1224 gfx::PointF anchor,
1225 gfx::PointF position,
1226 gfx::Size bounds,
1227 bool opaque) {
1228 layer->RemoveAllChildren();
1229 if (parent)
1230 parent->AddChild(layer);
1231 layer->SetTransform(transform);
1232 layer->SetAnchorPoint(anchor);
1233 layer->SetPosition(position);
1234 layer->SetBounds(bounds);
1235 layer->SetContentsOpaque(opaque);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001236}
1237
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001238class LayerTreeHostTestAtomicCommitWithPartialUpdate
1239 : public LayerTreeHostTest {
1240 public:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001241 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1242 // Allow one partial texture update.
1243 settings->max_partial_texture_updates = 1;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01001244 // No partial updates when impl side painting is enabled.
1245 settings->impl_side_painting = false;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001246 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001247
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001248 virtual void SetupTree() OVERRIDE {
1249 parent_ = FakeContentLayer::Create(&client_);
1250 parent_->SetBounds(gfx::Size(10, 20));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001251
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001252 child_ = FakeContentLayer::Create(&client_);
1253 child_->SetPosition(gfx::Point(0, 10));
1254 child_->SetBounds(gfx::Size(3, 10));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001255
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001256 parent_->AddChild(child_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001257
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001258 layer_tree_host()->SetRootLayer(parent_);
1259 LayerTreeHostTest::SetupTree();
1260 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001261
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001262 virtual void BeginTest() OVERRIDE {
1263 PostSetNeedsCommitToMainThread();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001264 }
1265
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001266 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01001267 switch (layer_tree_host()->source_frame_number()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001268 case 1:
1269 parent_->SetNeedsDisplay();
1270 child_->SetNeedsDisplay();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001271 break;
1272 case 2:
1273 // Damage part of layers.
1274 parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1275 child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001276 break;
1277 case 3:
1278 child_->SetNeedsDisplay();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001279 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1280 break;
1281 case 4:
1282 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1283 break;
1284 case 5:
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001285 EndTest();
1286 break;
1287 default:
Ben Murdochbbcdd452013-07-25 10:06:34 +01001288 NOTREACHED() << layer_tree_host()->source_frame_number();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001289 break;
1290 }
1291 }
1292
1293 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1294 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1295
1296 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1297 impl->output_surface()->context3d());
1298
1299 switch (impl->active_tree()->source_frame_number()) {
1300 case 0:
1301 // Number of textures should be one for each layer.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001302 ASSERT_EQ(2u, context->NumTextures());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001303 // Number of textures used for commit should be one for each layer.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001304 EXPECT_EQ(2u, context->NumUsedTextures());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001305 // Verify that used textures are correct.
1306 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1307 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001308 context->ResetUsedTextures();
1309 break;
1310 case 1:
1311 // Number of textures should be two for each content layer.
1312 ASSERT_EQ(4u, context->NumTextures());
1313 // Number of textures used for commit should be one for each content
1314 // layer.
1315 EXPECT_EQ(2u, context->NumUsedTextures());
1316
1317 // First content textures should not have been used.
1318 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1319 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1320 // New textures should have been used.
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001321 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1322 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1323
1324 context->ResetUsedTextures();
1325 break;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001326 case 2:
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001327 // Number of textures should be two for each content layer.
1328 ASSERT_EQ(4u, context->NumTextures());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001329 // Number of textures used for commit should be one for each content
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001330 // layer.
1331 EXPECT_EQ(2u, context->NumUsedTextures());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001332
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001333 // One content layer does a partial update also.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001334 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1335 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001336
1337 context->ResetUsedTextures();
1338 break;
1339 case 3:
1340 // No textures should be used for commit.
1341 EXPECT_EQ(0u, context->NumUsedTextures());
1342
1343 context->ResetUsedTextures();
1344 break;
1345 case 4:
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001346 // Number of textures used for commit should be one, for the
1347 // content layer.
1348 EXPECT_EQ(1u, context->NumUsedTextures());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001349
1350 context->ResetUsedTextures();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001351 break;
1352 default:
1353 NOTREACHED();
1354 break;
1355 }
1356 }
1357
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001358 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1359 EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1360
1361 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1362 impl->output_surface()->context3d());
1363
1364 // Number of textures used for drawing should one per layer except for
1365 // frame 3 where the viewport only contains one layer.
1366 if (impl->active_tree()->source_frame_number() == 3) {
1367 EXPECT_EQ(1u, context->NumUsedTextures());
1368 } else {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001369 EXPECT_EQ(2u, context->NumUsedTextures()) <<
1370 "For frame " << impl->active_tree()->source_frame_number();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001371 }
1372
1373 context->ResetUsedTextures();
1374 }
1375
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001376 virtual void AfterTest() OVERRIDE {}
1377
1378 private:
1379 FakeContentLayerClient client_;
1380 scoped_refptr<FakeContentLayer> parent_;
1381 scoped_refptr<FakeContentLayer> child_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001382};
1383
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01001384// Partial updates are not possible with a delegating renderer.
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001385SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01001386 LayerTreeHostTestAtomicCommitWithPartialUpdate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001387
1388class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001389 public:
1390 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001391
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001392 virtual void BeginTest() OVERRIDE {
1393 layer_tree_host()->SetNeedsRedraw();
1394 PostSetNeedsCommitToMainThread();
1395 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001396
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001397 virtual void DidCommitAndDrawFrame() OVERRIDE {
1398 if (once_)
1399 return;
1400 once_ = true;
1401 layer_tree_host()->SetNeedsRedraw();
1402 layer_tree_host()->AcquireLayerTextures();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001403 {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001404 base::AutoLock lock(lock_);
1405 draw_count_ = 0;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001406 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001407 layer_tree_host()->FinishAllRendering();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001408 {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001409 base::AutoLock lock(lock_);
1410 EXPECT_EQ(0, draw_count_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001411 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001412 EndTest();
1413 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001414
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001415 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1416 base::AutoLock lock(lock_);
1417 ++draw_count_;
1418 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001419
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001420 virtual void AfterTest() OVERRIDE {}
1421
1422 private:
1423 bool once_;
1424 base::Lock lock_;
1425 int draw_count_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001426};
1427
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001428SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001429
1430class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001431 public:
1432 virtual void BeginTest() OVERRIDE {
1433 Layer* root_layer = layer_tree_host()->root_layer();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001434
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001435 char pixels[4];
1436 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1437 gfx::Rect(0, 0, 1, 1));
1438 EXPECT_FALSE(root_layer->render_surface());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001439
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001440 EndTest();
1441 }
1442
1443 virtual void AfterTest() OVERRIDE {}
1444};
1445
1446SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1447
1448class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1449 : public LayerTreeHostTest {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001450 protected:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001451 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1452 settings->cache_render_pass_contents = true;
1453 }
1454
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001455 virtual void SetupTree() OVERRIDE {
1456 root_layer_ = FakeContentLayer::Create(&client_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001457 root_layer_->SetBounds(gfx::Size(100, 100));
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001458
1459 surface_layer1_ = FakeContentLayer::Create(&client_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001460 surface_layer1_->SetBounds(gfx::Size(100, 100));
1461 surface_layer1_->SetForceRenderSurface(true);
1462 surface_layer1_->SetOpacity(0.5f);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001463 root_layer_->AddChild(surface_layer1_);
1464
1465 surface_layer2_ = FakeContentLayer::Create(&client_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001466 surface_layer2_->SetBounds(gfx::Size(100, 100));
1467 surface_layer2_->SetForceRenderSurface(true);
1468 surface_layer2_->SetOpacity(0.5f);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001469 surface_layer1_->AddChild(surface_layer2_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001470
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001471 replica_layer1_ = FakeContentLayer::Create(&client_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001472 surface_layer1_->SetReplicaLayer(replica_layer1_.get());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001473
1474 replica_layer2_ = FakeContentLayer::Create(&client_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001475 surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1476
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001477 layer_tree_host()->SetRootLayer(root_layer_);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001478 LayerTreeHostTest::SetupTree();
1479 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001480
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001481 virtual void BeginTest() OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001482 PostSetNeedsCommitToMainThread();
1483 }
1484
1485 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1486 Renderer* renderer = host_impl->renderer();
1487 RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1488 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1489 RenderPass::Id surface2_render_pass_id =
1490 host_impl->active_tree()->root_layer()->children()[0]->children()[0]
1491 ->render_surface()->RenderPassId();
1492
1493 switch (host_impl->active_tree()->source_frame_number()) {
1494 case 0:
1495 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1496 surface1_render_pass_id));
1497 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1498 surface2_render_pass_id));
1499
1500 // Reduce the memory limit to only fit the root layer and one render
1501 // surface. This prevents any contents drawing into surfaces
1502 // from being allocated.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001503 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1504 host_impl->SetDiscardBackBufferWhenNotVisible(true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001505 break;
1506 case 1:
1507 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1508 surface1_render_pass_id));
1509 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1510 surface2_render_pass_id));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001511
1512 EndTest();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001513 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001514 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001515 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001516
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001517 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01001518 if (layer_tree_host()->source_frame_number() < 2)
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001519 root_layer_->SetNeedsDisplay();
1520 }
1521
1522 virtual void AfterTest() OVERRIDE {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001523 EXPECT_LE(2u, root_layer_->update_count());
1524 EXPECT_LE(2u, surface_layer1_->update_count());
1525 EXPECT_LE(2u, surface_layer2_->update_count());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001526 }
1527
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001528 FakeContentLayerClient client_;
1529 scoped_refptr<FakeContentLayer> root_layer_;
1530 scoped_refptr<FakeContentLayer> surface_layer1_;
1531 scoped_refptr<FakeContentLayer> replica_layer1_;
1532 scoped_refptr<FakeContentLayer> surface_layer2_;
1533 scoped_refptr<FakeContentLayer> replica_layer2_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001534};
1535
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001536// Surfaces don't exist with a delegated renderer.
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01001537SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001538 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001539
1540class EvictionTestLayer : public Layer {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001541 public:
1542 static scoped_refptr<EvictionTestLayer> Create() {
1543 return make_scoped_refptr(new EvictionTestLayer());
1544 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001545
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001546 virtual bool Update(ResourceUpdateQueue*,
Ben Murdocheb525c52013-07-10 11:40:50 +01001547 const OcclusionTracker*) OVERRIDE;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001548 virtual bool DrawsContent() const OVERRIDE { return true; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001549
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001550 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1551 OVERRIDE;
1552 virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1553 virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001554
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001555 bool HaveBackingTexture() const {
1556 return texture_.get() ? texture_->have_backing_texture() : false;
1557 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001558
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001559 private:
1560 EvictionTestLayer() : Layer() {}
1561 virtual ~EvictionTestLayer() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001562
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001563 void CreateTextureIfNeeded() {
1564 if (texture_)
1565 return;
1566 texture_ = PrioritizedResource::Create(
1567 layer_tree_host()->contents_texture_manager());
1568 texture_->SetDimensions(gfx::Size(10, 10), GL_RGBA);
1569 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1570 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001571
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001572 scoped_ptr<PrioritizedResource> texture_;
1573 SkBitmap bitmap_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001574};
1575
1576class EvictionTestLayerImpl : public LayerImpl {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001577 public:
1578 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1579 int id) {
1580 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1581 }
1582 virtual ~EvictionTestLayerImpl() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001583
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001584 virtual void AppendQuads(QuadSink* quad_sink,
1585 AppendQuadsData* append_quads_data) OVERRIDE {
1586 ASSERT_TRUE(has_texture_);
1587 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1588 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001589
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001590 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001591
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001592 private:
1593 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1594 : LayerImpl(tree_impl, id), has_texture_(false) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001595
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001596 bool has_texture_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001597};
1598
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001599void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1600 CreateTextureIfNeeded();
1601 if (!texture_)
1602 return;
1603 texture_->set_request_priority(PriorityCalculator::UIPriority(true));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001604}
1605
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001606bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
Ben Murdocheb525c52013-07-10 11:40:50 +01001607 const OcclusionTracker*) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001608 CreateTextureIfNeeded();
1609 if (!texture_)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001610 return false;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001611
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001612 gfx::Rect full_rect(0, 0, 10, 10);
1613 ResourceUpdate upload = ResourceUpdate::Create(
1614 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1615 queue->AppendFullUpload(upload);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001616 return true;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001617}
1618
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001619scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1620 LayerTreeImpl* tree_impl) {
1621 return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1622 .PassAs<LayerImpl>();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001623}
1624
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001625void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1626 Layer::PushPropertiesTo(layer_impl);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001627
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001628 EvictionTestLayerImpl* test_layer_impl =
1629 static_cast<EvictionTestLayerImpl*>(layer_impl);
1630 test_layer_impl->SetHasTexture(texture_->have_backing_texture());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001631}
1632
1633class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001634 public:
1635 LayerTreeHostTestEvictTextures()
1636 : layer_(EvictionTestLayer::Create()),
1637 impl_for_evict_textures_(0),
1638 num_commits_(0) {}
1639
1640 virtual void BeginTest() OVERRIDE {
1641 layer_tree_host()->SetRootLayer(layer_);
1642 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1643
1644 gfx::Transform identity_matrix;
1645 SetLayerPropertiesForTesting(layer_.get(),
1646 0,
1647 identity_matrix,
1648 gfx::PointF(0.f, 0.f),
1649 gfx::PointF(0.f, 0.f),
1650 gfx::Size(10, 20),
1651 true);
1652
1653 PostSetNeedsCommitToMainThread();
1654 }
1655
1656 void PostEvictTextures() {
Ben Murdocheb525c52013-07-10 11:40:50 +01001657 DCHECK(HasImplThread());
1658 ImplThreadTaskRunner()->PostTask(
1659 FROM_HERE,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001660 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1661 base::Unretained(this)));
1662 }
1663
1664 void EvictTexturesOnImplThread() {
1665 DCHECK(impl_for_evict_textures_);
Ben Murdocheb525c52013-07-10 11:40:50 +01001666 impl_for_evict_textures_->EvictTexturesForTesting();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001667 }
1668
1669 // Commit 1: Just commit and draw normally, then post an eviction at the end
1670 // that will trigger a commit.
1671 // Commit 2: Triggered by the eviction, let it go through and then set
1672 // needsCommit.
1673 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1674 // task, which will be handled before the commit. Don't set needsCommit, it
1675 // should have been posted. A frame should not be drawn (note,
1676 // didCommitAndDrawFrame may be called anyway).
1677 // Commit 4: Triggered by the eviction, let it go through and then set
1678 // needsCommit.
1679 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1680 // Layout(), a frame should not be drawn but a commit will be posted.
1681 // Commit 6: Triggered by the eviction, post an eviction task in
1682 // Layout(), which will be a noop, letting the commit (which recreates the
1683 // textures) go through and draw a frame, then end the test.
1684 //
1685 // Commits 1+2 test the eviction recovery path where eviction happens outside
1686 // of the beginFrame/commit pair.
1687 // Commits 3+4 test the eviction recovery path where eviction happens inside
1688 // the beginFrame/commit pair.
1689 // Commits 5+6 test the path where an eviction happens during the eviction
1690 // recovery path.
1691 virtual void DidCommit() OVERRIDE {
1692 switch (num_commits_) {
1693 case 1:
1694 EXPECT_TRUE(layer_->HaveBackingTexture());
1695 PostEvictTextures();
1696 break;
1697 case 2:
1698 EXPECT_TRUE(layer_->HaveBackingTexture());
1699 layer_tree_host()->SetNeedsCommit();
1700 break;
1701 case 3:
1702 break;
1703 case 4:
1704 EXPECT_TRUE(layer_->HaveBackingTexture());
1705 layer_tree_host()->SetNeedsCommit();
1706 break;
1707 case 5:
1708 break;
1709 case 6:
1710 EXPECT_TRUE(layer_->HaveBackingTexture());
1711 EndTest();
1712 break;
1713 default:
1714 NOTREACHED();
1715 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001716 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001717 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001718
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001719 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1720 impl_for_evict_textures_ = impl;
1721 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001722
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001723 virtual void Layout() OVERRIDE {
1724 ++num_commits_;
1725 switch (num_commits_) {
1726 case 1:
1727 case 2:
1728 break;
1729 case 3:
1730 PostEvictTextures();
1731 break;
1732 case 4:
1733 // We couldn't check in didCommitAndDrawFrame on commit 3,
1734 // so check here.
1735 EXPECT_FALSE(layer_->HaveBackingTexture());
1736 break;
1737 case 5:
1738 PostEvictTextures();
1739 break;
1740 case 6:
1741 // We couldn't check in didCommitAndDrawFrame on commit 5,
1742 // so check here.
1743 EXPECT_FALSE(layer_->HaveBackingTexture());
1744 PostEvictTextures();
1745 break;
1746 default:
1747 NOTREACHED();
1748 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001749 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001750 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001751
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001752 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001753
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001754 private:
1755 FakeContentLayerClient client_;
1756 scoped_refptr<EvictionTestLayer> layer_;
1757 LayerTreeHostImpl* impl_for_evict_textures_;
1758 int num_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001759};
1760
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001761MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001762
1763class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001764 public:
1765 LayerTreeHostTestContinuousCommit()
1766 : num_commit_complete_(0), num_draw_layers_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001767
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001768 virtual void BeginTest() OVERRIDE {
1769 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1770 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001771
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001772 PostSetNeedsCommitToMainThread();
1773 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001774
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001775 virtual void DidCommit() OVERRIDE {
1776 if (num_draw_layers_ == 2)
1777 return;
Ben Murdoch558790d2013-07-30 15:19:42 +01001778 layer_tree_host()->SetNeedsCommit();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001779 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001780
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001781 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1782 if (num_draw_layers_ == 1)
1783 num_commit_complete_++;
1784 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001785
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001786 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1787 num_draw_layers_++;
1788 if (num_draw_layers_ == 2)
1789 EndTest();
1790 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001791
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001792 virtual void AfterTest() OVERRIDE {
1793 // Check that we didn't commit twice between first and second draw.
1794 EXPECT_EQ(1, num_commit_complete_);
1795 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001796
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001797 private:
1798 int num_commit_complete_;
1799 int num_draw_layers_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001800};
1801
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001802MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001803
1804class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001805 public:
1806 LayerTreeHostTestContinuousInvalidate()
1807 : num_commit_complete_(0), num_draw_layers_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001808
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001809 virtual void BeginTest() OVERRIDE {
1810 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1811 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001812
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001813 content_layer_ = ContentLayer::Create(&client_);
1814 content_layer_->SetBounds(gfx::Size(10, 10));
1815 content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1816 content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1817 content_layer_->SetIsDrawable(true);
1818 layer_tree_host()->root_layer()->AddChild(content_layer_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001819
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001820 PostSetNeedsCommitToMainThread();
1821 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001822
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01001823 virtual void DidCommitAndDrawFrame() OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001824 if (num_draw_layers_ == 2)
1825 return;
1826 content_layer_->SetNeedsDisplay();
1827 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001828
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001829 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1830 if (num_draw_layers_ == 1)
1831 num_commit_complete_++;
1832 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001833
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001834 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1835 num_draw_layers_++;
1836 if (num_draw_layers_ == 2)
1837 EndTest();
1838 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001839
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001840 virtual void AfterTest() OVERRIDE {
1841 // Check that we didn't commit twice between first and second draw.
1842 EXPECT_EQ(1, num_commit_complete_);
1843 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001844
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001845 private:
1846 FakeContentLayerClient client_;
1847 scoped_refptr<Layer> content_layer_;
1848 int num_commit_complete_;
1849 int num_draw_layers_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001850};
1851
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001852MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001853
1854class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001855 public:
1856 LayerTreeHostTestDeferCommits()
1857 : num_commits_deferred_(0), num_complete_commits_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001858
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001859 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1860
1861 virtual void DidDeferCommit() OVERRIDE {
1862 num_commits_deferred_++;
1863 layer_tree_host()->SetDeferCommits(false);
1864 }
1865
1866 virtual void DidCommit() OVERRIDE {
1867 num_complete_commits_++;
1868 switch (num_complete_commits_) {
1869 case 1:
1870 EXPECT_EQ(0, num_commits_deferred_);
1871 layer_tree_host()->SetDeferCommits(true);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001872 PostSetNeedsCommitToMainThread();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001873 break;
1874 case 2:
1875 EndTest();
1876 break;
1877 default:
1878 NOTREACHED();
1879 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001880 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001881 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001882
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001883 virtual void AfterTest() OVERRIDE {
1884 EXPECT_EQ(1, num_commits_deferred_);
1885 EXPECT_EQ(2, num_complete_commits_);
1886 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001887
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001888 private:
1889 int num_commits_deferred_;
1890 int num_complete_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001891};
1892
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001893MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001894
1895class LayerTreeHostWithProxy : public LayerTreeHost {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001896 public:
1897 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1898 const LayerTreeSettings& settings,
1899 scoped_ptr<FakeProxy> proxy)
1900 : LayerTreeHost(client, settings) {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01001901 proxy->SetLayerTreeHost(this);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001902 EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
1903 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001904};
1905
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001906TEST(LayerTreeHostTest, LimitPartialUpdates) {
1907 // When partial updates are not allowed, max updates should be 0.
1908 {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001909 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1910
Ben Murdocheb525c52013-07-10 11:40:50 +01001911 scoped_ptr<FakeProxy> proxy(new FakeProxy);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001912 proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1913 proxy->SetMaxPartialTextureUpdates(5);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001914
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001915 LayerTreeSettings settings;
1916 settings.max_partial_texture_updates = 10;
1917
1918 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1919 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1920
1921 EXPECT_EQ(0u, host.settings().max_partial_texture_updates);
1922 }
1923
1924 // When partial updates are allowed,
1925 // max updates should be limited by the proxy.
1926 {
1927 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1928
Ben Murdocheb525c52013-07-10 11:40:50 +01001929 scoped_ptr<FakeProxy> proxy(new FakeProxy);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001930 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1931 proxy->SetMaxPartialTextureUpdates(5);
1932
1933 LayerTreeSettings settings;
1934 settings.max_partial_texture_updates = 10;
1935
1936 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1937 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1938
1939 EXPECT_EQ(5u, host.settings().max_partial_texture_updates);
1940 }
1941
1942 // When partial updates are allowed,
1943 // max updates should also be limited by the settings.
1944 {
1945 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1946
Ben Murdocheb525c52013-07-10 11:40:50 +01001947 scoped_ptr<FakeProxy> proxy(new FakeProxy);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001948 proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1949 proxy->SetMaxPartialTextureUpdates(20);
1950
1951 LayerTreeSettings settings;
1952 settings.max_partial_texture_updates = 10;
1953
1954 LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1955 EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1956
1957 EXPECT_EQ(10u, host.settings().max_partial_texture_updates);
1958 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001959}
1960
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001961TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
1962 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001963
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001964 LayerTreeSettings settings;
1965 settings.max_partial_texture_updates = 4;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001966
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001967 scoped_ptr<LayerTreeHost> host =
Ben Murdocheb525c52013-07-10 11:40:50 +01001968 LayerTreeHost::Create(&client, settings, NULL);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001969 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1970 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001971}
1972
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001973TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
1974 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001975
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001976 LayerTreeSettings settings;
1977 settings.max_partial_texture_updates = 4;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001978
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001979 scoped_ptr<LayerTreeHost> host =
Ben Murdocheb525c52013-07-10 11:40:50 +01001980 LayerTreeHost::Create(&client, settings, NULL);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001981 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1982 EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001983}
1984
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001985TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
1986 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001987
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001988 LayerTreeSettings settings;
1989 settings.max_partial_texture_updates = 4;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001990
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001991 scoped_ptr<LayerTreeHost> host =
Ben Murdocheb525c52013-07-10 11:40:50 +01001992 LayerTreeHost::Create(&client, settings, NULL);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001993 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
1994 EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
1995}
1996
1997TEST(LayerTreeHostTest,
1998 PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
1999 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2000
2001 LayerTreeSettings settings;
2002 settings.max_partial_texture_updates = 4;
2003
2004 scoped_ptr<LayerTreeHost> host =
Ben Murdocheb525c52013-07-10 11:40:50 +01002005 LayerTreeHost::Create(&client, settings, NULL);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002006 EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2007 EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002008}
2009
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002010class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2011 : public LayerTreeHostTest {
2012 public:
2013 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2014 : root_layer_(FakeContentLayer::Create(&client_)),
2015 child_layer1_(FakeContentLayer::Create(&client_)),
2016 child_layer2_(FakeContentLayer::Create(&client_)),
2017 num_commits_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002018
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002019 virtual void BeginTest() OVERRIDE {
2020 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2021 root_layer_->SetBounds(gfx::Size(100, 100));
2022 child_layer1_->SetBounds(gfx::Size(100, 100));
2023 child_layer2_->SetBounds(gfx::Size(100, 100));
2024 root_layer_->AddChild(child_layer1_);
2025 root_layer_->AddChild(child_layer2_);
2026 layer_tree_host()->SetRootLayer(root_layer_);
2027 PostSetNeedsCommitToMainThread();
2028 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002029
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002030 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2031 bool visible) OVERRIDE {
2032 // One backing should remain unevicted.
2033 EXPECT_EQ(100u * 100u * 4u * 1u,
2034 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2035 // Make sure that contents textures are marked as having been
2036 // purged.
2037 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2038 // End the test in this state.
2039 EndTest();
2040 }
2041
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002042 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002043 ++num_commits_;
2044 switch (num_commits_) {
2045 case 1:
2046 // All three backings should have memory.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002047 EXPECT_EQ(
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002048 100u * 100u * 4u * 3u,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002049 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002050 // Set a new policy that will kick out 1 of the 3 resources.
2051 // Because a resource was evicted, a commit will be kicked off.
Ben Murdocheb525c52013-07-10 11:40:50 +01002052 host_impl->SetMemoryPolicy(
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002053 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2054 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
2055 100 * 100 * 4 * 1,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01002056 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
2057 1000));
2058 host_impl->SetDiscardBackBufferWhenNotVisible(true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002059 break;
2060 case 2:
2061 // Only two backings should have memory.
2062 EXPECT_EQ(
2063 100u * 100u * 4u * 2u,
2064 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2065 // Become backgrounded, which will cause 1 more resource to be
2066 // evicted.
2067 PostSetVisibleToMainThread(false);
2068 break;
2069 default:
2070 // No further commits should happen because this is not visible
2071 // anymore.
2072 NOTREACHED();
2073 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002074 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002075 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002076
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002077 virtual void AfterTest() OVERRIDE {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002078
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002079 private:
2080 FakeContentLayerClient client_;
2081 scoped_refptr<FakeContentLayer> root_layer_;
2082 scoped_refptr<FakeContentLayer> child_layer1_;
2083 scoped_refptr<FakeContentLayer> child_layer2_;
2084 int num_commits_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002085};
2086
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002087SINGLE_AND_MULTI_THREAD_TEST_F(
2088 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002089
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002090class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002091 public:
2092 class NotificationClient : public ContentLayerClient {
2093 public:
2094 NotificationClient()
2095 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002096
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002097 void set_layer(Layer* layer) { layer_ = layer; }
2098 int paint_count() const { return paint_count_; }
2099 int lcd_notification_count() const { return lcd_notification_count_; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002100
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002101 virtual void PaintContents(SkCanvas* canvas,
2102 gfx::Rect clip,
2103 gfx::RectF* opaque) OVERRIDE {
2104 ++paint_count_;
2105 }
2106 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2107 ++lcd_notification_count_;
2108 layer_->SetNeedsDisplay();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002109 }
2110
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002111 private:
2112 Layer* layer_;
2113 int paint_count_;
2114 int lcd_notification_count_;
2115 };
2116
2117 virtual void SetupTree() OVERRIDE {
2118 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2119 root_layer->SetIsDrawable(true);
2120 root_layer->SetBounds(gfx::Size(1, 1));
2121
2122 layer_tree_host()->SetRootLayer(root_layer);
2123 client_.set_layer(root_layer.get());
2124
2125 // The expecations are based on the assumption that the default
2126 // LCD settings are:
2127 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2128 EXPECT_FALSE(root_layer->can_use_lcd_text());
2129
2130 LayerTreeHostTest::SetupTree();
2131 }
2132
2133 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2134 virtual void AfterTest() OVERRIDE {}
2135
2136 virtual void DidCommit() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01002137 switch (layer_tree_host()->source_frame_number()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002138 case 1:
2139 // The first update consists one LCD notification and one paint.
2140 EXPECT_EQ(1, client_.lcd_notification_count());
2141 EXPECT_EQ(1, client_.paint_count());
2142 // LCD text must have been enabled on the layer.
2143 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002144 PostSetNeedsCommitToMainThread();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002145 break;
2146 case 2:
2147 // Since nothing changed on layer, there should be no notification
2148 // or paint on the second update.
2149 EXPECT_EQ(1, client_.lcd_notification_count());
2150 EXPECT_EQ(1, client_.paint_count());
2151 // LCD text must not have changed.
2152 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2153 // Change layer opacity that should trigger lcd notification.
2154 layer_tree_host()->root_layer()->SetOpacity(.5f);
2155 // No need to request a commit - setting opacity will do it.
2156 break;
2157 default:
2158 // Verify that there is not extra commit due to layer invalidation.
Ben Murdochbbcdd452013-07-25 10:06:34 +01002159 EXPECT_EQ(3, layer_tree_host()->source_frame_number());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002160 // LCD notification count should have incremented due to
2161 // change in layer opacity.
2162 EXPECT_EQ(2, client_.lcd_notification_count());
2163 // Paint count should be incremented due to invalidation.
2164 EXPECT_EQ(2, client_.paint_count());
2165 // LCD text must have been disabled on the layer due to opacity.
2166 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2167 EndTest();
2168 break;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002169 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002170 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002171
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002172 private:
2173 NotificationClient client_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002174};
2175
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002176SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2177
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002178// Verify that the BeginFrame notification is used to initiate rendering.
2179class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002180 public:
2181 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01002182 settings->begin_frame_scheduling_enabled = true;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002183 }
2184
2185 virtual void BeginTest() OVERRIDE {
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002186 // This will trigger a SetNeedsBeginFrame which will trigger a BeginFrame.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002187 PostSetNeedsCommitToMainThread();
2188 }
2189
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002190 virtual bool PrepareToDrawOnThread(
2191 LayerTreeHostImpl* host_impl,
2192 LayerTreeHostImpl::FrameData* frame,
2193 bool result) OVERRIDE {
2194 EndTest();
2195 return true;
2196 }
2197
2198 virtual void AfterTest() OVERRIDE {}
2199
2200 private:
2201 base::TimeTicks frame_time_;
2202};
2203
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002204MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002205
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002206class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002207 : public LayerTreeHostTest {
2208 public:
2209 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01002210 settings->begin_frame_scheduling_enabled = true;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002211 settings->using_synchronous_renderer_compositor = true;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002212 }
2213
2214 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2215
2216 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002217 // The BeginFrame notification is turned off now but will get enabled
2218 // once we return. End test while it's enabled.
Ben Murdocheb525c52013-07-10 11:40:50 +01002219 ImplThreadTaskRunner()->PostTask(
2220 FROM_HERE,
2221 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2222 base::Unretained(this)));
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002223 }
2224
2225 virtual void AfterTest() OVERRIDE {}
2226};
2227
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002228MULTI_THREAD_TEST_F(
2229 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002230
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002231class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2232 : public LayerTreeHostTest {
2233 protected:
2234 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2235 settings->impl_side_painting = true;
2236 }
2237
2238 virtual void SetupTree() OVERRIDE {
2239 LayerTreeHostTest::SetupTree();
2240
2241 scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2242 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2243 layer->SetBounds(gfx::Size(10, 10));
2244 layer_tree_host()->root_layer()->AddChild(layer);
2245 }
2246
2247 virtual void BeginTest() OVERRIDE {
2248 PostSetNeedsCommitToMainThread();
2249 }
2250
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002251 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002252 EndTest();
2253 }
2254
2255 virtual void AfterTest() OVERRIDE {
2256 }
2257
2258 FakeContentLayerClient client_;
2259};
2260
2261MULTI_THREAD_TEST_F(
2262 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2263
2264class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2265 : public LayerTreeHostTest {
2266 public:
2267 class SetBoundsClient : public ContentLayerClient {
2268 public:
2269 SetBoundsClient() : layer_(0) {}
2270
2271 void set_layer(Layer* layer) { layer_ = layer; }
2272
2273 virtual void PaintContents(SkCanvas* canvas,
2274 gfx::Rect clip,
2275 gfx::RectF* opaque) OVERRIDE {
2276 layer_->SetBounds(gfx::Size(2, 2));
2277 }
2278
2279 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2280
2281 private:
2282 Layer* layer_;
2283 };
2284
2285 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2286
2287 virtual void SetupTree() OVERRIDE {
2288 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2289 root_layer->SetIsDrawable(true);
2290 root_layer->SetBounds(gfx::Size(1, 1));
2291
2292 layer_tree_host()->SetRootLayer(root_layer);
2293 client_.set_layer(root_layer.get());
2294
2295 LayerTreeHostTest::SetupTree();
2296 }
2297
2298 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2299 virtual void AfterTest() OVERRIDE {}
2300
2301 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2302 num_commits_++;
2303 if (num_commits_ == 1) {
2304 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2305 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2306 } else {
2307 LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2308 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2309 EndTest();
2310 }
2311 }
2312
2313 private:
2314 SetBoundsClient client_;
2315 int num_commits_;
2316};
2317
2318SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2319
2320class MockIOSurfaceWebGraphicsContext3D : public FakeWebGraphicsContext3D {
2321 public:
2322 MockIOSurfaceWebGraphicsContext3D()
2323 : FakeWebGraphicsContext3D() {}
2324
2325 virtual WebKit::WebGLId createTexture() OVERRIDE {
2326 return 1;
2327 }
2328
2329 virtual WebKit::WebString getString(WebKit::WGC3Denum name) OVERRIDE {
2330 if (name == GL_EXTENSIONS) {
2331 return WebKit::WebString(
2332 "GL_CHROMIUM_iosurface GL_ARB_texture_rectangle");
2333 }
2334 return WebKit::WebString();
2335 }
2336
2337 MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
2338 MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01002339 WebKit::WebGLId texture_id));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002340 MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
2341 WebKit::WGC3Denum pname,
2342 WebKit::WGC3Dint param));
2343 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
2344 WebKit::WGC3Dint width,
2345 WebKit::WGC3Dint height,
2346 WebKit::WGC3Duint ioSurfaceId,
2347 WebKit::WGC3Duint plane));
2348 MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
2349 WebKit::WGC3Dsizei count,
2350 WebKit::WGC3Denum type,
2351 WebKit::WGC3Dintptr offset));
2352};
2353
2354
2355class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2356 protected:
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01002357 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2358 OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002359 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> context(
2360 new MockIOSurfaceWebGraphicsContext3D);
2361 mock_context_ = context.get();
2362 scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(
2363 context.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>();
2364 return output_surface.Pass();
2365 }
2366
2367 virtual void SetupTree() OVERRIDE {
2368 LayerTreeHostTest::SetupTree();
2369
2370 layer_tree_host()->root_layer()->SetIsDrawable(false);
2371
2372 io_surface_id_ = 9;
2373 io_surface_size_ = gfx::Size(6, 7);
2374
2375 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2376 io_surface_layer->SetBounds(gfx::Size(10, 10));
2377 io_surface_layer->SetAnchorPoint(gfx::PointF());
2378 io_surface_layer->SetIsDrawable(true);
2379 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2380 layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2381 }
2382
2383 virtual void BeginTest() OVERRIDE {
2384 PostSetNeedsCommitToMainThread();
2385 }
2386
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002387 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002388 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2389
2390 EXPECT_CALL(*mock_context_, activeTexture(_))
2391 .Times(0);
2392 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2393 .Times(AtLeast(1));
2394 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2395 GL_TEXTURE_MIN_FILTER,
2396 GL_LINEAR))
2397 .Times(1);
2398 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2399 GL_TEXTURE_MAG_FILTER,
2400 GL_LINEAR))
2401 .Times(1);
2402 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2403 GL_TEXTURE_WRAP_S,
2404 GL_CLAMP_TO_EDGE))
2405 .Times(1);
2406 EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2407 GL_TEXTURE_WRAP_T,
2408 GL_CLAMP_TO_EDGE))
2409 .Times(1);
2410
2411 EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
2412 GL_TEXTURE_RECTANGLE_ARB,
2413 io_surface_size_.width(),
2414 io_surface_size_.height(),
2415 io_surface_id_,
2416 0))
2417 .Times(1);
2418
2419 EXPECT_CALL(*mock_context_, bindTexture(_, 0))
2420 .Times(AnyNumber());
2421 }
2422
2423 virtual bool PrepareToDrawOnThread(
2424 LayerTreeHostImpl* host_impl,
2425 LayerTreeHostImpl::FrameData* frame,
2426 bool result) OVERRIDE {
2427 Mock::VerifyAndClearExpectations(&mock_context_);
2428
2429 // The io surface layer's texture is drawn.
2430 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
2431 .Times(AtLeast(1));
2432 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2433 .Times(1);
2434 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2435 .Times(AtLeast(1));
2436
2437 return result;
2438 }
2439
2440 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2441 Mock::VerifyAndClearExpectations(&mock_context_);
2442 EndTest();
2443 }
2444
2445 virtual void AfterTest() OVERRIDE {}
2446
2447 int io_surface_id_;
2448 MockIOSurfaceWebGraphicsContext3D* mock_context_;
2449 gfx::Size io_surface_size_;
2450};
2451
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002452// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2453SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2454 LayerTreeHostTestIOSurfaceDrawing);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002455
2456class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2457 protected:
2458 virtual void SetupTree() OVERRIDE {
2459 root = FakeContentLayer::Create(&client_);
2460 root->SetBounds(gfx::Size(20, 20));
2461
2462 child = FakeContentLayer::Create(&client_);
2463 child->SetBounds(gfx::Size(10, 10));
2464 root->AddChild(child);
2465
2466 layer_tree_host()->SetRootLayer(root);
2467 LayerTreeHostTest::SetupTree();
2468 }
2469
2470 virtual void BeginTest() OVERRIDE {
2471 PostSetNeedsCommitToMainThread();
2472 }
2473
2474 virtual void DidCommitAndDrawFrame() OVERRIDE {
2475 WaitForCallback();
2476 }
2477
2478 void WaitForCallback() {
2479 base::MessageLoop::current()->PostTask(
2480 FROM_HERE,
2481 base::Bind(
2482 &LayerTreeHostTestAsyncReadback::NextStep,
2483 base::Unretained(this)));
2484 }
2485
2486 void NextStep() {
Ben Murdochbbcdd452013-07-25 10:06:34 +01002487 int frame = layer_tree_host()->source_frame_number();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002488 switch (frame) {
2489 case 1:
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002490 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002491 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002492 base::Unretained(this))));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002493 EXPECT_EQ(0u, callbacks_.size());
2494 break;
2495 case 2:
2496 if (callbacks_.size() < 1u) {
2497 WaitForCallback();
2498 return;
2499 }
2500 EXPECT_EQ(1u, callbacks_.size());
2501 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2502
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002503 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002504 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002505 base::Unretained(this))));
2506 root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002507 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002508 base::Unretained(this))));
2509 child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002510 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002511 base::Unretained(this))));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002512 EXPECT_EQ(1u, callbacks_.size());
2513 break;
2514 case 3:
2515 if (callbacks_.size() < 4u) {
2516 WaitForCallback();
2517 return;
2518 }
2519 EXPECT_EQ(4u, callbacks_.size());
2520 // The child was copied to a bitmap and passed back twice.
2521 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2522 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2523 // The root was copied to a bitmap and passed back also.
2524 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
2525 EndTest();
2526 break;
2527 }
2528 }
2529
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002530 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002531 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002532 EXPECT_TRUE(result->HasBitmap());
2533 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
2534 EXPECT_EQ(result->size().ToString(),
2535 gfx::Size(bitmap->width(), bitmap->height()).ToString());
2536 callbacks_.push_back(result->size());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002537 }
2538
2539 virtual void AfterTest() OVERRIDE {
2540 EXPECT_EQ(4u, callbacks_.size());
2541 }
2542
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01002543 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2544 OVERRIDE {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002545 if (use_gl_renderer_)
2546 return FakeOutputSurface::Create3d().PassAs<OutputSurface>();
2547 return FakeOutputSurface::CreateSoftware(
2548 make_scoped_ptr(new SoftwareOutputDevice)).PassAs<OutputSurface>();
2549 }
2550
2551 bool use_gl_renderer_;
2552 std::vector<gfx::Size> callbacks_;
2553 FakeContentLayerClient client_;
2554 scoped_refptr<FakeContentLayer> root;
2555 scoped_refptr<FakeContentLayer> child;
2556};
2557
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002558// Readback can't be done with a delegating renderer.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002559TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
2560 use_gl_renderer_ = true;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002561 RunTest(false, false, false);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002562}
2563
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002564TEST_F(LayerTreeHostTestAsyncReadback,
2565 GLRenderer_RunMultiThread_MainThreadPainting) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002566 use_gl_renderer_ = true;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002567 RunTest(true, false, false);
2568}
2569
2570TEST_F(LayerTreeHostTestAsyncReadback,
2571 GLRenderer_RunMultiThread_ImplSidePainting) {
2572 use_gl_renderer_ = true;
2573 RunTest(true, false, true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002574}
2575
2576TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
2577 use_gl_renderer_ = false;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002578 RunTest(false, false, false);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002579}
2580
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002581TEST_F(LayerTreeHostTestAsyncReadback,
2582 SoftwareRenderer_RunMultiThread_MainThreadPainting) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002583 use_gl_renderer_ = false;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002584 RunTest(true, false, false);
2585}
2586
2587TEST_F(LayerTreeHostTestAsyncReadback,
2588 SoftwareRenderer_RunMultiThread_ImplSidePainting) {
2589 use_gl_renderer_ = false;
2590 RunTest(true, false, true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002591}
2592
2593class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
2594 protected:
2595 virtual void SetupTree() OVERRIDE {
2596 root_ = FakeContentLayer::Create(&client_);
2597 root_->SetBounds(gfx::Size(20, 20));
2598
2599 main_destroyed_ = FakeContentLayer::Create(&client_);
2600 main_destroyed_->SetBounds(gfx::Size(15, 15));
2601 root_->AddChild(main_destroyed_);
2602
2603 impl_destroyed_ = FakeContentLayer::Create(&client_);
2604 impl_destroyed_->SetBounds(gfx::Size(10, 10));
2605 root_->AddChild(impl_destroyed_);
2606
2607 layer_tree_host()->SetRootLayer(root_);
2608 LayerTreeHostTest::SetupTree();
2609 }
2610
2611 virtual void BeginTest() OVERRIDE {
2612 callback_count_ = 0;
2613 PostSetNeedsCommitToMainThread();
2614 }
2615
2616 virtual void DidCommit() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01002617 int frame = layer_tree_host()->source_frame_number();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002618 switch (frame) {
2619 case 1:
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002620 main_destroyed_->RequestCopyOfOutput(
2621 CopyOutputRequest::CreateBitmapRequest(base::Bind(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002622 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2623 CopyOutputCallback,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002624 base::Unretained(this))));
2625 impl_destroyed_->RequestCopyOfOutput(
2626 CopyOutputRequest::CreateBitmapRequest(base::Bind(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002627 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2628 CopyOutputCallback,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01002629 base::Unretained(this))));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002630 EXPECT_EQ(0, callback_count_);
2631
2632 // Destroy the main thread layer right away.
2633 main_destroyed_->RemoveFromParent();
2634 main_destroyed_ = NULL;
2635
2636 // Should callback with a NULL bitmap.
2637 EXPECT_EQ(1, callback_count_);
2638
2639 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
2640 layer_tree_host()->SetViewportSize(gfx::Size());
2641 break;
2642 case 2:
2643 // Flush the message loops and make sure the callbacks run.
2644 layer_tree_host()->SetNeedsCommit();
2645 break;
2646 case 3:
2647 // No drawing means no readback yet.
2648 EXPECT_EQ(1, callback_count_);
2649
2650 // Destroy the impl thread layer.
2651 impl_destroyed_->RemoveFromParent();
2652 impl_destroyed_ = NULL;
2653
2654 // No callback yet because it's on the impl side.
2655 EXPECT_EQ(1, callback_count_);
2656 break;
2657 case 4:
2658 // Flush the message loops and make sure the callbacks run.
2659 layer_tree_host()->SetNeedsCommit();
2660 break;
2661 case 5:
2662 // We should get another callback with a NULL bitmap.
2663 EXPECT_EQ(2, callback_count_);
2664 EndTest();
2665 break;
2666 }
2667 }
2668
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002669 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002670 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01002671 EXPECT_TRUE(result->IsEmpty());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002672 ++callback_count_;
2673 }
2674
2675 virtual void AfterTest() OVERRIDE {}
2676
2677 int callback_count_;
2678 FakeContentLayerClient client_;
2679 scoped_refptr<FakeContentLayer> root_;
2680 scoped_refptr<FakeContentLayer> main_destroyed_;
2681 scoped_refptr<FakeContentLayer> impl_destroyed_;
2682};
2683
2684SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002685
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01002686class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
2687 protected:
2688 virtual void SetupTree() OVERRIDE {
2689 root_ = FakeContentLayer::Create(&client_);
2690 root_->SetBounds(gfx::Size(20, 20));
2691
2692 grand_parent_layer_ = FakeContentLayer::Create(&client_);
2693 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
2694 root_->AddChild(grand_parent_layer_);
2695
2696 // parent_layer_ owns a render surface.
2697 parent_layer_ = FakeContentLayer::Create(&client_);
2698 parent_layer_->SetBounds(gfx::Size(15, 15));
2699 parent_layer_->SetForceRenderSurface(true);
2700 grand_parent_layer_->AddChild(parent_layer_);
2701
2702 copy_layer_ = FakeContentLayer::Create(&client_);
2703 copy_layer_->SetBounds(gfx::Size(10, 10));
2704 parent_layer_->AddChild(copy_layer_);
2705
2706 layer_tree_host()->SetRootLayer(root_);
2707 LayerTreeHostTest::SetupTree();
2708 }
2709
2710 void AddCopyRequest(Layer* layer) {
2711 layer->RequestCopyOfOutput(
2712 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2713 &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
2714 base::Unretained(this))));
2715 }
2716
2717 virtual void BeginTest() OVERRIDE {
2718 callback_count_ = 0;
2719 PostSetNeedsCommitToMainThread();
2720
2721 AddCopyRequest(copy_layer_.get());
2722 }
2723
2724 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2725 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2726 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
2727 ++callback_count_;
2728
2729 switch (callback_count_) {
2730 case 1:
2731 // Hide the copy request layer.
2732 grand_parent_layer_->SetHideLayerAndSubtree(false);
2733 parent_layer_->SetHideLayerAndSubtree(false);
2734 copy_layer_->SetHideLayerAndSubtree(true);
2735 AddCopyRequest(copy_layer_.get());
2736 break;
2737 case 2:
2738 // Hide the copy request layer's parent only.
2739 grand_parent_layer_->SetHideLayerAndSubtree(false);
2740 parent_layer_->SetHideLayerAndSubtree(true);
2741 copy_layer_->SetHideLayerAndSubtree(false);
2742 AddCopyRequest(copy_layer_.get());
2743 break;
2744 case 3:
2745 // Hide the copy request layer's grand parent only.
2746 grand_parent_layer_->SetHideLayerAndSubtree(true);
2747 parent_layer_->SetHideLayerAndSubtree(false);
2748 copy_layer_->SetHideLayerAndSubtree(false);
2749 AddCopyRequest(copy_layer_.get());
2750 break;
2751 case 4:
2752 // Hide the copy request layer's parent and grandparent.
2753 grand_parent_layer_->SetHideLayerAndSubtree(true);
2754 parent_layer_->SetHideLayerAndSubtree(true);
2755 copy_layer_->SetHideLayerAndSubtree(false);
2756 AddCopyRequest(copy_layer_.get());
2757 break;
2758 case 5:
2759 // Hide the copy request layer as well as its parent and grandparent.
2760 grand_parent_layer_->SetHideLayerAndSubtree(true);
2761 parent_layer_->SetHideLayerAndSubtree(true);
2762 copy_layer_->SetHideLayerAndSubtree(true);
2763 AddCopyRequest(copy_layer_.get());
2764 break;
2765 case 6:
2766 EndTest();
2767 break;
2768 }
2769 }
2770
2771 virtual void AfterTest() OVERRIDE {}
2772
2773 int callback_count_;
2774 FakeContentLayerClient client_;
2775 scoped_refptr<FakeContentLayer> root_;
2776 scoped_refptr<FakeContentLayer> grand_parent_layer_;
2777 scoped_refptr<FakeContentLayer> parent_layer_;
2778 scoped_refptr<FakeContentLayer> copy_layer_;
2779};
2780
2781// No output to copy for delegated renderers.
2782SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2783 LayerTreeHostTestAsyncReadbackInHiddenSubtree);
2784
2785class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
2786 : public LayerTreeHostTest {
2787 protected:
2788 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2789 settings->cache_render_pass_contents = true;
2790 }
2791
2792 virtual void SetupTree() OVERRIDE {
2793 root_ = FakeContentLayer::Create(&client_);
2794 root_->SetBounds(gfx::Size(20, 20));
2795
2796 grand_parent_layer_ = FakeContentLayer::Create(&client_);
2797 grand_parent_layer_->SetBounds(gfx::Size(15, 15));
2798 grand_parent_layer_->SetHideLayerAndSubtree(true);
2799 root_->AddChild(grand_parent_layer_);
2800
2801 // parent_layer_ owns a render surface.
2802 parent_layer_ = FakeContentLayer::Create(&client_);
2803 parent_layer_->SetBounds(gfx::Size(15, 15));
2804 parent_layer_->SetForceRenderSurface(true);
2805 grand_parent_layer_->AddChild(parent_layer_);
2806
2807 copy_layer_ = FakeContentLayer::Create(&client_);
2808 copy_layer_->SetBounds(gfx::Size(10, 10));
2809 parent_layer_->AddChild(copy_layer_);
2810
2811 layer_tree_host()->SetRootLayer(root_);
2812 LayerTreeHostTest::SetupTree();
2813 }
2814
2815 virtual void BeginTest() OVERRIDE {
2816 did_draw_ = false;
2817 PostSetNeedsCommitToMainThread();
2818
2819 copy_layer_->RequestCopyOfOutput(
2820 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2821 &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
2822 CopyOutputCallback,
2823 base::Unretained(this))));
2824 }
2825
2826 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2827 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2828 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
2829 EndTest();
2830 }
2831
2832 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2833 Renderer* renderer = host_impl->renderer();
2834
2835 LayerImpl* root = host_impl->active_tree()->root_layer();
2836 LayerImpl* grand_parent = root->children()[0];
2837 LayerImpl* parent = grand_parent->children()[0];
2838 LayerImpl* copy_layer = parent->children()[0];
2839
2840 // |parent| owns a surface, but it was hidden and not part of the copy
2841 // request so it should not allocate any resource.
2842 EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
2843 parent->render_surface()->RenderPassId()));
2844
2845 // |copy_layer| should have been rendered to a texture since it was needed
2846 // for a copy request.
2847 EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
2848 copy_layer->render_surface()->RenderPassId()));
2849
2850 did_draw_ = true;
2851 }
2852
2853 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
2854
2855 FakeContentLayerClient client_;
2856 bool did_draw_;
2857 scoped_refptr<FakeContentLayer> root_;
2858 scoped_refptr<FakeContentLayer> grand_parent_layer_;
2859 scoped_refptr<FakeContentLayer> parent_layer_;
2860 scoped_refptr<FakeContentLayer> copy_layer_;
2861};
2862
2863// No output to copy for delegated renderers.
2864SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2865 LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
2866
2867class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
2868 protected:
2869 virtual void SetupTree() OVERRIDE {
2870 root_ = FakeContentLayer::Create(&client_);
2871 root_->SetBounds(gfx::Size(20, 20));
2872
2873 parent_layer_ = FakeContentLayer::Create(&client_);
2874 parent_layer_->SetBounds(gfx::Size(15, 15));
2875 parent_layer_->SetMasksToBounds(true);
2876 root_->AddChild(parent_layer_);
2877
2878 copy_layer_ = FakeContentLayer::Create(&client_);
2879 copy_layer_->SetPosition(gfx::Point(15, 15));
2880 copy_layer_->SetBounds(gfx::Size(10, 10));
2881 parent_layer_->AddChild(copy_layer_);
2882
2883 layer_tree_host()->SetRootLayer(root_);
2884 LayerTreeHostTest::SetupTree();
2885 }
2886
2887 virtual void BeginTest() OVERRIDE {
2888 PostSetNeedsCommitToMainThread();
2889
2890 copy_layer_->RequestCopyOfOutput(
2891 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2892 &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
2893 base::Unretained(this))));
2894 }
2895
2896 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2897 // We should still get a callback with no output if the copy requested layer
2898 // was completely clipped away.
2899 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2900 EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
2901 EndTest();
2902 }
2903
2904 virtual void AfterTest() OVERRIDE {}
2905
2906 FakeContentLayerClient client_;
2907 scoped_refptr<FakeContentLayer> root_;
2908 scoped_refptr<FakeContentLayer> parent_layer_;
2909 scoped_refptr<FakeContentLayer> copy_layer_;
2910};
2911
2912// No output to copy for delegated renderers.
2913SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2914 LayerTreeHostTestAsyncReadbackClippedOut);
2915
Ben Murdocha3f7b4e2013-07-24 10:36:34 +01002916class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
2917 protected:
2918 virtual void SetupTree() OVERRIDE {
2919 root_ = FakeContentLayer::Create(&client_);
2920 root_->SetBounds(gfx::Size(20, 20));
2921
2922 copy_layer_ = FakeContentLayer::Create(&client_);
2923 copy_layer_->SetBounds(gfx::Size(10, 10));
2924 root_->AddChild(copy_layer_);
2925
2926 layer_tree_host()->SetRootLayer(root_);
2927 LayerTreeHostTest::SetupTree();
2928 }
2929
2930 void AddCopyRequest(Layer* layer) {
2931 layer->RequestCopyOfOutput(
2932 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2933 &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
2934 base::Unretained(this))));
2935 }
2936
2937 virtual void BeginTest() OVERRIDE {
2938 saw_copy_request_ = false;
2939 callback_count_ = 0;
2940 PostSetNeedsCommitToMainThread();
2941
2942 // Prevent drawing.
2943 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
2944
2945 AddCopyRequest(copy_layer_.get());
2946 }
2947
2948 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2949 if (impl->active_tree()->source_frame_number() == 0) {
2950 LayerImpl* root = impl->active_tree()->root_layer();
2951 EXPECT_TRUE(root->children()[0]->HasCopyRequest());
2952 saw_copy_request_ = true;
2953 }
2954 }
2955
2956 virtual void DidCommit() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01002957 if (layer_tree_host()->source_frame_number() == 1) {
Ben Murdocha3f7b4e2013-07-24 10:36:34 +01002958 // Allow drawing.
2959 layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
2960
2961 AddCopyRequest(copy_layer_.get());
2962 }
2963 }
2964
2965 void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2966 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2967 EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
2968 ++callback_count_;
2969
2970 if (callback_count_ == 2)
2971 EndTest();
2972 }
2973
2974 virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
2975
2976 bool saw_copy_request_;
2977 int callback_count_;
2978 FakeContentLayerClient client_;
2979 scoped_refptr<FakeContentLayer> root_;
2980 scoped_refptr<FakeContentLayer> copy_layer_;
2981};
2982
2983// No output to copy for delegated renderers.
2984SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2985 LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
2986
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01002987class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
2988 public:
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01002989 virtual void BeginTest() OVERRIDE {
2990 frame_ = 0;
2991 PostSetNeedsCommitToMainThread();
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01002992 }
2993
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01002994 // Round 1: commit + draw
2995 // Round 2: commit only (no draw/swap)
2996 // Round 3: draw only (no commit)
2997 // Round 4: composite & readback (2 commits, no draw/swap)
2998 // Round 5: commit + draw
2999
3000 virtual void DidCommit() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003001 int commit = layer_tree_host()->source_frame_number();
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01003002 switch (commit) {
3003 case 2:
3004 // Round 2 done.
3005 EXPECT_EQ(1, frame_);
3006 layer_tree_host()->SetNeedsRedraw();
3007 break;
3008 case 3:
3009 // CompositeAndReadback in Round 4, first commit.
3010 EXPECT_EQ(2, frame_);
3011 break;
3012 case 4:
3013 // Round 4 done.
3014 EXPECT_EQ(2, frame_);
3015 layer_tree_host()->SetNeedsCommit();
3016 layer_tree_host()->SetNeedsRedraw();
3017 break;
3018 }
3019 }
3020
3021 virtual void DidCompleteSwapBuffers() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003022 int commit = layer_tree_host()->source_frame_number();
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01003023 ++frame_;
3024 char pixels[4] = {0};
3025 switch (frame_) {
3026 case 1:
3027 // Round 1 done.
3028 EXPECT_EQ(1, commit);
3029 layer_tree_host()->SetNeedsCommit();
3030 break;
3031 case 2:
3032 // Round 3 done.
3033 EXPECT_EQ(2, commit);
3034 layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
3035 break;
3036 case 3:
3037 // Round 5 done.
3038 EXPECT_EQ(5, commit);
3039 EndTest();
3040 break;
3041 }
3042 }
3043
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01003044 virtual void AfterTest() OVERRIDE {}
3045
3046 protected:
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01003047 int frame_;
3048};
3049
3050TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01003051 RunTest(true, true, true);
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01003052}
3053
3054TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01003055 RunTest(true, false, true);
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01003056}
3057
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003058class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3059 public:
3060 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3061 // PictureLayer can only be used with impl side painting enabled.
3062 settings->impl_side_painting = true;
Ben Murdocheb525c52013-07-10 11:40:50 +01003063 settings->solid_color_scrollbars = true;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003064 }
3065
3066 virtual void SetupTree() OVERRIDE {
3067 layer_ = FakePictureLayer::Create(&client_);
Ben Murdoch558790d2013-07-30 15:19:42 +01003068 // Force commits to not be aborted so new frames get drawn, otherwise
3069 // the renderer gets deferred initialized but nothing new needs drawing.
3070 layer_->set_always_update_resources(true);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003071 layer_tree_host()->SetRootLayer(layer_);
3072 LayerTreeHostTest::SetupTree();
3073 }
3074
3075 virtual void BeginTest() OVERRIDE {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003076 did_initialize_gl_ = false;
3077 did_release_gl_ = false;
Ben Murdochca12bfa2013-07-23 11:17:05 +01003078 last_source_frame_number_drawn_ = -1; // Never drawn.
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003079 PostSetNeedsCommitToMainThread();
3080 }
3081
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01003082 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3083 OVERRIDE {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003084 scoped_ptr<TestWebGraphicsContext3D> context3d(
3085 TestWebGraphicsContext3D::Create());
3086 context3d->set_support_swapbuffers_complete_callback(false);
3087
3088 return FakeOutputSurface::CreateDeferredGL(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003089 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))
3090 .PassAs<OutputSurface>();
3091 }
3092
3093 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3094 ASSERT_TRUE(host_impl->RootLayer());
3095 FakePictureLayerImpl* layer_impl =
3096 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
Ben Murdochca12bfa2013-07-23 11:17:05 +01003097
3098 // The same frame can be draw multiple times if new visible tiles are
3099 // rasterized. But we want to make sure we only post DeferredInitialize
3100 // and ReleaseGL once, so early out if the same frame is drawn again.
3101 if (last_source_frame_number_drawn_ ==
3102 host_impl->active_tree()->source_frame_number())
3103 return;
3104
3105 last_source_frame_number_drawn_ =
3106 host_impl->active_tree()->source_frame_number();
3107
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003108 if (!did_initialize_gl_) {
Ben Murdochca12bfa2013-07-23 11:17:05 +01003109 EXPECT_LE(1u, layer_impl->append_quads_count());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003110 ImplThreadTaskRunner()->PostTask(
3111 FROM_HERE,
3112 base::Bind(
3113 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3114 base::Unretained(this),
3115 base::Unretained(host_impl)));
3116 } else if (did_initialize_gl_ && !did_release_gl_) {
Ben Murdochca12bfa2013-07-23 11:17:05 +01003117 EXPECT_LE(2u, layer_impl->append_quads_count());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003118 ImplThreadTaskRunner()->PostTask(
3119 FROM_HERE,
3120 base::Bind(
3121 &LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3122 base::Unretained(this),
3123 base::Unretained(host_impl)));
3124 } else if (did_initialize_gl_ && did_release_gl_) {
Ben Murdochca12bfa2013-07-23 11:17:05 +01003125 EXPECT_LE(3u, layer_impl->append_quads_count());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003126 EndTest();
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003127 }
3128 }
3129
3130 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003131 EXPECT_FALSE(did_initialize_gl_);
3132 // SetAndInitializeContext3D calls SetNeedsCommit.
Ben Murdocheb525c52013-07-10 11:40:50 +01003133 EXPECT_TRUE(static_cast<FakeOutputSurface*>(host_impl->output_surface())
3134 ->SetAndInitializeContext3D(
3135 scoped_ptr<WebKit::WebGraphicsContext3D>(
3136 TestWebGraphicsContext3D::Create())));
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003137 did_initialize_gl_ = true;
3138 }
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003139
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003140 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3141 EXPECT_TRUE(did_initialize_gl_);
3142 EXPECT_FALSE(did_release_gl_);
3143 // ReleaseGL calls SetNeedsCommit.
3144 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3145 did_release_gl_ = true;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003146 }
3147
3148 virtual void AfterTest() OVERRIDE {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003149 EXPECT_TRUE(did_initialize_gl_);
3150 EXPECT_TRUE(did_release_gl_);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003151 }
3152
3153 private:
3154 FakeContentLayerClient client_;
3155 scoped_refptr<FakePictureLayer> layer_;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003156 bool did_initialize_gl_;
3157 bool did_release_gl_;
Ben Murdochca12bfa2013-07-23 11:17:05 +01003158 int last_source_frame_number_drawn_;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01003159};
3160
3161MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3162
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01003163// Test for UI Resource management.
3164class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3165 public:
3166 LayerTreeHostTestUIResource() : num_ui_resources_(0), num_commits_(0) {}
3167
3168 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3169
3170 virtual void DidCommit() OVERRIDE {
3171 int frame = num_commits_;
3172 switch (frame) {
3173 case 1:
3174 CreateResource();
3175 CreateResource();
3176 PostSetNeedsCommitToMainThread();
3177 break;
3178 case 2:
3179 // Usually ScopedUIResource are deleted from the manager in their
3180 // destructor. Here we just want to test that a direct call to
3181 // DeleteUIResource works.
3182 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3183 PostSetNeedsCommitToMainThread();
3184 break;
3185 case 3:
3186 // DeleteUIResource can be called with an invalid id.
3187 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3188 PostSetNeedsCommitToMainThread();
3189 break;
3190 case 4:
3191 CreateResource();
3192 CreateResource();
3193 PostSetNeedsCommitToMainThread();
3194 break;
3195 case 5:
3196 ClearResources();
3197 EndTest();
3198 break;
3199 }
3200 }
3201
3202 void PerformTest(LayerTreeHostImpl* impl) {
3203 TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
3204 impl->output_surface()->context3d());
3205
3206 int frame = num_commits_;
3207 switch (frame) {
3208 case 1:
3209 ASSERT_EQ(0u, context->NumTextures());
3210 break;
3211 case 2:
3212 // Created two textures.
3213 ASSERT_EQ(2u, context->NumTextures());
3214 break;
3215 case 3:
3216 // One texture left after one deletion.
3217 ASSERT_EQ(1u, context->NumTextures());
3218 break;
3219 case 4:
3220 // Resource manager state should not change when delete is called on an
3221 // invalid id.
3222 ASSERT_EQ(1u, context->NumTextures());
3223 break;
3224 case 5:
3225 // Creation after deletion: two more creates should total up to
3226 // three textures.
3227 ASSERT_EQ(3u, context->NumTextures());
3228 break;
3229 }
3230 }
3231
3232 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3233 ++num_commits_;
3234 if (!layer_tree_host()->settings().impl_side_painting)
3235 PerformTest(impl);
3236 }
3237
3238 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3239 if (layer_tree_host()->settings().impl_side_painting)
3240 PerformTest(impl);
3241 }
3242
3243 virtual void AfterTest() OVERRIDE {}
3244
3245 private:
3246 // Must clear all resources before exiting.
3247 void ClearResources() {
3248 for (int i = 0; i < num_ui_resources_; i++)
3249 ui_resources_[i].reset();
3250 }
3251
3252 void CreateResource() {
3253 ui_resources_[num_ui_resources_++] =
3254 FakeScopedUIResource::Create(layer_tree_host());
3255 }
3256
3257 scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3258 int num_ui_resources_;
3259 int num_commits_;
3260};
3261
3262MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3263
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003264class PushPropertiesCountingLayer : public Layer {
3265 public:
3266 static scoped_refptr<PushPropertiesCountingLayer> Create() {
3267 return new PushPropertiesCountingLayer();
3268 }
3269
3270 virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3271 Layer::PushPropertiesTo(layer);
3272 push_properties_count_++;
3273 if (persist_needs_push_properties_)
3274 needs_push_properties_ = true;
3275 }
3276
3277 size_t push_properties_count() const { return push_properties_count_; }
3278 void reset_push_properties_count() { push_properties_count_ = 0; }
3279
3280 void set_persist_needs_push_properties(bool persist) {
3281 persist_needs_push_properties_ = persist;
3282 }
3283
3284 private:
3285 PushPropertiesCountingLayer()
3286 : push_properties_count_(0),
3287 persist_needs_push_properties_(false) {
3288 SetAnchorPoint(gfx::PointF());
3289 SetBounds(gfx::Size(1, 1));
3290 SetIsDrawable(true);
3291 }
3292 virtual ~PushPropertiesCountingLayer() {}
3293
3294 size_t push_properties_count_;
3295 bool persist_needs_push_properties_;
3296};
3297
3298class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3299 protected:
3300 virtual void BeginTest() OVERRIDE {
3301 num_commits_ = 0;
3302 expected_push_properties_root_ = 0;
3303 expected_push_properties_child_ = 0;
3304 expected_push_properties_grandchild_ = 0;
3305 expected_push_properties_child2_ = 0;
3306 expected_push_properties_other_root_ = 0;
3307 expected_push_properties_leaf_layer_ = 0;
3308 PostSetNeedsCommitToMainThread();
3309 }
3310
3311 virtual void SetupTree() OVERRIDE {
3312 root_ = PushPropertiesCountingLayer::Create();
3313 child_ = PushPropertiesCountingLayer::Create();
3314 child2_ = PushPropertiesCountingLayer::Create();
3315 grandchild_ = PushPropertiesCountingLayer::Create();
Ben Murdochbb1529c2013-08-08 10:24:53 +01003316
3317 if (layer_tree_host()->settings().impl_side_painting)
3318 leaf_picture_layer_ = FakePictureLayer::Create(&client_);
3319 else
3320 leaf_content_layer_ = FakeContentLayer::Create(&client_);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003321
3322 root_->AddChild(child_);
3323 root_->AddChild(child2_);
3324 child_->AddChild(grandchild_);
Ben Murdochbb1529c2013-08-08 10:24:53 +01003325 if (leaf_picture_layer_)
3326 child2_->AddChild(leaf_picture_layer_);
3327 if (leaf_content_layer_)
3328 child2_->AddChild(leaf_content_layer_);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003329
3330 other_root_ = PushPropertiesCountingLayer::Create();
3331
3332 // Don't set the root layer here.
3333 LayerTreeHostTest::SetupTree();
3334 }
3335
3336 virtual void DidCommitAndDrawFrame() OVERRIDE {
3337 ++num_commits_;
3338
3339 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3340 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3341 EXPECT_EQ(expected_push_properties_grandchild_,
3342 grandchild_->push_properties_count());
3343 EXPECT_EQ(expected_push_properties_child2_,
3344 child2_->push_properties_count());
3345 EXPECT_EQ(expected_push_properties_other_root_,
3346 other_root_->push_properties_count());
Ben Murdochbb1529c2013-08-08 10:24:53 +01003347 if (leaf_content_layer_) {
3348 EXPECT_EQ(expected_push_properties_leaf_layer_,
3349 leaf_content_layer_->push_properties_count());
3350 }
3351 if (leaf_picture_layer_) {
3352 EXPECT_EQ(expected_push_properties_leaf_layer_,
3353 leaf_picture_layer_->push_properties_count());
3354 }
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003355
Ben Murdochbb1529c2013-08-08 10:24:53 +01003356 // The content/picture layer always needs to be pushed.
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003357 if (root_->layer_tree_host()) {
3358 EXPECT_TRUE(root_->descendant_needs_push_properties());
3359 EXPECT_FALSE(root_->needs_push_properties());
3360 }
3361 if (child2_->layer_tree_host()) {
3362 EXPECT_TRUE(child2_->descendant_needs_push_properties());
3363 EXPECT_FALSE(child2_->needs_push_properties());
3364 }
Ben Murdochbb1529c2013-08-08 10:24:53 +01003365 if (leaf_content_layer_.get() && leaf_content_layer_->layer_tree_host()) {
3366 EXPECT_FALSE(leaf_content_layer_->descendant_needs_push_properties());
3367 EXPECT_TRUE(leaf_content_layer_->needs_push_properties());
3368 }
3369 if (leaf_picture_layer_.get() && leaf_picture_layer_->layer_tree_host()) {
3370 EXPECT_FALSE(leaf_picture_layer_->descendant_needs_push_properties());
3371 EXPECT_TRUE(leaf_picture_layer_->needs_push_properties());
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003372 }
3373
3374 // child_ and grandchild_ don't persist their need to push properties.
3375 if (child_->layer_tree_host()) {
3376 EXPECT_FALSE(child_->descendant_needs_push_properties());
3377 EXPECT_FALSE(child_->needs_push_properties());
3378 }
3379 if (grandchild_->layer_tree_host()) {
3380 EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3381 EXPECT_FALSE(grandchild_->needs_push_properties());
3382 }
3383
3384 if (other_root_->layer_tree_host()) {
3385 EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3386 EXPECT_FALSE(other_root_->needs_push_properties());
3387 }
3388
3389 switch (num_commits_) {
3390 case 1:
3391 layer_tree_host()->SetRootLayer(root_);
3392 // Layers added to the tree get committed.
3393 ++expected_push_properties_root_;
3394 ++expected_push_properties_child_;
3395 ++expected_push_properties_grandchild_;
3396 ++expected_push_properties_child2_;
3397 break;
3398 case 2:
3399 layer_tree_host()->SetNeedsCommit();
3400 // No layers need commit.
3401 break;
3402 case 3:
3403 layer_tree_host()->SetRootLayer(other_root_);
3404 // Layers added to the tree get committed.
3405 ++expected_push_properties_other_root_;
3406 break;
3407 case 4:
3408 layer_tree_host()->SetRootLayer(root_);
3409 // Layers added to the tree get committed.
3410 ++expected_push_properties_root_;
3411 ++expected_push_properties_child_;
3412 ++expected_push_properties_grandchild_;
3413 ++expected_push_properties_child2_;
3414 break;
3415 case 5:
3416 layer_tree_host()->SetNeedsCommit();
3417 // No layers need commit.
3418 break;
3419 case 6:
3420 child_->RemoveFromParent();
3421 // No layers need commit.
3422 break;
3423 case 7:
3424 root_->AddChild(child_);
3425 // Layers added to the tree get committed.
3426 ++expected_push_properties_child_;
3427 ++expected_push_properties_grandchild_;
3428 break;
3429 case 8:
3430 grandchild_->RemoveFromParent();
3431 // No layers need commit.
3432 break;
3433 case 9:
3434 child_->AddChild(grandchild_);
3435 // Layers added to the tree get committed.
3436 ++expected_push_properties_grandchild_;
3437 break;
3438 case 10:
3439 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3440 // No layers need commit.
3441 break;
3442 case 11:
3443 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3444 // No layers need commit.
3445 break;
3446 case 12:
3447 child_->SetPosition(gfx::Point(1, 1));
3448 // The modified layer needs commit
3449 ++expected_push_properties_child_;
3450 break;
3451 case 13:
3452 child2_->SetPosition(gfx::Point(1, 1));
3453 // The modified layer needs commit
3454 ++expected_push_properties_child2_;
3455 break;
3456 case 14:
3457 child_->RemoveFromParent();
3458 root_->AddChild(child_);
3459 // Layers added to the tree get committed.
3460 ++expected_push_properties_child_;
3461 ++expected_push_properties_grandchild_;
3462 break;
3463 case 15:
3464 grandchild_->SetPosition(gfx::Point(1, 1));
3465 // The modified layer needs commit
3466 ++expected_push_properties_grandchild_;
3467 break;
3468 case 16:
Ben Murdoch558790d2013-07-30 15:19:42 +01003469 // SetNeedsDisplay does not always set needs commit (so call it
3470 // explicitly), but is a property change.
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003471 child_->SetNeedsDisplay();
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003472 ++expected_push_properties_child_;
Ben Murdoch558790d2013-07-30 15:19:42 +01003473 layer_tree_host()->SetNeedsCommit();
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003474 break;
3475 case 17:
3476 EndTest();
3477 break;
3478 }
3479
3480 // Content/Picture layers require PushProperties every commit that they are
3481 // in the tree.
Ben Murdochbb1529c2013-08-08 10:24:53 +01003482 if ((leaf_content_layer_.get() && leaf_content_layer_->layer_tree_host()) ||
3483 (leaf_picture_layer_.get() && leaf_picture_layer_->layer_tree_host()))
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003484 ++expected_push_properties_leaf_layer_;
3485 }
3486
3487 virtual void AfterTest() OVERRIDE {}
3488
3489 int num_commits_;
3490 FakeContentLayerClient client_;
3491 scoped_refptr<PushPropertiesCountingLayer> root_;
3492 scoped_refptr<PushPropertiesCountingLayer> child_;
3493 scoped_refptr<PushPropertiesCountingLayer> child2_;
3494 scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3495 scoped_refptr<PushPropertiesCountingLayer> other_root_;
Ben Murdochbb1529c2013-08-08 10:24:53 +01003496 scoped_refptr<FakeContentLayer> leaf_content_layer_;
3497 scoped_refptr<FakePictureLayer> leaf_picture_layer_;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003498 size_t expected_push_properties_root_;
3499 size_t expected_push_properties_child_;
3500 size_t expected_push_properties_child2_;
3501 size_t expected_push_properties_grandchild_;
3502 size_t expected_push_properties_other_root_;
3503 size_t expected_push_properties_leaf_layer_;
3504};
3505
3506MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3507
3508class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3509 : public LayerTreeHostTest {
3510 protected:
3511 virtual void BeginTest() OVERRIDE {
3512 PostSetNeedsCommitToMainThread();
3513 }
3514
3515 virtual void SetupTree() OVERRIDE {
3516 root_ = Layer::Create();
3517 root_->SetBounds(gfx::Size(1, 1));
3518
3519 bool paint_scrollbar = true;
3520 bool has_thumb = false;
3521 scrollbar_layer_ =
3522 FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, root_->id());
3523
3524 root_->AddChild(scrollbar_layer_);
3525
3526 layer_tree_host()->SetRootLayer(root_);
3527 LayerTreeHostTest::SetupTree();
3528 }
3529
3530 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003531 switch (layer_tree_host()->source_frame_number()) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003532 case 0:
3533 break;
3534 case 1: {
3535 // During update, the ignore_set_needs_commit_ bit is set to true to
3536 // avoid causing a second commit to be scheduled. If a property change
3537 // is made during this, however, it needs to be pushed in the upcoming
3538 // commit.
3539 scoped_ptr<base::AutoReset<bool> > ignore =
3540 scrollbar_layer_->IgnoreSetNeedsCommit();
3541
3542 scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3543
3544 EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3545 EXPECT_TRUE(root_->descendant_needs_push_properties());
3546 layer_tree_host()->SetNeedsCommit();
3547
3548 scrollbar_layer_->reset_push_properties_count();
3549 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3550 break;
3551 }
3552 case 2:
3553 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3554 EndTest();
3555 break;
3556 }
3557 }
3558
3559 virtual void AfterTest() OVERRIDE {}
3560
3561 scoped_refptr<Layer> root_;
3562 scoped_refptr<FakeScrollbarLayer> scrollbar_layer_;
3563};
3564
3565MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3566
3567class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3568 : public LayerTreeHostTest {
3569 protected:
3570 virtual void BeginTest() OVERRIDE {
3571 expected_push_properties_root_ = 0;
3572 expected_push_properties_child_ = 0;
3573 expected_push_properties_grandchild1_ = 0;
3574 expected_push_properties_grandchild2_ = 0;
3575 expected_push_properties_grandchild3_ = 0;
3576 PostSetNeedsCommitToMainThread();
3577 }
3578
3579 virtual void SetupTree() OVERRIDE {
3580 root_ = PushPropertiesCountingLayer::Create();
3581 child_ = PushPropertiesCountingLayer::Create();
3582 grandchild1_ = PushPropertiesCountingLayer::Create();
3583 grandchild2_ = PushPropertiesCountingLayer::Create();
3584 grandchild3_ = PushPropertiesCountingLayer::Create();
3585
3586 root_->AddChild(child_);
3587 child_->AddChild(grandchild1_);
3588 child_->AddChild(grandchild2_);
3589 child_->AddChild(grandchild3_);
3590
3591 // Don't set the root layer here.
3592 LayerTreeHostTest::SetupTree();
3593 }
3594
3595 virtual void AfterTest() OVERRIDE {}
3596
3597 FakeContentLayerClient client_;
3598 scoped_refptr<PushPropertiesCountingLayer> root_;
3599 scoped_refptr<PushPropertiesCountingLayer> child_;
3600 scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3601 scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3602 scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3603 size_t expected_push_properties_root_;
3604 size_t expected_push_properties_child_;
3605 size_t expected_push_properties_grandchild1_;
3606 size_t expected_push_properties_grandchild2_;
3607 size_t expected_push_properties_grandchild3_;
3608};
3609
3610class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3611 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3612 protected:
3613 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003614 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003615 switch (last_source_frame_number) {
3616 case 0:
3617 EXPECT_FALSE(root_->needs_push_properties());
3618 EXPECT_FALSE(root_->descendant_needs_push_properties());
3619 EXPECT_FALSE(child_->needs_push_properties());
3620 EXPECT_FALSE(child_->descendant_needs_push_properties());
3621 EXPECT_FALSE(grandchild1_->needs_push_properties());
3622 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3623 EXPECT_FALSE(grandchild2_->needs_push_properties());
3624 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3625 EXPECT_FALSE(grandchild3_->needs_push_properties());
3626 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3627
3628 layer_tree_host()->SetRootLayer(root_);
3629
3630 EXPECT_TRUE(root_->needs_push_properties());
3631 EXPECT_TRUE(root_->descendant_needs_push_properties());
3632 EXPECT_TRUE(child_->needs_push_properties());
3633 EXPECT_TRUE(child_->descendant_needs_push_properties());
3634 EXPECT_TRUE(grandchild1_->needs_push_properties());
3635 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3636 EXPECT_TRUE(grandchild2_->needs_push_properties());
3637 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3638 EXPECT_TRUE(grandchild3_->needs_push_properties());
3639 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3640 break;
3641 case 1:
3642 EndTest();
3643 break;
3644 }
3645 }
3646};
3647
3648MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3649
3650class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3651 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3652 protected:
3653 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003654 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003655 switch (last_source_frame_number) {
3656 case 0:
3657 layer_tree_host()->SetRootLayer(root_);
3658 break;
3659 case 1:
3660 EXPECT_FALSE(root_->needs_push_properties());
3661 EXPECT_FALSE(root_->descendant_needs_push_properties());
3662 EXPECT_FALSE(child_->needs_push_properties());
3663 EXPECT_FALSE(child_->descendant_needs_push_properties());
3664 EXPECT_FALSE(grandchild1_->needs_push_properties());
3665 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3666 EXPECT_FALSE(grandchild2_->needs_push_properties());
3667 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3668 EXPECT_FALSE(grandchild3_->needs_push_properties());
3669 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3670
3671 grandchild1_->RemoveFromParent();
3672 grandchild1_->SetPosition(gfx::Point(1, 1));
3673
3674 EXPECT_FALSE(root_->needs_push_properties());
3675 EXPECT_FALSE(root_->descendant_needs_push_properties());
3676 EXPECT_FALSE(child_->needs_push_properties());
3677 EXPECT_FALSE(child_->descendant_needs_push_properties());
3678 EXPECT_FALSE(grandchild2_->needs_push_properties());
3679 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3680 EXPECT_FALSE(grandchild3_->needs_push_properties());
3681 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3682
3683 child_->AddChild(grandchild1_);
3684
3685 EXPECT_FALSE(root_->needs_push_properties());
3686 EXPECT_TRUE(root_->descendant_needs_push_properties());
3687 EXPECT_FALSE(child_->needs_push_properties());
3688 EXPECT_TRUE(child_->descendant_needs_push_properties());
3689 EXPECT_TRUE(grandchild1_->needs_push_properties());
3690 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3691 EXPECT_FALSE(grandchild2_->needs_push_properties());
3692 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3693 EXPECT_FALSE(grandchild3_->needs_push_properties());
3694 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3695
3696 grandchild2_->SetPosition(gfx::Point(1, 1));
3697
3698 EXPECT_FALSE(root_->needs_push_properties());
3699 EXPECT_TRUE(root_->descendant_needs_push_properties());
3700 EXPECT_FALSE(child_->needs_push_properties());
3701 EXPECT_TRUE(child_->descendant_needs_push_properties());
3702 EXPECT_TRUE(grandchild1_->needs_push_properties());
3703 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3704 EXPECT_TRUE(grandchild2_->needs_push_properties());
3705 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3706 EXPECT_FALSE(grandchild3_->needs_push_properties());
3707 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3708
3709 // grandchild2_ will still need a push properties.
3710 grandchild1_->RemoveFromParent();
3711
3712 EXPECT_FALSE(root_->needs_push_properties());
3713 EXPECT_TRUE(root_->descendant_needs_push_properties());
3714 EXPECT_FALSE(child_->needs_push_properties());
3715 EXPECT_TRUE(child_->descendant_needs_push_properties());
3716
3717 // grandchild3_ does not need a push properties, so recursing should
3718 // no longer be needed.
3719 grandchild2_->RemoveFromParent();
3720
3721 EXPECT_FALSE(root_->needs_push_properties());
3722 EXPECT_FALSE(root_->descendant_needs_push_properties());
3723 EXPECT_FALSE(child_->needs_push_properties());
3724 EXPECT_FALSE(child_->descendant_needs_push_properties());
3725 EndTest();
3726 break;
3727 }
3728 }
3729};
3730
3731MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3732
3733class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3734 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3735 protected:
3736 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003737 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003738 switch (last_source_frame_number) {
3739 case 0:
3740 layer_tree_host()->SetRootLayer(root_);
3741 grandchild1_->set_persist_needs_push_properties(true);
3742 grandchild2_->set_persist_needs_push_properties(true);
3743 break;
3744 case 1:
3745 EXPECT_FALSE(root_->needs_push_properties());
3746 EXPECT_TRUE(root_->descendant_needs_push_properties());
3747 EXPECT_FALSE(child_->needs_push_properties());
3748 EXPECT_TRUE(child_->descendant_needs_push_properties());
3749 EXPECT_TRUE(grandchild1_->needs_push_properties());
3750 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3751 EXPECT_TRUE(grandchild2_->needs_push_properties());
3752 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3753 EXPECT_FALSE(grandchild3_->needs_push_properties());
3754 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3755
3756 // grandchild2_ will still need a push properties.
3757 grandchild1_->RemoveFromParent();
3758
3759 EXPECT_FALSE(root_->needs_push_properties());
3760 EXPECT_TRUE(root_->descendant_needs_push_properties());
3761 EXPECT_FALSE(child_->needs_push_properties());
3762 EXPECT_TRUE(child_->descendant_needs_push_properties());
3763
3764 // grandchild3_ does not need a push properties, so recursing should
3765 // no longer be needed.
3766 grandchild2_->RemoveFromParent();
3767
3768 EXPECT_FALSE(root_->needs_push_properties());
3769 EXPECT_FALSE(root_->descendant_needs_push_properties());
3770 EXPECT_FALSE(child_->needs_push_properties());
3771 EXPECT_FALSE(child_->descendant_needs_push_properties());
3772 EndTest();
3773 break;
3774 }
3775 }
3776};
3777
3778MULTI_THREAD_TEST_F(
3779 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3780
3781class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3782 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3783 protected:
3784 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003785 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003786 switch (last_source_frame_number) {
3787 case 0:
3788 layer_tree_host()->SetRootLayer(root_);
3789 break;
3790 case 1:
3791 EXPECT_FALSE(root_->needs_push_properties());
3792 EXPECT_FALSE(root_->descendant_needs_push_properties());
3793 EXPECT_FALSE(child_->needs_push_properties());
3794 EXPECT_FALSE(child_->descendant_needs_push_properties());
3795 EXPECT_FALSE(grandchild1_->needs_push_properties());
3796 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3797 EXPECT_FALSE(grandchild2_->needs_push_properties());
3798 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3799 EXPECT_FALSE(grandchild3_->needs_push_properties());
3800 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3801
3802 // Change grandchildren while their parent is not in the tree.
3803 child_->RemoveFromParent();
3804 grandchild1_->SetPosition(gfx::Point(1, 1));
3805 grandchild2_->SetPosition(gfx::Point(1, 1));
3806 root_->AddChild(child_);
3807
3808 EXPECT_FALSE(root_->needs_push_properties());
3809 EXPECT_TRUE(root_->descendant_needs_push_properties());
3810 EXPECT_TRUE(child_->needs_push_properties());
3811 EXPECT_TRUE(child_->descendant_needs_push_properties());
3812 EXPECT_TRUE(grandchild1_->needs_push_properties());
3813 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3814 EXPECT_TRUE(grandchild2_->needs_push_properties());
3815 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3816 EXPECT_TRUE(grandchild3_->needs_push_properties());
3817 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3818
3819 grandchild1_->RemoveFromParent();
3820
3821 EXPECT_FALSE(root_->needs_push_properties());
3822 EXPECT_TRUE(root_->descendant_needs_push_properties());
3823 EXPECT_TRUE(child_->needs_push_properties());
3824 EXPECT_TRUE(child_->descendant_needs_push_properties());
3825
3826 grandchild2_->RemoveFromParent();
3827
3828 EXPECT_FALSE(root_->needs_push_properties());
3829 EXPECT_TRUE(root_->descendant_needs_push_properties());
3830 EXPECT_TRUE(child_->needs_push_properties());
3831 EXPECT_TRUE(child_->descendant_needs_push_properties());
3832
3833 grandchild3_->RemoveFromParent();
3834
3835 EXPECT_FALSE(root_->needs_push_properties());
3836 EXPECT_TRUE(root_->descendant_needs_push_properties());
3837 EXPECT_TRUE(child_->needs_push_properties());
3838 EXPECT_FALSE(child_->descendant_needs_push_properties());
3839
3840 EndTest();
3841 break;
3842 }
3843 }
3844};
3845
3846MULTI_THREAD_TEST_F(
3847 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3848
3849class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3850 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3851 protected:
3852 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003853 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003854 switch (last_source_frame_number) {
3855 case 0:
3856 layer_tree_host()->SetRootLayer(root_);
3857 break;
3858 case 1:
3859 EXPECT_FALSE(root_->needs_push_properties());
3860 EXPECT_FALSE(root_->descendant_needs_push_properties());
3861 EXPECT_FALSE(child_->needs_push_properties());
3862 EXPECT_FALSE(child_->descendant_needs_push_properties());
3863 EXPECT_FALSE(grandchild1_->needs_push_properties());
3864 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3865 EXPECT_FALSE(grandchild2_->needs_push_properties());
3866 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3867 EXPECT_FALSE(grandchild3_->needs_push_properties());
3868 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3869
3870 child_->SetPosition(gfx::Point(1, 1));
3871 grandchild1_->SetPosition(gfx::Point(1, 1));
3872 grandchild2_->SetPosition(gfx::Point(1, 1));
3873
3874 EXPECT_FALSE(root_->needs_push_properties());
3875 EXPECT_TRUE(root_->descendant_needs_push_properties());
3876 EXPECT_TRUE(child_->needs_push_properties());
3877 EXPECT_TRUE(child_->descendant_needs_push_properties());
3878 EXPECT_TRUE(grandchild1_->needs_push_properties());
3879 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3880 EXPECT_TRUE(grandchild2_->needs_push_properties());
3881 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3882 EXPECT_FALSE(grandchild3_->needs_push_properties());
3883 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3884
3885 grandchild1_->RemoveFromParent();
3886
3887 EXPECT_FALSE(root_->needs_push_properties());
3888 EXPECT_TRUE(root_->descendant_needs_push_properties());
3889 EXPECT_TRUE(child_->needs_push_properties());
3890 EXPECT_TRUE(child_->descendant_needs_push_properties());
3891
3892 grandchild2_->RemoveFromParent();
3893
3894 EXPECT_FALSE(root_->needs_push_properties());
3895 EXPECT_TRUE(root_->descendant_needs_push_properties());
3896 EXPECT_TRUE(child_->needs_push_properties());
3897 EXPECT_FALSE(child_->descendant_needs_push_properties());
3898
3899 child_->RemoveFromParent();
3900
3901 EXPECT_FALSE(root_->needs_push_properties());
3902 EXPECT_FALSE(root_->descendant_needs_push_properties());
3903
3904 EndTest();
3905 break;
3906 }
3907 }
3908};
3909
3910MULTI_THREAD_TEST_F(
3911 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3912
3913class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3914 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3915 protected:
3916 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdochbbcdd452013-07-25 10:06:34 +01003917 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01003918 switch (last_source_frame_number) {
3919 case 0:
3920 layer_tree_host()->SetRootLayer(root_);
3921 break;
3922 case 1:
3923 EXPECT_FALSE(root_->needs_push_properties());
3924 EXPECT_FALSE(root_->descendant_needs_push_properties());
3925 EXPECT_FALSE(child_->needs_push_properties());
3926 EXPECT_FALSE(child_->descendant_needs_push_properties());
3927 EXPECT_FALSE(grandchild1_->needs_push_properties());
3928 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3929 EXPECT_FALSE(grandchild2_->needs_push_properties());
3930 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3931 EXPECT_FALSE(grandchild3_->needs_push_properties());
3932 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3933
3934 grandchild1_->SetPosition(gfx::Point(1, 1));
3935 grandchild2_->SetPosition(gfx::Point(1, 1));
3936 child_->SetPosition(gfx::Point(1, 1));
3937
3938 EXPECT_FALSE(root_->needs_push_properties());
3939 EXPECT_TRUE(root_->descendant_needs_push_properties());
3940 EXPECT_TRUE(child_->needs_push_properties());
3941 EXPECT_TRUE(child_->descendant_needs_push_properties());
3942 EXPECT_TRUE(grandchild1_->needs_push_properties());
3943 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3944 EXPECT_TRUE(grandchild2_->needs_push_properties());
3945 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3946 EXPECT_FALSE(grandchild3_->needs_push_properties());
3947 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3948
3949 grandchild1_->RemoveFromParent();
3950
3951 EXPECT_FALSE(root_->needs_push_properties());
3952 EXPECT_TRUE(root_->descendant_needs_push_properties());
3953 EXPECT_TRUE(child_->needs_push_properties());
3954 EXPECT_TRUE(child_->descendant_needs_push_properties());
3955
3956 grandchild2_->RemoveFromParent();
3957
3958 EXPECT_FALSE(root_->needs_push_properties());
3959 EXPECT_TRUE(root_->descendant_needs_push_properties());
3960 EXPECT_TRUE(child_->needs_push_properties());
3961 EXPECT_FALSE(child_->descendant_needs_push_properties());
3962
3963 child_->RemoveFromParent();
3964
3965 EXPECT_FALSE(root_->needs_push_properties());
3966 EXPECT_FALSE(root_->descendant_needs_push_properties());
3967
3968 EndTest();
3969 break;
3970 }
3971 }
3972};
3973
3974MULTI_THREAD_TEST_F(
3975 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3976
Ben Murdochca12bfa2013-07-23 11:17:05 +01003977// This test verifies that the tree activation callback is invoked correctly.
3978class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3979 public:
3980 LayerTreeHostTestTreeActivationCallback()
3981 : num_commits_(0), callback_count_(0) {}
3982
3983 virtual void BeginTest() OVERRIDE {
3984 EXPECT_TRUE(HasImplThread());
3985 PostSetNeedsCommitToMainThread();
3986 }
3987
3988 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3989 LayerTreeHostImpl::FrameData* frame_data,
3990 bool result) OVERRIDE {
3991 ++num_commits_;
3992 switch (num_commits_) {
3993 case 1:
3994 EXPECT_EQ(0, callback_count_);
3995 callback_count_ = 0;
3996 SetCallback(true);
3997 PostSetNeedsCommitToMainThread();
3998 break;
3999 case 2:
4000 EXPECT_EQ(1, callback_count_);
4001 callback_count_ = 0;
4002 SetCallback(false);
4003 PostSetNeedsCommitToMainThread();
4004 break;
4005 case 3:
4006 EXPECT_EQ(0, callback_count_);
4007 callback_count_ = 0;
4008 EndTest();
4009 break;
4010 default:
4011 ADD_FAILURE() << num_commits_;
4012 EndTest();
4013 break;
4014 }
4015 return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
4016 result);
4017 }
4018
4019 virtual void AfterTest() OVERRIDE {
4020 EXPECT_EQ(3, num_commits_);
4021 }
4022
4023 void SetCallback(bool enable) {
4024 output_surface()->SetTreeActivationCallback(enable ?
4025 base::Bind(&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4026 base::Unretained(this)) :
4027 base::Closure());
4028 }
4029
4030 void ActivationCallback() {
4031 ++callback_count_;
4032 }
4033
4034 int num_commits_;
4035 int callback_count_;
4036};
4037
4038TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4039 RunTest(true, false, true);
4040}
4041
4042TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4043 RunTest(true, true, true);
4044}
4045
Ben Murdoch2385ea32013-08-06 11:01:04 +01004046class LayerInvalidateCausesDraw : public LayerTreeHostTest {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004047 public:
Ben Murdoch2385ea32013-08-06 11:01:04 +01004048 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004049
4050 virtual void BeginTest() OVERRIDE {
Ben Murdoch2385ea32013-08-06 11:01:04 +01004051 ASSERT_TRUE(!!invalidate_layer_)
4052 << "Derived tests must set this in SetupTree";
4053
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004054 // One initial commit.
4055 PostSetNeedsCommitToMainThread();
4056 }
4057
4058 virtual void DidCommitAndDrawFrame() OVERRIDE {
Ben Murdoch2385ea32013-08-06 11:01:04 +01004059 // After commit, invalidate the layer. This should cause a commit.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004060 if (layer_tree_host()->source_frame_number() == 1)
Ben Murdoch2385ea32013-08-06 11:01:04 +01004061 invalidate_layer_->SetNeedsDisplay();
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004062 }
4063
4064 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4065 num_draws_++;
4066 if (impl->active_tree()->source_frame_number() == 1)
4067 EndTest();
4068 }
4069
4070 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4071 num_commits_++;
4072 }
4073
4074 virtual void AfterTest() OVERRIDE {
4075 EXPECT_GE(2, num_commits_);
4076 EXPECT_GE(2, num_draws_);
4077 }
4078
Ben Murdoch2385ea32013-08-06 11:01:04 +01004079 protected:
4080 scoped_refptr<Layer> invalidate_layer_;
4081
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004082 private:
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004083 int num_commits_;
4084 int num_draws_;
4085};
4086
Ben Murdoch2385ea32013-08-06 11:01:04 +01004087// VideoLayer must support being invalidated and then passing that along
4088// to the compositor thread, even though no resources are updated in
4089// response to that invalidation.
4090class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4091 public:
4092 virtual void SetupTree() OVERRIDE {
4093 LayerTreeHostTest::SetupTree();
4094 scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
4095 video_layer->SetBounds(gfx::Size(10, 10));
4096 video_layer->SetIsDrawable(true);
4097 layer_tree_host()->root_layer()->AddChild(video_layer);
4098
4099 invalidate_layer_ = video_layer;
4100 }
4101
4102 private:
4103 FakeVideoFrameProvider provider_;
4104};
4105
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004106SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4107
Ben Murdoch2385ea32013-08-06 11:01:04 +01004108// IOSurfaceLayer must support being invalidated and then passing that along
4109// to the compositor thread, even though no resources are updated in
4110// response to that invalidation.
4111class LayerTreeHostTestIOSurfaceLayerInvalidate
4112 : public LayerInvalidateCausesDraw {
4113 public:
4114 virtual void SetupTree() OVERRIDE {
4115 LayerTreeHostTest::SetupTree();
4116 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4117 layer->SetBounds(gfx::Size(10, 10));
4118 uint32_t fake_io_surface_id = 7;
4119 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4120 layer->SetIsDrawable(true);
4121 layer_tree_host()->root_layer()->AddChild(layer);
4122
4123 invalidate_layer_ = layer;
4124 }
4125};
4126
4127// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4128SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4129 LayerTreeHostTestIOSurfaceLayerInvalidate);
4130
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01004131class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4132 protected:
4133 virtual void SetupTree() OVERRIDE {
4134 root_layer_ = Layer::Create();
4135 root_layer_->SetAnchorPoint(gfx::PointF());
4136 root_layer_->SetPosition(gfx::Point());
4137 root_layer_->SetBounds(gfx::Size(10, 10));
4138
4139 parent_layer_ = SolidColorLayer::Create();
4140 parent_layer_->SetAnchorPoint(gfx::PointF());
4141 parent_layer_->SetPosition(gfx::Point());
4142 parent_layer_->SetBounds(gfx::Size(10, 10));
4143 parent_layer_->SetIsDrawable(true);
4144 root_layer_->AddChild(parent_layer_);
4145
4146 child_layer_ = SolidColorLayer::Create();
4147 child_layer_->SetAnchorPoint(gfx::PointF());
4148 child_layer_->SetPosition(gfx::Point());
4149 child_layer_->SetBounds(gfx::Size(10, 10));
4150 child_layer_->SetIsDrawable(true);
4151 parent_layer_->AddChild(child_layer_);
4152
4153 layer_tree_host()->SetRootLayer(root_layer_);
4154 LayerTreeHostTest::SetupTree();
4155 }
4156
4157 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4158
4159 virtual void DidCommitAndDrawFrame() OVERRIDE {
4160 switch (layer_tree_host()->source_frame_number()) {
4161 case 1:
4162 // The layer type used does not need to push properties every frame.
4163 EXPECT_FALSE(child_layer_->needs_push_properties());
4164
4165 // Change the bounds of the child layer, but make it skipped
4166 // by CalculateDrawProperties.
4167 parent_layer_->SetOpacity(0.f);
4168 child_layer_->SetBounds(gfx::Size(5, 5));
4169 break;
4170 case 2:
4171 // The bounds of the child layer were pushed to the impl side.
4172 EXPECT_FALSE(child_layer_->needs_push_properties());
4173
4174 EndTest();
4175 break;
4176 }
4177 }
4178
4179 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4180 LayerImpl* root = impl->active_tree()->root_layer();
4181 LayerImpl* parent = root->children()[0];
4182 LayerImpl* child = parent->children()[0];
4183
4184 switch (impl->active_tree()->source_frame_number()) {
4185 case 1:
4186 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4187 break;
4188 }
4189 }
4190
4191 virtual void AfterTest() OVERRIDE {}
4192
4193 scoped_refptr<Layer> root_layer_;
4194 scoped_refptr<SolidColorLayer> parent_layer_;
4195 scoped_refptr<SolidColorLayer> child_layer_;
4196};
4197
4198SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4199
4200class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4201 protected:
4202 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4203 settings->impl_side_painting = true;
4204 }
4205
4206 virtual void SetupTree() OVERRIDE {
4207 root_layer_ = FakePictureLayer::Create(&client_);
4208 root_layer_->SetAnchorPoint(gfx::PointF());
4209 root_layer_->SetBounds(gfx::Size(10, 10));
4210
4211 layer_tree_host()->SetRootLayer(root_layer_);
4212 LayerTreeHostTest::SetupTree();
4213 }
4214
4215 virtual void BeginTest() OVERRIDE {
4216 // The viewport is empty, but we still need to update layers on the main
4217 // thread.
4218 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4219 PostSetNeedsCommitToMainThread();
4220 }
4221
4222 virtual void DidCommit() OVERRIDE {
4223 // The layer should be updated even though the viewport is empty, so we
4224 // are capable of drawing it on the impl tree.
4225 EXPECT_GT(root_layer_->update_count(), 0u);
4226 EndTest();
4227 }
4228
4229 virtual void AfterTest() OVERRIDE {}
4230
4231 FakeContentLayerClient client_;
4232 scoped_refptr<FakePictureLayer> root_layer_;
4233};
4234
4235MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4236
Ben Murdoch32409262013-08-07 11:04:47 +01004237class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4238 public:
4239 LayerTreeHostTestAbortEvictedTextures()
4240 : num_will_begin_frames_(0), num_impl_commits_(0) {}
4241
4242 protected:
4243 virtual void SetupTree() OVERRIDE {
4244 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4245 root_layer->SetBounds(gfx::Size(200, 200));
4246 root_layer->SetIsDrawable(true);
4247
4248 layer_tree_host()->SetRootLayer(root_layer);
4249 LayerTreeHostTest::SetupTree();
4250 }
4251
4252 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4253
4254 virtual void WillBeginFrame() OVERRIDE {
4255 num_will_begin_frames_++;
4256 switch (num_will_begin_frames_) {
4257 case 2:
4258 // Send a redraw to the compositor thread. This will (wrongly) be
4259 // ignored unless aborting resets the texture state.
4260 layer_tree_host()->SetNeedsRedraw();
4261 break;
4262 }
4263 }
4264
4265 virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4266 num_impl_commits_++;
4267 }
4268
4269 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4270 switch (impl->SourceAnimationFrameNumber()) {
4271 case 1:
4272 // Prevent draws until commit.
4273 impl->active_tree()->SetContentsTexturesPurged();
4274 EXPECT_FALSE(impl->CanDraw());
4275 // Trigger an abortable commit.
4276 impl->SetNeedsCommit();
4277 break;
4278 case 2:
4279 EndTest();
4280 break;
4281 }
4282 }
4283
4284 virtual void AfterTest() OVERRIDE {
4285 // Ensure that the commit was truly aborted.
4286 EXPECT_EQ(2, num_will_begin_frames_);
4287 EXPECT_EQ(1, num_impl_commits_);
4288 }
4289
4290 private:
4291 int num_will_begin_frames_;
4292 int num_impl_commits_;
4293};
4294
4295// Commits can only be aborted when using the thread proxy.
4296MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4297
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004298} // namespace
Ben Murdoch32409262013-08-07 11:04:47 +01004299
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004300} // namespace cc