OLD | NEW |
| (Empty) |
1 // 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 | |
7 #include <algorithm> | |
8 | |
9 #include "base/auto_reset.h" | |
10 #include "base/synchronization/lock.h" | |
11 #include "cc/animation/timing_function.h" | |
12 #include "cc/debug/frame_rate_counter.h" | |
13 #include "cc/layers/content_layer.h" | |
14 #include "cc/layers/content_layer_client.h" | |
15 #include "cc/layers/io_surface_layer.h" | |
16 #include "cc/layers/layer_impl.h" | |
17 #include "cc/layers/painted_scrollbar_layer.h" | |
18 #include "cc/layers/picture_layer.h" | |
19 #include "cc/layers/solid_color_layer.h" | |
20 #include "cc/output/begin_frame_args.h" | |
21 #include "cc/output/compositor_frame_ack.h" | |
22 #include "cc/output/copy_output_request.h" | |
23 #include "cc/output/copy_output_result.h" | |
24 #include "cc/output/output_surface.h" | |
25 #include "cc/output/swap_promise.h" | |
26 #include "cc/quads/draw_quad.h" | |
27 #include "cc/quads/io_surface_draw_quad.h" | |
28 #include "cc/quads/tile_draw_quad.h" | |
29 #include "cc/resources/prioritized_resource.h" | |
30 #include "cc/resources/prioritized_resource_manager.h" | |
31 #include "cc/resources/resource_update_queue.h" | |
32 #include "cc/test/fake_content_layer.h" | |
33 #include "cc/test/fake_content_layer_client.h" | |
34 #include "cc/test/fake_content_layer_impl.h" | |
35 #include "cc/test/fake_layer_tree_host_client.h" | |
36 #include "cc/test/fake_output_surface.h" | |
37 #include "cc/test/fake_painted_scrollbar_layer.h" | |
38 #include "cc/test/fake_picture_layer.h" | |
39 #include "cc/test/fake_picture_layer_impl.h" | |
40 #include "cc/test/fake_picture_pile.h" | |
41 #include "cc/test/fake_proxy.h" | |
42 #include "cc/test/fake_scoped_ui_resource.h" | |
43 #include "cc/test/geometry_test_utils.h" | |
44 #include "cc/test/impl_side_painting_settings.h" | |
45 #include "cc/test/layer_tree_test.h" | |
46 #include "cc/test/test_shared_bitmap_manager.h" | |
47 #include "cc/test/test_web_graphics_context_3d.h" | |
48 #include "cc/trees/layer_tree_host_impl.h" | |
49 #include "cc/trees/layer_tree_impl.h" | |
50 #include "cc/trees/single_thread_proxy.h" | |
51 #include "cc/trees/thread_proxy.h" | |
52 #include "gpu/GLES2/gl2extchromium.h" | |
53 #include "skia/ext/refptr.h" | |
54 #include "testing/gmock/include/gmock/gmock.h" | |
55 #include "third_party/khronos/GLES2/gl2.h" | |
56 #include "third_party/khronos/GLES2/gl2ext.h" | |
57 #include "third_party/skia/include/core/SkPicture.h" | |
58 #include "ui/gfx/frame_time.h" | |
59 #include "ui/gfx/geometry/point_conversions.h" | |
60 #include "ui/gfx/geometry/size_conversions.h" | |
61 #include "ui/gfx/geometry/vector2d_conversions.h" | |
62 | |
63 using testing::_; | |
64 using testing::AnyNumber; | |
65 using testing::AtLeast; | |
66 using testing::Mock; | |
67 | |
68 namespace cc { | |
69 namespace { | |
70 | |
71 class LayerTreeHostTest : public LayerTreeTest { | |
72 public: | |
73 LayerTreeHostTest() : contents_texture_manager_(nullptr) {} | |
74 | |
75 void DidInitializeOutputSurface() override { | |
76 contents_texture_manager_ = layer_tree_host()->contents_texture_manager(); | |
77 } | |
78 | |
79 protected: | |
80 PrioritizedResourceManager* contents_texture_manager_; | |
81 }; | |
82 | |
83 // Test if the LTHI receives ReadyToActivate notifications from the TileManager | |
84 // when no raster tasks get scheduled. | |
85 class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest { | |
86 public: | |
87 LayerTreeHostTestReadyToActivateEmpty() | |
88 : did_notify_ready_to_activate_(false), | |
89 all_tiles_required_for_activation_are_ready_to_draw_(false), | |
90 required_for_activation_count_(0) {} | |
91 | |
92 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
93 | |
94 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
95 const std::vector<PictureLayerImpl*>& layers = | |
96 impl->sync_tree()->picture_layers(); | |
97 required_for_activation_count_ = 0; | |
98 for (const auto& layer : layers) { | |
99 FakePictureLayerImpl* fake_layer = | |
100 static_cast<FakePictureLayerImpl*>(layer); | |
101 required_for_activation_count_ += | |
102 fake_layer->CountTilesRequiredForActivation(); | |
103 } | |
104 } | |
105 | |
106 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { | |
107 did_notify_ready_to_activate_ = true; | |
108 all_tiles_required_for_activation_are_ready_to_draw_ = | |
109 impl->tile_manager()->IsReadyToActivate(); | |
110 EndTest(); | |
111 } | |
112 | |
113 void AfterTest() override { | |
114 EXPECT_TRUE(did_notify_ready_to_activate_); | |
115 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_); | |
116 EXPECT_EQ(size_t(0), required_for_activation_count_); | |
117 } | |
118 | |
119 protected: | |
120 bool did_notify_ready_to_activate_; | |
121 bool all_tiles_required_for_activation_are_ready_to_draw_; | |
122 size_t required_for_activation_count_; | |
123 }; | |
124 | |
125 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty); | |
126 | |
127 // Test if the LTHI receives ReadyToActivate notifications from the TileManager | |
128 // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled. | |
129 class LayerTreeHostTestReadyToActivateNonEmpty | |
130 : public LayerTreeHostTestReadyToActivateEmpty { | |
131 public: | |
132 void SetupTree() override { | |
133 client_.set_fill_with_nonsolid_color(true); | |
134 scoped_refptr<FakePictureLayer> root_layer = | |
135 FakePictureLayer::Create(&client_); | |
136 root_layer->SetBounds(gfx::Size(1024, 1024)); | |
137 root_layer->SetIsDrawable(true); | |
138 | |
139 layer_tree_host()->SetRootLayer(root_layer); | |
140 LayerTreeHostTest::SetupTree(); | |
141 } | |
142 | |
143 void AfterTest() override { | |
144 EXPECT_TRUE(did_notify_ready_to_activate_); | |
145 EXPECT_TRUE(all_tiles_required_for_activation_are_ready_to_draw_); | |
146 EXPECT_LE(size_t(1), required_for_activation_count_); | |
147 } | |
148 | |
149 private: | |
150 FakeContentLayerClient client_; | |
151 }; | |
152 | |
153 // Multi-thread only because in single thread the commit goes directly to the | |
154 // active tree, so notify ready to activate is skipped. | |
155 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); | |
156 | |
157 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when | |
158 // no raster tasks get scheduled. | |
159 class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest { | |
160 public: | |
161 LayerTreeHostTestReadyToDrawEmpty() | |
162 : did_notify_ready_to_draw_(false), | |
163 all_tiles_required_for_draw_are_ready_to_draw_(false), | |
164 required_for_draw_count_(0) {} | |
165 | |
166 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
167 | |
168 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* impl) override { | |
169 did_notify_ready_to_draw_ = true; | |
170 const std::vector<PictureLayerImpl*>& layers = | |
171 impl->active_tree()->picture_layers(); | |
172 all_tiles_required_for_draw_are_ready_to_draw_ = | |
173 impl->tile_manager()->IsReadyToDraw(); | |
174 for (const auto& layer : layers) { | |
175 FakePictureLayerImpl* fake_layer = | |
176 static_cast<FakePictureLayerImpl*>(layer); | |
177 required_for_draw_count_ += fake_layer->CountTilesRequiredForDraw(); | |
178 } | |
179 | |
180 EndTest(); | |
181 } | |
182 | |
183 void AfterTest() override { | |
184 EXPECT_TRUE(did_notify_ready_to_draw_); | |
185 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_); | |
186 EXPECT_EQ(size_t(0), required_for_draw_count_); | |
187 } | |
188 | |
189 protected: | |
190 bool did_notify_ready_to_draw_; | |
191 bool all_tiles_required_for_draw_are_ready_to_draw_; | |
192 size_t required_for_draw_count_; | |
193 }; | |
194 | |
195 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty); | |
196 | |
197 // Test if the LTHI receives ReadyToDraw notifications from the TileManager when | |
198 // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled. | |
199 class LayerTreeHostTestReadyToDrawNonEmpty | |
200 : public LayerTreeHostTestReadyToDrawEmpty { | |
201 public: | |
202 void SetupTree() override { | |
203 client_.set_fill_with_nonsolid_color(true); | |
204 scoped_refptr<FakePictureLayer> root_layer = | |
205 FakePictureLayer::Create(&client_); | |
206 root_layer->SetBounds(gfx::Size(1024, 1024)); | |
207 root_layer->SetIsDrawable(true); | |
208 | |
209 layer_tree_host()->SetRootLayer(root_layer); | |
210 LayerTreeHostTest::SetupTree(); | |
211 } | |
212 | |
213 void AfterTest() override { | |
214 EXPECT_TRUE(did_notify_ready_to_draw_); | |
215 EXPECT_TRUE(all_tiles_required_for_draw_are_ready_to_draw_); | |
216 EXPECT_LE(size_t(1), required_for_draw_count_); | |
217 } | |
218 | |
219 private: | |
220 FakeContentLayerClient client_; | |
221 }; | |
222 | |
223 // Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in | |
224 // single threaded mode. | |
225 SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty); | |
226 | |
227 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 | |
228 // draw with frame 0. | |
229 class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { | |
230 public: | |
231 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {} | |
232 | |
233 void BeginTest() override { | |
234 PostSetNeedsCommitToMainThread(); | |
235 PostSetNeedsCommitToMainThread(); | |
236 } | |
237 | |
238 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
239 num_draws_++; | |
240 if (!impl->active_tree()->source_frame_number()) | |
241 EndTest(); | |
242 } | |
243 | |
244 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
245 num_commits_++; | |
246 } | |
247 | |
248 void AfterTest() override { | |
249 EXPECT_LE(1, num_commits_); | |
250 EXPECT_LE(1, num_draws_); | |
251 } | |
252 | |
253 private: | |
254 int num_commits_; | |
255 int num_draws_; | |
256 }; | |
257 | |
258 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1); | |
259 | |
260 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that | |
261 // first committed frame draws should lead to another commit. | |
262 class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { | |
263 public: | |
264 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {} | |
265 | |
266 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
267 | |
268 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; } | |
269 | |
270 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
271 ++num_commits_; | |
272 switch (num_commits_) { | |
273 case 1: | |
274 PostSetNeedsCommitToMainThread(); | |
275 break; | |
276 case 2: | |
277 EndTest(); | |
278 break; | |
279 default: | |
280 NOTREACHED(); | |
281 } | |
282 } | |
283 | |
284 void AfterTest() override { | |
285 EXPECT_EQ(2, num_commits_); | |
286 EXPECT_LE(1, num_draws_); | |
287 } | |
288 | |
289 private: | |
290 int num_commits_; | |
291 int num_draws_; | |
292 }; | |
293 | |
294 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); | |
295 | |
296 // Verify that we pass property values in PushPropertiesTo. | |
297 class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { | |
298 protected: | |
299 void SetupTree() override { | |
300 scoped_refptr<Layer> root = Layer::Create(); | |
301 root->CreateRenderSurface(); | |
302 root->SetBounds(gfx::Size(10, 10)); | |
303 layer_tree_host()->SetRootLayer(root); | |
304 LayerTreeHostTest::SetupTree(); | |
305 } | |
306 | |
307 enum Properties { | |
308 STARTUP, | |
309 BOUNDS, | |
310 HIDE_LAYER_AND_SUBTREE, | |
311 DRAWS_CONTENT, | |
312 DONE, | |
313 }; | |
314 | |
315 void BeginTest() override { | |
316 index_ = STARTUP; | |
317 PostSetNeedsCommitToMainThread(); | |
318 } | |
319 | |
320 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
321 VerifyAfterValues(impl->active_tree()->root_layer()); | |
322 } | |
323 | |
324 void DidCommitAndDrawFrame() override { | |
325 SetBeforeValues(layer_tree_host()->root_layer()); | |
326 VerifyBeforeValues(layer_tree_host()->root_layer()); | |
327 | |
328 ++index_; | |
329 if (index_ == DONE) { | |
330 EndTest(); | |
331 return; | |
332 } | |
333 | |
334 SetAfterValues(layer_tree_host()->root_layer()); | |
335 } | |
336 | |
337 void AfterTest() override {} | |
338 | |
339 void VerifyBeforeValues(Layer* layer) { | |
340 EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString()); | |
341 EXPECT_FALSE(layer->hide_layer_and_subtree()); | |
342 EXPECT_FALSE(layer->DrawsContent()); | |
343 } | |
344 | |
345 void SetBeforeValues(Layer* layer) { | |
346 layer->SetBounds(gfx::Size(10, 10)); | |
347 layer->SetHideLayerAndSubtree(false); | |
348 layer->SetIsDrawable(false); | |
349 } | |
350 | |
351 void VerifyAfterValues(LayerImpl* layer) { | |
352 switch (static_cast<Properties>(index_)) { | |
353 case STARTUP: | |
354 case DONE: | |
355 break; | |
356 case BOUNDS: | |
357 EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString()); | |
358 break; | |
359 case HIDE_LAYER_AND_SUBTREE: | |
360 EXPECT_TRUE(layer->hide_layer_and_subtree()); | |
361 break; | |
362 case DRAWS_CONTENT: | |
363 EXPECT_TRUE(layer->DrawsContent()); | |
364 break; | |
365 } | |
366 } | |
367 | |
368 void SetAfterValues(Layer* layer) { | |
369 switch (static_cast<Properties>(index_)) { | |
370 case STARTUP: | |
371 case DONE: | |
372 break; | |
373 case BOUNDS: | |
374 layer->SetBounds(gfx::Size(20, 20)); | |
375 break; | |
376 case HIDE_LAYER_AND_SUBTREE: | |
377 layer->SetHideLayerAndSubtree(true); | |
378 break; | |
379 case DRAWS_CONTENT: | |
380 layer->SetIsDrawable(true); | |
381 break; | |
382 } | |
383 } | |
384 | |
385 int index_; | |
386 }; | |
387 | |
388 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo); | |
389 | |
390 // 1 setNeedsRedraw after the first commit has completed should lead to 1 | |
391 // additional draw. | |
392 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { | |
393 public: | |
394 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {} | |
395 | |
396 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
397 | |
398 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
399 EXPECT_EQ(0, impl->active_tree()->source_frame_number()); | |
400 if (!num_draws_) { | |
401 // Redraw again to verify that the second redraw doesn't commit. | |
402 PostSetNeedsRedrawToMainThread(); | |
403 } else { | |
404 EndTest(); | |
405 } | |
406 num_draws_++; | |
407 } | |
408 | |
409 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
410 EXPECT_EQ(0, num_draws_); | |
411 num_commits_++; | |
412 } | |
413 | |
414 void AfterTest() override { | |
415 EXPECT_GE(2, num_draws_); | |
416 EXPECT_EQ(1, num_commits_); | |
417 } | |
418 | |
419 private: | |
420 int num_commits_; | |
421 int num_draws_; | |
422 }; | |
423 | |
424 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw); | |
425 | |
426 // After setNeedsRedrawRect(invalid_rect) the final damage_rect | |
427 // must contain invalid_rect. | |
428 class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { | |
429 public: | |
430 LayerTreeHostTestSetNeedsRedrawRect() | |
431 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {} | |
432 | |
433 void BeginTest() override { | |
434 if (layer_tree_host()->settings().impl_side_painting) | |
435 root_layer_ = FakePictureLayer::Create(&client_); | |
436 else | |
437 root_layer_ = ContentLayer::Create(&client_); | |
438 root_layer_->SetIsDrawable(true); | |
439 root_layer_->SetBounds(bounds_); | |
440 layer_tree_host()->SetRootLayer(root_layer_); | |
441 layer_tree_host()->SetViewportSize(bounds_); | |
442 PostSetNeedsCommitToMainThread(); | |
443 } | |
444 | |
445 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
446 LayerTreeHostImpl::FrameData* frame_data, | |
447 DrawResult draw_result) override { | |
448 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
449 | |
450 gfx::RectF root_damage_rect; | |
451 if (!frame_data->render_passes.empty()) | |
452 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
453 | |
454 if (!num_draws_) { | |
455 // If this is the first frame, expect full frame damage. | |
456 EXPECT_EQ(root_damage_rect, gfx::Rect(bounds_)); | |
457 } else { | |
458 // Check that invalid_rect_ is indeed repainted. | |
459 EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_)); | |
460 } | |
461 | |
462 return draw_result; | |
463 } | |
464 | |
465 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
466 if (!num_draws_) { | |
467 PostSetNeedsRedrawRectToMainThread(invalid_rect_); | |
468 } else { | |
469 EndTest(); | |
470 } | |
471 num_draws_++; | |
472 } | |
473 | |
474 void AfterTest() override { EXPECT_EQ(2, num_draws_); } | |
475 | |
476 private: | |
477 int num_draws_; | |
478 const gfx::Size bounds_; | |
479 const gfx::Rect invalid_rect_; | |
480 FakeContentLayerClient client_; | |
481 scoped_refptr<Layer> root_layer_; | |
482 }; | |
483 | |
484 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); | |
485 | |
486 // Ensure the texture size of the pending and active trees are identical when a | |
487 // layer is not in the viewport and a resize happens on the viewport | |
488 class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { | |
489 public: | |
490 LayerTreeHostTestGpuRasterDeviceSizeChanged() | |
491 : num_draws_(0), bounds_(500, 64), invalid_rect_(10, 10, 20, 20) {} | |
492 | |
493 void BeginTest() override { | |
494 client_.set_fill_with_nonsolid_color(true); | |
495 root_layer_ = FakePictureLayer::Create(&client_); | |
496 root_layer_->SetIsDrawable(true); | |
497 gfx::Transform transform; | |
498 // Translate the layer out of the viewport to force it to not update its | |
499 // tile size via PushProperties. | |
500 transform.Translate(10000.0, 10000.0); | |
501 root_layer_->SetTransform(transform); | |
502 root_layer_->SetBounds(bounds_); | |
503 layer_tree_host()->SetRootLayer(root_layer_); | |
504 layer_tree_host()->SetViewportSize(bounds_); | |
505 | |
506 PostSetNeedsCommitToMainThread(); | |
507 } | |
508 | |
509 void InitializeSettings(LayerTreeSettings* settings) override { | |
510 settings->gpu_rasterization_enabled = true; | |
511 settings->gpu_rasterization_forced = true; | |
512 } | |
513 | |
514 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
515 // Perform 2 commits. | |
516 if (!num_draws_) { | |
517 PostSetNeedsRedrawRectToMainThread(invalid_rect_); | |
518 } else { | |
519 EndTest(); | |
520 } | |
521 num_draws_++; | |
522 } | |
523 | |
524 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
525 if (num_draws_ == 2) { | |
526 auto pending_tree = host_impl->pending_tree(); | |
527 auto pending_layer_impl = | |
528 static_cast<FakePictureLayerImpl*>(pending_tree->root_layer()); | |
529 EXPECT_NE(pending_layer_impl, nullptr); | |
530 | |
531 auto active_tree = host_impl->pending_tree(); | |
532 auto active_layer_impl = | |
533 static_cast<FakePictureLayerImpl*>(active_tree->root_layer()); | |
534 EXPECT_NE(pending_layer_impl, nullptr); | |
535 | |
536 auto active_tiling_set = active_layer_impl->picture_layer_tiling_set(); | |
537 auto active_tiling = active_tiling_set->tiling_at(0); | |
538 auto pending_tiling_set = pending_layer_impl->picture_layer_tiling_set(); | |
539 auto pending_tiling = pending_tiling_set->tiling_at(0); | |
540 EXPECT_EQ( | |
541 pending_tiling->TilingDataForTesting().max_texture_size().width(), | |
542 active_tiling->TilingDataForTesting().max_texture_size().width()); | |
543 } | |
544 } | |
545 | |
546 void DidCommitAndDrawFrame() override { | |
547 // On the second commit, resize the viewport. | |
548 if (num_draws_ == 1) { | |
549 layer_tree_host()->SetViewportSize(gfx::Size(400, 64)); | |
550 } | |
551 } | |
552 | |
553 void AfterTest() override {} | |
554 | |
555 private: | |
556 int num_draws_; | |
557 const gfx::Size bounds_; | |
558 const gfx::Rect invalid_rect_; | |
559 FakeContentLayerClient client_; | |
560 scoped_refptr<FakePictureLayer> root_layer_; | |
561 }; | |
562 | |
563 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F( | |
564 LayerTreeHostTestGpuRasterDeviceSizeChanged); | |
565 | |
566 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { | |
567 public: | |
568 void InitializeSettings(LayerTreeSettings* settings) override { | |
569 settings->layer_transforms_should_scale_layer_contents = true; | |
570 } | |
571 | |
572 void SetupTree() override { | |
573 root_layer_ = Layer::Create(); | |
574 root_layer_->SetBounds(gfx::Size(10, 20)); | |
575 root_layer_->CreateRenderSurface(); | |
576 | |
577 if (layer_tree_host()->settings().impl_side_painting) | |
578 scaled_layer_ = FakePictureLayer::Create(&client_); | |
579 else | |
580 scaled_layer_ = FakeContentLayer::Create(&client_); | |
581 scaled_layer_->SetBounds(gfx::Size(1, 1)); | |
582 root_layer_->AddChild(scaled_layer_); | |
583 | |
584 layer_tree_host()->SetRootLayer(root_layer_); | |
585 LayerTreeHostTest::SetupTree(); | |
586 } | |
587 | |
588 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
589 | |
590 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
591 if (host_impl->active_tree()->source_frame_number() == 1) | |
592 EndTest(); | |
593 } | |
594 | |
595 void DidCommit() override { | |
596 switch (layer_tree_host()->source_frame_number()) { | |
597 case 1: | |
598 // SetBounds grows the layer and exposes new content. | |
599 if (layer_tree_host()->settings().impl_side_painting) { | |
600 scaled_layer_->SetBounds(gfx::Size(4, 4)); | |
601 } else { | |
602 // Changing the device scale factor causes a commit. It also changes | |
603 // the content bounds of |scaled_layer_|, which should not generate | |
604 // a second commit as a result. | |
605 layer_tree_host()->SetDeviceScaleFactor(4.f); | |
606 } | |
607 break; | |
608 default: | |
609 // No extra commits. | |
610 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); | |
611 } | |
612 } | |
613 | |
614 void AfterTest() override { | |
615 EXPECT_EQ(gfx::Size(4, 4).ToString(), | |
616 scaled_layer_->content_bounds().ToString()); | |
617 } | |
618 | |
619 private: | |
620 FakeContentLayerClient client_; | |
621 scoped_refptr<Layer> root_layer_; | |
622 scoped_refptr<Layer> scaled_layer_; | |
623 }; | |
624 | |
625 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); | |
626 | |
627 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate | |
628 : public LayerTreeHostTest { | |
629 public: | |
630 void InitializeSettings(LayerTreeSettings* settings) override { | |
631 settings->layer_transforms_should_scale_layer_contents = true; | |
632 } | |
633 | |
634 void SetupTree() override { | |
635 root_layer_ = Layer::Create(); | |
636 root_layer_->SetBounds(gfx::Size(10, 20)); | |
637 root_layer_->CreateRenderSurface(); | |
638 | |
639 bool paint_scrollbar = true; | |
640 bool has_thumb = false; | |
641 scrollbar_ = FakePaintedScrollbarLayer::Create( | |
642 paint_scrollbar, has_thumb, root_layer_->id()); | |
643 scrollbar_->SetPosition(gfx::Point(0, 10)); | |
644 scrollbar_->SetBounds(gfx::Size(10, 10)); | |
645 | |
646 root_layer_->AddChild(scrollbar_); | |
647 | |
648 layer_tree_host()->SetRootLayer(root_layer_); | |
649 LayerTreeHostTest::SetupTree(); | |
650 } | |
651 | |
652 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
653 | |
654 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
655 if (host_impl->active_tree()->source_frame_number() == 1) | |
656 EndTest(); | |
657 } | |
658 | |
659 void DidCommit() override { | |
660 switch (layer_tree_host()->source_frame_number()) { | |
661 case 1: | |
662 // Changing the device scale factor causes a commit. It also changes | |
663 // the content bounds of |scrollbar_|, which should not generate | |
664 // a second commit as a result. | |
665 layer_tree_host()->SetDeviceScaleFactor(4.f); | |
666 break; | |
667 default: | |
668 // No extra commits. | |
669 EXPECT_EQ(2, layer_tree_host()->source_frame_number()); | |
670 } | |
671 } | |
672 | |
673 void AfterTest() override { | |
674 EXPECT_EQ(gfx::Size(40, 40).ToString(), | |
675 scrollbar_->internal_content_bounds().ToString()); | |
676 } | |
677 | |
678 private: | |
679 FakeContentLayerClient client_; | |
680 scoped_refptr<Layer> root_layer_; | |
681 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; | |
682 }; | |
683 | |
684 SINGLE_AND_MULTI_THREAD_TEST_F( | |
685 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate); | |
686 | |
687 class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { | |
688 public: | |
689 LayerTreeHostTestSetNextCommitForcesRedraw() | |
690 : num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {} | |
691 | |
692 void BeginTest() override { | |
693 if (layer_tree_host()->settings().impl_side_painting) | |
694 root_layer_ = FakePictureLayer::Create(&client_); | |
695 else | |
696 root_layer_ = ContentLayer::Create(&client_); | |
697 root_layer_->SetIsDrawable(true); | |
698 root_layer_->SetBounds(bounds_); | |
699 layer_tree_host()->SetRootLayer(root_layer_); | |
700 layer_tree_host()->SetViewportSize(bounds_); | |
701 PostSetNeedsCommitToMainThread(); | |
702 } | |
703 | |
704 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
705 if (num_draws_ == 3 && host_impl->settings().impl_side_painting) | |
706 host_impl->SetNeedsRedrawRect(invalid_rect_); | |
707 } | |
708 | |
709 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
710 LayerTreeHostImpl::FrameData* frame_data, | |
711 DrawResult draw_result) override { | |
712 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
713 | |
714 gfx::RectF root_damage_rect; | |
715 if (!frame_data->render_passes.empty()) | |
716 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
717 | |
718 switch (num_draws_) { | |
719 case 0: | |
720 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect); | |
721 break; | |
722 case 1: | |
723 case 2: | |
724 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect); | |
725 break; | |
726 case 3: | |
727 EXPECT_EQ(invalid_rect_, root_damage_rect); | |
728 break; | |
729 case 4: | |
730 EXPECT_EQ(gfx::Rect(bounds_), root_damage_rect); | |
731 break; | |
732 default: | |
733 NOTREACHED(); | |
734 } | |
735 | |
736 return draw_result; | |
737 } | |
738 | |
739 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
740 switch (num_draws_) { | |
741 case 0: | |
742 case 1: | |
743 // Cycle through a couple of empty commits to ensure we're observing the | |
744 // right behavior | |
745 PostSetNeedsCommitToMainThread(); | |
746 break; | |
747 case 2: | |
748 // Should force full frame damage on the next commit | |
749 PostSetNextCommitForcesRedrawToMainThread(); | |
750 PostSetNeedsCommitToMainThread(); | |
751 if (host_impl->settings().impl_side_painting) | |
752 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
753 else | |
754 num_draws_++; | |
755 break; | |
756 case 3: | |
757 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
758 break; | |
759 default: | |
760 EndTest(); | |
761 break; | |
762 } | |
763 num_draws_++; | |
764 } | |
765 | |
766 void AfterTest() override { EXPECT_EQ(5, num_draws_); } | |
767 | |
768 private: | |
769 int num_draws_; | |
770 const gfx::Size bounds_; | |
771 const gfx::Rect invalid_rect_; | |
772 FakeContentLayerClient client_; | |
773 scoped_refptr<Layer> root_layer_; | |
774 }; | |
775 | |
776 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
777 LayerTreeHostTestSetNextCommitForcesRedraw); | |
778 | |
779 // Tests that if a layer is not drawn because of some reason in the parent then | |
780 // its damage is preserved until the next time it is drawn. | |
781 class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { | |
782 public: | |
783 LayerTreeHostTestUndrawnLayersDamageLater() {} | |
784 | |
785 void InitializeSettings(LayerTreeSettings* settings) override { | |
786 // If we don't set the minimum contents scale, it's harder to verify whether | |
787 // the damage we get is correct. For other scale amounts, please see | |
788 // LayerTreeHostTestDamageWithScale. | |
789 settings->minimum_contents_scale = 1.f; | |
790 } | |
791 | |
792 void SetupTree() override { | |
793 if (layer_tree_host()->settings().impl_side_painting) | |
794 root_layer_ = FakePictureLayer::Create(&client_); | |
795 else | |
796 root_layer_ = ContentLayer::Create(&client_); | |
797 root_layer_->SetIsDrawable(true); | |
798 root_layer_->SetBounds(gfx::Size(50, 50)); | |
799 layer_tree_host()->SetRootLayer(root_layer_); | |
800 | |
801 // The initially transparent layer has a larger child layer, which is | |
802 // not initially drawn because of the this (parent) layer. | |
803 if (layer_tree_host()->settings().impl_side_painting) | |
804 parent_layer_ = FakePictureLayer::Create(&client_); | |
805 else | |
806 parent_layer_ = FakeContentLayer::Create(&client_); | |
807 parent_layer_->SetBounds(gfx::Size(15, 15)); | |
808 parent_layer_->SetOpacity(0.0f); | |
809 root_layer_->AddChild(parent_layer_); | |
810 | |
811 if (layer_tree_host()->settings().impl_side_painting) | |
812 child_layer_ = FakePictureLayer::Create(&client_); | |
813 else | |
814 child_layer_ = FakeContentLayer::Create(&client_); | |
815 child_layer_->SetBounds(gfx::Size(25, 25)); | |
816 parent_layer_->AddChild(child_layer_); | |
817 | |
818 LayerTreeHostTest::SetupTree(); | |
819 } | |
820 | |
821 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
822 | |
823 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
824 LayerTreeHostImpl::FrameData* frame_data, | |
825 DrawResult draw_result) override { | |
826 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
827 | |
828 gfx::RectF root_damage_rect; | |
829 if (!frame_data->render_passes.empty()) | |
830 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
831 | |
832 // The first time, the whole view needs be drawn. | |
833 // Afterwards, just the opacity of surface_layer1 is changed a few times, | |
834 // and each damage should be the bounding box of it and its child. If this | |
835 // was working improperly, the damage might not include its childs bounding | |
836 // box. | |
837 switch (host_impl->active_tree()->source_frame_number()) { | |
838 case 0: | |
839 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); | |
840 break; | |
841 case 1: | |
842 case 2: | |
843 case 3: | |
844 EXPECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect); | |
845 break; | |
846 default: | |
847 NOTREACHED(); | |
848 } | |
849 | |
850 return draw_result; | |
851 } | |
852 | |
853 void DidCommitAndDrawFrame() override { | |
854 switch (layer_tree_host()->source_frame_number()) { | |
855 case 1: | |
856 // Test not owning the surface. | |
857 parent_layer_->SetOpacity(1.0f); | |
858 break; | |
859 case 2: | |
860 parent_layer_->SetOpacity(0.0f); | |
861 break; | |
862 case 3: | |
863 // Test owning the surface. | |
864 parent_layer_->SetOpacity(0.5f); | |
865 parent_layer_->SetForceRenderSurface(true); | |
866 break; | |
867 case 4: | |
868 EndTest(); | |
869 break; | |
870 default: | |
871 NOTREACHED(); | |
872 } | |
873 } | |
874 | |
875 void AfterTest() override {} | |
876 | |
877 private: | |
878 FakeContentLayerClient client_; | |
879 scoped_refptr<Layer> root_layer_; | |
880 scoped_refptr<Layer> parent_layer_; | |
881 scoped_refptr<Layer> child_layer_; | |
882 }; | |
883 | |
884 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater); | |
885 | |
886 // Tests that if a layer is not drawn because of some reason in the parent then | |
887 // its damage is preserved until the next time it is drawn. | |
888 class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest { | |
889 public: | |
890 LayerTreeHostTestDamageWithScale() {} | |
891 | |
892 void SetupTree() override { | |
893 client_.set_fill_with_nonsolid_color(true); | |
894 | |
895 scoped_ptr<FakePicturePile> pile( | |
896 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
897 ImplSidePaintingSettings().default_tile_grid_size)); | |
898 root_layer_ = | |
899 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
900 root_layer_->SetBounds(gfx::Size(50, 50)); | |
901 | |
902 pile.reset( | |
903 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
904 ImplSidePaintingSettings().default_tile_grid_size)); | |
905 child_layer_ = | |
906 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
907 child_layer_->SetBounds(gfx::Size(25, 25)); | |
908 child_layer_->SetIsDrawable(true); | |
909 child_layer_->SetContentsOpaque(true); | |
910 root_layer_->AddChild(child_layer_); | |
911 | |
912 layer_tree_host()->SetRootLayer(root_layer_); | |
913 LayerTreeHostTest::SetupTree(); | |
914 } | |
915 | |
916 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
917 // Force the layer to have a tiling at 1.3f scale. Note that if we simply | |
918 // add tiling, it will be gone by the time we draw because of aggressive | |
919 // cleanup. AddTilingUntilNextDraw ensures that it remains there during | |
920 // damage calculation. | |
921 FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( | |
922 host_impl->active_tree()->LayerById(child_layer_->id())); | |
923 child_layer_impl->AddTilingUntilNextDraw(1.3f); | |
924 } | |
925 | |
926 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
927 | |
928 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
929 LayerTreeHostImpl::FrameData* frame_data, | |
930 DrawResult draw_result) override { | |
931 EXPECT_EQ(DRAW_SUCCESS, draw_result); | |
932 | |
933 gfx::RectF root_damage_rect; | |
934 if (!frame_data->render_passes.empty()) | |
935 root_damage_rect = frame_data->render_passes.back()->damage_rect; | |
936 | |
937 // The first time, the whole view needs be drawn. | |
938 // Afterwards, just the opacity of surface_layer1 is changed a few times, | |
939 // and each damage should be the bounding box of it and its child. If this | |
940 // was working improperly, the damage might not include its childs bounding | |
941 // box. | |
942 switch (host_impl->active_tree()->source_frame_number()) { | |
943 case 0: | |
944 EXPECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect); | |
945 break; | |
946 case 1: { | |
947 FakePictureLayerImpl* child_layer_impl = | |
948 static_cast<FakePictureLayerImpl*>( | |
949 host_impl->active_tree()->LayerById(child_layer_->id())); | |
950 // We remove tilings pretty aggressively if they are not ideal. Add this | |
951 // back in so that we can compare | |
952 // child_layer_impl->GetEnclosingRectInTargetSpace to the damage. | |
953 child_layer_impl->AddTilingUntilNextDraw(1.3f); | |
954 | |
955 EXPECT_EQ(gfx::Rect(26, 26), root_damage_rect); | |
956 EXPECT_EQ(child_layer_impl->GetEnclosingRectInTargetSpace(), | |
957 root_damage_rect); | |
958 EXPECT_TRUE(child_layer_impl->GetEnclosingRectInTargetSpace().Contains( | |
959 gfx::Rect(child_layer_->bounds()))); | |
960 break; | |
961 } | |
962 default: | |
963 NOTREACHED(); | |
964 } | |
965 | |
966 return draw_result; | |
967 } | |
968 | |
969 void DidCommitAndDrawFrame() override { | |
970 switch (layer_tree_host()->source_frame_number()) { | |
971 case 1: { | |
972 // Test not owning the surface. | |
973 child_layer_->SetOpacity(0.5f); | |
974 break; | |
975 } | |
976 case 2: | |
977 EndTest(); | |
978 break; | |
979 default: | |
980 NOTREACHED(); | |
981 } | |
982 } | |
983 | |
984 void AfterTest() override {} | |
985 | |
986 private: | |
987 FakeContentLayerClient client_; | |
988 scoped_refptr<Layer> root_layer_; | |
989 scoped_refptr<Layer> child_layer_; | |
990 }; | |
991 | |
992 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale); | |
993 | |
994 // Tests that if a layer is not drawn because of some reason in the parent, | |
995 // causing its content bounds to not be computed, then when it is later drawn, | |
996 // its content bounds get pushed. | |
997 class LayerTreeHostTestUndrawnLayersPushContentBoundsLater | |
998 : public LayerTreeHostTest { | |
999 public: | |
1000 LayerTreeHostTestUndrawnLayersPushContentBoundsLater() | |
1001 : root_layer_(Layer::Create()) {} | |
1002 | |
1003 void SetupTree() override { | |
1004 root_layer_->CreateRenderSurface(); | |
1005 root_layer_->SetIsDrawable(true); | |
1006 root_layer_->SetBounds(gfx::Size(20, 20)); | |
1007 layer_tree_host()->SetRootLayer(root_layer_); | |
1008 | |
1009 parent_layer_ = Layer::Create(); | |
1010 parent_layer_->SetBounds(gfx::Size(20, 20)); | |
1011 parent_layer_->SetOpacity(0.0f); | |
1012 root_layer_->AddChild(parent_layer_); | |
1013 | |
1014 child_layer_ = Layer::Create(); | |
1015 child_layer_->SetBounds(gfx::Size(15, 15)); | |
1016 parent_layer_->AddChild(child_layer_); | |
1017 | |
1018 LayerTreeHostTest::SetupTree(); | |
1019 } | |
1020 | |
1021 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1022 | |
1023 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
1024 LayerImpl* root = host_impl->active_tree()->root_layer(); | |
1025 LayerImpl* parent = root->children()[0]; | |
1026 LayerImpl* child = parent->children()[0]; | |
1027 | |
1028 switch (host_impl->active_tree()->source_frame_number()) { | |
1029 case 0: | |
1030 EXPECT_EQ(0.f, parent->opacity()); | |
1031 EXPECT_EQ(gfx::SizeF(), child->content_bounds()); | |
1032 break; | |
1033 case 1: | |
1034 EXPECT_EQ(1.f, parent->opacity()); | |
1035 EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds()); | |
1036 EndTest(); | |
1037 break; | |
1038 default: | |
1039 NOTREACHED(); | |
1040 } | |
1041 } | |
1042 | |
1043 void DidCommit() override { | |
1044 switch (layer_tree_host()->source_frame_number()) { | |
1045 case 1: | |
1046 parent_layer_->SetOpacity(1.0f); | |
1047 break; | |
1048 case 2: | |
1049 break; | |
1050 default: | |
1051 NOTREACHED(); | |
1052 } | |
1053 } | |
1054 | |
1055 void AfterTest() override {} | |
1056 | |
1057 private: | |
1058 scoped_refptr<Layer> root_layer_; | |
1059 scoped_refptr<Layer> parent_layer_; | |
1060 scoped_refptr<Layer> child_layer_; | |
1061 }; | |
1062 | |
1063 SINGLE_AND_MULTI_THREAD_TEST_F( | |
1064 LayerTreeHostTestUndrawnLayersPushContentBoundsLater); | |
1065 | |
1066 // This test verifies that properties on the layer tree host are commited | |
1067 // to the impl side. | |
1068 class LayerTreeHostTestCommit : public LayerTreeHostTest { | |
1069 public: | |
1070 LayerTreeHostTestCommit() {} | |
1071 | |
1072 void BeginTest() override { | |
1073 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
1074 layer_tree_host()->set_background_color(SK_ColorGRAY); | |
1075 | |
1076 PostSetNeedsCommitToMainThread(); | |
1077 } | |
1078 | |
1079 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
1080 EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize()); | |
1081 EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color()); | |
1082 | |
1083 EndTest(); | |
1084 } | |
1085 | |
1086 void AfterTest() override {} | |
1087 }; | |
1088 | |
1089 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); | |
1090 | |
1091 // This test verifies that LayerTreeHostImpl's current frame time gets | |
1092 // updated in consecutive frames when it doesn't draw due to tree | |
1093 // activation failure. | |
1094 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails | |
1095 : public LayerTreeHostTest { | |
1096 public: | |
1097 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() | |
1098 : frame_count_with_pending_tree_(0) {} | |
1099 | |
1100 void BeginTest() override { | |
1101 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
1102 layer_tree_host()->set_background_color(SK_ColorGRAY); | |
1103 | |
1104 PostSetNeedsCommitToMainThread(); | |
1105 } | |
1106 | |
1107 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
1108 EXPECT_EQ(frame_count_with_pending_tree_, 0); | |
1109 if (impl->settings().impl_side_painting) | |
1110 impl->BlockNotifyReadyToActivateForTesting(true); | |
1111 } | |
1112 | |
1113 void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, | |
1114 const BeginFrameArgs& args) override { | |
1115 if (impl->pending_tree()) | |
1116 frame_count_with_pending_tree_++; | |
1117 | |
1118 if (frame_count_with_pending_tree_ == 1) { | |
1119 EXPECT_EQ(first_frame_time_.ToInternalValue(), 0); | |
1120 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; | |
1121 } else if (frame_count_with_pending_tree_ == 2 && | |
1122 impl->settings().impl_side_painting) { | |
1123 impl->BlockNotifyReadyToActivateForTesting(false); | |
1124 } | |
1125 } | |
1126 | |
1127 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1128 if (frame_count_with_pending_tree_ > 1) { | |
1129 EXPECT_NE(first_frame_time_.ToInternalValue(), 0); | |
1130 EXPECT_NE(first_frame_time_.ToInternalValue(), | |
1131 impl->CurrentBeginFrameArgs().frame_time.ToInternalValue()); | |
1132 EndTest(); | |
1133 return; | |
1134 } | |
1135 | |
1136 EXPECT_FALSE(impl->settings().impl_side_painting); | |
1137 EndTest(); | |
1138 } | |
1139 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
1140 if (impl->settings().impl_side_painting) | |
1141 EXPECT_NE(frame_count_with_pending_tree_, 1); | |
1142 } | |
1143 | |
1144 void AfterTest() override {} | |
1145 | |
1146 private: | |
1147 int frame_count_with_pending_tree_; | |
1148 base::TimeTicks first_frame_time_; | |
1149 }; | |
1150 | |
1151 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
1152 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); | |
1153 | |
1154 // This test verifies that LayerTreeHostImpl's current frame time gets | |
1155 // updated in consecutive frames when it draws in each frame. | |
1156 class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { | |
1157 public: | |
1158 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {} | |
1159 | |
1160 void BeginTest() override { | |
1161 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
1162 layer_tree_host()->set_background_color(SK_ColorGRAY); | |
1163 | |
1164 PostSetNeedsCommitToMainThread(); | |
1165 } | |
1166 | |
1167 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1168 frame_++; | |
1169 if (frame_ == 1) { | |
1170 first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; | |
1171 impl->SetNeedsRedraw(); | |
1172 | |
1173 // Since we might use a low-resolution clock on Windows, we need to | |
1174 // make sure that the clock has incremented past first_frame_time_. | |
1175 while (first_frame_time_ == gfx::FrameTime::Now()) { | |
1176 } | |
1177 | |
1178 return; | |
1179 } | |
1180 | |
1181 EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time); | |
1182 EndTest(); | |
1183 } | |
1184 | |
1185 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
1186 // Ensure there isn't a commit between the two draws, to ensure that a | |
1187 // commit isn't required for updating the current frame time. We can | |
1188 // only check for this in the multi-threaded case, since in the single- | |
1189 // threaded case there will always be a commit between consecutive draws. | |
1190 if (HasImplThread()) | |
1191 EXPECT_EQ(0, frame_); | |
1192 } | |
1193 | |
1194 void AfterTest() override {} | |
1195 | |
1196 private: | |
1197 int frame_; | |
1198 base::TimeTicks first_frame_time_; | |
1199 }; | |
1200 | |
1201 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); | |
1202 | |
1203 // Verifies that StartPageScaleAnimation events propagate correctly | |
1204 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor. | |
1205 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { | |
1206 public: | |
1207 LayerTreeHostTestStartPageScaleAnimation() {} | |
1208 | |
1209 void SetupTree() override { | |
1210 LayerTreeHostTest::SetupTree(); | |
1211 | |
1212 if (layer_tree_host()->settings().impl_side_painting) { | |
1213 scoped_refptr<FakePictureLayer> layer = | |
1214 FakePictureLayer::Create(&client_); | |
1215 layer->set_always_update_resources(true); | |
1216 scroll_layer_ = layer; | |
1217 } else { | |
1218 scroll_layer_ = FakeContentLayer::Create(&client_); | |
1219 } | |
1220 | |
1221 Layer* root_layer = layer_tree_host()->root_layer(); | |
1222 scroll_layer_->SetScrollClipLayerId(root_layer->id()); | |
1223 scroll_layer_->SetIsContainerForFixedPositionLayers(true); | |
1224 scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), | |
1225 2 * root_layer->bounds().height())); | |
1226 scroll_layer_->SetScrollOffset(gfx::ScrollOffset()); | |
1227 layer_tree_host()->root_layer()->AddChild(scroll_layer_); | |
1228 // This test requires the page_scale and inner viewport layers to be | |
1229 // identified. | |
1230 layer_tree_host()->RegisterViewportLayers(NULL, root_layer, | |
1231 scroll_layer_.get(), NULL); | |
1232 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f); | |
1233 } | |
1234 | |
1235 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1236 | |
1237 void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, | |
1238 float scale, | |
1239 float) override { | |
1240 gfx::ScrollOffset offset = scroll_layer_->scroll_offset(); | |
1241 scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset, | |
1242 scroll_delta)); | |
1243 layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f); | |
1244 } | |
1245 | |
1246 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
1247 // We get one commit before the first draw, and the animation doesn't happen | |
1248 // until the second draw. | |
1249 switch (impl->active_tree()->source_frame_number()) { | |
1250 case 0: | |
1251 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); | |
1252 // We'll start an animation when we get back to the main thread. | |
1253 break; | |
1254 case 1: | |
1255 EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor()); | |
1256 break; | |
1257 case 2: | |
1258 EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor()); | |
1259 EndTest(); | |
1260 break; | |
1261 default: | |
1262 NOTREACHED(); | |
1263 } | |
1264 } | |
1265 | |
1266 void DidCommitAndDrawFrame() override { | |
1267 switch (layer_tree_host()->source_frame_number()) { | |
1268 case 1: | |
1269 layer_tree_host()->StartPageScaleAnimation( | |
1270 gfx::Vector2d(), false, 1.25f, base::TimeDelta()); | |
1271 break; | |
1272 } | |
1273 } | |
1274 | |
1275 void AfterTest() override {} | |
1276 | |
1277 FakeContentLayerClient client_; | |
1278 scoped_refptr<Layer> scroll_layer_; | |
1279 }; | |
1280 | |
1281 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); | |
1282 | |
1283 class LayerTreeHostTestSetVisible : public LayerTreeHostTest { | |
1284 public: | |
1285 LayerTreeHostTestSetVisible() : num_draws_(0) {} | |
1286 | |
1287 void BeginTest() override { | |
1288 PostSetNeedsCommitToMainThread(); | |
1289 PostSetVisibleToMainThread(false); | |
1290 // This is suppressed while we're invisible. | |
1291 PostSetNeedsRedrawToMainThread(); | |
1292 // Triggers the redraw. | |
1293 PostSetVisibleToMainThread(true); | |
1294 } | |
1295 | |
1296 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1297 EXPECT_TRUE(impl->visible()); | |
1298 ++num_draws_; | |
1299 EndTest(); | |
1300 } | |
1301 | |
1302 void AfterTest() override { EXPECT_EQ(1, num_draws_); } | |
1303 | |
1304 private: | |
1305 int num_draws_; | |
1306 }; | |
1307 | |
1308 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible); | |
1309 | |
1310 class TestOpacityChangeLayerDelegate : public ContentLayerClient { | |
1311 public: | |
1312 TestOpacityChangeLayerDelegate() : test_layer_(0) {} | |
1313 | |
1314 void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } | |
1315 | |
1316 void PaintContents(SkCanvas* canvas, | |
1317 const gfx::Rect& clip, | |
1318 PaintingControlSetting picture_control) override { | |
1319 // Set layer opacity to 0. | |
1320 if (test_layer_) | |
1321 test_layer_->SetOpacity(0.f); | |
1322 } | |
1323 scoped_refptr<DisplayItemList> PaintContentsToDisplayList( | |
1324 const gfx::Rect& clip, | |
1325 PaintingControlSetting picture_control) override { | |
1326 NOTIMPLEMENTED(); | |
1327 return DisplayItemList::Create(); | |
1328 } | |
1329 bool FillsBoundsCompletely() const override { return false; } | |
1330 | |
1331 private: | |
1332 Layer* test_layer_; | |
1333 }; | |
1334 | |
1335 class ContentLayerWithUpdateTracking : public ContentLayer { | |
1336 public: | |
1337 static scoped_refptr<ContentLayerWithUpdateTracking> Create( | |
1338 ContentLayerClient* client) { | |
1339 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client)); | |
1340 } | |
1341 | |
1342 int PaintContentsCount() { return paint_contents_count_; } | |
1343 void ResetPaintContentsCount() { paint_contents_count_ = 0; } | |
1344 | |
1345 bool Update(ResourceUpdateQueue* queue, | |
1346 const OcclusionTracker<Layer>* occlusion) override { | |
1347 bool updated = ContentLayer::Update(queue, occlusion); | |
1348 paint_contents_count_++; | |
1349 return updated; | |
1350 } | |
1351 | |
1352 private: | |
1353 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client) | |
1354 : ContentLayer(client), paint_contents_count_(0) { | |
1355 SetBounds(gfx::Size(10, 10)); | |
1356 SetIsDrawable(true); | |
1357 } | |
1358 ~ContentLayerWithUpdateTracking() override {} | |
1359 | |
1360 int paint_contents_count_; | |
1361 }; | |
1362 | |
1363 // Layer opacity change during paint should not prevent compositor resources | |
1364 // from being updated during commit. | |
1365 class LayerTreeHostTestOpacityChange : public LayerTreeHostTest { | |
1366 public: | |
1367 LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {} | |
1368 | |
1369 void BeginTest() override { | |
1370 if (layer_tree_host()->settings().impl_side_painting) { | |
1371 update_check_picture_layer_ = | |
1372 FakePictureLayer::Create(&test_opacity_change_delegate_); | |
1373 test_opacity_change_delegate_.SetTestLayer( | |
1374 update_check_picture_layer_.get()); | |
1375 is_impl_paint_ = true; | |
1376 } else { | |
1377 update_check_content_layer_ = ContentLayerWithUpdateTracking::Create( | |
1378 &test_opacity_change_delegate_); | |
1379 test_opacity_change_delegate_.SetTestLayer( | |
1380 update_check_content_layer_.get()); | |
1381 is_impl_paint_ = false; | |
1382 } | |
1383 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); | |
1384 if (layer_tree_host()->settings().impl_side_painting) | |
1385 layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_); | |
1386 else | |
1387 layer_tree_host()->root_layer()->AddChild(update_check_content_layer_); | |
1388 | |
1389 PostSetNeedsCommitToMainThread(); | |
1390 } | |
1391 | |
1392 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); } | |
1393 | |
1394 void AfterTest() override { | |
1395 // Update() should have been called once. | |
1396 if (is_impl_paint_) | |
1397 EXPECT_EQ(1u, update_check_picture_layer_->update_count()); | |
1398 else | |
1399 EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount()); | |
1400 } | |
1401 | |
1402 private: | |
1403 TestOpacityChangeLayerDelegate test_opacity_change_delegate_; | |
1404 scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_; | |
1405 scoped_refptr<FakePictureLayer> update_check_picture_layer_; | |
1406 bool is_impl_paint_; | |
1407 }; | |
1408 | |
1409 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange); | |
1410 | |
1411 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers | |
1412 : public LayerTreeHostTest { | |
1413 public: | |
1414 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {} | |
1415 | |
1416 void InitializeSettings(LayerTreeSettings* settings) override { | |
1417 // PictureLayer can only be used with impl side painting enabled. | |
1418 settings->impl_side_painting = true; | |
1419 } | |
1420 | |
1421 void BeginTest() override { | |
1422 client_.set_fill_with_nonsolid_color(true); | |
1423 root_layer_ = FakePictureLayer::Create(&client_); | |
1424 child_layer_ = FakePictureLayer::Create(&client_); | |
1425 | |
1426 layer_tree_host()->SetViewportSize(gfx::Size(60, 60)); | |
1427 layer_tree_host()->SetDeviceScaleFactor(1.5); | |
1428 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size()); | |
1429 | |
1430 root_layer_->AddChild(child_layer_); | |
1431 | |
1432 root_layer_->SetIsDrawable(true); | |
1433 root_layer_->SetBounds(gfx::Size(30, 30)); | |
1434 | |
1435 child_layer_->SetIsDrawable(true); | |
1436 child_layer_->SetPosition(gfx::Point(2, 2)); | |
1437 child_layer_->SetBounds(gfx::Size(10, 10)); | |
1438 | |
1439 layer_tree_host()->SetRootLayer(root_layer_); | |
1440 | |
1441 PostSetNeedsCommitToMainThread(); | |
1442 } | |
1443 | |
1444 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
1445 // Should only do one commit. | |
1446 EXPECT_EQ(0, impl->active_tree()->source_frame_number()); | |
1447 // Device scale factor should come over to impl. | |
1448 EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f); | |
1449 | |
1450 // Both layers are on impl. | |
1451 ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size()); | |
1452 | |
1453 // Device viewport is scaled. | |
1454 EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize()); | |
1455 | |
1456 FakePictureLayerImpl* root = | |
1457 static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); | |
1458 FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>( | |
1459 impl->active_tree()->root_layer()->children()[0]); | |
1460 | |
1461 // Positions remain in layout pixels. | |
1462 EXPECT_EQ(gfx::Point(0, 0), root->position()); | |
1463 EXPECT_EQ(gfx::Point(2, 2), child->position()); | |
1464 | |
1465 // Compute all the layer transforms for the frame. | |
1466 LayerTreeHostImpl::FrameData frame_data; | |
1467 impl->PrepareToDraw(&frame_data); | |
1468 impl->DidDrawAllLayers(frame_data); | |
1469 | |
1470 const LayerImplList& render_surface_layer_list = | |
1471 *frame_data.render_surface_layer_list; | |
1472 | |
1473 // Both layers should be drawing into the root render surface. | |
1474 ASSERT_EQ(1u, render_surface_layer_list.size()); | |
1475 ASSERT_EQ(root->render_surface(), | |
1476 render_surface_layer_list[0]->render_surface()); | |
1477 ASSERT_EQ(2u, root->render_surface()->layer_list().size()); | |
1478 | |
1479 // The root render surface is the size of the viewport. | |
1480 EXPECT_EQ(gfx::Rect(0, 0, 60, 60), root->render_surface()->content_rect()); | |
1481 | |
1482 // The max tiling scale of the child should be scaled. | |
1483 EXPECT_FLOAT_EQ(1.5f, child->MaximumTilingContentsScale()); | |
1484 | |
1485 gfx::Transform scale_transform; | |
1486 scale_transform.Scale(impl->device_scale_factor(), | |
1487 impl->device_scale_factor()); | |
1488 | |
1489 // The root layer is scaled by 2x. | |
1490 gfx::Transform root_screen_space_transform = scale_transform; | |
1491 gfx::Transform root_draw_transform = scale_transform; | |
1492 | |
1493 EXPECT_EQ(root_draw_transform, root->draw_transform()); | |
1494 EXPECT_EQ(root_screen_space_transform, root->screen_space_transform()); | |
1495 | |
1496 // The child is at position 2,2, which is transformed to 3,3 after the scale | |
1497 gfx::Transform child_transform; | |
1498 child_transform.Translate(3.f, 3.f); | |
1499 child_transform.Scale(child->MaximumTilingContentsScale(), | |
1500 child->MaximumTilingContentsScale()); | |
1501 | |
1502 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, child->draw_transform()); | |
1503 EXPECT_TRANSFORMATION_MATRIX_EQ(child_transform, | |
1504 child->screen_space_transform()); | |
1505 | |
1506 EndTest(); | |
1507 } | |
1508 | |
1509 void AfterTest() override {} | |
1510 | |
1511 private: | |
1512 FakeContentLayerClient client_; | |
1513 scoped_refptr<FakePictureLayer> root_layer_; | |
1514 scoped_refptr<FakePictureLayer> child_layer_; | |
1515 }; | |
1516 | |
1517 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); | |
1518 | |
1519 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
1520 // Verify atomicity of commits and reuse of textures. | |
1521 class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { | |
1522 public: | |
1523 void InitializeSettings(LayerTreeSettings* settings) override { | |
1524 settings->renderer_settings.texture_id_allocation_chunk_size = 1; | |
1525 // Make sure partial texture updates are turned off. | |
1526 settings->max_partial_texture_updates = 0; | |
1527 // Linear fade animator prevents scrollbars from drawing immediately. | |
1528 settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR; | |
1529 } | |
1530 | |
1531 void SetupTree() override { | |
1532 layer_ = FakeContentLayer::Create(&client_); | |
1533 layer_->SetBounds(gfx::Size(10, 20)); | |
1534 | |
1535 bool paint_scrollbar = true; | |
1536 bool has_thumb = false; | |
1537 scrollbar_ = FakePaintedScrollbarLayer::Create( | |
1538 paint_scrollbar, has_thumb, layer_->id()); | |
1539 scrollbar_->SetPosition(gfx::Point(0, 10)); | |
1540 scrollbar_->SetBounds(gfx::Size(10, 10)); | |
1541 | |
1542 layer_->AddChild(scrollbar_); | |
1543 | |
1544 layer_tree_host()->SetRootLayer(layer_); | |
1545 LayerTreeHostTest::SetupTree(); | |
1546 } | |
1547 | |
1548 void BeginTest() override { | |
1549 drew_frame_ = -1; | |
1550 PostSetNeedsCommitToMainThread(); | |
1551 } | |
1552 | |
1553 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
1554 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates); | |
1555 | |
1556 TestWebGraphicsContext3D* context = TestContext(); | |
1557 | |
1558 switch (impl->active_tree()->source_frame_number()) { | |
1559 case 0: | |
1560 // Number of textures should be one for each layer | |
1561 ASSERT_EQ(2u, context->NumTextures()); | |
1562 // Number of textures used for commit should be one for each layer. | |
1563 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1564 // Verify that used texture is correct. | |
1565 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
1566 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
1567 | |
1568 context->ResetUsedTextures(); | |
1569 break; | |
1570 case 1: | |
1571 // Number of textures should be one for scrollbar layer since it was | |
1572 // requested and deleted on the impl-thread, and double for the content | |
1573 // layer since its first texture is used by impl thread and cannot by | |
1574 // used for update. | |
1575 ASSERT_EQ(3u, context->NumTextures()); | |
1576 // Number of textures used for commit should be one for each layer. | |
1577 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1578 // First textures should not have been used. | |
1579 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); | |
1580 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
1581 // New textures should have been used. | |
1582 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
1583 context->ResetUsedTextures(); | |
1584 break; | |
1585 case 2: | |
1586 EndTest(); | |
1587 break; | |
1588 default: | |
1589 NOTREACHED(); | |
1590 break; | |
1591 } | |
1592 } | |
1593 | |
1594 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1595 TestWebGraphicsContext3D* context = TestContext(); | |
1596 | |
1597 if (drew_frame_ == impl->active_tree()->source_frame_number()) { | |
1598 EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_; | |
1599 return; | |
1600 } | |
1601 drew_frame_ = impl->active_tree()->source_frame_number(); | |
1602 | |
1603 // We draw/ship one texture each frame for each layer. | |
1604 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1605 context->ResetUsedTextures(); | |
1606 | |
1607 if (!TestEnded()) | |
1608 PostSetNeedsCommitToMainThread(); | |
1609 } | |
1610 | |
1611 void Layout() override { | |
1612 layer_->SetNeedsDisplay(); | |
1613 scrollbar_->SetNeedsDisplay(); | |
1614 } | |
1615 | |
1616 void AfterTest() override {} | |
1617 | |
1618 protected: | |
1619 FakeContentLayerClient client_; | |
1620 scoped_refptr<FakeContentLayer> layer_; | |
1621 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; | |
1622 int drew_frame_; | |
1623 }; | |
1624 | |
1625 MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
1626 LayerTreeHostTestDirectRendererAtomicCommit); | |
1627 | |
1628 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
1629 class LayerTreeHostTestDelegatingRendererAtomicCommit | |
1630 : public LayerTreeHostTestDirectRendererAtomicCommit { | |
1631 public: | |
1632 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
1633 ASSERT_EQ(0u, impl->settings().max_partial_texture_updates); | |
1634 | |
1635 TestWebGraphicsContext3D* context = TestContext(); | |
1636 | |
1637 switch (impl->active_tree()->source_frame_number()) { | |
1638 case 0: | |
1639 // Number of textures should be one for each layer | |
1640 ASSERT_EQ(2u, context->NumTextures()); | |
1641 // Number of textures used for commit should be one for each layer. | |
1642 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1643 // Verify that used texture is correct. | |
1644 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
1645 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
1646 break; | |
1647 case 1: | |
1648 // Number of textures should be doubled as the first context layer | |
1649 // texture is being used by the impl-thread and cannot be used for | |
1650 // update. The scrollbar behavior is different direct renderer because | |
1651 // UI resource deletion with delegating renderer occurs after tree | |
1652 // activation. | |
1653 ASSERT_EQ(4u, context->NumTextures()); | |
1654 // Number of textures used for commit should still be | |
1655 // one for each layer. | |
1656 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1657 // First textures should not have been used. | |
1658 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); | |
1659 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); | |
1660 // New textures should have been used. | |
1661 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
1662 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); | |
1663 break; | |
1664 case 2: | |
1665 EndTest(); | |
1666 break; | |
1667 default: | |
1668 NOTREACHED(); | |
1669 break; | |
1670 } | |
1671 } | |
1672 }; | |
1673 | |
1674 MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F( | |
1675 LayerTreeHostTestDelegatingRendererAtomicCommit); | |
1676 | |
1677 static void SetLayerPropertiesForTesting(Layer* layer, | |
1678 Layer* parent, | |
1679 const gfx::Transform& transform, | |
1680 const gfx::Point3F& transform_origin, | |
1681 const gfx::PointF& position, | |
1682 const gfx::Size& bounds, | |
1683 bool opaque) { | |
1684 layer->RemoveAllChildren(); | |
1685 if (parent) | |
1686 parent->AddChild(layer); | |
1687 layer->SetTransform(transform); | |
1688 layer->SetTransformOrigin(transform_origin); | |
1689 layer->SetPosition(position); | |
1690 layer->SetBounds(bounds); | |
1691 layer->SetContentsOpaque(opaque); | |
1692 } | |
1693 | |
1694 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
1695 class LayerTreeHostTestAtomicCommitWithPartialUpdate | |
1696 : public LayerTreeHostTest { | |
1697 public: | |
1698 void InitializeSettings(LayerTreeSettings* settings) override { | |
1699 settings->renderer_settings.texture_id_allocation_chunk_size = 1; | |
1700 // Allow one partial texture update. | |
1701 settings->max_partial_texture_updates = 1; | |
1702 // No partial updates when impl side painting is enabled. | |
1703 settings->impl_side_painting = false; | |
1704 } | |
1705 | |
1706 void SetupTree() override { | |
1707 parent_ = FakeContentLayer::Create(&client_); | |
1708 parent_->SetBounds(gfx::Size(10, 20)); | |
1709 | |
1710 child_ = FakeContentLayer::Create(&client_); | |
1711 child_->SetPosition(gfx::Point(0, 10)); | |
1712 child_->SetBounds(gfx::Size(3, 10)); | |
1713 | |
1714 parent_->AddChild(child_); | |
1715 | |
1716 layer_tree_host()->SetRootLayer(parent_); | |
1717 LayerTreeHostTest::SetupTree(); | |
1718 } | |
1719 | |
1720 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1721 | |
1722 void DidCommitAndDrawFrame() override { | |
1723 switch (layer_tree_host()->source_frame_number()) { | |
1724 case 1: | |
1725 parent_->SetNeedsDisplay(); | |
1726 child_->SetNeedsDisplay(); | |
1727 break; | |
1728 case 2: | |
1729 // Damage part of layers. | |
1730 parent_->SetNeedsDisplayRect(gfx::Rect(5, 5)); | |
1731 child_->SetNeedsDisplayRect(gfx::Rect(5, 5)); | |
1732 break; | |
1733 case 3: | |
1734 child_->SetNeedsDisplay(); | |
1735 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); | |
1736 break; | |
1737 case 4: | |
1738 layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); | |
1739 break; | |
1740 case 5: | |
1741 EndTest(); | |
1742 break; | |
1743 default: | |
1744 NOTREACHED() << layer_tree_host()->source_frame_number(); | |
1745 break; | |
1746 } | |
1747 } | |
1748 | |
1749 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
1750 ASSERT_EQ(1u, impl->settings().max_partial_texture_updates); | |
1751 | |
1752 TestWebGraphicsContext3D* context = TestContext(); | |
1753 | |
1754 switch (impl->active_tree()->source_frame_number()) { | |
1755 case 0: | |
1756 // Number of textures should be one for each layer. | |
1757 ASSERT_EQ(2u, context->NumTextures()); | |
1758 // Number of textures used for commit should be one for each layer. | |
1759 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1760 // Verify that used textures are correct. | |
1761 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
1762 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
1763 context->ResetUsedTextures(); | |
1764 break; | |
1765 case 1: | |
1766 if (HasImplThread()) { | |
1767 // Number of textures should be two for each content layer. | |
1768 ASSERT_EQ(4u, context->NumTextures()); | |
1769 } else { | |
1770 // In single thread we can always do partial updates, so the limit has | |
1771 // no effect. | |
1772 ASSERT_EQ(2u, context->NumTextures()); | |
1773 } | |
1774 // Number of textures used for commit should be one for each content | |
1775 // layer. | |
1776 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1777 | |
1778 if (HasImplThread()) { | |
1779 // First content textures should not have been used. | |
1780 EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); | |
1781 EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); | |
1782 // New textures should have been used. | |
1783 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
1784 EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); | |
1785 } else { | |
1786 // In single thread we can always do partial updates, so the limit has | |
1787 // no effect. | |
1788 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
1789 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
1790 } | |
1791 | |
1792 context->ResetUsedTextures(); | |
1793 break; | |
1794 case 2: | |
1795 if (HasImplThread()) { | |
1796 // Number of textures should be two for each content layer. | |
1797 ASSERT_EQ(4u, context->NumTextures()); | |
1798 } else { | |
1799 // In single thread we can always do partial updates, so the limit has | |
1800 // no effect. | |
1801 ASSERT_EQ(2u, context->NumTextures()); | |
1802 } | |
1803 // Number of textures used for commit should be one for each content | |
1804 // layer. | |
1805 EXPECT_EQ(2u, context->NumUsedTextures()); | |
1806 | |
1807 if (HasImplThread()) { | |
1808 // One content layer does a partial update also. | |
1809 EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); | |
1810 EXPECT_FALSE(context->UsedTexture(context->TextureAt(3))); | |
1811 } else { | |
1812 // In single thread we can always do partial updates, so the limit has | |
1813 // no effect. | |
1814 EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); | |
1815 EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); | |
1816 } | |
1817 | |
1818 context->ResetUsedTextures(); | |
1819 break; | |
1820 case 3: | |
1821 // No textures should be used for commit. | |
1822 EXPECT_EQ(0u, context->NumUsedTextures()); | |
1823 | |
1824 context->ResetUsedTextures(); | |
1825 break; | |
1826 case 4: | |
1827 // Number of textures used for commit should be one, for the | |
1828 // content layer. | |
1829 EXPECT_EQ(1u, context->NumUsedTextures()); | |
1830 | |
1831 context->ResetUsedTextures(); | |
1832 break; | |
1833 default: | |
1834 NOTREACHED(); | |
1835 break; | |
1836 } | |
1837 } | |
1838 | |
1839 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
1840 EXPECT_LT(impl->active_tree()->source_frame_number(), 5); | |
1841 | |
1842 TestWebGraphicsContext3D* context = TestContext(); | |
1843 | |
1844 // Number of textures used for drawing should one per layer except for | |
1845 // frame 3 where the viewport only contains one layer. | |
1846 if (impl->active_tree()->source_frame_number() == 3) { | |
1847 EXPECT_EQ(1u, context->NumUsedTextures()); | |
1848 } else { | |
1849 EXPECT_EQ(2u, context->NumUsedTextures()) | |
1850 << "For frame " << impl->active_tree()->source_frame_number(); | |
1851 } | |
1852 | |
1853 context->ResetUsedTextures(); | |
1854 } | |
1855 | |
1856 void AfterTest() override {} | |
1857 | |
1858 private: | |
1859 FakeContentLayerClient client_; | |
1860 scoped_refptr<FakeContentLayer> parent_; | |
1861 scoped_refptr<FakeContentLayer> child_; | |
1862 }; | |
1863 | |
1864 // Partial updates are not possible with a delegating renderer. | |
1865 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | |
1866 LayerTreeHostTestAtomicCommitWithPartialUpdate); | |
1867 | |
1868 // TODO(sohanjg) : Make it work with impl-side painting. | |
1869 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit | |
1870 : public LayerTreeHostTest { | |
1871 protected: | |
1872 void SetupTree() override { | |
1873 root_layer_ = FakeContentLayer::Create(&client_); | |
1874 root_layer_->SetBounds(gfx::Size(100, 100)); | |
1875 | |
1876 surface_layer1_ = FakeContentLayer::Create(&client_); | |
1877 surface_layer1_->SetBounds(gfx::Size(100, 100)); | |
1878 surface_layer1_->SetForceRenderSurface(true); | |
1879 surface_layer1_->SetOpacity(0.5f); | |
1880 root_layer_->AddChild(surface_layer1_); | |
1881 | |
1882 surface_layer2_ = FakeContentLayer::Create(&client_); | |
1883 surface_layer2_->SetBounds(gfx::Size(100, 100)); | |
1884 surface_layer2_->SetForceRenderSurface(true); | |
1885 surface_layer2_->SetOpacity(0.5f); | |
1886 surface_layer1_->AddChild(surface_layer2_); | |
1887 | |
1888 replica_layer1_ = FakeContentLayer::Create(&client_); | |
1889 surface_layer1_->SetReplicaLayer(replica_layer1_.get()); | |
1890 | |
1891 replica_layer2_ = FakeContentLayer::Create(&client_); | |
1892 surface_layer2_->SetReplicaLayer(replica_layer2_.get()); | |
1893 | |
1894 layer_tree_host()->SetRootLayer(root_layer_); | |
1895 LayerTreeHostTest::SetupTree(); | |
1896 } | |
1897 | |
1898 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
1899 | |
1900 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
1901 Renderer* renderer = host_impl->renderer(); | |
1902 RenderPassId surface1_render_pass_id = host_impl->active_tree() | |
1903 ->root_layer() | |
1904 ->children()[0] | |
1905 ->render_surface() | |
1906 ->GetRenderPassId(); | |
1907 RenderPassId surface2_render_pass_id = host_impl->active_tree() | |
1908 ->root_layer() | |
1909 ->children()[0] | |
1910 ->children()[0] | |
1911 ->render_surface() | |
1912 ->GetRenderPassId(); | |
1913 | |
1914 switch (host_impl->active_tree()->source_frame_number()) { | |
1915 case 0: | |
1916 EXPECT_TRUE( | |
1917 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); | |
1918 EXPECT_TRUE( | |
1919 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); | |
1920 | |
1921 // Reduce the memory limit to only fit the root layer and one render | |
1922 // surface. This prevents any contents drawing into surfaces | |
1923 // from being allocated. | |
1924 host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2)); | |
1925 break; | |
1926 case 1: | |
1927 EXPECT_FALSE( | |
1928 renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id)); | |
1929 EXPECT_FALSE( | |
1930 renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id)); | |
1931 | |
1932 EndTest(); | |
1933 break; | |
1934 } | |
1935 } | |
1936 | |
1937 void DidCommitAndDrawFrame() override { | |
1938 if (layer_tree_host()->source_frame_number() < 2) | |
1939 root_layer_->SetNeedsDisplay(); | |
1940 } | |
1941 | |
1942 void AfterTest() override { | |
1943 EXPECT_LE(2u, root_layer_->update_count()); | |
1944 EXPECT_LE(2u, surface_layer1_->update_count()); | |
1945 EXPECT_LE(2u, surface_layer2_->update_count()); | |
1946 } | |
1947 | |
1948 FakeContentLayerClient client_; | |
1949 scoped_refptr<FakeContentLayer> root_layer_; | |
1950 scoped_refptr<FakeContentLayer> surface_layer1_; | |
1951 scoped_refptr<FakeContentLayer> replica_layer1_; | |
1952 scoped_refptr<FakeContentLayer> surface_layer2_; | |
1953 scoped_refptr<FakeContentLayer> replica_layer2_; | |
1954 }; | |
1955 | |
1956 // Surfaces don't exist with a delegated renderer. | |
1957 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( | |
1958 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit); | |
1959 | |
1960 class EvictionTestLayer : public Layer { | |
1961 public: | |
1962 static scoped_refptr<EvictionTestLayer> Create() { | |
1963 return make_scoped_refptr(new EvictionTestLayer()); | |
1964 } | |
1965 | |
1966 bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override; | |
1967 bool DrawsContent() const override { return true; } | |
1968 | |
1969 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; | |
1970 void PushPropertiesTo(LayerImpl* impl) override; | |
1971 void SetTexturePriorities(const PriorityCalculator&) override; | |
1972 | |
1973 bool HaveBackingTexture() const { | |
1974 return texture_.get() ? texture_->have_backing_texture() : false; | |
1975 } | |
1976 | |
1977 private: | |
1978 EvictionTestLayer() : Layer() {} | |
1979 ~EvictionTestLayer() override {} | |
1980 | |
1981 void CreateTextureIfNeeded() { | |
1982 if (texture_) | |
1983 return; | |
1984 texture_ = PrioritizedResource::Create( | |
1985 layer_tree_host()->contents_texture_manager()); | |
1986 texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888); | |
1987 bitmap_.allocN32Pixels(10, 10); | |
1988 } | |
1989 | |
1990 scoped_ptr<PrioritizedResource> texture_; | |
1991 SkBitmap bitmap_; | |
1992 }; | |
1993 | |
1994 class EvictionTestLayerImpl : public LayerImpl { | |
1995 public: | |
1996 static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl, | |
1997 int id) { | |
1998 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id)); | |
1999 } | |
2000 ~EvictionTestLayerImpl() override {} | |
2001 | |
2002 void AppendQuads(RenderPass* render_pass, | |
2003 AppendQuadsData* append_quads_data) override { | |
2004 ASSERT_TRUE(has_texture_); | |
2005 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources()); | |
2006 } | |
2007 | |
2008 void SetHasTexture(bool has_texture) { has_texture_ = has_texture; } | |
2009 | |
2010 private: | |
2011 EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id) | |
2012 : LayerImpl(tree_impl, id), has_texture_(false) {} | |
2013 | |
2014 bool has_texture_; | |
2015 }; | |
2016 | |
2017 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) { | |
2018 CreateTextureIfNeeded(); | |
2019 if (!texture_) | |
2020 return; | |
2021 texture_->set_request_priority(PriorityCalculator::UIPriority(true)); | |
2022 } | |
2023 | |
2024 bool EvictionTestLayer::Update(ResourceUpdateQueue* queue, | |
2025 const OcclusionTracker<Layer>* occlusion) { | |
2026 CreateTextureIfNeeded(); | |
2027 if (!texture_) | |
2028 return false; | |
2029 | |
2030 gfx::Rect full_rect(0, 0, 10, 10); | |
2031 ResourceUpdate upload = ResourceUpdate::Create( | |
2032 texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d()); | |
2033 queue->AppendFullUpload(upload); | |
2034 return true; | |
2035 } | |
2036 | |
2037 scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl( | |
2038 LayerTreeImpl* tree_impl) { | |
2039 return EvictionTestLayerImpl::Create(tree_impl, layer_id_); | |
2040 } | |
2041 | |
2042 void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) { | |
2043 Layer::PushPropertiesTo(layer_impl); | |
2044 | |
2045 EvictionTestLayerImpl* test_layer_impl = | |
2046 static_cast<EvictionTestLayerImpl*>(layer_impl); | |
2047 test_layer_impl->SetHasTexture(texture_->have_backing_texture()); | |
2048 } | |
2049 | |
2050 class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { | |
2051 public: | |
2052 LayerTreeHostTestEvictTextures() | |
2053 : layer_(EvictionTestLayer::Create()), | |
2054 impl_for_evict_textures_(0), | |
2055 num_commits_(0) {} | |
2056 | |
2057 void BeginTest() override { | |
2058 layer_tree_host()->SetRootLayer(layer_); | |
2059 layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); | |
2060 | |
2061 gfx::Transform identity_matrix; | |
2062 SetLayerPropertiesForTesting(layer_.get(), | |
2063 0, | |
2064 identity_matrix, | |
2065 gfx::Point3F(0.f, 0.f, 0.f), | |
2066 gfx::PointF(0.f, 0.f), | |
2067 gfx::Size(10, 20), | |
2068 true); | |
2069 | |
2070 PostSetNeedsCommitToMainThread(); | |
2071 } | |
2072 | |
2073 void PostEvictTextures() { | |
2074 ImplThreadTaskRunner()->PostTask( | |
2075 FROM_HERE, | |
2076 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread, | |
2077 base::Unretained(this))); | |
2078 } | |
2079 | |
2080 void EvictTexturesOnImplThread() { | |
2081 DCHECK(impl_for_evict_textures_); | |
2082 impl_for_evict_textures_->EvictTexturesForTesting(); | |
2083 } | |
2084 | |
2085 // Commit 1: Just commit and draw normally, then post an eviction at the end | |
2086 // that will trigger a commit. | |
2087 // Commit 2: Triggered by the eviction, let it go through and then set | |
2088 // needsCommit. | |
2089 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction | |
2090 // task, which will be handled before the commit. Don't set needsCommit, it | |
2091 // should have been posted. A frame should not be drawn (note, | |
2092 // didCommitAndDrawFrame may be called anyway). | |
2093 // Commit 4: Triggered by the eviction, let it go through and then set | |
2094 // needsCommit. | |
2095 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in | |
2096 // Layout(), a frame should not be drawn but a commit will be posted. | |
2097 // Commit 6: Triggered by the eviction, post an eviction task in | |
2098 // Layout(), which will be a noop, letting the commit (which recreates the | |
2099 // textures) go through and draw a frame, then end the test. | |
2100 // | |
2101 // Commits 1+2 test the eviction recovery path where eviction happens outside | |
2102 // of the beginFrame/commit pair. | |
2103 // Commits 3+4 test the eviction recovery path where eviction happens inside | |
2104 // the beginFrame/commit pair. | |
2105 // Commits 5+6 test the path where an eviction happens during the eviction | |
2106 // recovery path. | |
2107 void DidCommit() override { | |
2108 switch (num_commits_) { | |
2109 case 1: | |
2110 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
2111 PostEvictTextures(); | |
2112 break; | |
2113 case 2: | |
2114 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
2115 layer_tree_host()->SetNeedsCommit(); | |
2116 break; | |
2117 case 3: | |
2118 break; | |
2119 case 4: | |
2120 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
2121 layer_tree_host()->SetNeedsCommit(); | |
2122 break; | |
2123 case 5: | |
2124 break; | |
2125 case 6: | |
2126 EXPECT_TRUE(layer_->HaveBackingTexture()); | |
2127 EndTest(); | |
2128 break; | |
2129 default: | |
2130 NOTREACHED(); | |
2131 break; | |
2132 } | |
2133 } | |
2134 | |
2135 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
2136 impl_for_evict_textures_ = impl; | |
2137 } | |
2138 | |
2139 void Layout() override { | |
2140 ++num_commits_; | |
2141 switch (num_commits_) { | |
2142 case 1: | |
2143 case 2: | |
2144 break; | |
2145 case 3: | |
2146 PostEvictTextures(); | |
2147 break; | |
2148 case 4: | |
2149 // We couldn't check in didCommitAndDrawFrame on commit 3, | |
2150 // so check here. | |
2151 EXPECT_FALSE(layer_->HaveBackingTexture()); | |
2152 break; | |
2153 case 5: | |
2154 PostEvictTextures(); | |
2155 break; | |
2156 case 6: | |
2157 // We couldn't check in didCommitAndDrawFrame on commit 5, | |
2158 // so check here. | |
2159 EXPECT_FALSE(layer_->HaveBackingTexture()); | |
2160 PostEvictTextures(); | |
2161 break; | |
2162 default: | |
2163 NOTREACHED(); | |
2164 break; | |
2165 } | |
2166 } | |
2167 | |
2168 void AfterTest() override {} | |
2169 | |
2170 private: | |
2171 FakeContentLayerClient client_; | |
2172 scoped_refptr<EvictionTestLayer> layer_; | |
2173 LayerTreeHostImpl* impl_for_evict_textures_; | |
2174 int num_commits_; | |
2175 }; | |
2176 | |
2177 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures); | |
2178 | |
2179 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { | |
2180 public: | |
2181 LayerTreeHostTestContinuousInvalidate() | |
2182 : num_commit_complete_(0), num_draw_layers_(0) {} | |
2183 | |
2184 void BeginTest() override { | |
2185 layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); | |
2186 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); | |
2187 | |
2188 if (layer_tree_host()->settings().impl_side_painting) | |
2189 layer_ = FakePictureLayer::Create(&client_); | |
2190 else | |
2191 layer_ = FakeContentLayer::Create(&client_); | |
2192 | |
2193 layer_->SetBounds(gfx::Size(10, 10)); | |
2194 layer_->SetPosition(gfx::PointF(0.f, 0.f)); | |
2195 layer_->SetIsDrawable(true); | |
2196 layer_tree_host()->root_layer()->AddChild(layer_); | |
2197 | |
2198 PostSetNeedsCommitToMainThread(); | |
2199 } | |
2200 | |
2201 void DidCommitAndDrawFrame() override { | |
2202 if (num_draw_layers_ == 2) | |
2203 return; | |
2204 layer_->SetNeedsDisplay(); | |
2205 } | |
2206 | |
2207 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
2208 if (num_draw_layers_ == 1) | |
2209 num_commit_complete_++; | |
2210 } | |
2211 | |
2212 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
2213 num_draw_layers_++; | |
2214 if (num_draw_layers_ == 2) | |
2215 EndTest(); | |
2216 } | |
2217 | |
2218 void AfterTest() override { | |
2219 // Check that we didn't commit twice between first and second draw. | |
2220 EXPECT_EQ(1, num_commit_complete_); | |
2221 } | |
2222 | |
2223 private: | |
2224 FakeContentLayerClient client_; | |
2225 scoped_refptr<Layer> layer_; | |
2226 int num_commit_complete_; | |
2227 int num_draw_layers_; | |
2228 }; | |
2229 | |
2230 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate); | |
2231 | |
2232 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { | |
2233 public: | |
2234 LayerTreeHostTestDeferCommits() | |
2235 : num_will_begin_impl_frame_(0), | |
2236 num_send_begin_main_frame_(0) {} | |
2237 | |
2238 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2239 | |
2240 void WillBeginImplFrame(const BeginFrameArgs& args) override { | |
2241 num_will_begin_impl_frame_++; | |
2242 switch (num_will_begin_impl_frame_) { | |
2243 case 1: | |
2244 break; | |
2245 case 2: | |
2246 PostSetNeedsCommitToMainThread(); | |
2247 break; | |
2248 case 3: | |
2249 PostSetDeferCommitsToMainThread(false); | |
2250 break; | |
2251 default: | |
2252 // Sometimes |num_will_begin_impl_frame_| will be greater than 3 if the | |
2253 // main thread is slow to respond. | |
2254 break; | |
2255 } | |
2256 } | |
2257 | |
2258 void ScheduledActionSendBeginMainFrame() override { | |
2259 num_send_begin_main_frame_++; | |
2260 switch (num_send_begin_main_frame_) { | |
2261 case 1: | |
2262 PostSetDeferCommitsToMainThread(true); | |
2263 break; | |
2264 case 2: | |
2265 EndTest(); | |
2266 break; | |
2267 default: | |
2268 NOTREACHED(); | |
2269 break; | |
2270 } | |
2271 } | |
2272 | |
2273 void AfterTest() override { | |
2274 EXPECT_GE(num_will_begin_impl_frame_, 3); | |
2275 EXPECT_EQ(2, num_send_begin_main_frame_); | |
2276 } | |
2277 | |
2278 private: | |
2279 int num_will_begin_impl_frame_; | |
2280 int num_send_begin_main_frame_; | |
2281 }; | |
2282 | |
2283 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); | |
2284 | |
2285 class LayerTreeHostWithProxy : public LayerTreeHost { | |
2286 public: | |
2287 LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, | |
2288 const LayerTreeSettings& settings, | |
2289 scoped_ptr<FakeProxy> proxy) | |
2290 : LayerTreeHost(client, NULL, NULL, NULL, settings) { | |
2291 proxy->SetLayerTreeHost(this); | |
2292 client->SetLayerTreeHost(this); | |
2293 InitializeForTesting(proxy.Pass()); | |
2294 } | |
2295 }; | |
2296 | |
2297 TEST(LayerTreeHostTest, LimitPartialUpdates) { | |
2298 // When partial updates are not allowed, max updates should be 0. | |
2299 { | |
2300 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
2301 | |
2302 scoped_ptr<FakeProxy> proxy(new FakeProxy); | |
2303 proxy->GetRendererCapabilities().allow_partial_texture_updates = false; | |
2304 proxy->SetMaxPartialTextureUpdates(5); | |
2305 | |
2306 LayerTreeSettings settings; | |
2307 settings.impl_side_painting = false; | |
2308 settings.max_partial_texture_updates = 10; | |
2309 | |
2310 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); | |
2311 | |
2312 EXPECT_EQ(0u, host.MaxPartialTextureUpdates()); | |
2313 } | |
2314 | |
2315 // When partial updates are allowed, | |
2316 // max updates should be limited by the proxy. | |
2317 { | |
2318 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
2319 | |
2320 scoped_ptr<FakeProxy> proxy(new FakeProxy); | |
2321 proxy->GetRendererCapabilities().allow_partial_texture_updates = true; | |
2322 proxy->SetMaxPartialTextureUpdates(5); | |
2323 | |
2324 LayerTreeSettings settings; | |
2325 settings.impl_side_painting = false; | |
2326 settings.max_partial_texture_updates = 10; | |
2327 | |
2328 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); | |
2329 | |
2330 EXPECT_EQ(5u, host.MaxPartialTextureUpdates()); | |
2331 } | |
2332 | |
2333 // When partial updates are allowed, | |
2334 // max updates should also be limited by the settings. | |
2335 { | |
2336 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
2337 | |
2338 scoped_ptr<FakeProxy> proxy(new FakeProxy); | |
2339 proxy->GetRendererCapabilities().allow_partial_texture_updates = true; | |
2340 proxy->SetMaxPartialTextureUpdates(20); | |
2341 | |
2342 LayerTreeSettings settings; | |
2343 settings.impl_side_painting = false; | |
2344 settings.max_partial_texture_updates = 10; | |
2345 | |
2346 LayerTreeHostWithProxy host(&client, settings, proxy.Pass()); | |
2347 | |
2348 EXPECT_EQ(10u, host.MaxPartialTextureUpdates()); | |
2349 } | |
2350 } | |
2351 | |
2352 TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { | |
2353 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); | |
2354 | |
2355 LayerTreeSettings settings; | |
2356 settings.max_partial_texture_updates = 4; | |
2357 settings.single_thread_proxy_scheduler = false; | |
2358 settings.impl_side_painting = false; | |
2359 | |
2360 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
2361 new TestSharedBitmapManager()); | |
2362 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
2363 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
2364 base::MessageLoopProxy::current(), nullptr); | |
2365 client.SetLayerTreeHost(host.get()); | |
2366 host->Composite(base::TimeTicks::Now()); | |
2367 | |
2368 EXPECT_EQ(4u, host->settings().max_partial_texture_updates); | |
2369 } | |
2370 | |
2371 TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { | |
2372 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE); | |
2373 | |
2374 LayerTreeSettings settings; | |
2375 settings.max_partial_texture_updates = 4; | |
2376 settings.single_thread_proxy_scheduler = false; | |
2377 settings.impl_side_painting = false; | |
2378 | |
2379 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
2380 new TestSharedBitmapManager()); | |
2381 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
2382 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
2383 base::MessageLoopProxy::current(), nullptr); | |
2384 client.SetLayerTreeHost(host.get()); | |
2385 host->Composite(base::TimeTicks::Now()); | |
2386 | |
2387 EXPECT_EQ(4u, host->settings().max_partial_texture_updates); | |
2388 } | |
2389 | |
2390 TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { | |
2391 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D); | |
2392 | |
2393 LayerTreeSettings settings; | |
2394 settings.max_partial_texture_updates = 4; | |
2395 settings.single_thread_proxy_scheduler = false; | |
2396 settings.impl_side_painting = false; | |
2397 | |
2398 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
2399 new TestSharedBitmapManager()); | |
2400 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
2401 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
2402 base::MessageLoopProxy::current(), nullptr); | |
2403 client.SetLayerTreeHost(host.get()); | |
2404 host->Composite(base::TimeTicks::Now()); | |
2405 | |
2406 EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); | |
2407 } | |
2408 | |
2409 TEST(LayerTreeHostTest, | |
2410 PartialUpdatesWithDelegatingRendererAndSoftwareContent) { | |
2411 FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE); | |
2412 | |
2413 LayerTreeSettings settings; | |
2414 settings.max_partial_texture_updates = 4; | |
2415 settings.single_thread_proxy_scheduler = false; | |
2416 settings.impl_side_painting = false; | |
2417 | |
2418 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( | |
2419 new TestSharedBitmapManager()); | |
2420 scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( | |
2421 &client, &client, shared_bitmap_manager.get(), NULL, NULL, settings, | |
2422 base::MessageLoopProxy::current(), nullptr); | |
2423 client.SetLayerTreeHost(host.get()); | |
2424 host->Composite(base::TimeTicks::Now()); | |
2425 | |
2426 EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); | |
2427 } | |
2428 | |
2429 // TODO(sohanjg) : Remove it once impl-side painting ships everywhere. | |
2430 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted | |
2431 : public LayerTreeHostTest { | |
2432 public: | |
2433 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted() | |
2434 : root_layer_(FakeContentLayer::Create(&client_)), | |
2435 child_layer1_(FakeContentLayer::Create(&client_)), | |
2436 child_layer2_(FakeContentLayer::Create(&client_)), | |
2437 num_commits_(0) {} | |
2438 | |
2439 void BeginTest() override { | |
2440 layer_tree_host()->SetViewportSize(gfx::Size(100, 100)); | |
2441 root_layer_->SetBounds(gfx::Size(100, 100)); | |
2442 child_layer1_->SetBounds(gfx::Size(100, 100)); | |
2443 child_layer2_->SetBounds(gfx::Size(100, 100)); | |
2444 root_layer_->AddChild(child_layer1_); | |
2445 root_layer_->AddChild(child_layer2_); | |
2446 layer_tree_host()->SetRootLayer(root_layer_); | |
2447 PostSetNeedsCommitToMainThread(); | |
2448 } | |
2449 | |
2450 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, | |
2451 bool visible) override { | |
2452 if (visible) { | |
2453 // One backing should remain unevicted. | |
2454 EXPECT_EQ(100u * 100u * 4u * 1u, | |
2455 contents_texture_manager_->MemoryUseBytes()); | |
2456 } else { | |
2457 EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes()); | |
2458 } | |
2459 | |
2460 // Make sure that contents textures are marked as having been | |
2461 // purged. | |
2462 EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged()); | |
2463 // End the test in this state. | |
2464 EndTest(); | |
2465 } | |
2466 | |
2467 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
2468 ++num_commits_; | |
2469 switch (num_commits_) { | |
2470 case 1: | |
2471 // All three backings should have memory. | |
2472 EXPECT_EQ(100u * 100u * 4u * 3u, | |
2473 contents_texture_manager_->MemoryUseBytes()); | |
2474 | |
2475 // Set a new policy that will kick out 1 of the 3 resources. | |
2476 // Because a resource was evicted, a commit will be kicked off. | |
2477 host_impl->SetMemoryPolicy( | |
2478 ManagedMemoryPolicy(100 * 100 * 4 * 2, | |
2479 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, | |
2480 1000)); | |
2481 break; | |
2482 case 2: | |
2483 // Only two backings should have memory. | |
2484 EXPECT_EQ(100u * 100u * 4u * 2u, | |
2485 contents_texture_manager_->MemoryUseBytes()); | |
2486 // Become backgrounded, which will cause 1 more resource to be | |
2487 // evicted. | |
2488 PostSetVisibleToMainThread(false); | |
2489 break; | |
2490 default: | |
2491 // No further commits should happen because this is not visible | |
2492 // anymore. | |
2493 NOTREACHED(); | |
2494 break; | |
2495 } | |
2496 } | |
2497 | |
2498 void AfterTest() override {} | |
2499 | |
2500 private: | |
2501 FakeContentLayerClient client_; | |
2502 scoped_refptr<FakeContentLayer> root_layer_; | |
2503 scoped_refptr<FakeContentLayer> child_layer1_; | |
2504 scoped_refptr<FakeContentLayer> child_layer2_; | |
2505 int num_commits_; | |
2506 }; | |
2507 | |
2508 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( | |
2509 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted); | |
2510 | |
2511 class LayerTreeHostTestLCDChange : public LayerTreeHostTest { | |
2512 public: | |
2513 void SetupTree() override { | |
2514 num_tiles_rastered_ = 0; | |
2515 | |
2516 scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_); | |
2517 client_.set_fill_with_nonsolid_color(true); | |
2518 root_layer->SetIsDrawable(true); | |
2519 root_layer->SetBounds(gfx::Size(10, 10)); | |
2520 root_layer->SetContentsOpaque(true); | |
2521 | |
2522 layer_tree_host()->SetRootLayer(root_layer); | |
2523 | |
2524 // The expectations are based on the assumption that the default | |
2525 // LCD settings are: | |
2526 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text); | |
2527 | |
2528 LayerTreeHostTest::SetupTree(); | |
2529 } | |
2530 | |
2531 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2532 | |
2533 void DidCommitAndDrawFrame() override { | |
2534 switch (layer_tree_host()->source_frame_number()) { | |
2535 case 1: | |
2536 PostSetNeedsCommitToMainThread(); | |
2537 break; | |
2538 case 2: | |
2539 // Change layer opacity that should trigger lcd change. | |
2540 layer_tree_host()->root_layer()->SetOpacity(.5f); | |
2541 break; | |
2542 case 3: | |
2543 // Change layer opacity that should not trigger lcd change. | |
2544 layer_tree_host()->root_layer()->SetOpacity(1.f); | |
2545 break; | |
2546 case 4: | |
2547 EndTest(); | |
2548 break; | |
2549 } | |
2550 } | |
2551 | |
2552 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, | |
2553 const Tile* tile) override { | |
2554 ++num_tiles_rastered_; | |
2555 } | |
2556 | |
2557 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
2558 PictureLayerImpl* root_layer = | |
2559 static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); | |
2560 bool can_use_lcd_text = | |
2561 host_impl->active_tree()->root_layer()->can_use_lcd_text(); | |
2562 switch (host_impl->active_tree()->source_frame_number()) { | |
2563 case 0: | |
2564 // The first draw. | |
2565 EXPECT_EQ(1, num_tiles_rastered_); | |
2566 EXPECT_TRUE(can_use_lcd_text); | |
2567 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); | |
2568 break; | |
2569 case 1: | |
2570 // Nothing changed on the layer. | |
2571 EXPECT_EQ(1, num_tiles_rastered_); | |
2572 EXPECT_TRUE(can_use_lcd_text); | |
2573 EXPECT_TRUE(root_layer->RasterSourceUsesLCDText()); | |
2574 break; | |
2575 case 2: | |
2576 // LCD text was disabled; it should be re-rastered with LCD text off. | |
2577 EXPECT_EQ(2, num_tiles_rastered_); | |
2578 EXPECT_FALSE(can_use_lcd_text); | |
2579 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); | |
2580 break; | |
2581 case 3: | |
2582 // LCD text was enabled, but it's sticky and stays off. | |
2583 EXPECT_EQ(2, num_tiles_rastered_); | |
2584 EXPECT_TRUE(can_use_lcd_text); | |
2585 EXPECT_FALSE(root_layer->RasterSourceUsesLCDText()); | |
2586 break; | |
2587 } | |
2588 } | |
2589 | |
2590 void AfterTest() override {} | |
2591 | |
2592 private: | |
2593 FakeContentLayerClient client_; | |
2594 int num_tiles_rastered_; | |
2595 }; | |
2596 | |
2597 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange); | |
2598 | |
2599 // Verify that the BeginFrame notification is used to initiate rendering. | |
2600 class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { | |
2601 public: | |
2602 void InitializeSettings(LayerTreeSettings* settings) override { | |
2603 settings->use_external_begin_frame_source = true; | |
2604 } | |
2605 | |
2606 void BeginTest() override { | |
2607 // This will trigger a SetNeedsBeginFrame which will trigger a | |
2608 // BeginFrame. | |
2609 PostSetNeedsCommitToMainThread(); | |
2610 } | |
2611 | |
2612 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
2613 LayerTreeHostImpl::FrameData* frame, | |
2614 DrawResult draw_result) override { | |
2615 EndTest(); | |
2616 return DRAW_SUCCESS; | |
2617 } | |
2618 | |
2619 void AfterTest() override {} | |
2620 | |
2621 private: | |
2622 base::TimeTicks frame_time_; | |
2623 }; | |
2624 | |
2625 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); | |
2626 | |
2627 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled | |
2628 : public LayerTreeHostTest { | |
2629 public: | |
2630 void InitializeSettings(LayerTreeSettings* settings) override { | |
2631 settings->use_external_begin_frame_source = true; | |
2632 settings->using_synchronous_renderer_compositor = true; | |
2633 } | |
2634 | |
2635 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2636 | |
2637 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
2638 // The BeginFrame notification is turned off now but will get enabled | |
2639 // once we return. End test while it's enabled. | |
2640 ImplThreadTaskRunner()->PostTask( | |
2641 FROM_HERE, | |
2642 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest, | |
2643 base::Unretained(this))); | |
2644 } | |
2645 | |
2646 void AfterTest() override {} | |
2647 }; | |
2648 | |
2649 MULTI_THREAD_TEST_F( | |
2650 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled); | |
2651 | |
2652 class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { | |
2653 protected: | |
2654 LayerTreeHostTestAbortedCommitDoesntStall() | |
2655 : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {} | |
2656 | |
2657 void InitializeSettings(LayerTreeSettings* settings) override { | |
2658 settings->use_external_begin_frame_source = true; | |
2659 } | |
2660 | |
2661 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2662 | |
2663 void DidCommit() override { | |
2664 commit_count_++; | |
2665 if (commit_count_ == 4) { | |
2666 // After two aborted commits, request a real commit now to make sure a | |
2667 // real commit following an aborted commit will still complete and | |
2668 // end the test even when the Impl thread is idle. | |
2669 layer_tree_host()->SetNeedsCommit(); | |
2670 } | |
2671 } | |
2672 | |
2673 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, | |
2674 CommitEarlyOutReason reason) override { | |
2675 commit_abort_count_++; | |
2676 // Initiate another abortable commit. | |
2677 host_impl->SetNeedsCommit(); | |
2678 } | |
2679 | |
2680 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
2681 commit_complete_count_++; | |
2682 if (commit_complete_count_ == 1) { | |
2683 // Initiate an abortable commit after the first commit. | |
2684 host_impl->SetNeedsCommit(); | |
2685 } else { | |
2686 EndTest(); | |
2687 } | |
2688 } | |
2689 | |
2690 void AfterTest() override { | |
2691 EXPECT_EQ(commit_count_, 5); | |
2692 EXPECT_EQ(commit_abort_count_, 3); | |
2693 EXPECT_EQ(commit_complete_count_, 2); | |
2694 } | |
2695 | |
2696 int commit_count_; | |
2697 int commit_abort_count_; | |
2698 int commit_complete_count_; | |
2699 }; | |
2700 | |
2701 class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor | |
2702 : public LayerTreeHostTestAbortedCommitDoesntStall { | |
2703 void InitializeSettings(LayerTreeSettings* settings) override { | |
2704 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); | |
2705 settings->using_synchronous_renderer_compositor = true; | |
2706 } | |
2707 }; | |
2708 | |
2709 MULTI_THREAD_TEST_F( | |
2710 LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor); | |
2711 | |
2712 class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync | |
2713 : public LayerTreeHostTestAbortedCommitDoesntStall { | |
2714 void InitializeSettings(LayerTreeSettings* settings) override { | |
2715 LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); | |
2716 settings->throttle_frame_production = false; | |
2717 } | |
2718 }; | |
2719 | |
2720 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync); | |
2721 | |
2722 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation | |
2723 : public LayerTreeHostTest { | |
2724 protected: | |
2725 void InitializeSettings(LayerTreeSettings* settings) override { | |
2726 settings->impl_side_painting = true; | |
2727 } | |
2728 | |
2729 void SetupTree() override { | |
2730 LayerTreeHostTest::SetupTree(); | |
2731 | |
2732 scoped_refptr<Layer> layer = PictureLayer::Create(&client_); | |
2733 layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); | |
2734 layer->SetBounds(gfx::Size(10, 10)); | |
2735 layer_tree_host()->root_layer()->AddChild(layer); | |
2736 } | |
2737 | |
2738 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2739 | |
2740 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
2741 EndTest(); | |
2742 } | |
2743 | |
2744 void AfterTest() override {} | |
2745 | |
2746 FakeContentLayerClient client_; | |
2747 }; | |
2748 | |
2749 MULTI_THREAD_TEST_F( | |
2750 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation); | |
2751 | |
2752 class LayerTreeHostTestChangeLayerPropertiesInPaintContents | |
2753 : public LayerTreeHostTest { | |
2754 public: | |
2755 class SetBoundsClient : public ContentLayerClient { | |
2756 public: | |
2757 SetBoundsClient() : layer_(0) {} | |
2758 | |
2759 void set_layer(Layer* layer) { layer_ = layer; } | |
2760 | |
2761 void PaintContents(SkCanvas* canvas, | |
2762 const gfx::Rect& clip, | |
2763 PaintingControlSetting picture_control) override { | |
2764 layer_->SetBounds(gfx::Size(2, 2)); | |
2765 } | |
2766 | |
2767 scoped_refptr<DisplayItemList> PaintContentsToDisplayList( | |
2768 const gfx::Rect& clip, | |
2769 PaintingControlSetting picture_control) override { | |
2770 NOTIMPLEMENTED(); | |
2771 return DisplayItemList::Create(); | |
2772 } | |
2773 | |
2774 bool FillsBoundsCompletely() const override { return false; } | |
2775 | |
2776 private: | |
2777 Layer* layer_; | |
2778 }; | |
2779 | |
2780 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {} | |
2781 | |
2782 void SetupTree() override { | |
2783 if (layer_tree_host()->settings().impl_side_painting) { | |
2784 scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_); | |
2785 layer_tree_host()->SetRootLayer(root_layer); | |
2786 } else { | |
2787 scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); | |
2788 layer_tree_host()->SetRootLayer(root_layer); | |
2789 } | |
2790 Layer* root_layer = layer_tree_host()->root_layer(); | |
2791 root_layer->SetIsDrawable(true); | |
2792 root_layer->SetBounds(gfx::Size(1, 1)); | |
2793 | |
2794 client_.set_layer(root_layer); | |
2795 | |
2796 LayerTreeHostTest::SetupTree(); | |
2797 } | |
2798 | |
2799 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2800 void AfterTest() override {} | |
2801 | |
2802 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
2803 num_commits_++; | |
2804 if (num_commits_ == 1) { | |
2805 LayerImpl* root_layer = host_impl->active_tree()->root_layer(); | |
2806 EXPECT_EQ(gfx::Size(1, 1), root_layer->bounds()); | |
2807 } else { | |
2808 LayerImpl* root_layer = host_impl->active_tree()->root_layer(); | |
2809 EXPECT_EQ(gfx::Size(2, 2), root_layer->bounds()); | |
2810 EndTest(); | |
2811 } | |
2812 } | |
2813 | |
2814 private: | |
2815 SetBoundsClient client_; | |
2816 int num_commits_; | |
2817 }; | |
2818 | |
2819 SINGLE_AND_MULTI_THREAD_TEST_F( | |
2820 LayerTreeHostTestChangeLayerPropertiesInPaintContents); | |
2821 | |
2822 class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { | |
2823 public: | |
2824 MockIOSurfaceWebGraphicsContext3D() { | |
2825 test_capabilities_.gpu.iosurface = true; | |
2826 test_capabilities_.gpu.texture_rectangle = true; | |
2827 } | |
2828 | |
2829 GLuint createTexture() override { return 1; } | |
2830 MOCK_METHOD1(activeTexture, void(GLenum texture)); | |
2831 MOCK_METHOD2(bindTexture, void(GLenum target, | |
2832 GLuint texture_id)); | |
2833 MOCK_METHOD3(texParameteri, void(GLenum target, | |
2834 GLenum pname, | |
2835 GLint param)); | |
2836 MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target, | |
2837 GLint width, | |
2838 GLint height, | |
2839 GLuint ioSurfaceId, | |
2840 GLuint plane)); | |
2841 MOCK_METHOD4(drawElements, void(GLenum mode, | |
2842 GLsizei count, | |
2843 GLenum type, | |
2844 GLintptr offset)); | |
2845 MOCK_METHOD1(deleteTexture, void(GLenum texture)); | |
2846 MOCK_METHOD3(produceTextureDirectCHROMIUM, | |
2847 void(GLuint texture, GLenum target, const GLbyte* mailbox)); | |
2848 }; | |
2849 | |
2850 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { | |
2851 protected: | |
2852 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
2853 scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned( | |
2854 new MockIOSurfaceWebGraphicsContext3D); | |
2855 mock_context_ = mock_context_owned.get(); | |
2856 | |
2857 if (delegating_renderer()) | |
2858 return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass()); | |
2859 else | |
2860 return FakeOutputSurface::Create3d(mock_context_owned.Pass()); | |
2861 } | |
2862 | |
2863 void SetupTree() override { | |
2864 LayerTreeHostTest::SetupTree(); | |
2865 | |
2866 layer_tree_host()->root_layer()->SetIsDrawable(false); | |
2867 | |
2868 io_surface_id_ = 9; | |
2869 io_surface_size_ = gfx::Size(6, 7); | |
2870 | |
2871 scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create(); | |
2872 io_surface_layer->SetBounds(gfx::Size(10, 10)); | |
2873 io_surface_layer->SetIsDrawable(true); | |
2874 io_surface_layer->SetContentsOpaque(true); | |
2875 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); | |
2876 layer_tree_host()->root_layer()->AddChild(io_surface_layer); | |
2877 } | |
2878 | |
2879 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
2880 | |
2881 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
2882 EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); | |
2883 // In WillDraw, the IOSurfaceLayer sets up the io surface texture. | |
2884 | |
2885 EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0); | |
2886 EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) | |
2887 .Times(AtLeast(1)); | |
2888 EXPECT_CALL(*mock_context_, | |
2889 texParameteri( | |
2890 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)) | |
2891 .Times(1); | |
2892 EXPECT_CALL(*mock_context_, | |
2893 texParameteri( | |
2894 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)) | |
2895 .Times(1); | |
2896 EXPECT_CALL(*mock_context_, | |
2897 texParameteri(GL_TEXTURE_RECTANGLE_ARB, | |
2898 GL_TEXTURE_POOL_CHROMIUM, | |
2899 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1); | |
2900 EXPECT_CALL(*mock_context_, | |
2901 texParameteri(GL_TEXTURE_RECTANGLE_ARB, | |
2902 GL_TEXTURE_WRAP_S, | |
2903 GL_CLAMP_TO_EDGE)).Times(1); | |
2904 EXPECT_CALL(*mock_context_, | |
2905 texParameteri(GL_TEXTURE_RECTANGLE_ARB, | |
2906 GL_TEXTURE_WRAP_T, | |
2907 GL_CLAMP_TO_EDGE)).Times(1); | |
2908 | |
2909 EXPECT_CALL(*mock_context_, | |
2910 texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, | |
2911 io_surface_size_.width(), | |
2912 io_surface_size_.height(), | |
2913 io_surface_id_, | |
2914 0)).Times(1); | |
2915 | |
2916 EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber()); | |
2917 } | |
2918 | |
2919 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
2920 LayerTreeHostImpl::FrameData* frame, | |
2921 DrawResult draw_result) override { | |
2922 Mock::VerifyAndClearExpectations(&mock_context_); | |
2923 ResourceProvider* resource_provider = host_impl->resource_provider(); | |
2924 EXPECT_EQ(1u, resource_provider->num_resources()); | |
2925 CHECK_EQ(1u, frame->render_passes.size()); | |
2926 CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); | |
2927 const DrawQuad* quad = frame->render_passes[0]->quad_list.front(); | |
2928 CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); | |
2929 const IOSurfaceDrawQuad* io_surface_draw_quad = | |
2930 IOSurfaceDrawQuad::MaterialCast(quad); | |
2931 EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size); | |
2932 EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id); | |
2933 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), | |
2934 resource_provider->TargetForTesting( | |
2935 io_surface_draw_quad->io_surface_resource_id)); | |
2936 | |
2937 if (delegating_renderer()) { | |
2938 // The io surface layer's resource should be sent to the parent. | |
2939 EXPECT_CALL(*mock_context_, produceTextureDirectCHROMIUM( | |
2940 _, GL_TEXTURE_RECTANGLE_ARB, _)).Times(1); | |
2941 } else { | |
2942 // The io surface layer's texture is drawn. | |
2943 EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); | |
2944 EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) | |
2945 .Times(AtLeast(1)); | |
2946 } | |
2947 | |
2948 return draw_result; | |
2949 } | |
2950 | |
2951 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
2952 Mock::VerifyAndClearExpectations(&mock_context_); | |
2953 | |
2954 EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); | |
2955 EndTest(); | |
2956 } | |
2957 | |
2958 void AfterTest() override {} | |
2959 | |
2960 int io_surface_id_; | |
2961 MockIOSurfaceWebGraphicsContext3D* mock_context_; | |
2962 gfx::Size io_surface_size_; | |
2963 }; | |
2964 | |
2965 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); | |
2966 | |
2967 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { | |
2968 public: | |
2969 void BeginTest() override { | |
2970 frame_ = 0; | |
2971 PostSetNeedsCommitToMainThread(); | |
2972 } | |
2973 | |
2974 // Round 1: commit + draw | |
2975 // Round 2: commit only (no draw/swap) | |
2976 // Round 3: draw only (no commit) | |
2977 | |
2978 void DidCommit() override { | |
2979 int commit = layer_tree_host()->source_frame_number(); | |
2980 switch (commit) { | |
2981 case 2: | |
2982 // Round 2 done. | |
2983 EXPECT_EQ(1, frame_); | |
2984 layer_tree_host()->SetNeedsRedraw(); | |
2985 break; | |
2986 } | |
2987 } | |
2988 | |
2989 void DidCompleteSwapBuffers() override { | |
2990 int commit = layer_tree_host()->source_frame_number(); | |
2991 ++frame_; | |
2992 switch (frame_) { | |
2993 case 1: | |
2994 // Round 1 done. | |
2995 EXPECT_EQ(1, commit); | |
2996 layer_tree_host()->SetNeedsCommit(); | |
2997 break; | |
2998 case 2: | |
2999 // Round 3 done. | |
3000 EXPECT_EQ(2, commit); | |
3001 EndTest(); | |
3002 break; | |
3003 } | |
3004 } | |
3005 | |
3006 void AfterTest() override {} | |
3007 | |
3008 protected: | |
3009 int frame_; | |
3010 }; | |
3011 | |
3012 // Flaky on all platforms: http://crbug.com/327498 | |
3013 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) { | |
3014 RunTest(true, true, true); | |
3015 } | |
3016 | |
3017 TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) { | |
3018 RunTest(true, false, true); | |
3019 } | |
3020 | |
3021 class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { | |
3022 public: | |
3023 void InitializeSettings(LayerTreeSettings* settings) override { | |
3024 // PictureLayer can only be used with impl side painting enabled. | |
3025 settings->impl_side_painting = true; | |
3026 } | |
3027 | |
3028 void SetupTree() override { | |
3029 layer_ = FakePictureLayer::Create(&client_); | |
3030 // Force commits to not be aborted so new frames get drawn, otherwise | |
3031 // the renderer gets deferred initialized but nothing new needs drawing. | |
3032 layer_->set_always_update_resources(true); | |
3033 layer_tree_host()->SetRootLayer(layer_); | |
3034 LayerTreeHostTest::SetupTree(); | |
3035 } | |
3036 | |
3037 void BeginTest() override { | |
3038 did_initialize_gl_ = false; | |
3039 did_release_gl_ = false; | |
3040 last_source_frame_number_drawn_ = -1; // Never drawn. | |
3041 PostSetNeedsCommitToMainThread(); | |
3042 } | |
3043 | |
3044 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
3045 scoped_ptr<TestWebGraphicsContext3D> context3d( | |
3046 TestWebGraphicsContext3D::Create()); | |
3047 | |
3048 return FakeOutputSurface::CreateDeferredGL( | |
3049 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice), | |
3050 delegating_renderer()); | |
3051 } | |
3052 | |
3053 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
3054 ASSERT_TRUE(host_impl->RootLayer()); | |
3055 FakePictureLayerImpl* layer_impl = | |
3056 static_cast<FakePictureLayerImpl*>(host_impl->RootLayer()); | |
3057 | |
3058 // The same frame can be draw multiple times if new visible tiles are | |
3059 // rasterized. But we want to make sure we only post DeferredInitialize | |
3060 // and ReleaseGL once, so early out if the same frame is drawn again. | |
3061 if (last_source_frame_number_drawn_ == | |
3062 host_impl->active_tree()->source_frame_number()) | |
3063 return; | |
3064 | |
3065 last_source_frame_number_drawn_ = | |
3066 host_impl->active_tree()->source_frame_number(); | |
3067 | |
3068 if (!did_initialize_gl_) { | |
3069 EXPECT_LE(1u, layer_impl->append_quads_count()); | |
3070 ImplThreadTaskRunner()->PostTask( | |
3071 FROM_HERE, | |
3072 base::Bind( | |
3073 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw, | |
3074 base::Unretained(this), | |
3075 base::Unretained(host_impl))); | |
3076 } else if (did_initialize_gl_ && !did_release_gl_) { | |
3077 EXPECT_LE(2u, layer_impl->append_quads_count()); | |
3078 ImplThreadTaskRunner()->PostTask( | |
3079 FROM_HERE, | |
3080 base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw, | |
3081 base::Unretained(this), | |
3082 base::Unretained(host_impl))); | |
3083 } else if (did_initialize_gl_ && did_release_gl_) { | |
3084 EXPECT_LE(3u, layer_impl->append_quads_count()); | |
3085 EndTest(); | |
3086 } | |
3087 } | |
3088 | |
3089 void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) { | |
3090 EXPECT_FALSE(did_initialize_gl_); | |
3091 // SetAndInitializeContext3D calls SetNeedsCommit. | |
3092 FakeOutputSurface* fake_output_surface = | |
3093 static_cast<FakeOutputSurface*>(host_impl->output_surface()); | |
3094 scoped_refptr<TestContextProvider> context_provider = | |
3095 TestContextProvider::Create(); // Not bound to thread. | |
3096 scoped_refptr<TestContextProvider> worker_context_provider = | |
3097 TestContextProvider::Create(); // Not bound to thread. | |
3098 EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d( | |
3099 context_provider, worker_context_provider)); | |
3100 did_initialize_gl_ = true; | |
3101 } | |
3102 | |
3103 void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) { | |
3104 EXPECT_TRUE(did_initialize_gl_); | |
3105 EXPECT_FALSE(did_release_gl_); | |
3106 // ReleaseGL calls SetNeedsCommit. | |
3107 static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL(); | |
3108 did_release_gl_ = true; | |
3109 } | |
3110 | |
3111 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
3112 ASSERT_TRUE(result); | |
3113 DelegatedFrameData* delegated_frame_data = | |
3114 output_surface()->last_sent_frame().delegated_frame_data.get(); | |
3115 if (!delegated_frame_data) | |
3116 return; | |
3117 | |
3118 // Return all resources immediately. | |
3119 TransferableResourceArray resources_to_return = | |
3120 output_surface()->resources_held_by_parent(); | |
3121 | |
3122 CompositorFrameAck ack; | |
3123 for (size_t i = 0; i < resources_to_return.size(); ++i) | |
3124 output_surface()->ReturnResource(resources_to_return[i].id, &ack); | |
3125 host_impl->ReclaimResources(&ack); | |
3126 } | |
3127 | |
3128 void AfterTest() override { | |
3129 EXPECT_TRUE(did_initialize_gl_); | |
3130 EXPECT_TRUE(did_release_gl_); | |
3131 } | |
3132 | |
3133 private: | |
3134 FakeContentLayerClient client_; | |
3135 scoped_refptr<FakePictureLayer> layer_; | |
3136 bool did_initialize_gl_; | |
3137 bool did_release_gl_; | |
3138 int last_source_frame_number_drawn_; | |
3139 }; | |
3140 | |
3141 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize); | |
3142 | |
3143 class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { | |
3144 public: | |
3145 void SetupTree() override { | |
3146 root_layer_ = FakePictureLayer::Create(&client_); | |
3147 root_layer_->SetIsDrawable(true); | |
3148 root_layer_->SetBounds(gfx::Size(50, 50)); | |
3149 | |
3150 parent_layer_ = FakePictureLayer::Create(&client_); | |
3151 parent_layer_->SetIsDrawable(true); | |
3152 parent_layer_->SetBounds(gfx::Size(50, 50)); | |
3153 parent_layer_->SetForceRenderSurface(true); | |
3154 | |
3155 child_layer_ = FakePictureLayer::Create(&client_); | |
3156 child_layer_->SetIsDrawable(true); | |
3157 child_layer_->SetBounds(gfx::Size(50, 50)); | |
3158 | |
3159 root_layer_->AddChild(parent_layer_); | |
3160 parent_layer_->AddChild(child_layer_); | |
3161 layer_tree_host()->SetRootLayer(root_layer_); | |
3162 | |
3163 LayerTreeHostTest::SetupTree(); | |
3164 } | |
3165 | |
3166 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
3167 return FakeOutputSurface::CreateDeferredGL( | |
3168 make_scoped_ptr(new SoftwareOutputDevice), delegating_renderer()); | |
3169 } | |
3170 | |
3171 void BeginTest() override { | |
3172 PostSetNeedsCommitToMainThread(); | |
3173 swap_count_ = 0; | |
3174 } | |
3175 | |
3176 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
3177 LayerTreeHostImpl::FrameData* frame_data, | |
3178 DrawResult draw_result) override { | |
3179 if (host_impl->GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) { | |
3180 EXPECT_EQ(1u, frame_data->render_passes.size()); | |
3181 // Has at least 3 quads for each layer. | |
3182 RenderPass* render_pass = frame_data->render_passes[0]; | |
3183 EXPECT_GE(render_pass->quad_list.size(), 3u); | |
3184 } else { | |
3185 EXPECT_EQ(2u, frame_data->render_passes.size()); | |
3186 | |
3187 // At least root layer quad in root render pass. | |
3188 EXPECT_GE(frame_data->render_passes[0]->quad_list.size(), 1u); | |
3189 // At least parent and child layer quads in parent render pass. | |
3190 EXPECT_GE(frame_data->render_passes[1]->quad_list.size(), 2u); | |
3191 } | |
3192 return draw_result; | |
3193 } | |
3194 | |
3195 void SwapBuffersCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
3196 swap_count_++; | |
3197 switch (swap_count_) { | |
3198 case 1: { | |
3199 gfx::Transform identity; | |
3200 gfx::Rect empty_rect; | |
3201 bool resourceless_software_draw = true; | |
3202 host_impl->SetExternalDrawConstraints(identity, empty_rect, empty_rect, | |
3203 empty_rect, identity, | |
3204 resourceless_software_draw); | |
3205 host_impl->SetFullRootLayerDamage(); | |
3206 host_impl->SetNeedsRedraw(); | |
3207 break; | |
3208 } | |
3209 case 2: | |
3210 EndTest(); | |
3211 break; | |
3212 default: | |
3213 NOTREACHED(); | |
3214 } | |
3215 } | |
3216 | |
3217 void AfterTest() override {} | |
3218 | |
3219 private: | |
3220 FakeContentLayerClient client_; | |
3221 scoped_refptr<Layer> root_layer_; | |
3222 scoped_refptr<Layer> parent_layer_; | |
3223 scoped_refptr<Layer> child_layer_; | |
3224 int swap_count_; | |
3225 }; | |
3226 | |
3227 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw); | |
3228 | |
3229 class LayerTreeHostTestDeferredInitializeWithGpuRasterization | |
3230 : public LayerTreeHostTestDeferredInitialize { | |
3231 void InitializeSettings(LayerTreeSettings* settings) override { | |
3232 // PictureLayer can only be used with impl side painting enabled. | |
3233 settings->impl_side_painting = true; | |
3234 settings->gpu_rasterization_enabled = true; | |
3235 settings->gpu_rasterization_forced = true; | |
3236 } | |
3237 }; | |
3238 | |
3239 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization); | |
3240 | |
3241 // Test for UI Resource management. | |
3242 class LayerTreeHostTestUIResource : public LayerTreeHostTest { | |
3243 public: | |
3244 LayerTreeHostTestUIResource() : num_ui_resources_(0) {} | |
3245 | |
3246 void InitializeSettings(LayerTreeSettings* settings) override { | |
3247 settings->renderer_settings.texture_id_allocation_chunk_size = 1; | |
3248 } | |
3249 | |
3250 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
3251 | |
3252 void DidCommit() override { | |
3253 int frame = layer_tree_host()->source_frame_number(); | |
3254 switch (frame) { | |
3255 case 1: | |
3256 CreateResource(); | |
3257 CreateResource(); | |
3258 PostSetNeedsCommitToMainThread(); | |
3259 break; | |
3260 case 2: | |
3261 // Usually ScopedUIResource are deleted from the manager in their | |
3262 // destructor. Here we just want to test that a direct call to | |
3263 // DeleteUIResource works. | |
3264 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); | |
3265 PostSetNeedsCommitToMainThread(); | |
3266 break; | |
3267 case 3: | |
3268 // DeleteUIResource can be called with an invalid id. | |
3269 layer_tree_host()->DeleteUIResource(ui_resources_[0]->id()); | |
3270 PostSetNeedsCommitToMainThread(); | |
3271 break; | |
3272 case 4: | |
3273 CreateResource(); | |
3274 CreateResource(); | |
3275 PostSetNeedsCommitToMainThread(); | |
3276 break; | |
3277 case 5: | |
3278 ClearResources(); | |
3279 EndTest(); | |
3280 break; | |
3281 } | |
3282 } | |
3283 | |
3284 void PerformTest(LayerTreeHostImpl* impl) { | |
3285 TestWebGraphicsContext3D* context = TestContext(); | |
3286 | |
3287 int frame = impl->active_tree()->source_frame_number(); | |
3288 switch (frame) { | |
3289 case 0: | |
3290 ASSERT_EQ(0u, context->NumTextures()); | |
3291 break; | |
3292 case 1: | |
3293 // Created two textures. | |
3294 ASSERT_EQ(2u, context->NumTextures()); | |
3295 break; | |
3296 case 2: | |
3297 // One texture left after one deletion. | |
3298 ASSERT_EQ(1u, context->NumTextures()); | |
3299 break; | |
3300 case 3: | |
3301 // Resource manager state should not change when delete is called on an | |
3302 // invalid id. | |
3303 ASSERT_EQ(1u, context->NumTextures()); | |
3304 break; | |
3305 case 4: | |
3306 // Creation after deletion: two more creates should total up to | |
3307 // three textures. | |
3308 ASSERT_EQ(3u, context->NumTextures()); | |
3309 break; | |
3310 } | |
3311 } | |
3312 | |
3313 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
3314 if (!impl->settings().impl_side_painting) | |
3315 PerformTest(impl); | |
3316 } | |
3317 | |
3318 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
3319 if (impl->settings().impl_side_painting) | |
3320 PerformTest(impl); | |
3321 } | |
3322 | |
3323 void AfterTest() override {} | |
3324 | |
3325 private: | |
3326 // Must clear all resources before exiting. | |
3327 void ClearResources() { | |
3328 for (int i = 0; i < num_ui_resources_; i++) | |
3329 ui_resources_[i] = nullptr; | |
3330 } | |
3331 | |
3332 void CreateResource() { | |
3333 ui_resources_[num_ui_resources_++] = | |
3334 FakeScopedUIResource::Create(layer_tree_host()); | |
3335 } | |
3336 | |
3337 scoped_ptr<FakeScopedUIResource> ui_resources_[5]; | |
3338 int num_ui_resources_; | |
3339 }; | |
3340 | |
3341 MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); | |
3342 | |
3343 class PushPropertiesCountingLayerImpl : public LayerImpl { | |
3344 public: | |
3345 static scoped_ptr<PushPropertiesCountingLayerImpl> Create( | |
3346 LayerTreeImpl* tree_impl, int id) { | |
3347 return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); | |
3348 } | |
3349 | |
3350 ~PushPropertiesCountingLayerImpl() override {} | |
3351 | |
3352 void PushPropertiesTo(LayerImpl* layer) override { | |
3353 LayerImpl::PushPropertiesTo(layer); | |
3354 push_properties_count_++; | |
3355 // Push state to the active tree because we can only access it from there. | |
3356 static_cast<PushPropertiesCountingLayerImpl*>( | |
3357 layer)->push_properties_count_ = push_properties_count_; | |
3358 } | |
3359 | |
3360 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { | |
3361 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); | |
3362 } | |
3363 | |
3364 size_t push_properties_count() const { return push_properties_count_; } | |
3365 void reset_push_properties_count() { push_properties_count_ = 0; } | |
3366 | |
3367 private: | |
3368 size_t push_properties_count_; | |
3369 | |
3370 PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id) | |
3371 : LayerImpl(tree_impl, id), | |
3372 push_properties_count_(0) { | |
3373 SetBounds(gfx::Size(1, 1)); | |
3374 } | |
3375 }; | |
3376 | |
3377 class PushPropertiesCountingLayer : public Layer { | |
3378 public: | |
3379 static scoped_refptr<PushPropertiesCountingLayer> Create() { | |
3380 return new PushPropertiesCountingLayer(); | |
3381 } | |
3382 | |
3383 void PushPropertiesTo(LayerImpl* layer) override { | |
3384 Layer::PushPropertiesTo(layer); | |
3385 push_properties_count_++; | |
3386 if (persist_needs_push_properties_) | |
3387 needs_push_properties_ = true; | |
3388 } | |
3389 | |
3390 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { | |
3391 return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); | |
3392 } | |
3393 | |
3394 void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); } | |
3395 | |
3396 size_t push_properties_count() const { return push_properties_count_; } | |
3397 void reset_push_properties_count() { push_properties_count_ = 0; } | |
3398 | |
3399 void set_persist_needs_push_properties(bool persist) { | |
3400 persist_needs_push_properties_ = persist; | |
3401 } | |
3402 | |
3403 private: | |
3404 PushPropertiesCountingLayer() | |
3405 : push_properties_count_(0), persist_needs_push_properties_(false) { | |
3406 SetBounds(gfx::Size(1, 1)); | |
3407 } | |
3408 ~PushPropertiesCountingLayer() override {} | |
3409 | |
3410 size_t push_properties_count_; | |
3411 bool persist_needs_push_properties_; | |
3412 }; | |
3413 | |
3414 class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { | |
3415 protected: | |
3416 void BeginTest() override { | |
3417 num_commits_ = 0; | |
3418 expected_push_properties_root_ = 0; | |
3419 expected_push_properties_child_ = 0; | |
3420 expected_push_properties_grandchild_ = 0; | |
3421 expected_push_properties_child2_ = 0; | |
3422 expected_push_properties_other_root_ = 0; | |
3423 expected_push_properties_leaf_layer_ = 0; | |
3424 PostSetNeedsCommitToMainThread(); | |
3425 } | |
3426 | |
3427 void SetupTree() override { | |
3428 root_ = PushPropertiesCountingLayer::Create(); | |
3429 root_->CreateRenderSurface(); | |
3430 child_ = PushPropertiesCountingLayer::Create(); | |
3431 child2_ = PushPropertiesCountingLayer::Create(); | |
3432 grandchild_ = PushPropertiesCountingLayer::Create(); | |
3433 leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create(); | |
3434 leaf_always_pushing_layer_->set_persist_needs_push_properties(true); | |
3435 | |
3436 root_->AddChild(child_); | |
3437 root_->AddChild(child2_); | |
3438 child_->AddChild(grandchild_); | |
3439 child2_->AddChild(leaf_always_pushing_layer_); | |
3440 | |
3441 other_root_ = PushPropertiesCountingLayer::Create(); | |
3442 other_root_->CreateRenderSurface(); | |
3443 | |
3444 // Don't set the root layer here. | |
3445 LayerTreeHostTest::SetupTree(); | |
3446 } | |
3447 | |
3448 void DidCommitAndDrawFrame() override { | |
3449 ++num_commits_; | |
3450 | |
3451 EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count()); | |
3452 EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count()); | |
3453 EXPECT_EQ(expected_push_properties_grandchild_, | |
3454 grandchild_->push_properties_count()); | |
3455 EXPECT_EQ(expected_push_properties_child2_, | |
3456 child2_->push_properties_count()); | |
3457 EXPECT_EQ(expected_push_properties_other_root_, | |
3458 other_root_->push_properties_count()); | |
3459 EXPECT_EQ(expected_push_properties_leaf_layer_, | |
3460 leaf_always_pushing_layer_->push_properties_count()); | |
3461 | |
3462 // The scrollbar layer always needs to be pushed. | |
3463 if (root_->layer_tree_host()) { | |
3464 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
3465 EXPECT_FALSE(root_->needs_push_properties()); | |
3466 } | |
3467 if (child2_->layer_tree_host()) { | |
3468 EXPECT_TRUE(child2_->descendant_needs_push_properties()); | |
3469 EXPECT_FALSE(child2_->needs_push_properties()); | |
3470 } | |
3471 if (leaf_always_pushing_layer_->layer_tree_host()) { | |
3472 EXPECT_FALSE( | |
3473 leaf_always_pushing_layer_->descendant_needs_push_properties()); | |
3474 EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties()); | |
3475 } | |
3476 | |
3477 // child_ and grandchild_ don't persist their need to push properties. | |
3478 if (child_->layer_tree_host()) { | |
3479 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
3480 EXPECT_FALSE(child_->needs_push_properties()); | |
3481 } | |
3482 if (grandchild_->layer_tree_host()) { | |
3483 EXPECT_FALSE(grandchild_->descendant_needs_push_properties()); | |
3484 EXPECT_FALSE(grandchild_->needs_push_properties()); | |
3485 } | |
3486 | |
3487 if (other_root_->layer_tree_host()) { | |
3488 EXPECT_FALSE(other_root_->descendant_needs_push_properties()); | |
3489 EXPECT_FALSE(other_root_->needs_push_properties()); | |
3490 } | |
3491 | |
3492 switch (num_commits_) { | |
3493 case 1: | |
3494 layer_tree_host()->SetRootLayer(root_); | |
3495 // Layers added to the tree get committed. | |
3496 ++expected_push_properties_root_; | |
3497 ++expected_push_properties_child_; | |
3498 ++expected_push_properties_grandchild_; | |
3499 ++expected_push_properties_child2_; | |
3500 break; | |
3501 case 2: | |
3502 layer_tree_host()->SetNeedsCommit(); | |
3503 // No layers need commit. | |
3504 break; | |
3505 case 3: | |
3506 layer_tree_host()->SetRootLayer(other_root_); | |
3507 // Layers added to the tree get committed. | |
3508 ++expected_push_properties_other_root_; | |
3509 break; | |
3510 case 4: | |
3511 layer_tree_host()->SetRootLayer(root_); | |
3512 // Layers added to the tree get committed. | |
3513 ++expected_push_properties_root_; | |
3514 ++expected_push_properties_child_; | |
3515 ++expected_push_properties_grandchild_; | |
3516 ++expected_push_properties_child2_; | |
3517 break; | |
3518 case 5: | |
3519 layer_tree_host()->SetNeedsCommit(); | |
3520 // No layers need commit. | |
3521 break; | |
3522 case 6: | |
3523 child_->RemoveFromParent(); | |
3524 // No layers need commit. | |
3525 break; | |
3526 case 7: | |
3527 root_->AddChild(child_); | |
3528 // Layers added to the tree get committed. | |
3529 ++expected_push_properties_child_; | |
3530 ++expected_push_properties_grandchild_; | |
3531 break; | |
3532 case 8: | |
3533 grandchild_->RemoveFromParent(); | |
3534 // No layers need commit. | |
3535 break; | |
3536 case 9: | |
3537 child_->AddChild(grandchild_); | |
3538 // Layers added to the tree get committed. | |
3539 ++expected_push_properties_grandchild_; | |
3540 break; | |
3541 case 10: | |
3542 layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); | |
3543 // No layers need commit. | |
3544 break; | |
3545 case 11: | |
3546 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f); | |
3547 // No layers need commit. | |
3548 break; | |
3549 case 12: | |
3550 child_->SetPosition(gfx::Point(1, 1)); | |
3551 // The modified layer needs commit | |
3552 ++expected_push_properties_child_; | |
3553 break; | |
3554 case 13: | |
3555 child2_->SetPosition(gfx::Point(1, 1)); | |
3556 // The modified layer needs commit | |
3557 ++expected_push_properties_child2_; | |
3558 break; | |
3559 case 14: | |
3560 child_->RemoveFromParent(); | |
3561 root_->AddChild(child_); | |
3562 // Layers added to the tree get committed. | |
3563 ++expected_push_properties_child_; | |
3564 ++expected_push_properties_grandchild_; | |
3565 break; | |
3566 case 15: | |
3567 grandchild_->SetPosition(gfx::Point(1, 1)); | |
3568 // The modified layer needs commit | |
3569 ++expected_push_properties_grandchild_; | |
3570 break; | |
3571 case 16: | |
3572 // SetNeedsDisplay does not always set needs commit (so call it | |
3573 // explicitly), but is a property change. | |
3574 child_->SetNeedsDisplay(); | |
3575 ++expected_push_properties_child_; | |
3576 layer_tree_host()->SetNeedsCommit(); | |
3577 break; | |
3578 case 17: | |
3579 EndTest(); | |
3580 break; | |
3581 } | |
3582 | |
3583 // The leaf layer always pushes. | |
3584 if (leaf_always_pushing_layer_->layer_tree_host()) | |
3585 ++expected_push_properties_leaf_layer_; | |
3586 } | |
3587 | |
3588 void AfterTest() override {} | |
3589 | |
3590 int num_commits_; | |
3591 FakeContentLayerClient client_; | |
3592 scoped_refptr<PushPropertiesCountingLayer> root_; | |
3593 scoped_refptr<PushPropertiesCountingLayer> child_; | |
3594 scoped_refptr<PushPropertiesCountingLayer> child2_; | |
3595 scoped_refptr<PushPropertiesCountingLayer> grandchild_; | |
3596 scoped_refptr<PushPropertiesCountingLayer> other_root_; | |
3597 scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_; | |
3598 size_t expected_push_properties_root_; | |
3599 size_t expected_push_properties_child_; | |
3600 size_t expected_push_properties_child2_; | |
3601 size_t expected_push_properties_grandchild_; | |
3602 size_t expected_push_properties_other_root_; | |
3603 size_t expected_push_properties_leaf_layer_; | |
3604 }; | |
3605 | |
3606 MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); | |
3607 | |
3608 class LayerTreeHostTestImplLayersPushProperties | |
3609 : public LayerTreeHostTestLayersPushProperties { | |
3610 protected: | |
3611 void BeginTest() override { | |
3612 expected_push_properties_root_impl_ = 0; | |
3613 expected_push_properties_child_impl_ = 0; | |
3614 expected_push_properties_grandchild_impl_ = 0; | |
3615 expected_push_properties_child2_impl_ = 0; | |
3616 expected_push_properties_grandchild2_impl_ = 0; | |
3617 LayerTreeHostTestLayersPushProperties::BeginTest(); | |
3618 } | |
3619 | |
3620 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
3621 // These commits are in response to the changes made in | |
3622 // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame() | |
3623 switch (num_commits_) { | |
3624 case 0: | |
3625 // Tree hasn't been setup yet don't bother to check anything. | |
3626 return; | |
3627 case 1: | |
3628 // Root gets set up, Everyone is initialized. | |
3629 ++expected_push_properties_root_impl_; | |
3630 ++expected_push_properties_child_impl_; | |
3631 ++expected_push_properties_grandchild_impl_; | |
3632 ++expected_push_properties_child2_impl_; | |
3633 ++expected_push_properties_grandchild2_impl_; | |
3634 break; | |
3635 case 2: | |
3636 // Tree doesn't change but the one leaf that always pushes is pushed. | |
3637 ++expected_push_properties_grandchild2_impl_; | |
3638 break; | |
3639 case 3: | |
3640 // Root is swapped here. | |
3641 // Clear the expected push properties the tree will be rebuilt. | |
3642 expected_push_properties_root_impl_ = 0; | |
3643 expected_push_properties_child_impl_ = 0; | |
3644 expected_push_properties_grandchild_impl_ = 0; | |
3645 expected_push_properties_child2_impl_ = 0; | |
3646 expected_push_properties_grandchild2_impl_ = 0; | |
3647 | |
3648 // Make sure the new root is pushed. | |
3649 EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( | |
3650 host_impl->RootLayer())->push_properties_count()); | |
3651 return; | |
3652 case 4: | |
3653 // Root is swapped back all of the layers in the tree get pushed. | |
3654 ++expected_push_properties_root_impl_; | |
3655 ++expected_push_properties_child_impl_; | |
3656 ++expected_push_properties_grandchild_impl_; | |
3657 ++expected_push_properties_child2_impl_; | |
3658 ++expected_push_properties_grandchild2_impl_; | |
3659 break; | |
3660 case 5: | |
3661 // Tree doesn't change but the one leaf that always pushes is pushed. | |
3662 ++expected_push_properties_grandchild2_impl_; | |
3663 break; | |
3664 case 6: | |
3665 // First child is removed. Structure of the tree changes here so swap | |
3666 // some of the values. child_impl becomes child2_impl. | |
3667 expected_push_properties_child_impl_ = | |
3668 expected_push_properties_child2_impl_; | |
3669 expected_push_properties_child2_impl_ = 0; | |
3670 // grandchild_impl becomes grandchild2_impl. | |
3671 expected_push_properties_grandchild_impl_ = | |
3672 expected_push_properties_grandchild2_impl_; | |
3673 expected_push_properties_grandchild2_impl_ = 0; | |
3674 | |
3675 // grandchild_impl is now the leaf that always pushes. It is pushed. | |
3676 ++expected_push_properties_grandchild_impl_; | |
3677 break; | |
3678 case 7: | |
3679 // The leaf that always pushes is pushed. | |
3680 ++expected_push_properties_grandchild_impl_; | |
3681 | |
3682 // Child is added back. New layers are initialized. | |
3683 ++expected_push_properties_grandchild2_impl_; | |
3684 ++expected_push_properties_child2_impl_; | |
3685 break; | |
3686 case 8: | |
3687 // Leaf is removed. | |
3688 expected_push_properties_grandchild2_impl_ = 0; | |
3689 | |
3690 // Always pushing. | |
3691 ++expected_push_properties_grandchild_impl_; | |
3692 break; | |
3693 case 9: | |
3694 // Leaf is added back | |
3695 ++expected_push_properties_grandchild2_impl_; | |
3696 | |
3697 // The leaf that always pushes is pushed. | |
3698 ++expected_push_properties_grandchild_impl_; | |
3699 break; | |
3700 case 10: | |
3701 // The leaf that always pushes is pushed. | |
3702 ++expected_push_properties_grandchild_impl_; | |
3703 break; | |
3704 case 11: | |
3705 // The leaf that always pushes is pushed. | |
3706 ++expected_push_properties_grandchild_impl_; | |
3707 break; | |
3708 case 12: | |
3709 // The leaf that always pushes is pushed. | |
3710 ++expected_push_properties_grandchild_impl_; | |
3711 | |
3712 // This child position was changed. | |
3713 ++expected_push_properties_child2_impl_; | |
3714 break; | |
3715 case 13: | |
3716 // The position of this child was changed. | |
3717 ++expected_push_properties_child_impl_; | |
3718 | |
3719 // The leaf that always pushes is pushed. | |
3720 ++expected_push_properties_grandchild_impl_; | |
3721 break; | |
3722 case 14: | |
3723 // Second child is removed from tree. Don't discard counts because | |
3724 // they are added back before commit. | |
3725 | |
3726 // The leaf that always pushes is pushed. | |
3727 ++expected_push_properties_grandchild_impl_; | |
3728 | |
3729 // Second child added back. | |
3730 ++expected_push_properties_child2_impl_; | |
3731 ++expected_push_properties_grandchild2_impl_; | |
3732 | |
3733 break; | |
3734 case 15: | |
3735 // The position of this child was changed. | |
3736 ++expected_push_properties_grandchild2_impl_; | |
3737 | |
3738 // The leaf that always pushes is pushed. | |
3739 ++expected_push_properties_grandchild_impl_; | |
3740 break; | |
3741 case 16: | |
3742 // Second child is invalidated with SetNeedsDisplay | |
3743 ++expected_push_properties_child2_impl_; | |
3744 | |
3745 // The leaf that always pushed is pushed. | |
3746 ++expected_push_properties_grandchild_impl_; | |
3747 break; | |
3748 } | |
3749 | |
3750 PushPropertiesCountingLayerImpl* root_impl_ = NULL; | |
3751 PushPropertiesCountingLayerImpl* child_impl_ = NULL; | |
3752 PushPropertiesCountingLayerImpl* child2_impl_ = NULL; | |
3753 PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL; | |
3754 PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL; | |
3755 | |
3756 // Pull the layers that we need from the tree assuming the same structure | |
3757 // as LayerTreeHostTestLayersPushProperties | |
3758 root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
3759 host_impl->RootLayer()); | |
3760 | |
3761 if (root_impl_ && root_impl_->children().size() > 0) { | |
3762 child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
3763 root_impl_->children()[0]); | |
3764 | |
3765 if (child_impl_ && child_impl_->children().size() > 0) | |
3766 grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
3767 child_impl_->children()[0]); | |
3768 } | |
3769 | |
3770 if (root_impl_ && root_impl_->children().size() > 1) { | |
3771 child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( | |
3772 root_impl_->children()[1]); | |
3773 | |
3774 if (child2_impl_ && child2_impl_->children().size() > 0) | |
3775 leaf_always_pushing_layer_impl_ = | |
3776 static_cast<PushPropertiesCountingLayerImpl*>( | |
3777 child2_impl_->children()[0]); | |
3778 } | |
3779 | |
3780 if (root_impl_) | |
3781 EXPECT_EQ(expected_push_properties_root_impl_, | |
3782 root_impl_->push_properties_count()); | |
3783 if (child_impl_) | |
3784 EXPECT_EQ(expected_push_properties_child_impl_, | |
3785 child_impl_->push_properties_count()); | |
3786 if (grandchild_impl_) | |
3787 EXPECT_EQ(expected_push_properties_grandchild_impl_, | |
3788 grandchild_impl_->push_properties_count()); | |
3789 if (child2_impl_) | |
3790 EXPECT_EQ(expected_push_properties_child2_impl_, | |
3791 child2_impl_->push_properties_count()); | |
3792 if (leaf_always_pushing_layer_impl_) | |
3793 EXPECT_EQ(expected_push_properties_grandchild2_impl_, | |
3794 leaf_always_pushing_layer_impl_->push_properties_count()); | |
3795 } | |
3796 | |
3797 size_t expected_push_properties_root_impl_; | |
3798 size_t expected_push_properties_child_impl_; | |
3799 size_t expected_push_properties_child2_impl_; | |
3800 size_t expected_push_properties_grandchild_impl_; | |
3801 size_t expected_push_properties_grandchild2_impl_; | |
3802 }; | |
3803 | |
3804 TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) { | |
3805 RunTestWithImplSidePainting(); | |
3806 } | |
3807 | |
3808 class LayerTreeHostTestPropertyChangesDuringUpdateArePushed | |
3809 : public LayerTreeHostTest { | |
3810 protected: | |
3811 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
3812 | |
3813 void SetupTree() override { | |
3814 root_ = Layer::Create(); | |
3815 root_->CreateRenderSurface(); | |
3816 root_->SetBounds(gfx::Size(1, 1)); | |
3817 | |
3818 bool paint_scrollbar = true; | |
3819 bool has_thumb = false; | |
3820 scrollbar_layer_ = FakePaintedScrollbarLayer::Create( | |
3821 paint_scrollbar, has_thumb, root_->id()); | |
3822 | |
3823 root_->AddChild(scrollbar_layer_); | |
3824 | |
3825 layer_tree_host()->SetRootLayer(root_); | |
3826 LayerTreeHostTest::SetupTree(); | |
3827 } | |
3828 | |
3829 void DidCommitAndDrawFrame() override { | |
3830 switch (layer_tree_host()->source_frame_number()) { | |
3831 case 0: | |
3832 break; | |
3833 case 1: { | |
3834 // During update, the ignore_set_needs_commit_ bit is set to true to | |
3835 // avoid causing a second commit to be scheduled. If a property change | |
3836 // is made during this, however, it needs to be pushed in the upcoming | |
3837 // commit. | |
3838 scoped_ptr<base::AutoReset<bool>> ignore = | |
3839 scrollbar_layer_->IgnoreSetNeedsCommit(); | |
3840 | |
3841 scrollbar_layer_->SetBounds(gfx::Size(30, 30)); | |
3842 | |
3843 EXPECT_TRUE(scrollbar_layer_->needs_push_properties()); | |
3844 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
3845 layer_tree_host()->SetNeedsCommit(); | |
3846 | |
3847 scrollbar_layer_->reset_push_properties_count(); | |
3848 EXPECT_EQ(0u, scrollbar_layer_->push_properties_count()); | |
3849 break; | |
3850 } | |
3851 case 2: | |
3852 EXPECT_EQ(1u, scrollbar_layer_->push_properties_count()); | |
3853 EndTest(); | |
3854 break; | |
3855 } | |
3856 } | |
3857 | |
3858 void AfterTest() override {} | |
3859 | |
3860 scoped_refptr<Layer> root_; | |
3861 scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; | |
3862 }; | |
3863 | |
3864 MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed); | |
3865 | |
3866 class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { | |
3867 protected: | |
3868 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
3869 | |
3870 void SetupTree() override { | |
3871 root_ = PushPropertiesCountingLayer::Create(); | |
3872 root_->CreateRenderSurface(); | |
3873 child_ = PushPropertiesCountingLayer::Create(); | |
3874 root_->AddChild(child_); | |
3875 | |
3876 layer_tree_host()->SetRootLayer(root_); | |
3877 LayerTreeHostTest::SetupTree(); | |
3878 } | |
3879 | |
3880 void DidCommitAndDrawFrame() override { | |
3881 switch (layer_tree_host()->source_frame_number()) { | |
3882 case 0: | |
3883 break; | |
3884 case 1: { | |
3885 // During update, the ignore_set_needs_commit_ bit is set to true to | |
3886 // avoid causing a second commit to be scheduled. If a property change | |
3887 // is made during this, however, it needs to be pushed in the upcoming | |
3888 // commit. | |
3889 EXPECT_FALSE(root_->needs_push_properties()); | |
3890 EXPECT_FALSE(child_->needs_push_properties()); | |
3891 EXPECT_EQ(0, root_->NumDescendantsThatDrawContent()); | |
3892 root_->reset_push_properties_count(); | |
3893 child_->reset_push_properties_count(); | |
3894 child_->SetDrawsContent(true); | |
3895 EXPECT_EQ(1, root_->NumDescendantsThatDrawContent()); | |
3896 EXPECT_EQ(0u, root_->push_properties_count()); | |
3897 EXPECT_EQ(0u, child_->push_properties_count()); | |
3898 EXPECT_TRUE(root_->needs_push_properties()); | |
3899 EXPECT_TRUE(child_->needs_push_properties()); | |
3900 break; | |
3901 } | |
3902 case 2: | |
3903 EXPECT_EQ(1u, root_->push_properties_count()); | |
3904 EXPECT_EQ(1u, child_->push_properties_count()); | |
3905 EXPECT_FALSE(root_->needs_push_properties()); | |
3906 EXPECT_FALSE(child_->needs_push_properties()); | |
3907 EndTest(); | |
3908 break; | |
3909 } | |
3910 } | |
3911 | |
3912 void AfterTest() override {} | |
3913 | |
3914 scoped_refptr<PushPropertiesCountingLayer> root_; | |
3915 scoped_refptr<PushPropertiesCountingLayer> child_; | |
3916 }; | |
3917 | |
3918 MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit); | |
3919 | |
3920 class LayerTreeHostTestCasePushPropertiesThreeGrandChildren | |
3921 : public LayerTreeHostTest { | |
3922 protected: | |
3923 void BeginTest() override { | |
3924 expected_push_properties_root_ = 0; | |
3925 expected_push_properties_child_ = 0; | |
3926 expected_push_properties_grandchild1_ = 0; | |
3927 expected_push_properties_grandchild2_ = 0; | |
3928 expected_push_properties_grandchild3_ = 0; | |
3929 PostSetNeedsCommitToMainThread(); | |
3930 } | |
3931 | |
3932 void SetupTree() override { | |
3933 root_ = PushPropertiesCountingLayer::Create(); | |
3934 root_->CreateRenderSurface(); | |
3935 child_ = PushPropertiesCountingLayer::Create(); | |
3936 grandchild1_ = PushPropertiesCountingLayer::Create(); | |
3937 grandchild2_ = PushPropertiesCountingLayer::Create(); | |
3938 grandchild3_ = PushPropertiesCountingLayer::Create(); | |
3939 | |
3940 root_->AddChild(child_); | |
3941 child_->AddChild(grandchild1_); | |
3942 child_->AddChild(grandchild2_); | |
3943 child_->AddChild(grandchild3_); | |
3944 | |
3945 // Don't set the root layer here. | |
3946 LayerTreeHostTest::SetupTree(); | |
3947 } | |
3948 | |
3949 void AfterTest() override {} | |
3950 | |
3951 FakeContentLayerClient client_; | |
3952 scoped_refptr<PushPropertiesCountingLayer> root_; | |
3953 scoped_refptr<PushPropertiesCountingLayer> child_; | |
3954 scoped_refptr<PushPropertiesCountingLayer> grandchild1_; | |
3955 scoped_refptr<PushPropertiesCountingLayer> grandchild2_; | |
3956 scoped_refptr<PushPropertiesCountingLayer> grandchild3_; | |
3957 size_t expected_push_properties_root_; | |
3958 size_t expected_push_properties_child_; | |
3959 size_t expected_push_properties_grandchild1_; | |
3960 size_t expected_push_properties_grandchild2_; | |
3961 size_t expected_push_properties_grandchild3_; | |
3962 }; | |
3963 | |
3964 class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush | |
3965 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
3966 protected: | |
3967 void DidCommitAndDrawFrame() override { | |
3968 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
3969 switch (last_source_frame_number) { | |
3970 case 0: | |
3971 EXPECT_FALSE(root_->needs_push_properties()); | |
3972 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
3973 EXPECT_FALSE(child_->needs_push_properties()); | |
3974 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
3975 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
3976 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
3977 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
3978 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
3979 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
3980 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
3981 | |
3982 layer_tree_host()->SetRootLayer(root_); | |
3983 | |
3984 EXPECT_TRUE(root_->needs_push_properties()); | |
3985 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
3986 EXPECT_TRUE(child_->needs_push_properties()); | |
3987 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
3988 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
3989 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
3990 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
3991 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
3992 EXPECT_TRUE(grandchild3_->needs_push_properties()); | |
3993 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
3994 break; | |
3995 case 1: | |
3996 EndTest(); | |
3997 break; | |
3998 } | |
3999 } | |
4000 }; | |
4001 | |
4002 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); | |
4003 | |
4004 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion | |
4005 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
4006 protected: | |
4007 void DidCommitAndDrawFrame() override { | |
4008 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
4009 switch (last_source_frame_number) { | |
4010 case 0: | |
4011 layer_tree_host()->SetRootLayer(root_); | |
4012 break; | |
4013 case 1: | |
4014 EXPECT_FALSE(root_->needs_push_properties()); | |
4015 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4016 EXPECT_FALSE(child_->needs_push_properties()); | |
4017 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4018 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
4019 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4020 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
4021 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4022 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4023 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4024 | |
4025 grandchild1_->RemoveFromParent(); | |
4026 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
4027 | |
4028 EXPECT_FALSE(root_->needs_push_properties()); | |
4029 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4030 EXPECT_FALSE(child_->needs_push_properties()); | |
4031 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4032 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
4033 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4034 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4035 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4036 | |
4037 child_->AddChild(grandchild1_); | |
4038 | |
4039 EXPECT_FALSE(root_->needs_push_properties()); | |
4040 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4041 EXPECT_FALSE(child_->needs_push_properties()); | |
4042 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4043 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
4044 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4045 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
4046 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4047 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4048 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4049 | |
4050 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
4051 | |
4052 EXPECT_FALSE(root_->needs_push_properties()); | |
4053 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4054 EXPECT_FALSE(child_->needs_push_properties()); | |
4055 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4056 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
4057 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4058 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
4059 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4060 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4061 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4062 | |
4063 // grandchild2_ will still need a push properties. | |
4064 grandchild1_->RemoveFromParent(); | |
4065 | |
4066 EXPECT_FALSE(root_->needs_push_properties()); | |
4067 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4068 EXPECT_FALSE(child_->needs_push_properties()); | |
4069 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4070 | |
4071 // grandchild3_ does not need a push properties, so recursing should | |
4072 // no longer be needed. | |
4073 grandchild2_->RemoveFromParent(); | |
4074 | |
4075 EXPECT_FALSE(root_->needs_push_properties()); | |
4076 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4077 EXPECT_FALSE(child_->needs_push_properties()); | |
4078 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4079 EndTest(); | |
4080 break; | |
4081 } | |
4082 } | |
4083 }; | |
4084 | |
4085 MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); | |
4086 | |
4087 class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence | |
4088 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
4089 protected: | |
4090 void DidCommitAndDrawFrame() override { | |
4091 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
4092 switch (last_source_frame_number) { | |
4093 case 0: | |
4094 layer_tree_host()->SetRootLayer(root_); | |
4095 grandchild1_->set_persist_needs_push_properties(true); | |
4096 grandchild2_->set_persist_needs_push_properties(true); | |
4097 break; | |
4098 case 1: | |
4099 EXPECT_FALSE(root_->needs_push_properties()); | |
4100 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4101 EXPECT_FALSE(child_->needs_push_properties()); | |
4102 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4103 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
4104 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4105 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
4106 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4107 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4108 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4109 | |
4110 // grandchild2_ will still need a push properties. | |
4111 grandchild1_->RemoveFromParent(); | |
4112 | |
4113 EXPECT_FALSE(root_->needs_push_properties()); | |
4114 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4115 EXPECT_FALSE(child_->needs_push_properties()); | |
4116 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4117 | |
4118 // grandchild3_ does not need a push properties, so recursing should | |
4119 // no longer be needed. | |
4120 grandchild2_->RemoveFromParent(); | |
4121 | |
4122 EXPECT_FALSE(root_->needs_push_properties()); | |
4123 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4124 EXPECT_FALSE(child_->needs_push_properties()); | |
4125 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4126 EndTest(); | |
4127 break; | |
4128 } | |
4129 } | |
4130 }; | |
4131 | |
4132 MULTI_THREAD_TEST_F( | |
4133 LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence); | |
4134 | |
4135 class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree | |
4136 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
4137 protected: | |
4138 void DidCommitAndDrawFrame() override { | |
4139 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
4140 switch (last_source_frame_number) { | |
4141 case 0: | |
4142 layer_tree_host()->SetRootLayer(root_); | |
4143 break; | |
4144 case 1: | |
4145 EXPECT_FALSE(root_->needs_push_properties()); | |
4146 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4147 EXPECT_FALSE(child_->needs_push_properties()); | |
4148 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4149 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
4150 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4151 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
4152 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4153 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4154 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4155 | |
4156 // Change grandchildren while their parent is not in the tree. | |
4157 child_->RemoveFromParent(); | |
4158 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
4159 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
4160 root_->AddChild(child_); | |
4161 | |
4162 EXPECT_FALSE(root_->needs_push_properties()); | |
4163 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4164 EXPECT_TRUE(child_->needs_push_properties()); | |
4165 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4166 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
4167 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4168 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
4169 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4170 EXPECT_TRUE(grandchild3_->needs_push_properties()); | |
4171 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4172 | |
4173 grandchild1_->RemoveFromParent(); | |
4174 | |
4175 EXPECT_FALSE(root_->needs_push_properties()); | |
4176 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4177 EXPECT_TRUE(child_->needs_push_properties()); | |
4178 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4179 | |
4180 grandchild2_->RemoveFromParent(); | |
4181 | |
4182 EXPECT_FALSE(root_->needs_push_properties()); | |
4183 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4184 EXPECT_TRUE(child_->needs_push_properties()); | |
4185 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4186 | |
4187 grandchild3_->RemoveFromParent(); | |
4188 | |
4189 EXPECT_FALSE(root_->needs_push_properties()); | |
4190 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4191 EXPECT_TRUE(child_->needs_push_properties()); | |
4192 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4193 | |
4194 EndTest(); | |
4195 break; | |
4196 } | |
4197 } | |
4198 }; | |
4199 | |
4200 MULTI_THREAD_TEST_F( | |
4201 LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree); | |
4202 | |
4203 class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild | |
4204 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
4205 protected: | |
4206 void DidCommitAndDrawFrame() override { | |
4207 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
4208 switch (last_source_frame_number) { | |
4209 case 0: | |
4210 layer_tree_host()->SetRootLayer(root_); | |
4211 break; | |
4212 case 1: | |
4213 EXPECT_FALSE(root_->needs_push_properties()); | |
4214 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4215 EXPECT_FALSE(child_->needs_push_properties()); | |
4216 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4217 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
4218 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4219 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
4220 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4221 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4222 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4223 | |
4224 child_->SetPosition(gfx::Point(1, 1)); | |
4225 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
4226 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
4227 | |
4228 EXPECT_FALSE(root_->needs_push_properties()); | |
4229 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4230 EXPECT_TRUE(child_->needs_push_properties()); | |
4231 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4232 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
4233 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4234 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
4235 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4236 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4237 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4238 | |
4239 grandchild1_->RemoveFromParent(); | |
4240 | |
4241 EXPECT_FALSE(root_->needs_push_properties()); | |
4242 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4243 EXPECT_TRUE(child_->needs_push_properties()); | |
4244 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4245 | |
4246 grandchild2_->RemoveFromParent(); | |
4247 | |
4248 EXPECT_FALSE(root_->needs_push_properties()); | |
4249 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4250 EXPECT_TRUE(child_->needs_push_properties()); | |
4251 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4252 | |
4253 child_->RemoveFromParent(); | |
4254 | |
4255 EXPECT_FALSE(root_->needs_push_properties()); | |
4256 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4257 | |
4258 EndTest(); | |
4259 break; | |
4260 } | |
4261 } | |
4262 }; | |
4263 | |
4264 MULTI_THREAD_TEST_F( | |
4265 LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild); | |
4266 | |
4267 class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent | |
4268 : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { | |
4269 protected: | |
4270 void DidCommitAndDrawFrame() override { | |
4271 int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; | |
4272 switch (last_source_frame_number) { | |
4273 case 0: | |
4274 layer_tree_host()->SetRootLayer(root_); | |
4275 break; | |
4276 case 1: | |
4277 EXPECT_FALSE(root_->needs_push_properties()); | |
4278 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4279 EXPECT_FALSE(child_->needs_push_properties()); | |
4280 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4281 EXPECT_FALSE(grandchild1_->needs_push_properties()); | |
4282 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4283 EXPECT_FALSE(grandchild2_->needs_push_properties()); | |
4284 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4285 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4286 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4287 | |
4288 grandchild1_->SetPosition(gfx::Point(1, 1)); | |
4289 grandchild2_->SetPosition(gfx::Point(1, 1)); | |
4290 child_->SetPosition(gfx::Point(1, 1)); | |
4291 | |
4292 EXPECT_FALSE(root_->needs_push_properties()); | |
4293 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4294 EXPECT_TRUE(child_->needs_push_properties()); | |
4295 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4296 EXPECT_TRUE(grandchild1_->needs_push_properties()); | |
4297 EXPECT_FALSE(grandchild1_->descendant_needs_push_properties()); | |
4298 EXPECT_TRUE(grandchild2_->needs_push_properties()); | |
4299 EXPECT_FALSE(grandchild2_->descendant_needs_push_properties()); | |
4300 EXPECT_FALSE(grandchild3_->needs_push_properties()); | |
4301 EXPECT_FALSE(grandchild3_->descendant_needs_push_properties()); | |
4302 | |
4303 grandchild1_->RemoveFromParent(); | |
4304 | |
4305 EXPECT_FALSE(root_->needs_push_properties()); | |
4306 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4307 EXPECT_TRUE(child_->needs_push_properties()); | |
4308 EXPECT_TRUE(child_->descendant_needs_push_properties()); | |
4309 | |
4310 grandchild2_->RemoveFromParent(); | |
4311 | |
4312 EXPECT_FALSE(root_->needs_push_properties()); | |
4313 EXPECT_TRUE(root_->descendant_needs_push_properties()); | |
4314 EXPECT_TRUE(child_->needs_push_properties()); | |
4315 EXPECT_FALSE(child_->descendant_needs_push_properties()); | |
4316 | |
4317 child_->RemoveFromParent(); | |
4318 | |
4319 EXPECT_FALSE(root_->needs_push_properties()); | |
4320 EXPECT_FALSE(root_->descendant_needs_push_properties()); | |
4321 | |
4322 EndTest(); | |
4323 break; | |
4324 } | |
4325 } | |
4326 }; | |
4327 | |
4328 MULTI_THREAD_TEST_F( | |
4329 LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent); | |
4330 | |
4331 // This test verifies that the tree activation callback is invoked correctly. | |
4332 class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { | |
4333 public: | |
4334 LayerTreeHostTestTreeActivationCallback() | |
4335 : num_commits_(0), callback_count_(0) {} | |
4336 | |
4337 void BeginTest() override { | |
4338 EXPECT_TRUE(HasImplThread()); | |
4339 PostSetNeedsCommitToMainThread(); | |
4340 } | |
4341 | |
4342 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
4343 LayerTreeHostImpl::FrameData* frame_data, | |
4344 DrawResult draw_result) override { | |
4345 ++num_commits_; | |
4346 switch (num_commits_) { | |
4347 case 1: | |
4348 EXPECT_EQ(0, callback_count_); | |
4349 callback_count_ = 0; | |
4350 SetCallback(true); | |
4351 PostSetNeedsCommitToMainThread(); | |
4352 break; | |
4353 case 2: | |
4354 EXPECT_EQ(1, callback_count_); | |
4355 callback_count_ = 0; | |
4356 SetCallback(false); | |
4357 PostSetNeedsCommitToMainThread(); | |
4358 break; | |
4359 case 3: | |
4360 EXPECT_EQ(0, callback_count_); | |
4361 callback_count_ = 0; | |
4362 EndTest(); | |
4363 break; | |
4364 default: | |
4365 ADD_FAILURE() << num_commits_; | |
4366 EndTest(); | |
4367 break; | |
4368 } | |
4369 return LayerTreeHostTest::PrepareToDrawOnThread( | |
4370 host_impl, frame_data, draw_result); | |
4371 } | |
4372 | |
4373 void AfterTest() override { EXPECT_EQ(3, num_commits_); } | |
4374 | |
4375 void SetCallback(bool enable) { | |
4376 output_surface()->SetTreeActivationCallback( | |
4377 enable | |
4378 ? base::Bind( | |
4379 &LayerTreeHostTestTreeActivationCallback::ActivationCallback, | |
4380 base::Unretained(this)) | |
4381 : base::Closure()); | |
4382 } | |
4383 | |
4384 void ActivationCallback() { ++callback_count_; } | |
4385 | |
4386 int num_commits_; | |
4387 int callback_count_; | |
4388 }; | |
4389 | |
4390 TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) { | |
4391 RunTest(true, false, true); | |
4392 } | |
4393 | |
4394 TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) { | |
4395 RunTest(true, true, true); | |
4396 } | |
4397 | |
4398 class LayerInvalidateCausesDraw : public LayerTreeHostTest { | |
4399 public: | |
4400 LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {} | |
4401 | |
4402 void BeginTest() override { | |
4403 ASSERT_TRUE(!!invalidate_layer_.get()) | |
4404 << "Derived tests must set this in SetupTree"; | |
4405 | |
4406 // One initial commit. | |
4407 PostSetNeedsCommitToMainThread(); | |
4408 } | |
4409 | |
4410 void DidCommitAndDrawFrame() override { | |
4411 // After commit, invalidate the layer. This should cause a commit. | |
4412 if (layer_tree_host()->source_frame_number() == 1) | |
4413 invalidate_layer_->SetNeedsDisplay(); | |
4414 } | |
4415 | |
4416 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
4417 num_draws_++; | |
4418 if (impl->active_tree()->source_frame_number() == 1) | |
4419 EndTest(); | |
4420 } | |
4421 | |
4422 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
4423 num_commits_++; | |
4424 } | |
4425 | |
4426 void AfterTest() override { | |
4427 EXPECT_GE(2, num_commits_); | |
4428 EXPECT_GE(2, num_draws_); | |
4429 } | |
4430 | |
4431 protected: | |
4432 scoped_refptr<Layer> invalidate_layer_; | |
4433 | |
4434 private: | |
4435 int num_commits_; | |
4436 int num_draws_; | |
4437 }; | |
4438 | |
4439 // IOSurfaceLayer must support being invalidated and then passing that along | |
4440 // to the compositor thread, even though no resources are updated in | |
4441 // response to that invalidation. | |
4442 class LayerTreeHostTestIOSurfaceLayerInvalidate | |
4443 : public LayerInvalidateCausesDraw { | |
4444 public: | |
4445 void SetupTree() override { | |
4446 LayerTreeHostTest::SetupTree(); | |
4447 scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create(); | |
4448 layer->SetBounds(gfx::Size(10, 10)); | |
4449 uint32_t fake_io_surface_id = 7; | |
4450 layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds()); | |
4451 layer->SetIsDrawable(true); | |
4452 layer_tree_host()->root_layer()->AddChild(layer); | |
4453 | |
4454 invalidate_layer_ = layer; | |
4455 } | |
4456 }; | |
4457 | |
4458 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 | |
4459 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( | |
4460 LayerTreeHostTestIOSurfaceLayerInvalidate); | |
4461 | |
4462 class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { | |
4463 protected: | |
4464 void SetupTree() override { | |
4465 root_layer_ = Layer::Create(); | |
4466 root_layer_->CreateRenderSurface(); | |
4467 root_layer_->SetPosition(gfx::Point()); | |
4468 root_layer_->SetBounds(gfx::Size(10, 10)); | |
4469 | |
4470 parent_layer_ = SolidColorLayer::Create(); | |
4471 parent_layer_->SetPosition(gfx::Point()); | |
4472 parent_layer_->SetBounds(gfx::Size(10, 10)); | |
4473 parent_layer_->SetIsDrawable(true); | |
4474 root_layer_->AddChild(parent_layer_); | |
4475 | |
4476 child_layer_ = SolidColorLayer::Create(); | |
4477 child_layer_->SetPosition(gfx::Point()); | |
4478 child_layer_->SetBounds(gfx::Size(10, 10)); | |
4479 child_layer_->SetIsDrawable(true); | |
4480 parent_layer_->AddChild(child_layer_); | |
4481 | |
4482 layer_tree_host()->SetRootLayer(root_layer_); | |
4483 LayerTreeHostTest::SetupTree(); | |
4484 } | |
4485 | |
4486 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
4487 | |
4488 void DidCommitAndDrawFrame() override { | |
4489 switch (layer_tree_host()->source_frame_number()) { | |
4490 case 1: | |
4491 // The layer type used does not need to push properties every frame. | |
4492 EXPECT_FALSE(child_layer_->needs_push_properties()); | |
4493 | |
4494 // Change the bounds of the child layer, but make it skipped | |
4495 // by CalculateDrawProperties. | |
4496 parent_layer_->SetOpacity(0.f); | |
4497 child_layer_->SetBounds(gfx::Size(5, 5)); | |
4498 break; | |
4499 case 2: | |
4500 // The bounds of the child layer were pushed to the impl side. | |
4501 EXPECT_FALSE(child_layer_->needs_push_properties()); | |
4502 | |
4503 EndTest(); | |
4504 break; | |
4505 } | |
4506 } | |
4507 | |
4508 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
4509 LayerImpl* root = impl->active_tree()->root_layer(); | |
4510 LayerImpl* parent = root->children()[0]; | |
4511 LayerImpl* child = parent->children()[0]; | |
4512 | |
4513 switch (impl->active_tree()->source_frame_number()) { | |
4514 case 1: | |
4515 EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString()); | |
4516 break; | |
4517 } | |
4518 } | |
4519 | |
4520 void AfterTest() override {} | |
4521 | |
4522 scoped_refptr<Layer> root_layer_; | |
4523 scoped_refptr<SolidColorLayer> parent_layer_; | |
4524 scoped_refptr<SolidColorLayer> child_layer_; | |
4525 }; | |
4526 | |
4527 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer); | |
4528 | |
4529 class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { | |
4530 protected: | |
4531 void InitializeSettings(LayerTreeSettings* settings) override { | |
4532 settings->impl_side_painting = true; | |
4533 } | |
4534 | |
4535 void SetupTree() override { | |
4536 root_layer_ = FakePictureLayer::Create(&client_); | |
4537 root_layer_->SetBounds(gfx::Size(10, 10)); | |
4538 | |
4539 layer_tree_host()->SetRootLayer(root_layer_); | |
4540 LayerTreeHostTest::SetupTree(); | |
4541 } | |
4542 | |
4543 void BeginTest() override { | |
4544 // The viewport is empty, but we still need to update layers on the main | |
4545 // thread. | |
4546 layer_tree_host()->SetViewportSize(gfx::Size(0, 0)); | |
4547 PostSetNeedsCommitToMainThread(); | |
4548 } | |
4549 | |
4550 void DidCommit() override { | |
4551 // The layer should be updated even though the viewport is empty, so we | |
4552 // are capable of drawing it on the impl tree. | |
4553 EXPECT_GT(root_layer_->update_count(), 0u); | |
4554 EndTest(); | |
4555 } | |
4556 | |
4557 void AfterTest() override {} | |
4558 | |
4559 FakeContentLayerClient client_; | |
4560 scoped_refptr<FakePictureLayer> root_layer_; | |
4561 }; | |
4562 | |
4563 MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); | |
4564 | |
4565 class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { | |
4566 public: | |
4567 LayerTreeHostTestAbortEvictedTextures() | |
4568 : num_will_begin_main_frames_(0), num_impl_commits_(0) {} | |
4569 | |
4570 protected: | |
4571 void SetupTree() override { | |
4572 scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create(); | |
4573 root_layer->SetBounds(gfx::Size(200, 200)); | |
4574 root_layer->SetIsDrawable(true); | |
4575 root_layer->CreateRenderSurface(); | |
4576 | |
4577 layer_tree_host()->SetRootLayer(root_layer); | |
4578 LayerTreeHostTest::SetupTree(); | |
4579 } | |
4580 | |
4581 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
4582 | |
4583 void WillBeginMainFrame() override { | |
4584 num_will_begin_main_frames_++; | |
4585 switch (num_will_begin_main_frames_) { | |
4586 case 2: | |
4587 // Send a redraw to the compositor thread. This will (wrongly) be | |
4588 // ignored unless aborting resets the texture state. | |
4589 layer_tree_host()->SetNeedsRedraw(); | |
4590 break; | |
4591 } | |
4592 } | |
4593 | |
4594 void BeginCommitOnThread(LayerTreeHostImpl* impl) override { | |
4595 num_impl_commits_++; | |
4596 } | |
4597 | |
4598 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
4599 switch (impl->SourceAnimationFrameNumber()) { | |
4600 case 1: | |
4601 // Prevent draws until commit. | |
4602 impl->active_tree()->SetContentsTexturesPurged(); | |
4603 EXPECT_FALSE(impl->CanDraw()); | |
4604 // Trigger an abortable commit. | |
4605 impl->SetNeedsCommit(); | |
4606 break; | |
4607 case 2: | |
4608 EndTest(); | |
4609 break; | |
4610 } | |
4611 } | |
4612 | |
4613 void AfterTest() override { | |
4614 // Ensure that the commit was truly aborted. | |
4615 EXPECT_EQ(2, num_will_begin_main_frames_); | |
4616 EXPECT_EQ(1, num_impl_commits_); | |
4617 } | |
4618 | |
4619 private: | |
4620 int num_will_begin_main_frames_; | |
4621 int num_impl_commits_; | |
4622 }; | |
4623 | |
4624 // Commits can only be aborted when using the thread proxy. | |
4625 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures); | |
4626 | |
4627 class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest { | |
4628 protected: | |
4629 void InitializeSettings(LayerTreeSettings* settings) override { | |
4630 settings->impl_side_painting = true; | |
4631 settings->use_zero_copy = false; | |
4632 settings->use_one_copy = false; | |
4633 } | |
4634 | |
4635 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
4636 scoped_refptr<TestContextProvider> context_provider = | |
4637 TestContextProvider::Create(); | |
4638 context_provider->SetMaxTransferBufferUsageBytes(512 * 512); | |
4639 if (delegating_renderer()) | |
4640 return FakeOutputSurface::CreateDelegating3d(context_provider); | |
4641 else | |
4642 return FakeOutputSurface::Create3d(context_provider); | |
4643 } | |
4644 | |
4645 void SetupTree() override { | |
4646 client_.set_fill_with_nonsolid_color(true); | |
4647 scoped_refptr<FakePictureLayer> root_layer = | |
4648 FakePictureLayer::Create(&client_); | |
4649 root_layer->SetBounds(gfx::Size(1024, 1024)); | |
4650 root_layer->SetIsDrawable(true); | |
4651 | |
4652 layer_tree_host()->SetRootLayer(root_layer); | |
4653 LayerTreeHostTest::SetupTree(); | |
4654 } | |
4655 | |
4656 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
4657 | |
4658 void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { | |
4659 TestWebGraphicsContext3D* context = TestContext(); | |
4660 | |
4661 // Expect that the transfer buffer memory used is equal to the | |
4662 // MaxTransferBufferUsageBytes value set in CreateOutputSurface. | |
4663 EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes()); | |
4664 EndTest(); | |
4665 } | |
4666 | |
4667 void AfterTest() override {} | |
4668 | |
4669 private: | |
4670 FakeContentLayerClient client_; | |
4671 }; | |
4672 | |
4673 // Impl-side painting is a multi-threaded compositor feature. | |
4674 MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes); | |
4675 | |
4676 // Test ensuring that memory limits are sent to the prioritized resource | |
4677 // manager. | |
4678 class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { | |
4679 public: | |
4680 LayerTreeHostTestMemoryLimits() : num_commits_(0) {} | |
4681 | |
4682 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
4683 | |
4684 void WillCommit() override { | |
4685 // Some commits are aborted, so increment number of attempted commits here. | |
4686 num_commits_++; | |
4687 } | |
4688 | |
4689 void DidCommit() override { | |
4690 switch (num_commits_) { | |
4691 case 1: | |
4692 // Verify default values. | |
4693 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), | |
4694 layer_tree_host() | |
4695 ->contents_texture_manager() | |
4696 ->MaxMemoryLimitBytes()); | |
4697 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), | |
4698 layer_tree_host() | |
4699 ->contents_texture_manager() | |
4700 ->ExternalPriorityCutoff()); | |
4701 PostSetNeedsCommitToMainThread(); | |
4702 break; | |
4703 case 2: | |
4704 // The values should remain the same until the commit after the policy | |
4705 // is changed. | |
4706 EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(), | |
4707 layer_tree_host() | |
4708 ->contents_texture_manager() | |
4709 ->MaxMemoryLimitBytes()); | |
4710 EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(), | |
4711 layer_tree_host() | |
4712 ->contents_texture_manager() | |
4713 ->ExternalPriorityCutoff()); | |
4714 break; | |
4715 case 3: | |
4716 // Verify values were correctly passed. | |
4717 EXPECT_EQ(16u * 1024u * 1024u, | |
4718 layer_tree_host() | |
4719 ->contents_texture_manager() | |
4720 ->MaxMemoryLimitBytes()); | |
4721 EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(), | |
4722 layer_tree_host() | |
4723 ->contents_texture_manager() | |
4724 ->ExternalPriorityCutoff()); | |
4725 EndTest(); | |
4726 break; | |
4727 case 4: | |
4728 // Make sure no extra commits happen. | |
4729 NOTREACHED(); | |
4730 break; | |
4731 } | |
4732 } | |
4733 | |
4734 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
4735 switch (num_commits_) { | |
4736 case 1: | |
4737 break; | |
4738 case 2: | |
4739 // This will trigger a commit because the priority cutoff has changed. | |
4740 impl->SetMemoryPolicy(ManagedMemoryPolicy( | |
4741 16u * 1024u * 1024u, | |
4742 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, | |
4743 1000)); | |
4744 break; | |
4745 case 3: | |
4746 // This will not trigger a commit because the priority cutoff has not | |
4747 // changed, and there is already enough memory for all allocations. | |
4748 impl->SetMemoryPolicy(ManagedMemoryPolicy( | |
4749 32u * 1024u * 1024u, | |
4750 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, | |
4751 1000)); | |
4752 break; | |
4753 case 4: | |
4754 NOTREACHED(); | |
4755 break; | |
4756 } | |
4757 } | |
4758 | |
4759 void AfterTest() override {} | |
4760 | |
4761 private: | |
4762 int num_commits_; | |
4763 }; | |
4764 | |
4765 SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits); | |
4766 | |
4767 } // namespace | |
4768 | |
4769 class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface | |
4770 : public LayerTreeHostTest { | |
4771 protected: | |
4772 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface() | |
4773 : first_output_surface_memory_limit_(4321234), | |
4774 second_output_surface_memory_limit_(1234321) {} | |
4775 | |
4776 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
4777 if (!first_context_provider_.get()) { | |
4778 first_context_provider_ = TestContextProvider::Create(); | |
4779 } else { | |
4780 EXPECT_FALSE(second_context_provider_.get()); | |
4781 second_context_provider_ = TestContextProvider::Create(); | |
4782 } | |
4783 | |
4784 scoped_refptr<TestContextProvider> provider(second_context_provider_.get() | |
4785 ? second_context_provider_ | |
4786 : first_context_provider_); | |
4787 scoped_ptr<FakeOutputSurface> output_surface; | |
4788 if (delegating_renderer()) | |
4789 output_surface = FakeOutputSurface::CreateDelegating3d(provider); | |
4790 else | |
4791 output_surface = FakeOutputSurface::Create3d(provider); | |
4792 output_surface->SetMemoryPolicyToSetAtBind( | |
4793 make_scoped_ptr(new ManagedMemoryPolicy( | |
4794 second_context_provider_.get() ? second_output_surface_memory_limit_ | |
4795 : first_output_surface_memory_limit_, | |
4796 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, | |
4797 ManagedMemoryPolicy::kDefaultNumResourcesLimit))); | |
4798 return output_surface.Pass(); | |
4799 } | |
4800 | |
4801 void SetupTree() override { | |
4802 if (layer_tree_host()->settings().impl_side_painting) | |
4803 root_ = FakePictureLayer::Create(&client_); | |
4804 else | |
4805 root_ = FakeContentLayer::Create(&client_); | |
4806 root_->SetBounds(gfx::Size(20, 20)); | |
4807 layer_tree_host()->SetRootLayer(root_); | |
4808 LayerTreeHostTest::SetupTree(); | |
4809 } | |
4810 | |
4811 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
4812 | |
4813 void DidCommitAndDrawFrame() override { | |
4814 // Lost context sometimes takes two frames to recreate. The third frame | |
4815 // is sometimes aborted, so wait until the fourth frame to verify that | |
4816 // the memory has been set, and the fifth frame to end the test. | |
4817 if (layer_tree_host()->source_frame_number() < 5) { | |
4818 layer_tree_host()->SetNeedsCommit(); | |
4819 } else if (layer_tree_host()->source_frame_number() == 5) { | |
4820 EndTest(); | |
4821 } | |
4822 } | |
4823 | |
4824 void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override { | |
4825 switch (impl->active_tree()->source_frame_number()) { | |
4826 case 1: | |
4827 EXPECT_EQ(first_output_surface_memory_limit_, | |
4828 impl->memory_allocation_limit_bytes()); | |
4829 // Lose the output surface. | |
4830 first_context_provider_->TestContext3d()->loseContextCHROMIUM( | |
4831 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); | |
4832 break; | |
4833 case 4: | |
4834 EXPECT_EQ(second_output_surface_memory_limit_, | |
4835 impl->memory_allocation_limit_bytes()); | |
4836 break; | |
4837 } | |
4838 } | |
4839 | |
4840 void AfterTest() override {} | |
4841 | |
4842 scoped_refptr<TestContextProvider> first_context_provider_; | |
4843 scoped_refptr<TestContextProvider> second_context_provider_; | |
4844 size_t first_output_surface_memory_limit_; | |
4845 size_t second_output_surface_memory_limit_; | |
4846 FakeContentLayerClient client_; | |
4847 scoped_refptr<Layer> root_; | |
4848 }; | |
4849 | |
4850 SINGLE_AND_MULTI_THREAD_TEST_F( | |
4851 LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface); | |
4852 | |
4853 struct TestSwapPromiseResult { | |
4854 TestSwapPromiseResult() | |
4855 : did_swap_called(false), | |
4856 did_not_swap_called(false), | |
4857 dtor_called(false), | |
4858 reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {} | |
4859 | |
4860 bool did_swap_called; | |
4861 bool did_not_swap_called; | |
4862 bool dtor_called; | |
4863 SwapPromise::DidNotSwapReason reason; | |
4864 base::Lock lock; | |
4865 }; | |
4866 | |
4867 class TestSwapPromise : public SwapPromise { | |
4868 public: | |
4869 explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {} | |
4870 | |
4871 ~TestSwapPromise() override { | |
4872 base::AutoLock lock(result_->lock); | |
4873 result_->dtor_called = true; | |
4874 } | |
4875 | |
4876 void DidSwap(CompositorFrameMetadata* metadata) override { | |
4877 base::AutoLock lock(result_->lock); | |
4878 EXPECT_FALSE(result_->did_swap_called); | |
4879 EXPECT_FALSE(result_->did_not_swap_called); | |
4880 result_->did_swap_called = true; | |
4881 } | |
4882 | |
4883 void DidNotSwap(DidNotSwapReason reason) override { | |
4884 base::AutoLock lock(result_->lock); | |
4885 EXPECT_FALSE(result_->did_swap_called); | |
4886 EXPECT_FALSE(result_->did_not_swap_called); | |
4887 result_->did_not_swap_called = true; | |
4888 result_->reason = reason; | |
4889 } | |
4890 | |
4891 int64 TraceId() const override { return 0; } | |
4892 | |
4893 private: | |
4894 // Not owned. | |
4895 TestSwapPromiseResult* result_; | |
4896 }; | |
4897 | |
4898 class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { | |
4899 protected: | |
4900 LayerTreeHostTestBreakSwapPromise() | |
4901 : commit_count_(0), commit_complete_count_(0) {} | |
4902 | |
4903 void WillBeginMainFrame() override { | |
4904 ASSERT_LE(commit_count_, 2); | |
4905 scoped_ptr<SwapPromise> swap_promise( | |
4906 new TestSwapPromise(&swap_promise_result_[commit_count_])); | |
4907 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); | |
4908 } | |
4909 | |
4910 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
4911 | |
4912 void DidCommit() override { | |
4913 commit_count_++; | |
4914 if (commit_count_ == 2) { | |
4915 // This commit will finish. | |
4916 layer_tree_host()->SetNeedsCommit(); | |
4917 } | |
4918 } | |
4919 | |
4920 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
4921 commit_complete_count_++; | |
4922 if (commit_complete_count_ == 1) { | |
4923 // This commit will be aborted because no actual update. | |
4924 PostSetNeedsUpdateLayersToMainThread(); | |
4925 } else { | |
4926 EndTest(); | |
4927 } | |
4928 } | |
4929 | |
4930 void AfterTest() override { | |
4931 // 3 commits are scheduled. 2 completes. 1 is aborted. | |
4932 EXPECT_EQ(commit_count_, 3); | |
4933 EXPECT_EQ(commit_complete_count_, 2); | |
4934 | |
4935 { | |
4936 // The first commit completes and causes swap buffer which finishes | |
4937 // the promise. | |
4938 base::AutoLock lock(swap_promise_result_[0].lock); | |
4939 EXPECT_TRUE(swap_promise_result_[0].did_swap_called); | |
4940 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); | |
4941 EXPECT_TRUE(swap_promise_result_[0].dtor_called); | |
4942 } | |
4943 | |
4944 { | |
4945 // The second commit is aborted since it contains no updates. | |
4946 base::AutoLock lock(swap_promise_result_[1].lock); | |
4947 EXPECT_FALSE(swap_promise_result_[1].did_swap_called); | |
4948 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); | |
4949 EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason); | |
4950 EXPECT_TRUE(swap_promise_result_[1].dtor_called); | |
4951 } | |
4952 | |
4953 { | |
4954 // The last commit completes but it does not cause swap buffer because | |
4955 // there is no damage in the frame data. | |
4956 base::AutoLock lock(swap_promise_result_[2].lock); | |
4957 EXPECT_FALSE(swap_promise_result_[2].did_swap_called); | |
4958 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); | |
4959 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); | |
4960 EXPECT_TRUE(swap_promise_result_[2].dtor_called); | |
4961 } | |
4962 } | |
4963 | |
4964 int commit_count_; | |
4965 int commit_complete_count_; | |
4966 TestSwapPromiseResult swap_promise_result_[3]; | |
4967 }; | |
4968 | |
4969 MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); | |
4970 | |
4971 class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest { | |
4972 public: | |
4973 LayerTreeHostTestKeepSwapPromise() {} | |
4974 | |
4975 void BeginTest() override { | |
4976 layer_ = SolidColorLayer::Create(); | |
4977 layer_->SetIsDrawable(true); | |
4978 layer_->SetBounds(gfx::Size(10, 10)); | |
4979 layer_tree_host()->SetRootLayer(layer_); | |
4980 gfx::Size bounds(100, 100); | |
4981 layer_tree_host()->SetViewportSize(bounds); | |
4982 PostSetNeedsCommitToMainThread(); | |
4983 } | |
4984 | |
4985 void DidCommit() override { | |
4986 MainThreadTaskRunner()->PostTask( | |
4987 FROM_HERE, base::Bind(&LayerTreeHostTestKeepSwapPromise::ChangeFrame, | |
4988 base::Unretained(this))); | |
4989 } | |
4990 | |
4991 void ChangeFrame() { | |
4992 switch (layer_tree_host()->source_frame_number()) { | |
4993 case 1: | |
4994 layer_->SetBounds(gfx::Size(10, 11)); | |
4995 layer_tree_host()->QueueSwapPromise( | |
4996 make_scoped_ptr(new TestSwapPromise(&swap_promise_result_))); | |
4997 break; | |
4998 case 2: | |
4999 break; | |
5000 default: | |
5001 NOTREACHED(); | |
5002 break; | |
5003 } | |
5004 } | |
5005 | |
5006 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
5007 EXPECT_TRUE(result); | |
5008 if (host_impl->active_tree()->source_frame_number() >= 1) { | |
5009 // The commit changes layers so it should cause a swap. | |
5010 base::AutoLock lock(swap_promise_result_.lock); | |
5011 EXPECT_TRUE(swap_promise_result_.did_swap_called); | |
5012 EXPECT_FALSE(swap_promise_result_.did_not_swap_called); | |
5013 EXPECT_TRUE(swap_promise_result_.dtor_called); | |
5014 EndTest(); | |
5015 } | |
5016 } | |
5017 | |
5018 void AfterTest() override {} | |
5019 | |
5020 private: | |
5021 scoped_refptr<Layer> layer_; | |
5022 TestSwapPromiseResult swap_promise_result_; | |
5023 }; | |
5024 | |
5025 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise); | |
5026 | |
5027 class LayerTreeHostTestBreakSwapPromiseForVisibility | |
5028 : public LayerTreeHostTest { | |
5029 protected: | |
5030 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
5031 | |
5032 void SetVisibleFalseAndQueueSwapPromise() { | |
5033 layer_tree_host()->SetVisible(false); | |
5034 scoped_ptr<SwapPromise> swap_promise( | |
5035 new TestSwapPromise(&swap_promise_result_)); | |
5036 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); | |
5037 } | |
5038 | |
5039 void ScheduledActionWillSendBeginMainFrame() override { | |
5040 MainThreadTaskRunner()->PostTask( | |
5041 FROM_HERE, | |
5042 base::Bind(&LayerTreeHostTestBreakSwapPromiseForVisibility | |
5043 ::SetVisibleFalseAndQueueSwapPromise, | |
5044 base::Unretained(this))); | |
5045 } | |
5046 | |
5047 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, | |
5048 CommitEarlyOutReason reason) override { | |
5049 EndTest(); | |
5050 } | |
5051 | |
5052 void AfterTest() override { | |
5053 { | |
5054 base::AutoLock lock(swap_promise_result_.lock); | |
5055 EXPECT_FALSE(swap_promise_result_.did_swap_called); | |
5056 EXPECT_TRUE(swap_promise_result_.did_not_swap_called); | |
5057 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); | |
5058 EXPECT_TRUE(swap_promise_result_.dtor_called); | |
5059 } | |
5060 } | |
5061 | |
5062 TestSwapPromiseResult swap_promise_result_; | |
5063 }; | |
5064 | |
5065 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility); | |
5066 | |
5067 class LayerTreeHostTestBreakSwapPromiseForContext : public LayerTreeHostTest { | |
5068 protected: | |
5069 LayerTreeHostTestBreakSwapPromiseForContext() | |
5070 : output_surface_lost_triggered_(false) { | |
5071 } | |
5072 | |
5073 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
5074 | |
5075 void LoseOutputSurfaceAndQueueSwapPromise() { | |
5076 layer_tree_host()->DidLoseOutputSurface(); | |
5077 scoped_ptr<SwapPromise> swap_promise( | |
5078 new TestSwapPromise(&swap_promise_result_)); | |
5079 layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); | |
5080 } | |
5081 | |
5082 void ScheduledActionWillSendBeginMainFrame() override { | |
5083 if (output_surface_lost_triggered_) | |
5084 return; | |
5085 output_surface_lost_triggered_ = true; | |
5086 | |
5087 MainThreadTaskRunner()->PostTask( | |
5088 FROM_HERE, | |
5089 base::Bind(&LayerTreeHostTestBreakSwapPromiseForContext | |
5090 ::LoseOutputSurfaceAndQueueSwapPromise, | |
5091 base::Unretained(this))); | |
5092 } | |
5093 | |
5094 void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, | |
5095 CommitEarlyOutReason reason) override { | |
5096 // This is needed so that the impl-thread state matches main-thread state. | |
5097 host_impl->DidLoseOutputSurface(); | |
5098 EndTest(); | |
5099 } | |
5100 | |
5101 void AfterTest() override { | |
5102 { | |
5103 base::AutoLock lock(swap_promise_result_.lock); | |
5104 EXPECT_FALSE(swap_promise_result_.did_swap_called); | |
5105 EXPECT_TRUE(swap_promise_result_.did_not_swap_called); | |
5106 EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); | |
5107 EXPECT_TRUE(swap_promise_result_.dtor_called); | |
5108 } | |
5109 } | |
5110 | |
5111 bool output_surface_lost_triggered_; | |
5112 TestSwapPromiseResult swap_promise_result_; | |
5113 }; | |
5114 | |
5115 SINGLE_AND_MULTI_THREAD_TEST_F( | |
5116 LayerTreeHostTestBreakSwapPromiseForContext); | |
5117 | |
5118 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { | |
5119 public: | |
5120 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, | |
5121 LayerTreeHostImpl* layer_tree_host_impl, | |
5122 int* set_needs_commit_count, | |
5123 int* set_needs_redraw_count) | |
5124 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl), | |
5125 set_needs_commit_count_(set_needs_commit_count) {} | |
5126 | |
5127 ~SimpleSwapPromiseMonitor() override {} | |
5128 | |
5129 void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; } | |
5130 | |
5131 void OnSetNeedsRedrawOnImpl() override { | |
5132 ADD_FAILURE() << "Should not get called on main thread."; | |
5133 } | |
5134 | |
5135 void OnForwardScrollUpdateToMainThreadOnImpl() override { | |
5136 ADD_FAILURE() << "Should not get called on main thread."; | |
5137 } | |
5138 | |
5139 private: | |
5140 int* set_needs_commit_count_; | |
5141 }; | |
5142 | |
5143 class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { | |
5144 public: | |
5145 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
5146 | |
5147 void WillBeginMainFrame() override { | |
5148 if (TestEnded()) | |
5149 return; | |
5150 | |
5151 int set_needs_commit_count = 0; | |
5152 int set_needs_redraw_count = 0; | |
5153 | |
5154 { | |
5155 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( | |
5156 new SimpleSwapPromiseMonitor(layer_tree_host(), | |
5157 NULL, | |
5158 &set_needs_commit_count, | |
5159 &set_needs_redraw_count)); | |
5160 layer_tree_host()->SetNeedsCommit(); | |
5161 EXPECT_EQ(1, set_needs_commit_count); | |
5162 EXPECT_EQ(0, set_needs_redraw_count); | |
5163 } | |
5164 | |
5165 // Now the monitor is destroyed, SetNeedsCommit() is no longer being | |
5166 // monitored. | |
5167 layer_tree_host()->SetNeedsCommit(); | |
5168 EXPECT_EQ(1, set_needs_commit_count); | |
5169 EXPECT_EQ(0, set_needs_redraw_count); | |
5170 | |
5171 { | |
5172 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( | |
5173 new SimpleSwapPromiseMonitor(layer_tree_host(), | |
5174 NULL, | |
5175 &set_needs_commit_count, | |
5176 &set_needs_redraw_count)); | |
5177 layer_tree_host()->SetNeedsUpdateLayers(); | |
5178 EXPECT_EQ(2, set_needs_commit_count); | |
5179 EXPECT_EQ(0, set_needs_redraw_count); | |
5180 } | |
5181 | |
5182 { | |
5183 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( | |
5184 new SimpleSwapPromiseMonitor(layer_tree_host(), | |
5185 NULL, | |
5186 &set_needs_commit_count, | |
5187 &set_needs_redraw_count)); | |
5188 layer_tree_host()->SetNeedsAnimate(); | |
5189 EXPECT_EQ(3, set_needs_commit_count); | |
5190 EXPECT_EQ(0, set_needs_redraw_count); | |
5191 } | |
5192 | |
5193 EndTest(); | |
5194 } | |
5195 | |
5196 void AfterTest() override {} | |
5197 }; | |
5198 | |
5199 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); | |
5200 | |
5201 class LayerTreeHostTestHighResRequiredAfterEvictingUIResources | |
5202 : public LayerTreeHostTest { | |
5203 protected: | |
5204 void InitializeSettings(LayerTreeSettings* settings) override { | |
5205 settings->impl_side_painting = true; | |
5206 } | |
5207 | |
5208 void SetupTree() override { | |
5209 LayerTreeHostTest::SetupTree(); | |
5210 ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); | |
5211 } | |
5212 | |
5213 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
5214 | |
5215 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
5216 host_impl->EvictAllUIResources(); | |
5217 // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY | |
5218 // mode. Active tree should require high-res to draw after entering this | |
5219 // mode to ensure that high-res tiles are also required for a pending tree | |
5220 // to be activated. | |
5221 EXPECT_TRUE(host_impl->RequiresHighResToDraw()); | |
5222 } | |
5223 | |
5224 void DidCommit() override { | |
5225 int frame = layer_tree_host()->source_frame_number(); | |
5226 switch (frame) { | |
5227 case 1: | |
5228 PostSetNeedsCommitToMainThread(); | |
5229 break; | |
5230 case 2: | |
5231 ui_resource_ = nullptr; | |
5232 EndTest(); | |
5233 break; | |
5234 } | |
5235 } | |
5236 | |
5237 void AfterTest() override {} | |
5238 | |
5239 FakeContentLayerClient client_; | |
5240 scoped_ptr<FakeScopedUIResource> ui_resource_; | |
5241 }; | |
5242 | |
5243 // This test is flaky, see http://crbug.com/386199 | |
5244 // MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources) | |
5245 | |
5246 class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { | |
5247 protected: | |
5248 void InitializeSettings(LayerTreeSettings* settings) override { | |
5249 settings->impl_side_painting = true; | |
5250 | |
5251 EXPECT_FALSE(settings->gpu_rasterization_enabled); | |
5252 EXPECT_FALSE(settings->gpu_rasterization_forced); | |
5253 } | |
5254 | |
5255 void SetupTree() override { | |
5256 LayerTreeHostTest::SetupTree(); | |
5257 | |
5258 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); | |
5259 layer->SetBounds(gfx::Size(10, 10)); | |
5260 layer->SetIsDrawable(true); | |
5261 layer_tree_host()->root_layer()->AddChild(layer); | |
5262 } | |
5263 | |
5264 void BeginTest() override { | |
5265 Layer* root = layer_tree_host()->root_layer(); | |
5266 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); | |
5267 RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); | |
5268 | |
5269 // Verify default values. | |
5270 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); | |
5271 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); | |
5272 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); | |
5273 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
5274 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); | |
5275 | |
5276 // Setting gpu rasterization trigger does not enable gpu rasterization. | |
5277 layer_tree_host()->SetHasGpuRasterizationTrigger(true); | |
5278 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
5279 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); | |
5280 | |
5281 PostSetNeedsCommitToMainThread(); | |
5282 } | |
5283 | |
5284 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
5285 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); | |
5286 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
5287 } | |
5288 | |
5289 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
5290 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); | |
5291 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
5292 EndTest(); | |
5293 } | |
5294 | |
5295 void AfterTest() override {} | |
5296 | |
5297 FakeContentLayerClient layer_client_; | |
5298 }; | |
5299 | |
5300 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); | |
5301 | |
5302 class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { | |
5303 protected: | |
5304 void InitializeSettings(LayerTreeSettings* settings) override { | |
5305 settings->impl_side_painting = true; | |
5306 | |
5307 EXPECT_FALSE(settings->gpu_rasterization_enabled); | |
5308 settings->gpu_rasterization_enabled = true; | |
5309 } | |
5310 | |
5311 void SetupTree() override { | |
5312 LayerTreeHostTest::SetupTree(); | |
5313 | |
5314 scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); | |
5315 layer->SetBounds(gfx::Size(10, 10)); | |
5316 layer->SetIsDrawable(true); | |
5317 layer_tree_host()->root_layer()->AddChild(layer); | |
5318 } | |
5319 | |
5320 void BeginTest() override { | |
5321 Layer* root = layer_tree_host()->root_layer(); | |
5322 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); | |
5323 RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); | |
5324 | |
5325 // Verify default values. | |
5326 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); | |
5327 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); | |
5328 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); | |
5329 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
5330 EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); | |
5331 | |
5332 // Gpu rasterization trigger is relevant. | |
5333 layer_tree_host()->SetHasGpuRasterizationTrigger(true); | |
5334 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
5335 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); | |
5336 | |
5337 // Content-based veto is relevant as well. | |
5338 recording_source->SetUnsuitableForGpuRasterizationForTesting(); | |
5339 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization()); | |
5340 EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); | |
5341 // Veto will take effect when layers are updated. | |
5342 // The results will be verified after commit is completed below. | |
5343 // Since we are manually marking picture pile as unsuitable, | |
5344 // make sure that the layer gets a chance to update. | |
5345 layer->SetNeedsDisplay(); | |
5346 PostSetNeedsCommitToMainThread(); | |
5347 } | |
5348 | |
5349 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
5350 EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); | |
5351 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
5352 } | |
5353 | |
5354 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
5355 EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); | |
5356 EXPECT_FALSE(host_impl->use_gpu_rasterization()); | |
5357 EndTest(); | |
5358 } | |
5359 | |
5360 void AfterTest() override {} | |
5361 | |
5362 FakeContentLayerClient layer_client_; | |
5363 }; | |
5364 | |
5365 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); | |
5366 | |
5367 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { | |
5368 protected: | |
5369 void InitializeSettings(LayerTreeSettings* settings) override { | |
5370 ASSERT_TRUE(settings->impl_side_painting); | |
5371 | |
5372 EXPECT_FALSE(settings->gpu_rasterization_forced); | |
5373 settings->gpu_rasterization_forced = true; | |
5374 } | |
5375 | |
5376 void SetupTree() override { | |
5377 LayerTreeHostTest::SetupTree(); | |
5378 | |
5379 scoped_refptr<FakePictureLayer> layer = | |
5380 FakePictureLayer::Create(&layer_client_); | |
5381 layer->SetBounds(gfx::Size(10, 10)); | |
5382 layer->SetIsDrawable(true); | |
5383 layer_tree_host()->root_layer()->AddChild(layer); | |
5384 } | |
5385 | |
5386 void BeginTest() override { | |
5387 Layer* root = layer_tree_host()->root_layer(); | |
5388 PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); | |
5389 RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); | |
5390 | |
5391 // Verify default values. | |
5392 EXPECT_TRUE(root->IsSuitableForGpuRasterization()); | |
5393 EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); | |
5394 EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); | |
5395 EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
5396 | |
5397 // With gpu rasterization forced, gpu rasterization trigger is irrelevant. | |
5398 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); | |
5399 layer_tree_host()->SetHasGpuRasterizationTrigger(true); | |
5400 EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); | |
5401 EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); | |
5402 | |
5403 // Content-based veto is irrelevant as well. | |
5404 recording_source->SetUnsuitableForGpuRasterizationForTesting(); | |
5405 EXPECT_FALSE(recording_source->IsSuitableForGpuRasterization()); | |
5406 EXPECT_FALSE(layer->IsSuitableForGpuRasterization()); | |
5407 // Veto will take effect when layers are updated. | |
5408 // The results will be verified after commit is completed below. | |
5409 // Since we are manually marking picture pile as unsuitable, | |
5410 // make sure that the layer gets a chance to update. | |
5411 layer->SetNeedsDisplay(); | |
5412 PostSetNeedsCommitToMainThread(); | |
5413 } | |
5414 | |
5415 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
5416 EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization()); | |
5417 EXPECT_TRUE(host_impl->use_gpu_rasterization()); | |
5418 } | |
5419 | |
5420 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
5421 EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); | |
5422 EXPECT_TRUE(host_impl->use_gpu_rasterization()); | |
5423 EndTest(); | |
5424 } | |
5425 | |
5426 void AfterTest() override {} | |
5427 | |
5428 FakeContentLayerClient layer_client_; | |
5429 }; | |
5430 | |
5431 SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced); | |
5432 | |
5433 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { | |
5434 public: | |
5435 LayerTreeHostTestContinuousPainting() | |
5436 : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {} | |
5437 | |
5438 protected: | |
5439 enum { kExpectedNumCommits = 10 }; | |
5440 | |
5441 void SetupTree() override { | |
5442 scoped_refptr<Layer> root_layer = Layer::Create(); | |
5443 root_layer->SetBounds(bounds_); | |
5444 root_layer->CreateRenderSurface(); | |
5445 | |
5446 if (layer_tree_host()->settings().impl_side_painting) { | |
5447 picture_layer_ = FakePictureLayer::Create(&client_); | |
5448 child_layer_ = picture_layer_.get(); | |
5449 } else { | |
5450 content_layer_ = ContentLayerWithUpdateTracking::Create(&client_); | |
5451 child_layer_ = content_layer_.get(); | |
5452 } | |
5453 child_layer_->SetBounds(bounds_); | |
5454 child_layer_->SetIsDrawable(true); | |
5455 root_layer->AddChild(child_layer_); | |
5456 | |
5457 layer_tree_host()->SetRootLayer(root_layer); | |
5458 layer_tree_host()->SetViewportSize(bounds_); | |
5459 LayerTreeHostTest::SetupTree(); | |
5460 } | |
5461 | |
5462 void BeginTest() override { | |
5463 MainThreadTaskRunner()->PostTask( | |
5464 FROM_HERE, | |
5465 base::Bind( | |
5466 &LayerTreeHostTestContinuousPainting::EnableContinuousPainting, | |
5467 base::Unretained(this))); | |
5468 // Wait 50x longer than expected. | |
5469 double milliseconds_per_frame = | |
5470 1000.0 / layer_tree_host()->settings().renderer_settings.refresh_rate; | |
5471 MainThreadTaskRunner()->PostDelayedTask( | |
5472 FROM_HERE, | |
5473 base::Bind( | |
5474 &LayerTreeHostTestContinuousPainting::DisableContinuousPainting, | |
5475 base::Unretained(this)), | |
5476 base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits * | |
5477 milliseconds_per_frame)); | |
5478 } | |
5479 | |
5480 void BeginMainFrame(const BeginFrameArgs& args) override { | |
5481 child_layer_->SetNeedsDisplay(); | |
5482 } | |
5483 | |
5484 void AfterTest() override { | |
5485 EXPECT_LE(kExpectedNumCommits, num_commits_); | |
5486 EXPECT_LE(kExpectedNumCommits, num_draws_); | |
5487 int update_count = content_layer_.get() | |
5488 ? content_layer_->PaintContentsCount() | |
5489 : picture_layer_->update_count(); | |
5490 EXPECT_LE(kExpectedNumCommits, update_count); | |
5491 } | |
5492 | |
5493 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { | |
5494 if (++num_draws_ == kExpectedNumCommits) | |
5495 EndTest(); | |
5496 } | |
5497 | |
5498 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { | |
5499 ++num_commits_; | |
5500 } | |
5501 | |
5502 private: | |
5503 void EnableContinuousPainting() { | |
5504 LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); | |
5505 debug_state.continuous_painting = true; | |
5506 layer_tree_host()->SetDebugState(debug_state); | |
5507 } | |
5508 | |
5509 void DisableContinuousPainting() { | |
5510 LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); | |
5511 debug_state.continuous_painting = false; | |
5512 layer_tree_host()->SetDebugState(debug_state); | |
5513 EndTest(); | |
5514 } | |
5515 | |
5516 int num_commits_; | |
5517 int num_draws_; | |
5518 const gfx::Size bounds_; | |
5519 FakeContentLayerClient client_; | |
5520 scoped_refptr<ContentLayerWithUpdateTracking> content_layer_; | |
5521 scoped_refptr<FakePictureLayer> picture_layer_; | |
5522 Layer* child_layer_; | |
5523 }; | |
5524 | |
5525 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting); | |
5526 | |
5527 class LayerTreeHostTestSendBeginFramesToChildren : public LayerTreeHostTest { | |
5528 public: | |
5529 LayerTreeHostTestSendBeginFramesToChildren() | |
5530 : begin_frame_sent_to_children_(false) { | |
5531 } | |
5532 | |
5533 void BeginTest() override { | |
5534 // Kick off the test with a commit. | |
5535 PostSetNeedsCommitToMainThread(); | |
5536 } | |
5537 | |
5538 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | |
5539 begin_frame_sent_to_children_ = true; | |
5540 EndTest(); | |
5541 } | |
5542 | |
5543 void DidBeginMainFrame() override { | |
5544 // Children requested BeginFrames. | |
5545 layer_tree_host()->SetChildrenNeedBeginFrames(true); | |
5546 } | |
5547 | |
5548 void AfterTest() override { | |
5549 // Ensure that BeginFrame message is sent to children during parent | |
5550 // scheduler handles its BeginFrame. | |
5551 EXPECT_TRUE(begin_frame_sent_to_children_); | |
5552 } | |
5553 | |
5554 private: | |
5555 bool begin_frame_sent_to_children_; | |
5556 }; | |
5557 | |
5558 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildren); | |
5559 | |
5560 class LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS | |
5561 : public LayerTreeHostTest { | |
5562 public: | |
5563 LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS() | |
5564 : begin_frame_sent_to_children_(false) { | |
5565 } | |
5566 | |
5567 void InitializeSettings(LayerTreeSettings* settings) override { | |
5568 settings->use_external_begin_frame_source = true; | |
5569 } | |
5570 | |
5571 void BeginTest() override { | |
5572 // Kick off the test with a commit. | |
5573 PostSetNeedsCommitToMainThread(); | |
5574 } | |
5575 | |
5576 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | |
5577 begin_frame_sent_to_children_ = true; | |
5578 EndTest(); | |
5579 } | |
5580 | |
5581 void DidBeginMainFrame() override { | |
5582 // Children requested BeginFrames. | |
5583 layer_tree_host()->SetChildrenNeedBeginFrames(true); | |
5584 } | |
5585 | |
5586 void AfterTest() override { | |
5587 // Ensure that BeginFrame message is sent to children during parent | |
5588 // scheduler handles its BeginFrame. | |
5589 EXPECT_TRUE(begin_frame_sent_to_children_); | |
5590 } | |
5591 | |
5592 private: | |
5593 bool begin_frame_sent_to_children_; | |
5594 }; | |
5595 | |
5596 SINGLE_THREAD_TEST_F(LayerTreeHostTestSendBeginFramesToChildrenWithExternalBFS); | |
5597 | |
5598 class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest { | |
5599 public: | |
5600 LayerTreeHostTestActivateOnInvisible() | |
5601 : activation_count_(0), visible_(true) {} | |
5602 | |
5603 void InitializeSettings(LayerTreeSettings* settings) override { | |
5604 settings->impl_side_painting = true; | |
5605 } | |
5606 | |
5607 void BeginTest() override { | |
5608 // Kick off the test with a commit. | |
5609 PostSetNeedsCommitToMainThread(); | |
5610 } | |
5611 | |
5612 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
5613 // Make sure we don't activate using the notify signal from tile manager. | |
5614 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
5615 } | |
5616 | |
5617 void DidCommit() override { layer_tree_host()->SetVisible(false); } | |
5618 | |
5619 void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, | |
5620 bool visible) override { | |
5621 visible_ = visible; | |
5622 | |
5623 // Once invisible, we can go visible again. | |
5624 if (!visible) { | |
5625 PostSetVisibleToMainThread(true); | |
5626 } else { | |
5627 EXPECT_TRUE(host_impl->RequiresHighResToDraw()); | |
5628 EndTest(); | |
5629 } | |
5630 } | |
5631 | |
5632 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
5633 ++activation_count_; | |
5634 EXPECT_FALSE(visible_); | |
5635 } | |
5636 | |
5637 void AfterTest() override { | |
5638 // Ensure we activated even though the signal was blocked. | |
5639 EXPECT_EQ(1, activation_count_); | |
5640 EXPECT_TRUE(visible_); | |
5641 } | |
5642 | |
5643 private: | |
5644 int activation_count_; | |
5645 bool visible_; | |
5646 | |
5647 FakeContentLayerClient client_; | |
5648 scoped_refptr<FakePictureLayer> picture_layer_; | |
5649 }; | |
5650 | |
5651 // TODO(vmpstr): Enable with single thread impl-side painting. | |
5652 MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible); | |
5653 | |
5654 // Do a synchronous composite and assert that the swap promise succeeds. | |
5655 class LayerTreeHostTestSynchronousCompositeSwapPromise | |
5656 : public LayerTreeHostTest { | |
5657 public: | |
5658 LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {} | |
5659 | |
5660 void InitializeSettings(LayerTreeSettings* settings) override { | |
5661 settings->single_thread_proxy_scheduler = false; | |
5662 } | |
5663 | |
5664 void BeginTest() override { | |
5665 // Successful composite. | |
5666 scoped_ptr<SwapPromise> swap_promise0( | |
5667 new TestSwapPromise(&swap_promise_result_[0])); | |
5668 layer_tree_host()->QueueSwapPromise(swap_promise0.Pass()); | |
5669 layer_tree_host()->Composite(gfx::FrameTime::Now()); | |
5670 | |
5671 // Fail to swap (no damage). | |
5672 scoped_ptr<SwapPromise> swap_promise1( | |
5673 new TestSwapPromise(&swap_promise_result_[1])); | |
5674 layer_tree_host()->QueueSwapPromise(swap_promise1.Pass()); | |
5675 layer_tree_host()->SetNeedsCommit(); | |
5676 layer_tree_host()->Composite(gfx::FrameTime::Now()); | |
5677 | |
5678 // Fail to draw (not visible). | |
5679 scoped_ptr<SwapPromise> swap_promise2( | |
5680 new TestSwapPromise(&swap_promise_result_[2])); | |
5681 layer_tree_host()->QueueSwapPromise(swap_promise2.Pass()); | |
5682 layer_tree_host()->SetNeedsDisplayOnAllLayers(); | |
5683 layer_tree_host()->SetVisible(false); | |
5684 layer_tree_host()->Composite(gfx::FrameTime::Now()); | |
5685 | |
5686 EndTest(); | |
5687 } | |
5688 | |
5689 void DidCommit() override { | |
5690 commit_count_++; | |
5691 ASSERT_LE(commit_count_, 3); | |
5692 } | |
5693 | |
5694 void AfterTest() override { | |
5695 EXPECT_EQ(3, commit_count_); | |
5696 | |
5697 // Initial swap promise should have succeded. | |
5698 { | |
5699 base::AutoLock lock(swap_promise_result_[0].lock); | |
5700 EXPECT_TRUE(swap_promise_result_[0].did_swap_called); | |
5701 EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); | |
5702 EXPECT_TRUE(swap_promise_result_[0].dtor_called); | |
5703 } | |
5704 | |
5705 // Second swap promise fails to swap. | |
5706 { | |
5707 base::AutoLock lock(swap_promise_result_[1].lock); | |
5708 EXPECT_FALSE(swap_promise_result_[1].did_swap_called); | |
5709 EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); | |
5710 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); | |
5711 EXPECT_TRUE(swap_promise_result_[1].dtor_called); | |
5712 } | |
5713 | |
5714 // Third swap promises also fails to swap (and draw). | |
5715 { | |
5716 base::AutoLock lock(swap_promise_result_[2].lock); | |
5717 EXPECT_FALSE(swap_promise_result_[2].did_swap_called); | |
5718 EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); | |
5719 EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); | |
5720 EXPECT_TRUE(swap_promise_result_[2].dtor_called); | |
5721 } | |
5722 } | |
5723 | |
5724 int commit_count_; | |
5725 TestSwapPromiseResult swap_promise_result_[3]; | |
5726 }; | |
5727 | |
5728 // Impl-side painting is not supported for synchronous compositing. | |
5729 SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); | |
5730 | |
5731 // Make sure page scale and top control deltas are applied to the client even | |
5732 // when the LayerTreeHost doesn't have a root layer. | |
5733 class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer | |
5734 : public LayerTreeHostTest { | |
5735 public: | |
5736 LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer() | |
5737 : deltas_sent_to_client_(false) {} | |
5738 | |
5739 void BeginTest() override { | |
5740 layer_tree_host()->SetRootLayer(nullptr); | |
5741 info_.page_scale_delta = 3.14f; | |
5742 info_.top_controls_delta = 2.73f; | |
5743 | |
5744 PostSetNeedsCommitToMainThread(); | |
5745 } | |
5746 | |
5747 void BeginMainFrame(const BeginFrameArgs& args) override { | |
5748 EXPECT_EQ(nullptr, layer_tree_host()->root_layer()); | |
5749 | |
5750 layer_tree_host()->ApplyScrollAndScale(&info_); | |
5751 EndTest(); | |
5752 } | |
5753 | |
5754 void ApplyViewportDeltas(const gfx::Vector2dF& inner, | |
5755 const gfx::Vector2dF& outer, | |
5756 const gfx::Vector2dF& elastic_overscroll_delta, | |
5757 float scale_delta, | |
5758 float top_controls_delta) override { | |
5759 EXPECT_EQ(info_.page_scale_delta, scale_delta); | |
5760 EXPECT_EQ(info_.top_controls_delta, top_controls_delta); | |
5761 deltas_sent_to_client_ = true; | |
5762 } | |
5763 | |
5764 void ApplyViewportDeltas( | |
5765 const gfx::Vector2d& scroll, | |
5766 float scale_delta, | |
5767 float top_controls_delta) override { | |
5768 EXPECT_EQ(info_.page_scale_delta, scale_delta); | |
5769 EXPECT_EQ(info_.top_controls_delta, top_controls_delta); | |
5770 deltas_sent_to_client_ = true; | |
5771 } | |
5772 | |
5773 void AfterTest() override { | |
5774 EXPECT_TRUE(deltas_sent_to_client_); | |
5775 } | |
5776 | |
5777 ScrollAndScaleSet info_; | |
5778 bool deltas_sent_to_client_; | |
5779 }; | |
5780 | |
5781 MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer); | |
5782 | |
5783 class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { | |
5784 protected: | |
5785 LayerTreeHostTestCrispUpAfterPinchEnds() | |
5786 : playback_allowed_event_(true, true) {} | |
5787 | |
5788 void SetupTree() override { | |
5789 frame_ = 1; | |
5790 posted_ = false; | |
5791 client_.set_fill_with_nonsolid_color(true); | |
5792 | |
5793 scoped_refptr<Layer> root = Layer::Create(); | |
5794 root->SetBounds(gfx::Size(500, 500)); | |
5795 | |
5796 scoped_refptr<Layer> pinch = Layer::Create(); | |
5797 pinch->SetBounds(gfx::Size(500, 500)); | |
5798 pinch->SetScrollClipLayerId(root->id()); | |
5799 pinch->SetIsContainerForFixedPositionLayers(true); | |
5800 root->AddChild(pinch); | |
5801 | |
5802 scoped_ptr<FakePicturePile> pile( | |
5803 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
5804 ImplSidePaintingSettings().default_tile_grid_size)); | |
5805 pile->SetPlaybackAllowedEvent(&playback_allowed_event_); | |
5806 scoped_refptr<FakePictureLayer> layer = | |
5807 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
5808 layer->SetBounds(gfx::Size(500, 500)); | |
5809 layer->SetContentsOpaque(true); | |
5810 // Avoid LCD text on the layer so we don't cause extra commits when we | |
5811 // pinch. | |
5812 layer->disable_lcd_text(); | |
5813 pinch->AddChild(layer); | |
5814 | |
5815 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch); | |
5816 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); | |
5817 layer_tree_host()->SetRootLayer(root); | |
5818 LayerTreeHostTest::SetupTree(); | |
5819 } | |
5820 | |
5821 // Returns the delta scale of all quads in the frame's root pass from their | |
5822 // ideal, or 0 if they are not all the same. | |
5823 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) { | |
5824 if (frame_data->has_no_damage) | |
5825 return 0.f; | |
5826 float frame_scale = 0.f; | |
5827 RenderPass* root_pass = frame_data->render_passes.back(); | |
5828 for (const auto& draw_quad : root_pass->quad_list) { | |
5829 // Checkerboards mean an incomplete frame. | |
5830 if (draw_quad->material != DrawQuad::TILED_CONTENT) | |
5831 return 0.f; | |
5832 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad); | |
5833 float quad_scale = | |
5834 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width()); | |
5835 float transform_scale = | |
5836 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0)); | |
5837 float scale = quad_scale / transform_scale; | |
5838 if (frame_scale != 0.f && frame_scale != scale) | |
5839 return 0.f; | |
5840 frame_scale = scale; | |
5841 } | |
5842 return frame_scale; | |
5843 } | |
5844 | |
5845 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
5846 | |
5847 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
5848 LayerTreeHostImpl::FrameData* frame_data, | |
5849 DrawResult draw_result) override { | |
5850 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data); | |
5851 switch (frame_) { | |
5852 case 1: | |
5853 // Drew at page scale 1 before any pinching. | |
5854 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
5855 EXPECT_EQ(1.f, quad_scale_delta); | |
5856 PostNextAfterDraw(host_impl); | |
5857 break; | |
5858 case 2: | |
5859 if (quad_scale_delta != 1.f) | |
5860 break; | |
5861 // Drew at page scale 1.5 after pinching in. | |
5862 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
5863 EXPECT_EQ(1.f, quad_scale_delta); | |
5864 PostNextAfterDraw(host_impl); | |
5865 break; | |
5866 case 3: | |
5867 // By pinching out, we will create a new tiling and raster it. This may | |
5868 // cause some additional draws, though we should still be drawing with | |
5869 // the old 1.5 tiling. | |
5870 if (frame_data->has_no_damage) | |
5871 break; | |
5872 // Drew at page scale 1 with the 1.5 tiling while pinching out. | |
5873 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
5874 EXPECT_EQ(1.5f, quad_scale_delta); | |
5875 // We don't PostNextAfterDraw here, instead we wait for the new tiling | |
5876 // to finish rastering so we don't get any noise in further steps. | |
5877 break; | |
5878 case 4: | |
5879 // Drew at page scale 1 with the 1.5 tiling after pinching out completed | |
5880 // while waiting for texture uploads to complete. | |
5881 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
5882 // This frame will not have any damage, since it's actually the same as | |
5883 // the last frame, and should contain no incomplete tiles. We just want | |
5884 // to make sure we drew here at least once after the pinch ended to be | |
5885 // sure that drawing after pinch doesn't leave us at the wrong scale | |
5886 EXPECT_TRUE(frame_data->has_no_damage); | |
5887 PostNextAfterDraw(host_impl); | |
5888 break; | |
5889 case 5: | |
5890 if (quad_scale_delta != 1.f) | |
5891 break; | |
5892 // Drew at scale 1 after texture uploads are done. | |
5893 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
5894 EXPECT_EQ(1.f, quad_scale_delta); | |
5895 EndTest(); | |
5896 break; | |
5897 } | |
5898 return draw_result; | |
5899 } | |
5900 | |
5901 void PostNextAfterDraw(LayerTreeHostImpl* host_impl) { | |
5902 if (posted_) | |
5903 return; | |
5904 posted_ = true; | |
5905 ImplThreadTaskRunner()->PostDelayedTask( | |
5906 FROM_HERE, base::Bind(&LayerTreeHostTestCrispUpAfterPinchEnds::Next, | |
5907 base::Unretained(this), host_impl), | |
5908 // Use a delay to allow raster/upload to happen in between frames. This | |
5909 // should cause flakiness if we fail to block raster/upload when | |
5910 // desired. | |
5911 base::TimeDelta::FromMilliseconds(16 * 4)); | |
5912 } | |
5913 | |
5914 void Next(LayerTreeHostImpl* host_impl) { | |
5915 ++frame_; | |
5916 posted_ = false; | |
5917 switch (frame_) { | |
5918 case 2: | |
5919 // Pinch zoom in. | |
5920 host_impl->PinchGestureBegin(); | |
5921 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100)); | |
5922 host_impl->PinchGestureEnd(); | |
5923 break; | |
5924 case 3: | |
5925 // Pinch zoom back to 1.f but don't end it. | |
5926 host_impl->PinchGestureBegin(); | |
5927 host_impl->PinchGestureUpdate(1.f / 1.5f, gfx::Point(100, 100)); | |
5928 break; | |
5929 case 4: | |
5930 // End the pinch, but delay tile production. | |
5931 playback_allowed_event_.Reset(); | |
5932 host_impl->PinchGestureEnd(); | |
5933 break; | |
5934 case 5: | |
5935 // Let tiles complete. | |
5936 playback_allowed_event_.Signal(); | |
5937 break; | |
5938 } | |
5939 } | |
5940 | |
5941 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, | |
5942 const Tile* tile) override { | |
5943 if (frame_ == 3) { | |
5944 // On frame 3, we will have a lower res tile complete for the pinch-out | |
5945 // gesture even though it's not displayed. We wait for it here to prevent | |
5946 // flakiness. | |
5947 EXPECT_EQ(0.75f, tile->contents_scale()); | |
5948 PostNextAfterDraw(host_impl); | |
5949 } | |
5950 // On frame_ == 4, we are preventing texture uploads from completing, | |
5951 // so this verifies they are not completing before frame_ == 5. | |
5952 // Flaky failures here indicate we're failing to prevent uploads from | |
5953 // completing. | |
5954 EXPECT_NE(4, frame_) << tile->contents_scale(); | |
5955 } | |
5956 | |
5957 void AfterTest() override {} | |
5958 | |
5959 FakeContentLayerClient client_; | |
5960 int frame_; | |
5961 bool posted_; | |
5962 base::WaitableEvent playback_allowed_event_; | |
5963 }; | |
5964 | |
5965 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds); | |
5966 | |
5967 class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy | |
5968 : public LayerTreeHostTestCrispUpAfterPinchEnds { | |
5969 protected: | |
5970 void InitializeSettings(LayerTreeSettings* settings) override { | |
5971 settings->use_one_copy = true; | |
5972 } | |
5973 | |
5974 scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override { | |
5975 scoped_ptr<TestWebGraphicsContext3D> context3d = | |
5976 TestWebGraphicsContext3D::Create(); | |
5977 context3d->set_support_image(true); | |
5978 context3d->set_support_sync_query(true); | |
5979 #if defined(OS_MACOSX) | |
5980 context3d->set_support_texture_rectangle(true); | |
5981 #endif | |
5982 | |
5983 if (delegating_renderer()) | |
5984 return FakeOutputSurface::CreateDelegating3d(context3d.Pass()); | |
5985 else | |
5986 return FakeOutputSurface::Create3d(context3d.Pass()); | |
5987 } | |
5988 }; | |
5989 | |
5990 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy); | |
5991 | |
5992 class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { | |
5993 protected: | |
5994 RasterizeWithGpuRasterizationCreatesResources() {} | |
5995 | |
5996 void InitializeSettings(LayerTreeSettings* settings) override { | |
5997 settings->impl_side_painting = true; | |
5998 settings->gpu_rasterization_forced = true; | |
5999 } | |
6000 | |
6001 void SetupTree() override { | |
6002 client_.set_fill_with_nonsolid_color(true); | |
6003 | |
6004 scoped_refptr<Layer> root = Layer::Create(); | |
6005 root->SetBounds(gfx::Size(500, 500)); | |
6006 | |
6007 scoped_ptr<FakePicturePile> pile( | |
6008 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
6009 ImplSidePaintingSettings().default_tile_grid_size)); | |
6010 scoped_refptr<FakePictureLayer> layer = | |
6011 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
6012 layer->SetBounds(gfx::Size(500, 500)); | |
6013 layer->SetContentsOpaque(true); | |
6014 root->AddChild(layer); | |
6015 | |
6016 layer_tree_host()->SetRootLayer(root); | |
6017 LayerTreeHostTest::SetupTree(); | |
6018 } | |
6019 | |
6020 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6021 | |
6022 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
6023 LayerTreeHostImpl::FrameData* frame_data, | |
6024 DrawResult draw_result) override { | |
6025 EXPECT_NE(0u, host_impl->resource_provider()->num_resources()); | |
6026 EndTest(); | |
6027 return draw_result; | |
6028 } | |
6029 void AfterTest() override {} | |
6030 | |
6031 FakeContentLayerClient client_; | |
6032 }; | |
6033 | |
6034 MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources); | |
6035 | |
6036 class SynchronousGpuRasterizationRasterizesVisibleOnly | |
6037 : public LayerTreeHostTest { | |
6038 protected: | |
6039 SynchronousGpuRasterizationRasterizesVisibleOnly() | |
6040 : viewport_size_(1024, 2048) {} | |
6041 | |
6042 void InitializeSettings(LayerTreeSettings* settings) override { | |
6043 settings->impl_side_painting = true; | |
6044 settings->gpu_rasterization_enabled = true; | |
6045 settings->gpu_rasterization_forced = true; | |
6046 settings->threaded_gpu_rasterization_enabled = false; | |
6047 } | |
6048 | |
6049 void SetupTree() override { | |
6050 client_.set_fill_with_nonsolid_color(true); | |
6051 | |
6052 scoped_ptr<FakePicturePile> pile( | |
6053 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
6054 ImplSidePaintingSettings().default_tile_grid_size)); | |
6055 scoped_refptr<FakePictureLayer> root = | |
6056 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
6057 root->SetBounds(gfx::Size(viewport_size_.width(), 10000)); | |
6058 root->SetContentsOpaque(true); | |
6059 | |
6060 layer_tree_host()->SetRootLayer(root); | |
6061 LayerTreeHostTest::SetupTree(); | |
6062 layer_tree_host()->SetViewportSize(viewport_size_); | |
6063 } | |
6064 | |
6065 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6066 | |
6067 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
6068 LayerTreeHostImpl::FrameData* frame_data, | |
6069 DrawResult draw_result) override { | |
6070 EXPECT_EQ(4u, host_impl->resource_provider()->num_resources()); | |
6071 | |
6072 // Verify which tiles got resources using an eviction iterator, which has to | |
6073 // return all tiles that have resources. | |
6074 scoped_ptr<EvictionTilePriorityQueue> eviction_queue( | |
6075 host_impl->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES)); | |
6076 int tile_count = 0; | |
6077 for (; !eviction_queue->IsEmpty(); eviction_queue->Pop()) { | |
6078 Tile* tile = eviction_queue->Top(); | |
6079 // Ensure this tile is within the viewport. | |
6080 EXPECT_TRUE(tile->content_rect().Intersects(gfx::Rect(viewport_size_))); | |
6081 // Ensure that the tile is 1/4 of the viewport tall (plus padding). | |
6082 EXPECT_EQ(tile->content_rect().height(), | |
6083 (viewport_size_.height() / 4) + 2); | |
6084 ++tile_count; | |
6085 } | |
6086 EXPECT_EQ(4, tile_count); | |
6087 EndTest(); | |
6088 return draw_result; | |
6089 } | |
6090 | |
6091 void AfterTest() override {} | |
6092 | |
6093 private: | |
6094 FakeContentLayerClient client_; | |
6095 gfx::Size viewport_size_; | |
6096 }; | |
6097 | |
6098 MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly); | |
6099 | |
6100 class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { | |
6101 protected: | |
6102 ThreadedGpuRasterizationRasterizesBorderTiles() | |
6103 : viewport_size_(1024, 2048) {} | |
6104 | |
6105 void InitializeSettings(LayerTreeSettings* settings) override { | |
6106 settings->impl_side_painting = true; | |
6107 settings->gpu_rasterization_enabled = true; | |
6108 settings->gpu_rasterization_forced = true; | |
6109 settings->threaded_gpu_rasterization_enabled = true; | |
6110 } | |
6111 | |
6112 void SetupTree() override { | |
6113 client_.set_fill_with_nonsolid_color(true); | |
6114 | |
6115 scoped_ptr<FakePicturePile> pile( | |
6116 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
6117 ImplSidePaintingSettings().default_tile_grid_size)); | |
6118 scoped_refptr<FakePictureLayer> root = | |
6119 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
6120 root->SetBounds(gfx::Size(10000, 10000)); | |
6121 root->SetContentsOpaque(true); | |
6122 | |
6123 layer_tree_host()->SetRootLayer(root); | |
6124 LayerTreeHostTest::SetupTree(); | |
6125 layer_tree_host()->SetViewportSize(viewport_size_); | |
6126 } | |
6127 | |
6128 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6129 | |
6130 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
6131 LayerTreeHostImpl::FrameData* frame_data, | |
6132 DrawResult draw_result) override { | |
6133 EXPECT_EQ(10u, host_impl->resource_provider()->num_resources()); | |
6134 EndTest(); | |
6135 return draw_result; | |
6136 } | |
6137 | |
6138 void AfterTest() override {} | |
6139 | |
6140 private: | |
6141 FakeContentLayerClient client_; | |
6142 gfx::Size viewport_size_; | |
6143 }; | |
6144 | |
6145 MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles); | |
6146 | |
6147 class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles | |
6148 : public LayerTreeHostTest { | |
6149 protected: | |
6150 LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles() | |
6151 : playback_allowed_event_(true, true) {} | |
6152 | |
6153 void InitializeSettings(LayerTreeSettings* settings) override { | |
6154 settings->impl_side_painting = true; | |
6155 } | |
6156 | |
6157 void SetupTree() override { | |
6158 step_ = 1; | |
6159 continuous_draws_ = 0; | |
6160 client_.set_fill_with_nonsolid_color(true); | |
6161 | |
6162 scoped_refptr<Layer> root = Layer::Create(); | |
6163 root->SetBounds(gfx::Size(500, 500)); | |
6164 | |
6165 scoped_refptr<Layer> pinch = Layer::Create(); | |
6166 pinch->SetBounds(gfx::Size(500, 500)); | |
6167 pinch->SetScrollClipLayerId(root->id()); | |
6168 pinch->SetIsContainerForFixedPositionLayers(true); | |
6169 root->AddChild(pinch); | |
6170 | |
6171 scoped_ptr<FakePicturePile> pile( | |
6172 new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, | |
6173 ImplSidePaintingSettings().default_tile_grid_size)); | |
6174 pile->SetPlaybackAllowedEvent(&playback_allowed_event_); | |
6175 scoped_refptr<FakePictureLayer> layer = | |
6176 FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); | |
6177 layer->SetBounds(gfx::Size(500, 500)); | |
6178 layer->SetContentsOpaque(true); | |
6179 // Avoid LCD text on the layer so we don't cause extra commits when we | |
6180 // pinch. | |
6181 layer->disable_lcd_text(); | |
6182 pinch->AddChild(layer); | |
6183 | |
6184 layer_tree_host()->RegisterViewportLayers(NULL, root, pinch, pinch); | |
6185 layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); | |
6186 layer_tree_host()->SetRootLayer(root); | |
6187 LayerTreeHostTest::SetupTree(); | |
6188 } | |
6189 | |
6190 // Returns the delta scale of all quads in the frame's root pass from their | |
6191 // ideal, or 0 if they are not all the same. | |
6192 float FrameQuadScaleDeltaFromIdeal(LayerTreeHostImpl::FrameData* frame_data) { | |
6193 if (frame_data->has_no_damage) | |
6194 return 0.f; | |
6195 float frame_scale = 0.f; | |
6196 RenderPass* root_pass = frame_data->render_passes.back(); | |
6197 for (const auto& draw_quad : root_pass->quad_list) { | |
6198 const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad); | |
6199 float quad_scale = | |
6200 quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width()); | |
6201 float transform_scale = | |
6202 SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0)); | |
6203 float scale = quad_scale / transform_scale; | |
6204 if (frame_scale != 0.f && frame_scale != scale) | |
6205 return 0.f; | |
6206 frame_scale = scale; | |
6207 } | |
6208 return frame_scale; | |
6209 } | |
6210 | |
6211 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6212 | |
6213 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
6214 LayerTreeHostImpl::FrameData* frame_data, | |
6215 DrawResult draw_result) override { | |
6216 float quad_scale_delta = FrameQuadScaleDeltaFromIdeal(frame_data); | |
6217 switch (step_) { | |
6218 case 1: | |
6219 // Drew at scale 1 before any pinching. | |
6220 EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor()); | |
6221 EXPECT_EQ(1.f, quad_scale_delta); | |
6222 break; | |
6223 case 2: | |
6224 if (quad_scale_delta != 1.f / 1.5f) | |
6225 break; | |
6226 // Drew at scale 1 still though the ideal is 1.5. | |
6227 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
6228 EXPECT_EQ(1.f / 1.5f, quad_scale_delta); | |
6229 break; | |
6230 case 3: | |
6231 // Continuous draws are attempted. | |
6232 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
6233 if (!frame_data->has_no_damage) | |
6234 EXPECT_EQ(1.f / 1.5f, quad_scale_delta); | |
6235 break; | |
6236 case 4: | |
6237 if (quad_scale_delta != 1.f) | |
6238 break; | |
6239 // Drew at scale 1.5 when all the tiles completed. | |
6240 EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor()); | |
6241 EXPECT_EQ(1.f, quad_scale_delta); | |
6242 break; | |
6243 case 5: | |
6244 // TODO(danakj): We get more draws before the NotifyReadyToDraw | |
6245 // because it is asynchronous from the previous draw and happens late. | |
6246 break; | |
6247 case 6: | |
6248 // NotifyReadyToDraw happened. If we were already inside a frame, we may | |
6249 // try to draw once more. | |
6250 break; | |
6251 case 7: | |
6252 NOTREACHED() << "No draws should happen once we have a complete frame."; | |
6253 break; | |
6254 } | |
6255 return draw_result; | |
6256 } | |
6257 | |
6258 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
6259 switch (step_) { | |
6260 case 1: | |
6261 // Delay tile production. | |
6262 playback_allowed_event_.Reset(); | |
6263 // Pinch zoom in to cause new tiles to be required. | |
6264 host_impl->PinchGestureBegin(); | |
6265 host_impl->PinchGestureUpdate(1.5f, gfx::Point(100, 100)); | |
6266 host_impl->PinchGestureEnd(); | |
6267 ++step_; | |
6268 break; | |
6269 case 2: | |
6270 ++step_; | |
6271 break; | |
6272 case 3: | |
6273 // We should continue to try draw while there are incomplete visible | |
6274 // tiles. | |
6275 if (++continuous_draws_ > 5) { | |
6276 // Allow the tiles to complete. | |
6277 playback_allowed_event_.Signal(); | |
6278 ++step_; | |
6279 } | |
6280 break; | |
6281 case 4: | |
6282 ++step_; | |
6283 break; | |
6284 case 5: | |
6285 // Waiting for NotifyReadyToDraw. | |
6286 break; | |
6287 case 6: | |
6288 // NotifyReadyToDraw happened. | |
6289 ++step_; | |
6290 break; | |
6291 } | |
6292 } | |
6293 | |
6294 void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) override { | |
6295 if (step_ == 5) { | |
6296 ++step_; | |
6297 // NotifyReadyToDraw has happened, we may draw once more, but should not | |
6298 // get any more draws after that. End the test after a timeout to watch | |
6299 // for any extraneous draws. | |
6300 // TODO(brianderson): We could remove this delay and instead wait until | |
6301 // the BeginFrameSource decides it doesn't need to send frames anymore, | |
6302 // or test that it already doesn't here. | |
6303 EndTestAfterDelayMs(16 * 4); | |
6304 } | |
6305 } | |
6306 | |
6307 void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, | |
6308 const Tile* tile) override { | |
6309 // On step_ == 2, we are preventing texture uploads from completing, | |
6310 // so this verifies they are not completing before step_ == 3. | |
6311 // Flaky failures here indicate we're failing to prevent uploads from | |
6312 // completing. | |
6313 EXPECT_NE(2, step_); | |
6314 } | |
6315 | |
6316 void AfterTest() override { EXPECT_GT(continuous_draws_, 5); } | |
6317 | |
6318 FakeContentLayerClient client_; | |
6319 int step_; | |
6320 int continuous_draws_; | |
6321 base::WaitableEvent playback_allowed_event_; | |
6322 }; | |
6323 | |
6324 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles); | |
6325 | |
6326 class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest { | |
6327 public: | |
6328 LayerTreeHostTestOneActivatePerPrepareTiles() | |
6329 : notify_ready_to_activate_count_(0u), | |
6330 scheduled_prepare_tiles_count_(0) {} | |
6331 | |
6332 void SetupTree() override { | |
6333 client_.set_fill_with_nonsolid_color(true); | |
6334 scoped_refptr<FakePictureLayer> root_layer = | |
6335 FakePictureLayer::Create(&client_); | |
6336 root_layer->SetBounds(gfx::Size(1500, 1500)); | |
6337 root_layer->SetIsDrawable(true); | |
6338 | |
6339 layer_tree_host()->SetRootLayer(root_layer); | |
6340 LayerTreeHostTest::SetupTree(); | |
6341 } | |
6342 | |
6343 void BeginTest() override { | |
6344 layer_tree_host()->SetViewportSize(gfx::Size(16, 16)); | |
6345 PostSetNeedsCommitToMainThread(); | |
6346 } | |
6347 | |
6348 void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, | |
6349 bool success) override { | |
6350 ASSERT_TRUE(success); | |
6351 host_impl->tile_manager()->SetScheduledRasterTaskLimitForTesting(1); | |
6352 } | |
6353 | |
6354 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { | |
6355 ++notify_ready_to_activate_count_; | |
6356 EndTestAfterDelayMs(100); | |
6357 } | |
6358 | |
6359 void ScheduledActionPrepareTiles() override { | |
6360 ++scheduled_prepare_tiles_count_; | |
6361 } | |
6362 | |
6363 void AfterTest() override { | |
6364 // Expect at most a notification for each scheduled prepare tiles, plus one | |
6365 // for the initial commit (which doesn't go through scheduled actions). | |
6366 // The reason this is not an equality is because depending on timing, we | |
6367 // might get a prepare tiles but not yet get a notification that we're | |
6368 // ready to activate. The intent of a test is to ensure that we don't | |
6369 // get more than one notification per prepare tiles, so this is OK. | |
6370 EXPECT_LE(notify_ready_to_activate_count_, | |
6371 1u + scheduled_prepare_tiles_count_); | |
6372 } | |
6373 | |
6374 protected: | |
6375 FakeContentLayerClient client_; | |
6376 size_t notify_ready_to_activate_count_; | |
6377 size_t scheduled_prepare_tiles_count_; | |
6378 }; | |
6379 | |
6380 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles); | |
6381 | |
6382 class LayerTreeHostTestFrameTimingRequestsSaveTimestamps | |
6383 : public LayerTreeHostTest { | |
6384 public: | |
6385 LayerTreeHostTestFrameTimingRequestsSaveTimestamps() | |
6386 : check_results_on_commit_(false) {} | |
6387 | |
6388 void SetupTree() override { | |
6389 scoped_refptr<FakePictureLayer> root_layer = | |
6390 FakePictureLayer::Create(&client_); | |
6391 root_layer->SetBounds(gfx::Size(200, 200)); | |
6392 root_layer->SetIsDrawable(true); | |
6393 | |
6394 scoped_refptr<FakePictureLayer> child_layer = | |
6395 FakePictureLayer::Create(&client_); | |
6396 child_layer->SetBounds(gfx::Size(1500, 1500)); | |
6397 child_layer->SetIsDrawable(true); | |
6398 | |
6399 std::vector<FrameTimingRequest> requests; | |
6400 requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100))); | |
6401 requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100))); | |
6402 child_layer->SetFrameTimingRequests(requests); | |
6403 | |
6404 root_layer->AddChild(child_layer); | |
6405 layer_tree_host()->SetRootLayer(root_layer); | |
6406 LayerTreeHostTest::SetupTree(); | |
6407 } | |
6408 | |
6409 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6410 | |
6411 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
6412 if (!check_results_on_commit_) | |
6413 return; | |
6414 | |
6415 // Since in reality, the events will be read by LayerTreeHost during commit, | |
6416 // we check the requests here to ensure that they are correct at the next | |
6417 // commit time (as opposed to checking in DrawLayers for instance). | |
6418 // TODO(vmpstr): Change this to read things from the main thread when this | |
6419 // information is propagated to the main thread (not yet implemented). | |
6420 FrameTimingTracker* tracker = host_impl->frame_timing_tracker(); | |
6421 scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set = | |
6422 tracker->GroupCountsByRectId(); | |
6423 EXPECT_EQ(1u, timing_set->size()); | |
6424 auto rect_1_it = timing_set->find(1); | |
6425 EXPECT_TRUE(rect_1_it != timing_set->end()); | |
6426 const auto& timing_events = rect_1_it->second; | |
6427 EXPECT_EQ(1u, timing_events.size()); | |
6428 EXPECT_EQ(host_impl->active_tree()->source_frame_number(), | |
6429 timing_events[0].frame_id); | |
6430 EXPECT_GT(timing_events[0].timestamp, base::TimeTicks()); | |
6431 | |
6432 EndTest(); | |
6433 } | |
6434 | |
6435 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
6436 check_results_on_commit_ = true; | |
6437 PostSetNeedsCommitToMainThread(); | |
6438 } | |
6439 | |
6440 void AfterTest() override {} | |
6441 | |
6442 private: | |
6443 FakeContentLayerClient client_; | |
6444 bool check_results_on_commit_; | |
6445 }; | |
6446 | |
6447 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps); | |
6448 | |
6449 class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest { | |
6450 public: | |
6451 LayerTreeHostTestActivationCausesPrepareTiles() | |
6452 : scheduled_prepare_tiles_count_(0) {} | |
6453 | |
6454 void SetupTree() override { | |
6455 client_.set_fill_with_nonsolid_color(true); | |
6456 scoped_refptr<FakePictureLayer> root_layer = | |
6457 FakePictureLayer::Create(&client_); | |
6458 root_layer->SetBounds(gfx::Size(150, 150)); | |
6459 root_layer->SetIsDrawable(true); | |
6460 | |
6461 layer_tree_host()->SetRootLayer(root_layer); | |
6462 LayerTreeHostTest::SetupTree(); | |
6463 } | |
6464 | |
6465 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6466 | |
6467 void NotifyReadyToActivateOnThread(LayerTreeHostImpl* impl) override { | |
6468 // Ensure we've already activated. | |
6469 EXPECT_FALSE(impl->pending_tree()); | |
6470 | |
6471 // After activating, we either need to prepare tiles, or we've already | |
6472 // called a scheduled prepare tiles. This is done because activation might | |
6473 // cause us to have to memory available (old active tree is gone), so we | |
6474 // need to ensure we will get a PrepareTiles call. | |
6475 if (!impl->prepare_tiles_needed()) | |
6476 EXPECT_GE(scheduled_prepare_tiles_count_, 1); | |
6477 EndTest(); | |
6478 } | |
6479 | |
6480 void ScheduledActionPrepareTiles() override { | |
6481 ++scheduled_prepare_tiles_count_; | |
6482 } | |
6483 | |
6484 void AfterTest() override {} | |
6485 | |
6486 protected: | |
6487 FakeContentLayerClient client_; | |
6488 int scheduled_prepare_tiles_count_; | |
6489 }; | |
6490 | |
6491 MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles); | |
6492 | |
6493 // This tests an assertion that DidCommit and WillCommit happen in the same | |
6494 // stack frame with no tasks that run between them. Various embedders of | |
6495 // cc depend on this logic. ui::Compositor holds a compositor lock between | |
6496 // these events and the inspector timeline wants begin/end CompositeLayers | |
6497 // to be properly nested with other begin/end events. | |
6498 class LayerTreeHostTestNoTasksBetweenWillAndDidCommit | |
6499 : public LayerTreeHostTest { | |
6500 public: | |
6501 LayerTreeHostTestNoTasksBetweenWillAndDidCommit() : did_commit_(false) {} | |
6502 | |
6503 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
6504 | |
6505 void WillCommit() override { | |
6506 MainThreadTaskRunner()->PostTask( | |
6507 FROM_HERE, base::Bind(&LayerTreeHostTestNoTasksBetweenWillAndDidCommit:: | |
6508 EndTestShouldRunAfterDidCommit, | |
6509 base::Unretained(this))); | |
6510 } | |
6511 | |
6512 void EndTestShouldRunAfterDidCommit() { | |
6513 EXPECT_TRUE(did_commit_); | |
6514 EndTest(); | |
6515 } | |
6516 | |
6517 void DidCommit() override { | |
6518 EXPECT_FALSE(did_commit_); | |
6519 did_commit_ = true; | |
6520 } | |
6521 | |
6522 void AfterTest() override { EXPECT_TRUE(did_commit_); } | |
6523 | |
6524 private: | |
6525 bool did_commit_; | |
6526 }; | |
6527 | |
6528 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit); | |
6529 | |
6530 // Verify that if a LayerImpl holds onto a copy request for multiple | |
6531 // frames that it will continue to have a render surface through | |
6532 // multiple commits, even though the Layer itself has no reason | |
6533 // to have a render surface. | |
6534 class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest { | |
6535 protected: | |
6536 void SetupTree() override { | |
6537 scoped_refptr<Layer> root = Layer::Create(); | |
6538 root->CreateRenderSurface(); | |
6539 root->SetBounds(gfx::Size(10, 10)); | |
6540 child_ = Layer::Create(); | |
6541 child_->SetBounds(gfx::Size(20, 20)); | |
6542 root->AddChild(child_); | |
6543 | |
6544 layer_tree_host()->SetRootLayer(root); | |
6545 LayerTreeHostTest::SetupTree(); | |
6546 } | |
6547 | |
6548 static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} | |
6549 | |
6550 void BeginTest() override { | |
6551 child_->RequestCopyOfOutput( | |
6552 CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback))); | |
6553 EXPECT_TRUE(child_->HasCopyRequest()); | |
6554 PostSetNeedsCommitToMainThread(); | |
6555 } | |
6556 | |
6557 void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); } | |
6558 | |
6559 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
6560 LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id()); | |
6561 | |
6562 switch (host_impl->sync_tree()->source_frame_number()) { | |
6563 case 0: | |
6564 EXPECT_TRUE(child_impl->HasCopyRequest()); | |
6565 EXPECT_TRUE(child_impl->render_surface()); | |
6566 break; | |
6567 case 1: | |
6568 if (host_impl->proxy()->CommitToActiveTree()) { | |
6569 EXPECT_TRUE(child_impl->HasCopyRequest()); | |
6570 EXPECT_TRUE(child_impl->render_surface()); | |
6571 } else { | |
6572 EXPECT_FALSE(child_impl->HasCopyRequest()); | |
6573 EXPECT_FALSE(child_impl->render_surface()); | |
6574 } | |
6575 break; | |
6576 default: | |
6577 NOTREACHED(); | |
6578 break; | |
6579 } | |
6580 } | |
6581 | |
6582 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
6583 LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id()); | |
6584 EXPECT_TRUE(child_impl->HasCopyRequest()); | |
6585 EXPECT_TRUE(child_impl->render_surface()); | |
6586 | |
6587 switch (host_impl->active_tree()->source_frame_number()) { | |
6588 case 0: | |
6589 // Lose output surface to prevent drawing and cause another commit. | |
6590 host_impl->DidLoseOutputSurface(); | |
6591 break; | |
6592 case 1: | |
6593 EndTest(); | |
6594 break; | |
6595 default: | |
6596 NOTREACHED(); | |
6597 break; | |
6598 } | |
6599 } | |
6600 | |
6601 void AfterTest() override {} | |
6602 | |
6603 private: | |
6604 scoped_refptr<Layer> child_; | |
6605 }; | |
6606 | |
6607 SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests); | |
6608 | |
6609 } // namespace cc | |
OLD | NEW |