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.
5 #include "cc/trees/layer_tree_host.h"
9 #include "base/synchronization/lock.h"
10 #include "cc/animation/timing_function.h"
11 #include "cc/debug/frame_rate_counter.h"
12 #include "cc/layers/content_layer.h"
13 #include "cc/layers/content_layer_client.h"
14 #include "cc/layers/io_surface_layer.h"
15 #include "cc/layers/layer_impl.h"
16 #include "cc/layers/picture_layer.h"
17 #include "cc/layers/scrollbar_layer.h"
18 #include "cc/output/begin_frame_args.h"
19 #include "cc/output/copy_output_request.h"
20 #include "cc/output/copy_output_result.h"
21 #include "cc/output/output_surface.h"
22 #include "cc/resources/prioritized_resource.h"
23 #include "cc/resources/prioritized_resource_manager.h"
24 #include "cc/resources/resource_update_queue.h"
25 #include "cc/scheduler/frame_rate_controller.h"
26 #include "cc/test/fake_content_layer.h"
27 #include "cc/test/fake_content_layer_client.h"
28 #include "cc/test/fake_layer_tree_host_client.h"
29 #include "cc/test/fake_output_surface.h"
30 #include "cc/test/fake_picture_layer.h"
31 #include "cc/test/fake_picture_layer_impl.h"
32 #include "cc/test/fake_proxy.h"
33 #include "cc/test/fake_scrollbar_layer.h"
34 #include "cc/test/geometry_test_utils.h"
35 #include "cc/test/layer_tree_test.h"
36 #include "cc/test/occlusion_tracker_test_common.h"
37 #include "cc/trees/layer_tree_host_impl.h"
38 #include "cc/trees/layer_tree_impl.h"
39 #include "cc/trees/single_thread_proxy.h"
40 #include "cc/trees/thread_proxy.h"
41 #include "gpu/GLES2/gl2extchromium.h"
42 #include "skia/ext/refptr.h"
43 #include "testing/gmock/include/gmock/gmock.h"
44 #include "third_party/khronos/GLES2/gl2.h"
45 #include "third_party/khronos/GLES2/gl2ext.h"
46 #include "third_party/skia/include/core/SkPicture.h"
47 #include "ui/gfx/point_conversions.h"
48 #include "ui/gfx/size_conversions.h"
49 #include "ui/gfx/vector2d_conversions.h"
52 using testing::AnyNumber
;
53 using testing::AtLeast
;
59 class LayerTreeHostTest
: public LayerTreeTest
{
62 // Test interleaving of redraws and commits
63 class LayerTreeHostTestCommitingWithContinuousRedraw
64 : public LayerTreeHostTest
{
66 LayerTreeHostTestCommitingWithContinuousRedraw()
67 : num_complete_commits_(0), num_draws_(0) {}
69 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
71 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
72 num_complete_commits_
++;
73 if (num_complete_commits_
== 2)
77 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
79 PostSetNeedsCommitToMainThread();
81 PostSetNeedsRedrawToMainThread();
84 virtual void AfterTest() OVERRIDE
{}
87 int num_complete_commits_
;
91 MULTI_THREAD_TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw
);
93 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
95 class LayerTreeHostTestSetNeedsCommit1
: public LayerTreeHostTest
{
97 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
99 virtual void BeginTest() OVERRIDE
{
100 PostSetNeedsCommitToMainThread();
101 PostSetNeedsCommitToMainThread();
104 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
106 if (!impl
->active_tree()->source_frame_number())
110 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
114 virtual void AfterTest() OVERRIDE
{
115 EXPECT_GE(1, num_commits_
);
116 EXPECT_GE(1, num_draws_
);
124 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1
);
126 // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
127 // first committed frame draws should lead to another commit.
128 class LayerTreeHostTestSetNeedsCommit2
: public LayerTreeHostTest
{
130 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
132 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
134 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
138 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
140 switch (num_commits_
) {
142 PostSetNeedsCommitToMainThread();
152 virtual void AfterTest() OVERRIDE
{
153 EXPECT_EQ(2, num_commits_
);
154 EXPECT_LE(1, num_draws_
);
162 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2
);
164 // 1 setNeedsRedraw after the first commit has completed should lead to 1
166 class LayerTreeHostTestSetNeedsRedraw
: public LayerTreeHostTest
{
168 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
170 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
172 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
173 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
175 // Redraw again to verify that the second redraw doesn't commit.
176 PostSetNeedsRedrawToMainThread();
183 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
184 EXPECT_EQ(0, num_draws_
);
188 virtual void AfterTest() OVERRIDE
{
189 EXPECT_GE(2, num_draws_
);
190 EXPECT_EQ(1, num_commits_
);
198 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw
);
200 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
201 // must contain invalid_rect.
202 class LayerTreeHostTestSetNeedsRedrawRect
: public LayerTreeHostTest
{
204 LayerTreeHostTestSetNeedsRedrawRect()
207 invalid_rect_(10, 10, 20, 20),
208 root_layer_(ContentLayer::Create(&client_
)) {
211 virtual void BeginTest() OVERRIDE
{
212 root_layer_
->SetIsDrawable(true);
213 root_layer_
->SetBounds(bounds_
);
214 layer_tree_host()->SetRootLayer(root_layer_
);
215 layer_tree_host()->SetViewportSize(bounds_
);
216 PostSetNeedsCommitToMainThread();
219 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
220 LayerTreeHostImpl::FrameData
* frame_data
,
221 bool result
) OVERRIDE
{
224 gfx::RectF root_damage_rect
;
225 if (!frame_data
->render_passes
.empty())
226 root_damage_rect
= frame_data
->render_passes
.back()->damage_rect
;
229 // If this is the first frame, expect full frame damage.
230 EXPECT_RECT_EQ(root_damage_rect
, gfx::Rect(bounds_
));
232 // Check that invalid_rect_ is indeed repainted.
233 EXPECT_TRUE(root_damage_rect
.Contains(invalid_rect_
));
239 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
241 PostSetNeedsRedrawRectToMainThread(invalid_rect_
);
248 virtual void AfterTest() OVERRIDE
{
249 EXPECT_EQ(2, num_draws_
);
254 const gfx::Size bounds_
;
255 const gfx::Rect invalid_rect_
;
256 FakeContentLayerClient client_
;
257 scoped_refptr
<ContentLayer
> root_layer_
;
260 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect
);
262 class LayerTreeHostTestNoExtraCommitFromInvalidate
: public LayerTreeHostTest
{
264 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
265 settings
->layer_transforms_should_scale_layer_contents
= true;
268 virtual void SetupTree() OVERRIDE
{
269 root_layer_
= Layer::Create();
270 root_layer_
->SetBounds(gfx::Size(10, 20));
272 scaled_layer_
= FakeContentLayer::Create(&client_
);
273 scaled_layer_
->SetBounds(gfx::Size(1, 1));
274 root_layer_
->AddChild(scaled_layer_
);
276 layer_tree_host()->SetRootLayer(root_layer_
);
277 LayerTreeHostTest::SetupTree();
280 virtual void BeginTest() OVERRIDE
{
281 PostSetNeedsCommitToMainThread();
284 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
285 if (host_impl
->active_tree()->source_frame_number() == 1)
289 virtual void DidCommit() OVERRIDE
{
290 switch (layer_tree_host()->commit_number()) {
292 // Changing the device scale factor causes a commit. It also changes
293 // the content bounds of |scaled_layer_|, which should not generate
294 // a second commit as a result.
295 layer_tree_host()->SetDeviceScaleFactor(4.f
);
299 EXPECT_EQ(2, layer_tree_host()->commit_number());
303 virtual void AfterTest() OVERRIDE
{
304 EXPECT_EQ(gfx::Size(4, 4).ToString(),
305 scaled_layer_
->content_bounds().ToString());
309 FakeContentLayerClient client_
;
310 scoped_refptr
<Layer
> root_layer_
;
311 scoped_refptr
<FakeContentLayer
> scaled_layer_
;
314 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate
);
316 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
317 : public LayerTreeHostTest
{
319 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
320 settings
->layer_transforms_should_scale_layer_contents
= true;
323 virtual void SetupTree() OVERRIDE
{
324 root_layer_
= Layer::Create();
325 root_layer_
->SetBounds(gfx::Size(10, 20));
327 bool paint_scrollbar
= true;
328 bool has_thumb
= false;
329 scrollbar_
= FakeScrollbarLayer::Create(paint_scrollbar
,
332 scrollbar_
->SetPosition(gfx::Point(0, 10));
333 scrollbar_
->SetBounds(gfx::Size(10, 10));
335 root_layer_
->AddChild(scrollbar_
);
337 layer_tree_host()->SetRootLayer(root_layer_
);
338 LayerTreeHostTest::SetupTree();
341 virtual void BeginTest() OVERRIDE
{
342 PostSetNeedsCommitToMainThread();
345 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
346 if (host_impl
->active_tree()->source_frame_number() == 1)
350 virtual void DidCommit() OVERRIDE
{
351 switch (layer_tree_host()->commit_number()) {
353 // Changing the device scale factor causes a commit. It also changes
354 // the content bounds of |scrollbar_|, which should not generate
355 // a second commit as a result.
356 layer_tree_host()->SetDeviceScaleFactor(4.f
);
360 EXPECT_EQ(2, layer_tree_host()->commit_number());
364 virtual void AfterTest() OVERRIDE
{
365 EXPECT_EQ(gfx::Size(40, 40).ToString(),
366 scrollbar_
->content_bounds().ToString());
370 FakeContentLayerClient client_
;
371 scoped_refptr
<Layer
> root_layer_
;
372 scoped_refptr
<FakeScrollbarLayer
> scrollbar_
;
375 SINGLE_AND_MULTI_THREAD_TEST_F(
376 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
);
378 class LayerTreeHostTestCompositeAndReadback
: public LayerTreeHostTest
{
380 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
382 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
384 virtual void DidCommit() OVERRIDE
{
386 if (num_commits_
== 1) {
388 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
389 } else if (num_commits_
== 2) {
390 // This is inside the readback. We should get another commit after it.
391 } else if (num_commits_
== 3) {
398 virtual void AfterTest() OVERRIDE
{}
404 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback
);
406 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
407 : public LayerTreeHostTest
{
409 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
412 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
414 virtual void DidCommit() OVERRIDE
{
416 if (num_commits_
== 1) {
417 layer_tree_host()->SetNeedsCommit();
418 } else if (num_commits_
== 2) {
420 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
421 } else if (num_commits_
== 3) {
422 // This is inside the readback. We should get another commit after it.
423 } else if (num_commits_
== 4) {
430 virtual void AfterTest() OVERRIDE
{}
437 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
);
439 // If the layerTreeHost says it can't draw, Then we should not try to draw.
440 class LayerTreeHostTestCanDrawBlocksDrawing
: public LayerTreeHostTest
{
442 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
444 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
446 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
449 // Only the initial draw should bring us here.
450 EXPECT_TRUE(impl
->CanDraw());
451 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
454 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
457 if (num_commits_
>= 1) {
458 // After the first commit, we should not be able to draw.
459 EXPECT_FALSE(impl
->CanDraw());
463 virtual void DidCommit() OVERRIDE
{
465 if (num_commits_
== 1) {
466 // Make the viewport empty so the host says it can't draw.
467 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
468 } else if (num_commits_
== 2) {
470 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
471 } else if (num_commits_
== 3) {
472 // Let it draw so we go idle and end the test.
473 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
479 virtual void AfterTest() OVERRIDE
{}
486 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing
);
488 // beginLayerWrite should prevent draws from executing until a commit occurs
489 class LayerTreeHostTestWriteLayersRedraw
: public LayerTreeHostTest
{
491 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
493 virtual void BeginTest() OVERRIDE
{
494 PostAcquireLayerTextures();
495 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
496 PostSetNeedsCommitToMainThread();
499 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
501 EXPECT_EQ(num_draws_
, num_commits_
);
504 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
509 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_commits_
); }
516 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw
);
518 // Verify that when resuming visibility, Requesting layer write permission
519 // will not deadlock the main thread even though there are not yet any
520 // scheduled redraws. This behavior is critical for reliably surviving tab
521 // switching. There are no failure conditions to this test, it just passes
522 // by not timing out.
523 class LayerTreeHostTestWriteLayersAfterVisible
: public LayerTreeHostTest
{
525 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
527 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
529 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
531 if (num_commits_
== 2)
533 else if (num_commits_
< 2) {
534 PostSetVisibleToMainThread(false);
535 PostSetVisibleToMainThread(true);
536 PostAcquireLayerTextures();
537 PostSetNeedsCommitToMainThread();
541 virtual void AfterTest() OVERRIDE
{}
547 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible
);
549 // A compositeAndReadback while invisible should force a normal commit without
551 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
552 : public LayerTreeHostTest
{
554 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
556 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
558 virtual void DidCommitAndDrawFrame() OVERRIDE
{
560 if (num_commits_
== 1) {
561 layer_tree_host()->SetVisible(false);
562 layer_tree_host()->SetNeedsCommit();
563 layer_tree_host()->SetNeedsCommit();
565 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
571 virtual void AfterTest() OVERRIDE
{}
577 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible
);
579 class LayerTreeHostTestAbortFrameWhenInvisible
: public LayerTreeHostTest
{
581 LayerTreeHostTestAbortFrameWhenInvisible() {}
583 virtual void BeginTest() OVERRIDE
{
584 // Request a commit (from the main thread), Which will trigger the commit
585 // flow from the impl side.
586 layer_tree_host()->SetNeedsCommit();
587 // Then mark ourselves as not visible before processing any more messages
588 // on the main thread.
589 layer_tree_host()->SetVisible(false);
590 // If we make it without kicking a frame, we pass!
591 EndTestAfterDelay(1);
594 virtual void Layout() OVERRIDE
{
599 virtual void AfterTest() OVERRIDE
{}
604 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible
);
606 // This test verifies that properties on the layer tree host are commited
608 class LayerTreeHostTestCommit
: public LayerTreeHostTest
{
610 LayerTreeHostTestCommit() {}
612 virtual void BeginTest() OVERRIDE
{
613 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
614 layer_tree_host()->set_background_color(SK_ColorGRAY
);
615 layer_tree_host()->SetPageScaleFactorAndLimits(5.f
, 5.f
, 5.f
);
617 PostSetNeedsCommitToMainThread();
620 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
621 EXPECT_EQ(gfx::Size(20, 20), impl
->device_viewport_size());
622 EXPECT_EQ(SK_ColorGRAY
, impl
->active_tree()->background_color());
623 EXPECT_EQ(5.f
, impl
->active_tree()->page_scale_factor());
628 virtual void AfterTest() OVERRIDE
{}
631 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit
);
633 // This test verifies that LayerTreeHostImpl's current frame time gets
634 // updated in consecutive frames when it doesn't draw due to tree
635 // activation failure.
636 class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
637 : public LayerTreeHostTest
{
639 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() : frame_(0) {}
641 virtual void BeginTest() OVERRIDE
{
642 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
643 layer_tree_host()->set_background_color(SK_ColorGRAY
);
645 PostSetNeedsCommitToMainThread();
648 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
650 EXPECT_NE(first_frame_time_
, impl
->CurrentFrameTimeTicks());
655 EXPECT_FALSE(impl
->settings().impl_side_painting
);
659 virtual bool CanActivatePendingTree(LayerTreeHostImpl
* impl
) OVERRIDE
{
662 first_frame_time_
= impl
->CurrentFrameTimeTicks();
664 // Since base::TimeTicks::Now() uses a low-resolution clock on
665 // Windows, we need to make sure that the clock has incremented past
666 // first_frame_time_.
667 while (first_frame_time_
== base::TimeTicks::Now()) {}
675 virtual void AfterTest() OVERRIDE
{}
679 base::TimeTicks first_frame_time_
;
682 SINGLE_AND_MULTI_THREAD_TEST_F(
683 LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
);
685 // This test verifies that LayerTreeHostImpl's current frame time gets
686 // updated in consecutive frames when it draws in each frame.
687 class LayerTreeHostTestFrameTimeUpdatesAfterDraw
: public LayerTreeHostTest
{
689 LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
691 virtual void BeginTest() OVERRIDE
{
692 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
693 layer_tree_host()->set_background_color(SK_ColorGRAY
);
695 PostSetNeedsCommitToMainThread();
698 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
701 first_frame_time_
= impl
->CurrentFrameTimeTicks();
702 impl
->SetNeedsRedraw();
704 // Since base::TimeTicks::Now() uses a low-resolution clock on
705 // Windows, we need to make sure that the clock has incremented past
706 // first_frame_time_.
707 while (first_frame_time_
== base::TimeTicks::Now()) {}
712 EXPECT_NE(first_frame_time_
, impl
->CurrentFrameTimeTicks());
716 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
717 // Ensure there isn't a commit between the two draws, to ensure that a
718 // commit isn't required for updating the current frame time. We can
719 // only check for this in the multi-threaded case, since in the single-
720 // threaded case there will always be a commit between consecutive draws.
722 EXPECT_EQ(0, frame_
);
725 virtual void AfterTest() OVERRIDE
{}
729 base::TimeTicks first_frame_time_
;
732 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw
);
734 // Verifies that StartPageScaleAnimation events propagate correctly
735 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
736 class LayerTreeHostTestStartPageScaleAnimation
: public LayerTreeHostTest
{
738 LayerTreeHostTestStartPageScaleAnimation() {}
740 virtual void SetupTree() OVERRIDE
{
741 LayerTreeHostTest::SetupTree();
743 scroll_layer_
= FakeContentLayer::Create(&client_
);
744 scroll_layer_
->SetScrollable(true);
745 scroll_layer_
->SetScrollOffset(gfx::Vector2d());
746 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
749 virtual void BeginTest() OVERRIDE
{
750 PostSetNeedsCommitToMainThread();
753 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
, float scale
)
755 gfx::Vector2d offset
= scroll_layer_
->scroll_offset();
756 scroll_layer_
->SetScrollOffset(offset
+ scroll_delta
);
757 layer_tree_host()->SetPageScaleFactorAndLimits(scale
, 0.5f
, 2.f
);
760 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
761 impl
->ProcessScrollDeltas();
762 // We get one commit before the first draw, and the animation doesn't happen
763 // until the second draw.
764 switch (impl
->active_tree()->source_frame_number()) {
766 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_factor());
767 // We'll start an animation when we get back to the main thread.
770 EXPECT_EQ(1.f
, impl
->active_tree()->page_scale_factor());
771 PostSetNeedsRedrawToMainThread();
774 EXPECT_EQ(1.25f
, impl
->active_tree()->page_scale_factor());
782 virtual void DidCommitAndDrawFrame() OVERRIDE
{
783 switch (layer_tree_host()->commit_number()) {
785 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 2.f
);
786 layer_tree_host()->StartPageScaleAnimation(
787 gfx::Vector2d(), false, 1.25f
, base::TimeDelta());
792 virtual void AfterTest() OVERRIDE
{}
794 FakeContentLayerClient client_
;
795 scoped_refptr
<FakeContentLayer
> scroll_layer_
;
798 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation
);
800 class LayerTreeHostTestSetVisible
: public LayerTreeHostTest
{
802 LayerTreeHostTestSetVisible() : num_draws_(0) {}
804 virtual void BeginTest() OVERRIDE
{
805 PostSetNeedsCommitToMainThread();
806 PostSetVisibleToMainThread(false);
807 // This is suppressed while we're invisible.
808 PostSetNeedsRedrawToMainThread();
809 // Triggers the redraw.
810 PostSetVisibleToMainThread(true);
813 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
814 EXPECT_TRUE(impl
->visible());
819 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_draws_
); }
825 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible
);
827 class TestOpacityChangeLayerDelegate
: public ContentLayerClient
{
829 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
831 void SetTestLayer(Layer
* test_layer
) { test_layer_
= test_layer
; }
833 virtual void PaintContents(SkCanvas
*, gfx::Rect
, gfx::RectF
*) OVERRIDE
{
834 // Set layer opacity to 0.
836 test_layer_
->SetOpacity(0.f
);
838 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
844 class ContentLayerWithUpdateTracking
: public ContentLayer
{
846 static scoped_refptr
<ContentLayerWithUpdateTracking
> Create(
847 ContentLayerClient
* client
) {
848 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client
));
851 int PaintContentsCount() { return paint_contents_count_
; }
852 void ResetPaintContentsCount() { paint_contents_count_
= 0; }
854 virtual void Update(ResourceUpdateQueue
* queue
,
855 const OcclusionTracker
* occlusion
,
856 RenderingStats
* stats
) OVERRIDE
{
857 ContentLayer::Update(queue
, occlusion
, stats
);
858 paint_contents_count_
++;
862 explicit ContentLayerWithUpdateTracking(ContentLayerClient
* client
)
863 : ContentLayer(client
), paint_contents_count_(0) {
864 SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
865 SetBounds(gfx::Size(10, 10));
868 virtual ~ContentLayerWithUpdateTracking() {}
870 int paint_contents_count_
;
873 // Layer opacity change during paint should not prevent compositor resources
874 // from being updated during commit.
875 class LayerTreeHostTestOpacityChange
: public LayerTreeHostTest
{
877 LayerTreeHostTestOpacityChange()
878 : test_opacity_change_delegate_(),
879 update_check_layer_(ContentLayerWithUpdateTracking::Create(
880 &test_opacity_change_delegate_
)) {
881 test_opacity_change_delegate_
.SetTestLayer(update_check_layer_
.get());
884 virtual void BeginTest() OVERRIDE
{
885 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
886 layer_tree_host()->root_layer()->AddChild(update_check_layer_
);
888 PostSetNeedsCommitToMainThread();
891 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
895 virtual void AfterTest() OVERRIDE
{
896 // Update() should have been called once.
897 EXPECT_EQ(1, update_check_layer_
->PaintContentsCount());
901 TestOpacityChangeLayerDelegate test_opacity_change_delegate_
;
902 scoped_refptr
<ContentLayerWithUpdateTracking
> update_check_layer_
;
905 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange
);
907 class NoScaleContentLayer
: public ContentLayer
{
909 static scoped_refptr
<NoScaleContentLayer
> Create(ContentLayerClient
* client
) {
910 return make_scoped_refptr(new NoScaleContentLayer(client
));
913 virtual void CalculateContentsScale(float ideal_contents_scale
,
914 float device_scale_factor
,
915 float page_scale_factor
,
916 bool animating_transform_to_screen
,
917 float* contents_scale_x
,
918 float* contents_scale_y
,
919 gfx::Size
* contentBounds
) OVERRIDE
{
920 // Skip over the ContentLayer's method to the base Layer class.
921 Layer::CalculateContentsScale(ideal_contents_scale
,
924 animating_transform_to_screen
,
931 explicit NoScaleContentLayer(ContentLayerClient
* client
)
932 : ContentLayer(client
) {}
933 virtual ~NoScaleContentLayer() {}
936 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
937 : public LayerTreeHostTest
{
939 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
940 : root_layer_(NoScaleContentLayer::Create(&client_
)),
941 child_layer_(ContentLayer::Create(&client_
)) {}
943 virtual void BeginTest() OVERRIDE
{
944 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
945 layer_tree_host()->SetDeviceScaleFactor(1.5);
946 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
948 root_layer_
->AddChild(child_layer_
);
950 root_layer_
->SetIsDrawable(true);
951 root_layer_
->SetBounds(gfx::Size(30, 30));
952 root_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
954 child_layer_
->SetIsDrawable(true);
955 child_layer_
->SetPosition(gfx::Point(2, 2));
956 child_layer_
->SetBounds(gfx::Size(10, 10));
957 child_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
959 layer_tree_host()->SetRootLayer(root_layer_
);
961 PostSetNeedsCommitToMainThread();
964 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
965 // Should only do one commit.
966 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
967 // Device scale factor should come over to impl.
968 EXPECT_NEAR(impl
->device_scale_factor(), 1.5f
, 0.00001f
);
970 // Both layers are on impl.
971 ASSERT_EQ(1u, impl
->active_tree()->root_layer()->children().size());
973 // Device viewport is scaled.
974 EXPECT_EQ(gfx::Size(60, 60), impl
->device_viewport_size());
976 LayerImpl
* root
= impl
->active_tree()->root_layer();
977 LayerImpl
* child
= impl
->active_tree()->root_layer()->children()[0];
979 // Positions remain in layout pixels.
980 EXPECT_EQ(gfx::Point(0, 0), root
->position());
981 EXPECT_EQ(gfx::Point(2, 2), child
->position());
983 // Compute all the layer transforms for the frame.
984 LayerTreeHostImpl::FrameData frame_data
;
985 impl
->PrepareToDraw(&frame_data
, gfx::Rect());
986 impl
->DidDrawAllLayers(frame_data
);
988 const LayerImplList
& render_surface_layer_list
=
989 *frame_data
.render_surface_layer_list
;
991 // Both layers should be drawing into the root render surface.
992 ASSERT_EQ(1u, render_surface_layer_list
.size());
993 ASSERT_EQ(root
->render_surface(),
994 render_surface_layer_list
[0]->render_surface());
995 ASSERT_EQ(2u, root
->render_surface()->layer_list().size());
997 // The root render surface is the size of the viewport.
998 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
999 root
->render_surface()->content_rect());
1001 // The content bounds of the child should be scaled.
1002 gfx::Size child_bounds_scaled
=
1003 gfx::ToCeiledSize(gfx::ScaleSize(child
->bounds(), 1.5));
1004 EXPECT_EQ(child_bounds_scaled
, child
->content_bounds());
1006 gfx::Transform scale_transform
;
1007 scale_transform
.Scale(impl
->device_scale_factor(),
1008 impl
->device_scale_factor());
1010 // The root layer is scaled by 2x.
1011 gfx::Transform root_screen_space_transform
= scale_transform
;
1012 gfx::Transform root_draw_transform
= scale_transform
;
1014 EXPECT_EQ(root_draw_transform
, root
->draw_transform());
1015 EXPECT_EQ(root_screen_space_transform
, root
->screen_space_transform());
1017 // The child is at position 2,2, which is transformed to 3,3 after the scale
1018 gfx::Transform child_screen_space_transform
;
1019 child_screen_space_transform
.Translate(3.f
, 3.f
);
1020 gfx::Transform child_draw_transform
= child_screen_space_transform
;
1022 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform
,
1023 child
->draw_transform());
1024 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform
,
1025 child
->screen_space_transform());
1030 virtual void AfterTest() OVERRIDE
{}
1033 FakeContentLayerClient client_
;
1034 scoped_refptr
<NoScaleContentLayer
> root_layer_
;
1035 scoped_refptr
<ContentLayer
> child_layer_
;
1038 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
);
1040 // Verify atomicity of commits and reuse of textures.
1041 class LayerTreeHostTestAtomicCommit
: public LayerTreeHostTest
{
1043 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1044 // Make sure partial texture updates are turned off.
1045 settings
->max_partial_texture_updates
= 0;
1046 // Linear fade animator prevents scrollbars from drawing immediately.
1047 settings
->use_linear_fade_scrollbar_animator
= false;
1050 virtual void SetupTree() OVERRIDE
{
1051 layer_
= FakeContentLayer::Create(&client_
);
1052 layer_
->SetBounds(gfx::Size(10, 20));
1054 bool paint_scrollbar
= true;
1055 bool has_thumb
= false;
1057 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, layer_
->id());
1058 scrollbar_
->SetPosition(gfx::Point(0, 10));
1059 scrollbar_
->SetBounds(gfx::Size(10, 10));
1061 layer_
->AddChild(scrollbar_
);
1063 layer_tree_host()->SetRootLayer(layer_
);
1064 LayerTreeHostTest::SetupTree();
1067 virtual void BeginTest() OVERRIDE
{
1069 PostSetNeedsCommitToMainThread();
1072 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1073 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates
);
1075 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1076 impl
->output_surface()->context3d());
1078 switch (impl
->active_tree()->source_frame_number()) {
1080 // Number of textures should be one for each layer
1081 ASSERT_EQ(2u, context
->NumTextures());
1082 // Number of textures used for commit should be one for each layer.
1083 EXPECT_EQ(2u, context
->NumUsedTextures());
1084 // Verify that used texture is correct.
1085 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1086 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1088 context
->ResetUsedTextures();
1089 PostSetNeedsCommitToMainThread();
1092 // Number of textures should be doubled as the first textures
1093 // are used by impl thread and cannot by used for update.
1094 ASSERT_EQ(4u, context
->NumTextures());
1095 // Number of textures used for commit should still be
1096 // one for each layer.
1097 EXPECT_EQ(2u, context
->NumUsedTextures());
1098 // First textures should not have been used.
1099 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1100 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1101 // New textures should have been used.
1102 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1103 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1105 context
->ResetUsedTextures();
1106 PostSetNeedsCommitToMainThread();
1117 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1118 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1119 impl
->output_surface()->context3d());
1121 if (drew_frame_
== impl
->active_tree()->source_frame_number()) {
1122 EXPECT_EQ(0u, context
->NumUsedTextures()) << "For frame " << drew_frame_
;
1125 drew_frame_
= impl
->active_tree()->source_frame_number();
1127 // We draw/ship one texture each frame for each layer.
1128 EXPECT_EQ(2u, context
->NumUsedTextures());
1129 context
->ResetUsedTextures();
1132 virtual void Layout() OVERRIDE
{
1133 layer_
->SetNeedsDisplay();
1134 scrollbar_
->SetNeedsDisplay();
1137 virtual void AfterTest() OVERRIDE
{}
1140 FakeContentLayerClient client_
;
1141 scoped_refptr
<FakeContentLayer
> layer_
;
1142 scoped_refptr
<FakeScrollbarLayer
> scrollbar_
;
1146 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit
);
1148 static void SetLayerPropertiesForTesting(Layer
* layer
,
1150 const gfx::Transform
& transform
,
1152 gfx::PointF position
,
1155 layer
->RemoveAllChildren();
1157 parent
->AddChild(layer
);
1158 layer
->SetTransform(transform
);
1159 layer
->SetAnchorPoint(anchor
);
1160 layer
->SetPosition(position
);
1161 layer
->SetBounds(bounds
);
1162 layer
->SetContentsOpaque(opaque
);
1165 class LayerTreeHostTestAtomicCommitWithPartialUpdate
1166 : public LayerTreeHostTest
{
1168 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1169 // Allow one partial texture update.
1170 settings
->max_partial_texture_updates
= 1;
1171 // Linear fade animator prevents scrollbars from drawing immediately.
1172 settings
->use_linear_fade_scrollbar_animator
= false;
1173 // No partial updates when impl side painting is enabled.
1174 settings
->impl_side_painting
= false;
1177 virtual void SetupTree() OVERRIDE
{
1178 parent_
= FakeContentLayer::Create(&client_
);
1179 parent_
->SetBounds(gfx::Size(10, 20));
1181 child_
= FakeContentLayer::Create(&client_
);
1182 child_
->SetPosition(gfx::Point(0, 10));
1183 child_
->SetBounds(gfx::Size(3, 10));
1185 bool paint_scrollbar
= true;
1186 bool has_thumb
= false;
1187 scrollbar_with_paints_
=
1188 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, parent_
->id());
1189 scrollbar_with_paints_
->SetPosition(gfx::Point(3, 10));
1190 scrollbar_with_paints_
->SetBounds(gfx::Size(3, 10));
1192 paint_scrollbar
= false;
1193 scrollbar_without_paints_
=
1194 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, parent_
->id());
1195 scrollbar_without_paints_
->SetPosition(gfx::Point(6, 10));
1196 scrollbar_without_paints_
->SetBounds(gfx::Size(3, 10));
1198 parent_
->AddChild(child_
);
1199 parent_
->AddChild(scrollbar_with_paints_
);
1200 parent_
->AddChild(scrollbar_without_paints_
);
1202 layer_tree_host()->SetRootLayer(parent_
);
1203 LayerTreeHostTest::SetupTree();
1206 virtual void BeginTest() OVERRIDE
{
1207 PostSetNeedsCommitToMainThread();
1210 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1211 switch (layer_tree_host()->commit_number()) {
1213 parent_
->SetNeedsDisplay();
1214 child_
->SetNeedsDisplay();
1215 scrollbar_with_paints_
->SetNeedsDisplay();
1216 scrollbar_without_paints_
->SetNeedsDisplay();
1219 // Damage part of layers.
1220 parent_
->SetNeedsDisplayRect(gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1221 child_
->SetNeedsDisplayRect(gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1222 scrollbar_with_paints_
->SetNeedsDisplayRect(
1223 gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1224 scrollbar_without_paints_
->SetNeedsDisplayRect(
1225 gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1228 child_
->SetNeedsDisplay();
1229 scrollbar_with_paints_
->SetNeedsDisplay();
1230 scrollbar_without_paints_
->SetNeedsDisplay();
1231 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1234 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1240 NOTREACHED() << layer_tree_host()->commit_number();
1245 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1246 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates
);
1248 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1249 impl
->output_surface()->context3d());
1251 switch (impl
->active_tree()->source_frame_number()) {
1253 // Number of textures should be one for each layer.
1254 ASSERT_EQ(4u, context
->NumTextures());
1255 // Number of textures used for commit should be one for each layer.
1256 EXPECT_EQ(4u, context
->NumUsedTextures());
1257 // Verify that used textures are correct.
1258 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1259 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1260 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1261 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1263 context
->ResetUsedTextures();
1266 // Number of textures should be two for each content layer and one
1267 // for each scrollbar, since they always do a partial update.
1268 ASSERT_EQ(6u, context
->NumTextures());
1269 // Number of textures used for commit should be one for each content
1270 // layer, and one for the scrollbar layer that paints.
1271 EXPECT_EQ(3u, context
->NumUsedTextures());
1273 // First content textures should not have been used.
1274 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1275 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1276 // The non-painting scrollbar's texture wasn't updated.
1277 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1278 // The painting scrollbar's partial update texture was used.
1279 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1280 // New textures should have been used.
1281 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1282 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(5)));
1284 context
->ResetUsedTextures();
1287 // Number of textures should be two for each content layer and one
1288 // for each scrollbar, since they always do a partial update.
1289 ASSERT_EQ(6u, context
->NumTextures());
1290 // Number of textures used for commit should be one for each content
1291 // layer, and one for the scrollbar layer that paints.
1292 EXPECT_EQ(3u, context
->NumUsedTextures());
1294 // The non-painting scrollbar's texture wasn't updated.
1295 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1296 // The painting scrollbar does a partial update.
1297 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1298 // One content layer does a partial update also.
1299 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1300 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(5)));
1302 context
->ResetUsedTextures();
1305 // No textures should be used for commit.
1306 EXPECT_EQ(0u, context
->NumUsedTextures());
1308 context
->ResetUsedTextures();
1311 // Number of textures used for commit should be two. One for the
1312 // content layer, and one for the painting scrollbar. The
1313 // non-painting scrollbar doesn't update its texture.
1314 EXPECT_EQ(2u, context
->NumUsedTextures());
1316 context
->ResetUsedTextures();
1324 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1325 EXPECT_LT(impl
->active_tree()->source_frame_number(), 5);
1327 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1328 impl
->output_surface()->context3d());
1330 // Number of textures used for drawing should one per layer except for
1331 // frame 3 where the viewport only contains one layer.
1332 if (impl
->active_tree()->source_frame_number() == 3) {
1333 EXPECT_EQ(1u, context
->NumUsedTextures());
1335 EXPECT_EQ(4u, context
->NumUsedTextures()) <<
1336 "For frame " << impl
->active_tree()->source_frame_number();
1339 context
->ResetUsedTextures();
1342 virtual void AfterTest() OVERRIDE
{}
1345 FakeContentLayerClient client_
;
1346 scoped_refptr
<FakeContentLayer
> parent_
;
1347 scoped_refptr
<FakeContentLayer
> child_
;
1348 scoped_refptr
<FakeScrollbarLayer
> scrollbar_with_paints_
;
1349 scoped_refptr
<FakeScrollbarLayer
> scrollbar_without_paints_
;
1352 // Partial updates are not possible with a delegating renderer.
1353 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1354 LayerTreeHostTestAtomicCommitWithPartialUpdate
);
1356 class LayerTreeHostTestFinishAllRendering
: public LayerTreeHostTest
{
1358 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1360 virtual void BeginTest() OVERRIDE
{
1361 layer_tree_host()->SetNeedsRedraw();
1362 PostSetNeedsCommitToMainThread();
1365 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1369 layer_tree_host()->SetNeedsRedraw();
1370 layer_tree_host()->AcquireLayerTextures();
1372 base::AutoLock
lock(lock_
);
1375 layer_tree_host()->FinishAllRendering();
1377 base::AutoLock
lock(lock_
);
1378 EXPECT_EQ(0, draw_count_
);
1383 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1384 base::AutoLock
lock(lock_
);
1388 virtual void AfterTest() OVERRIDE
{}
1396 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering
);
1398 class LayerTreeHostTestCompositeAndReadbackCleanup
: public LayerTreeHostTest
{
1400 virtual void BeginTest() OVERRIDE
{
1401 Layer
* root_layer
= layer_tree_host()->root_layer();
1404 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels
),
1405 gfx::Rect(0, 0, 1, 1));
1406 EXPECT_FALSE(root_layer
->render_surface());
1411 virtual void AfterTest() OVERRIDE
{}
1414 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup
);
1416 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1417 : public LayerTreeHostTest
{
1419 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1420 : root_layer_(FakeContentLayer::Create(&client_
)),
1422 FakeContentLayer::Create(&client_
)),
1424 FakeContentLayer::Create(&client_
)),
1426 FakeContentLayer::Create(&client_
)),
1428 FakeContentLayer::Create(&client_
)) {}
1430 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1431 settings
->cache_render_pass_contents
= true;
1434 virtual void BeginTest() OVERRIDE
{
1435 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1437 root_layer_
->SetBounds(gfx::Size(100, 100));
1438 surface_layer1_
->SetBounds(gfx::Size(100, 100));
1439 surface_layer1_
->SetForceRenderSurface(true);
1440 surface_layer1_
->SetOpacity(0.5f
);
1441 surface_layer2_
->SetBounds(gfx::Size(100, 100));
1442 surface_layer2_
->SetForceRenderSurface(true);
1443 surface_layer2_
->SetOpacity(0.5f
);
1445 surface_layer1_
->SetReplicaLayer(replica_layer1_
.get());
1446 surface_layer2_
->SetReplicaLayer(replica_layer2_
.get());
1448 root_layer_
->AddChild(surface_layer1_
);
1449 surface_layer1_
->AddChild(surface_layer2_
);
1450 layer_tree_host()->SetRootLayer(root_layer_
);
1452 PostSetNeedsCommitToMainThread();
1455 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1456 Renderer
* renderer
= host_impl
->renderer();
1457 RenderPass::Id surface1_render_pass_id
= host_impl
->active_tree()
1458 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1459 RenderPass::Id surface2_render_pass_id
=
1460 host_impl
->active_tree()->root_layer()->children()[0]->children()[0]
1461 ->render_surface()->RenderPassId();
1463 switch (host_impl
->active_tree()->source_frame_number()) {
1465 EXPECT_TRUE(renderer
->HaveCachedResourcesForRenderPassId(
1466 surface1_render_pass_id
));
1467 EXPECT_TRUE(renderer
->HaveCachedResourcesForRenderPassId(
1468 surface2_render_pass_id
));
1470 // Reduce the memory limit to only fit the root layer and one render
1471 // surface. This prevents any contents drawing into surfaces
1472 // from being allocated.
1473 host_impl
->SetManagedMemoryPolicy(
1474 ManagedMemoryPolicy(100 * 100 * 4 * 2));
1477 EXPECT_FALSE(renderer
->HaveCachedResourcesForRenderPassId(
1478 surface1_render_pass_id
));
1479 EXPECT_FALSE(renderer
->HaveCachedResourcesForRenderPassId(
1480 surface2_render_pass_id
));
1487 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1489 root_layer_
->SetNeedsDisplay();
1492 virtual void AfterTest() OVERRIDE
{
1493 EXPECT_EQ(3u, root_layer_
->update_count());
1494 EXPECT_EQ(3u, surface_layer1_
->update_count());
1495 EXPECT_EQ(3u, surface_layer2_
->update_count());
1499 FakeContentLayerClient client_
;
1500 scoped_refptr
<FakeContentLayer
> root_layer_
;
1501 scoped_refptr
<FakeContentLayer
> surface_layer1_
;
1502 scoped_refptr
<FakeContentLayer
> replica_layer1_
;
1503 scoped_refptr
<FakeContentLayer
> surface_layer2_
;
1504 scoped_refptr
<FakeContentLayer
> replica_layer2_
;
1507 // Surfaces don't exist with a delegated renderer.
1508 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1509 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
);
1511 class EvictionTestLayer
: public Layer
{
1513 static scoped_refptr
<EvictionTestLayer
> Create() {
1514 return make_scoped_refptr(new EvictionTestLayer());
1517 virtual void Update(ResourceUpdateQueue
*,
1518 const OcclusionTracker
*,
1519 RenderingStats
*) OVERRIDE
;
1520 virtual bool DrawsContent() const OVERRIDE
{ return true; }
1522 virtual scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
)
1524 virtual void PushPropertiesTo(LayerImpl
* impl
) OVERRIDE
;
1525 virtual void SetTexturePriorities(const PriorityCalculator
&) OVERRIDE
;
1527 bool HaveBackingTexture() const {
1528 return texture_
.get() ? texture_
->have_backing_texture() : false;
1532 EvictionTestLayer() : Layer() {}
1533 virtual ~EvictionTestLayer() {}
1535 void CreateTextureIfNeeded() {
1538 texture_
= PrioritizedResource::Create(
1539 layer_tree_host()->contents_texture_manager());
1540 texture_
->SetDimensions(gfx::Size(10, 10), GL_RGBA
);
1541 bitmap_
.setConfig(SkBitmap::kARGB_8888_Config
, 10, 10);
1544 scoped_ptr
<PrioritizedResource
> texture_
;
1548 class EvictionTestLayerImpl
: public LayerImpl
{
1550 static scoped_ptr
<EvictionTestLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1552 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl
, id
));
1554 virtual ~EvictionTestLayerImpl() {}
1556 virtual void AppendQuads(QuadSink
* quad_sink
,
1557 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1558 ASSERT_TRUE(has_texture_
);
1559 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1562 void SetHasTexture(bool has_texture
) { has_texture_
= has_texture
; }
1565 EvictionTestLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
1566 : LayerImpl(tree_impl
, id
), has_texture_(false) {}
1571 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator
&) {
1572 CreateTextureIfNeeded();
1575 texture_
->set_request_priority(PriorityCalculator::UIPriority(true));
1578 void EvictionTestLayer::Update(ResourceUpdateQueue
* queue
,
1579 const OcclusionTracker
*,
1581 CreateTextureIfNeeded();
1585 gfx::Rect
full_rect(0, 0, 10, 10);
1586 ResourceUpdate upload
= ResourceUpdate::Create(
1587 texture_
.get(), &bitmap_
, full_rect
, full_rect
, gfx::Vector2d());
1588 queue
->AppendFullUpload(upload
);
1591 scoped_ptr
<LayerImpl
> EvictionTestLayer::CreateLayerImpl(
1592 LayerTreeImpl
* tree_impl
) {
1593 return EvictionTestLayerImpl::Create(tree_impl
, layer_id_
)
1594 .PassAs
<LayerImpl
>();
1597 void EvictionTestLayer::PushPropertiesTo(LayerImpl
* layer_impl
) {
1598 Layer::PushPropertiesTo(layer_impl
);
1600 EvictionTestLayerImpl
* test_layer_impl
=
1601 static_cast<EvictionTestLayerImpl
*>(layer_impl
);
1602 test_layer_impl
->SetHasTexture(texture_
->have_backing_texture());
1605 class LayerTreeHostTestEvictTextures
: public LayerTreeHostTest
{
1607 LayerTreeHostTestEvictTextures()
1608 : layer_(EvictionTestLayer::Create()),
1609 impl_for_evict_textures_(0),
1612 virtual void BeginTest() OVERRIDE
{
1613 layer_tree_host()->SetRootLayer(layer_
);
1614 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1616 gfx::Transform identity_matrix
;
1617 SetLayerPropertiesForTesting(layer_
.get(),
1620 gfx::PointF(0.f
, 0.f
),
1621 gfx::PointF(0.f
, 0.f
),
1625 PostSetNeedsCommitToMainThread();
1628 void PostEvictTextures() {
1629 DCHECK(HasImplThread());
1630 ImplThreadTaskRunner()->PostTask(
1632 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread
,
1633 base::Unretained(this)));
1636 void EvictTexturesOnImplThread() {
1637 DCHECK(impl_for_evict_textures_
);
1638 impl_for_evict_textures_
->EnforceManagedMemoryPolicy(
1639 ManagedMemoryPolicy(0));
1642 // Commit 1: Just commit and draw normally, then post an eviction at the end
1643 // that will trigger a commit.
1644 // Commit 2: Triggered by the eviction, let it go through and then set
1646 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1647 // task, which will be handled before the commit. Don't set needsCommit, it
1648 // should have been posted. A frame should not be drawn (note,
1649 // didCommitAndDrawFrame may be called anyway).
1650 // Commit 4: Triggered by the eviction, let it go through and then set
1652 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1653 // Layout(), a frame should not be drawn but a commit will be posted.
1654 // Commit 6: Triggered by the eviction, post an eviction task in
1655 // Layout(), which will be a noop, letting the commit (which recreates the
1656 // textures) go through and draw a frame, then end the test.
1658 // Commits 1+2 test the eviction recovery path where eviction happens outside
1659 // of the beginFrame/commit pair.
1660 // Commits 3+4 test the eviction recovery path where eviction happens inside
1661 // the beginFrame/commit pair.
1662 // Commits 5+6 test the path where an eviction happens during the eviction
1664 virtual void DidCommit() OVERRIDE
{
1665 switch (num_commits_
) {
1667 EXPECT_TRUE(layer_
->HaveBackingTexture());
1668 PostEvictTextures();
1671 EXPECT_TRUE(layer_
->HaveBackingTexture());
1672 layer_tree_host()->SetNeedsCommit();
1677 EXPECT_TRUE(layer_
->HaveBackingTexture());
1678 layer_tree_host()->SetNeedsCommit();
1683 EXPECT_TRUE(layer_
->HaveBackingTexture());
1692 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1693 impl_for_evict_textures_
= impl
;
1696 virtual void Layout() OVERRIDE
{
1698 switch (num_commits_
) {
1703 PostEvictTextures();
1706 // We couldn't check in didCommitAndDrawFrame on commit 3,
1708 EXPECT_FALSE(layer_
->HaveBackingTexture());
1711 PostEvictTextures();
1714 // We couldn't check in didCommitAndDrawFrame on commit 5,
1716 EXPECT_FALSE(layer_
->HaveBackingTexture());
1717 PostEvictTextures();
1725 virtual void AfterTest() OVERRIDE
{}
1728 FakeContentLayerClient client_
;
1729 scoped_refptr
<EvictionTestLayer
> layer_
;
1730 LayerTreeHostImpl
* impl_for_evict_textures_
;
1734 MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures
);
1736 class LayerTreeHostTestContinuousCommit
: public LayerTreeHostTest
{
1738 LayerTreeHostTestContinuousCommit()
1739 : num_commit_complete_(0), num_draw_layers_(0) {}
1741 virtual void BeginTest() OVERRIDE
{
1742 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1743 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1745 PostSetNeedsCommitToMainThread();
1748 virtual void DidCommit() OVERRIDE
{
1749 if (num_draw_layers_
== 2)
1751 layer_tree_host()->root_layer()->SetNeedsDisplay();
1754 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1755 if (num_draw_layers_
== 1)
1756 num_commit_complete_
++;
1759 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1761 if (num_draw_layers_
== 2)
1765 virtual void AfterTest() OVERRIDE
{
1766 // Check that we didn't commit twice between first and second draw.
1767 EXPECT_EQ(1, num_commit_complete_
);
1771 int num_commit_complete_
;
1772 int num_draw_layers_
;
1775 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit
);
1777 class LayerTreeHostTestContinuousInvalidate
: public LayerTreeHostTest
{
1779 LayerTreeHostTestContinuousInvalidate()
1780 : num_commit_complete_(0), num_draw_layers_(0) {}
1782 virtual void BeginTest() OVERRIDE
{
1783 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1784 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1786 content_layer_
= ContentLayer::Create(&client_
);
1787 content_layer_
->SetBounds(gfx::Size(10, 10));
1788 content_layer_
->SetPosition(gfx::PointF(0.f
, 0.f
));
1789 content_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
1790 content_layer_
->SetIsDrawable(true);
1791 layer_tree_host()->root_layer()->AddChild(content_layer_
);
1793 PostSetNeedsCommitToMainThread();
1796 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1797 if (num_draw_layers_
== 2)
1799 content_layer_
->SetNeedsDisplay();
1802 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1803 if (num_draw_layers_
== 1)
1804 num_commit_complete_
++;
1807 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1809 if (num_draw_layers_
== 2)
1813 virtual void AfterTest() OVERRIDE
{
1814 // Check that we didn't commit twice between first and second draw.
1815 EXPECT_EQ(1, num_commit_complete_
);
1819 FakeContentLayerClient client_
;
1820 scoped_refptr
<Layer
> content_layer_
;
1821 int num_commit_complete_
;
1822 int num_draw_layers_
;
1825 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate
);
1827 class LayerTreeHostTestDeferCommits
: public LayerTreeHostTest
{
1829 LayerTreeHostTestDeferCommits()
1830 : num_commits_deferred_(0), num_complete_commits_(0) {}
1832 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1834 virtual void DidDeferCommit() OVERRIDE
{
1835 num_commits_deferred_
++;
1836 layer_tree_host()->SetDeferCommits(false);
1839 virtual void DidCommit() OVERRIDE
{
1840 num_complete_commits_
++;
1841 switch (num_complete_commits_
) {
1843 EXPECT_EQ(0, num_commits_deferred_
);
1844 layer_tree_host()->SetDeferCommits(true);
1845 PostSetNeedsCommitToMainThread();
1856 virtual void AfterTest() OVERRIDE
{
1857 EXPECT_EQ(1, num_commits_deferred_
);
1858 EXPECT_EQ(2, num_complete_commits_
);
1862 int num_commits_deferred_
;
1863 int num_complete_commits_
;
1866 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits
);
1868 class LayerTreeHostWithProxy
: public LayerTreeHost
{
1870 LayerTreeHostWithProxy(FakeLayerTreeHostClient
* client
,
1871 const LayerTreeSettings
& settings
,
1872 scoped_ptr
<FakeProxy
> proxy
)
1873 : LayerTreeHost(client
, settings
) {
1874 proxy
->SetLayerTreeHost(this);
1875 EXPECT_TRUE(InitializeForTesting(proxy
.PassAs
<Proxy
>()));
1879 TEST(LayerTreeHostTest
, LimitPartialUpdates
) {
1880 // When partial updates are not allowed, max updates should be 0.
1882 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1884 scoped_ptr
<FakeProxy
> proxy(new FakeProxy
);
1885 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= false;
1886 proxy
->SetMaxPartialTextureUpdates(5);
1888 LayerTreeSettings settings
;
1889 settings
.max_partial_texture_updates
= 10;
1891 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.Pass());
1892 EXPECT_TRUE(host
.InitializeOutputSurfaceIfNeeded());
1894 EXPECT_EQ(0u, host
.settings().max_partial_texture_updates
);
1897 // When partial updates are allowed,
1898 // max updates should be limited by the proxy.
1900 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1902 scoped_ptr
<FakeProxy
> proxy(new FakeProxy
);
1903 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= true;
1904 proxy
->SetMaxPartialTextureUpdates(5);
1906 LayerTreeSettings settings
;
1907 settings
.max_partial_texture_updates
= 10;
1909 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.Pass());
1910 EXPECT_TRUE(host
.InitializeOutputSurfaceIfNeeded());
1912 EXPECT_EQ(5u, host
.settings().max_partial_texture_updates
);
1915 // When partial updates are allowed,
1916 // max updates should also be limited by the settings.
1918 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1920 scoped_ptr
<FakeProxy
> proxy(new FakeProxy
);
1921 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= true;
1922 proxy
->SetMaxPartialTextureUpdates(20);
1924 LayerTreeSettings settings
;
1925 settings
.max_partial_texture_updates
= 10;
1927 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.Pass());
1928 EXPECT_TRUE(host
.InitializeOutputSurfaceIfNeeded());
1930 EXPECT_EQ(10u, host
.settings().max_partial_texture_updates
);
1934 TEST(LayerTreeHostTest
, PartialUpdatesWithGLRenderer
) {
1935 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1937 LayerTreeSettings settings
;
1938 settings
.max_partial_texture_updates
= 4;
1940 scoped_ptr
<LayerTreeHost
> host
=
1941 LayerTreeHost::Create(&client
, settings
, NULL
);
1942 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1943 EXPECT_EQ(4u, host
->settings().max_partial_texture_updates
);
1946 TEST(LayerTreeHostTest
, PartialUpdatesWithSoftwareRenderer
) {
1947 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_SOFTWARE
);
1949 LayerTreeSettings settings
;
1950 settings
.max_partial_texture_updates
= 4;
1952 scoped_ptr
<LayerTreeHost
> host
=
1953 LayerTreeHost::Create(&client
, settings
, NULL
);
1954 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1955 EXPECT_EQ(4u, host
->settings().max_partial_texture_updates
);
1958 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndGLContent
) {
1959 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DELEGATED_3D
);
1961 LayerTreeSettings settings
;
1962 settings
.max_partial_texture_updates
= 4;
1964 scoped_ptr
<LayerTreeHost
> host
=
1965 LayerTreeHost::Create(&client
, settings
, NULL
);
1966 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1967 EXPECT_EQ(0u, host
->settings().max_partial_texture_updates
);
1970 TEST(LayerTreeHostTest
,
1971 PartialUpdatesWithDelegatingRendererAndSoftwareContent
) {
1972 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE
);
1974 LayerTreeSettings settings
;
1975 settings
.max_partial_texture_updates
= 4;
1977 scoped_ptr
<LayerTreeHost
> host
=
1978 LayerTreeHost::Create(&client
, settings
, NULL
);
1979 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1980 EXPECT_EQ(0u, host
->settings().max_partial_texture_updates
);
1983 class LayerTreeHostTestCapturePicture
: public LayerTreeHostTest
{
1985 LayerTreeHostTestCapturePicture()
1986 : bounds_(gfx::Size(100, 100)),
1987 layer_(PictureLayer::Create(&content_client_
)) {}
1989 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1990 settings
->impl_side_painting
= true;
1993 class FillRectContentLayerClient
: public ContentLayerClient
{
1995 virtual void PaintContents(SkCanvas
* canvas
,
1997 gfx::RectF
* opaque
) OVERRIDE
{
1999 paint
.setColor(SK_ColorGREEN
);
2001 SkRect rect
= SkRect::MakeWH(canvas
->getDeviceSize().width(),
2002 canvas
->getDeviceSize().height());
2003 *opaque
= gfx::RectF(rect
.width(), rect
.height());
2004 canvas
->drawRect(rect
, paint
);
2006 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
2009 virtual void BeginTest() OVERRIDE
{
2010 layer_
->SetIsDrawable(true);
2011 layer_
->SetBounds(bounds_
);
2012 // Outside viewport so tiles don't have to be initialized for commit.
2013 layer_
->SetPosition(gfx::Point(100, 100));
2014 layer_tree_host()->SetViewportSize(bounds_
);
2015 layer_tree_host()->SetRootLayer(layer_
);
2017 PostSetNeedsCommitToMainThread();
2020 virtual void DidCommitAndDrawFrame() OVERRIDE
{
2021 picture_
= layer_tree_host()->CapturePicture();
2025 virtual void AfterTest() OVERRIDE
{
2026 EXPECT_EQ(bounds_
, gfx::Size(picture_
->width(), picture_
->height()));
2030 SkBitmap::kARGB_8888_Config
, bounds_
.width(), bounds_
.height());
2031 bitmap
.allocPixels();
2032 bitmap
.eraseARGB(0, 0, 0, 0);
2033 SkCanvas
canvas(bitmap
);
2035 picture_
->draw(&canvas
);
2037 bitmap
.lockPixels();
2038 SkColor
* pixels
= reinterpret_cast<SkColor
*>(bitmap
.getPixels());
2039 EXPECT_EQ(SK_ColorGREEN
, pixels
[0]);
2040 bitmap
.unlockPixels();
2045 FillRectContentLayerClient content_client_
;
2046 scoped_refptr
<PictureLayer
> layer_
;
2047 skia::RefPtr
<SkPicture
> picture_
;
2050 MULTI_THREAD_TEST_F(LayerTreeHostTestCapturePicture
);
2052 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2053 : public LayerTreeHostTest
{
2055 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2056 : root_layer_(FakeContentLayer::Create(&client_
)),
2057 child_layer1_(FakeContentLayer::Create(&client_
)),
2058 child_layer2_(FakeContentLayer::Create(&client_
)),
2061 virtual void BeginTest() OVERRIDE
{
2062 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2063 root_layer_
->SetBounds(gfx::Size(100, 100));
2064 child_layer1_
->SetBounds(gfx::Size(100, 100));
2065 child_layer2_
->SetBounds(gfx::Size(100, 100));
2066 root_layer_
->AddChild(child_layer1_
);
2067 root_layer_
->AddChild(child_layer2_
);
2068 layer_tree_host()->SetRootLayer(root_layer_
);
2069 PostSetNeedsCommitToMainThread();
2072 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl
* host_impl
,
2073 bool visible
) OVERRIDE
{
2074 // One backing should remain unevicted.
2075 EXPECT_EQ(100u * 100u * 4u * 1u,
2076 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2077 // Make sure that contents textures are marked as having been
2079 EXPECT_TRUE(host_impl
->active_tree()->ContentsTexturesPurged());
2080 // End the test in this state.
2084 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2086 switch (num_commits_
) {
2088 // All three backings should have memory.
2090 100u * 100u * 4u * 3u,
2091 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2092 // Set a new policy that will kick out 1 of the 3 resources.
2093 // Because a resource was evicted, a commit will be kicked off.
2094 host_impl
->SetManagedMemoryPolicy(
2095 ManagedMemoryPolicy(100 * 100 * 4 * 2,
2096 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
,
2098 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
));
2101 // Only two backings should have memory.
2103 100u * 100u * 4u * 2u,
2104 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2105 // Become backgrounded, which will cause 1 more resource to be
2107 PostSetVisibleToMainThread(false);
2110 // No further commits should happen because this is not visible
2117 virtual void AfterTest() OVERRIDE
{}
2120 FakeContentLayerClient client_
;
2121 scoped_refptr
<FakeContentLayer
> root_layer_
;
2122 scoped_refptr
<FakeContentLayer
> child_layer1_
;
2123 scoped_refptr
<FakeContentLayer
> child_layer2_
;
2127 SINGLE_AND_MULTI_THREAD_TEST_F(
2128 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
);
2130 class LayerTreeHostTestLCDNotification
: public LayerTreeHostTest
{
2132 class NotificationClient
: public ContentLayerClient
{
2134 NotificationClient()
2135 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2137 void set_layer(Layer
* layer
) { layer_
= layer
; }
2138 int paint_count() const { return paint_count_
; }
2139 int lcd_notification_count() const { return lcd_notification_count_
; }
2141 virtual void PaintContents(SkCanvas
* canvas
,
2143 gfx::RectF
* opaque
) OVERRIDE
{
2146 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{
2147 ++lcd_notification_count_
;
2148 layer_
->SetNeedsDisplay();
2154 int lcd_notification_count_
;
2157 virtual void SetupTree() OVERRIDE
{
2158 scoped_refptr
<ContentLayer
> root_layer
= ContentLayer::Create(&client_
);
2159 root_layer
->SetIsDrawable(true);
2160 root_layer
->SetBounds(gfx::Size(1, 1));
2162 layer_tree_host()->SetRootLayer(root_layer
);
2163 client_
.set_layer(root_layer
.get());
2165 // The expecations are based on the assumption that the default
2166 // LCD settings are:
2167 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text
);
2168 EXPECT_FALSE(root_layer
->can_use_lcd_text());
2170 LayerTreeHostTest::SetupTree();
2173 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2174 virtual void AfterTest() OVERRIDE
{}
2176 virtual void DidCommit() OVERRIDE
{
2177 switch (layer_tree_host()->commit_number()) {
2179 // The first update consists one LCD notification and one paint.
2180 EXPECT_EQ(1, client_
.lcd_notification_count());
2181 EXPECT_EQ(1, client_
.paint_count());
2182 // LCD text must have been enabled on the layer.
2183 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2184 PostSetNeedsCommitToMainThread();
2187 // Since nothing changed on layer, there should be no notification
2188 // or paint on the second update.
2189 EXPECT_EQ(1, client_
.lcd_notification_count());
2190 EXPECT_EQ(1, client_
.paint_count());
2191 // LCD text must not have changed.
2192 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2193 // Change layer opacity that should trigger lcd notification.
2194 layer_tree_host()->root_layer()->SetOpacity(.5f
);
2195 // No need to request a commit - setting opacity will do it.
2198 // Verify that there is not extra commit due to layer invalidation.
2199 EXPECT_EQ(3, layer_tree_host()->commit_number());
2200 // LCD notification count should have incremented due to
2201 // change in layer opacity.
2202 EXPECT_EQ(2, client_
.lcd_notification_count());
2203 // Paint count should be incremented due to invalidation.
2204 EXPECT_EQ(2, client_
.paint_count());
2205 // LCD text must have been disabled on the layer due to opacity.
2206 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2213 NotificationClient client_
;
2216 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification
);
2218 // Verify that the BeginFrame notification is used to initiate rendering.
2219 class LayerTreeHostTestBeginFrameNotification
: public LayerTreeHostTest
{
2221 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2222 settings
->begin_frame_scheduling_enabled
= true;
2225 virtual void BeginTest() OVERRIDE
{
2226 // This will trigger a SetNeedsBeginFrame which will trigger a BeginFrame.
2227 PostSetNeedsCommitToMainThread();
2230 virtual bool PrepareToDrawOnThread(
2231 LayerTreeHostImpl
* host_impl
,
2232 LayerTreeHostImpl::FrameData
* frame
,
2233 bool result
) OVERRIDE
{
2238 virtual void AfterTest() OVERRIDE
{}
2241 base::TimeTicks frame_time_
;
2244 MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification
);
2246 class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2247 : public LayerTreeHostTest
{
2249 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2250 settings
->begin_frame_scheduling_enabled
= true;
2251 settings
->using_synchronous_renderer_compositor
= true;
2254 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2256 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2257 // The BeginFrame notification is turned off now but will get enabled
2258 // once we return. End test while it's enabled.
2259 ImplThreadTaskRunner()->PostTask(
2261 base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest
,
2262 base::Unretained(this)));
2265 virtual void AfterTest() OVERRIDE
{}
2268 MULTI_THREAD_TEST_F(
2269 LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
);
2271 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2272 : public LayerTreeHostTest
{
2274 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2275 settings
->impl_side_painting
= true;
2278 virtual void SetupTree() OVERRIDE
{
2279 LayerTreeHostTest::SetupTree();
2281 scoped_refptr
<Layer
> layer
= PictureLayer::Create(&client_
);
2282 layer
->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2283 layer
->SetBounds(gfx::Size(10, 10));
2284 layer_tree_host()->root_layer()->AddChild(layer
);
2287 virtual void BeginTest() OVERRIDE
{
2288 PostSetNeedsCommitToMainThread();
2291 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2295 virtual void AfterTest() OVERRIDE
{
2298 FakeContentLayerClient client_
;
2301 MULTI_THREAD_TEST_F(
2302 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
);
2304 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2305 : public LayerTreeHostTest
{
2307 class SetBoundsClient
: public ContentLayerClient
{
2309 SetBoundsClient() : layer_(0) {}
2311 void set_layer(Layer
* layer
) { layer_
= layer
; }
2313 virtual void PaintContents(SkCanvas
* canvas
,
2315 gfx::RectF
* opaque
) OVERRIDE
{
2316 layer_
->SetBounds(gfx::Size(2, 2));
2319 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
2325 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2327 virtual void SetupTree() OVERRIDE
{
2328 scoped_refptr
<ContentLayer
> root_layer
= ContentLayer::Create(&client_
);
2329 root_layer
->SetIsDrawable(true);
2330 root_layer
->SetBounds(gfx::Size(1, 1));
2332 layer_tree_host()->SetRootLayer(root_layer
);
2333 client_
.set_layer(root_layer
.get());
2335 LayerTreeHostTest::SetupTree();
2338 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2339 virtual void AfterTest() OVERRIDE
{}
2341 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2343 if (num_commits_
== 1) {
2344 LayerImpl
* root_layer
= host_impl
->active_tree()->root_layer();
2345 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer
->bounds());
2347 LayerImpl
* root_layer
= host_impl
->active_tree()->root_layer();
2348 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer
->bounds());
2354 SetBoundsClient client_
;
2358 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents
);
2360 class MockIOSurfaceWebGraphicsContext3D
: public FakeWebGraphicsContext3D
{
2362 MockIOSurfaceWebGraphicsContext3D()
2363 : FakeWebGraphicsContext3D() {}
2365 virtual WebKit::WebGLId
createTexture() OVERRIDE
{
2369 virtual WebKit::WebString
getString(WebKit::WGC3Denum name
) OVERRIDE
{
2370 if (name
== GL_EXTENSIONS
) {
2371 return WebKit::WebString(
2372 "GL_CHROMIUM_iosurface GL_ARB_texture_rectangle");
2374 return WebKit::WebString();
2377 MOCK_METHOD1(activeTexture
, void(WebKit::WGC3Denum texture
));
2378 MOCK_METHOD2(bindTexture
, void(WebKit::WGC3Denum target
,
2379 WebKit::WebGLId texture_id
));
2380 MOCK_METHOD3(texParameteri
, void(WebKit::WGC3Denum target
,
2381 WebKit::WGC3Denum pname
,
2382 WebKit::WGC3Dint param
));
2383 MOCK_METHOD5(texImageIOSurface2DCHROMIUM
, void(WebKit::WGC3Denum target
,
2384 WebKit::WGC3Dint width
,
2385 WebKit::WGC3Dint height
,
2386 WebKit::WGC3Duint ioSurfaceId
,
2387 WebKit::WGC3Duint plane
));
2388 MOCK_METHOD4(drawElements
, void(WebKit::WGC3Denum mode
,
2389 WebKit::WGC3Dsizei count
,
2390 WebKit::WGC3Denum type
,
2391 WebKit::WGC3Dintptr offset
));
2395 class LayerTreeHostTestIOSurfaceDrawing
: public LayerTreeHostTest
{
2397 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
2398 scoped_ptr
<MockIOSurfaceWebGraphicsContext3D
> context(
2399 new MockIOSurfaceWebGraphicsContext3D
);
2400 mock_context_
= context
.get();
2401 scoped_ptr
<OutputSurface
> output_surface
= FakeOutputSurface::Create3d(
2402 context
.PassAs
<WebKit::WebGraphicsContext3D
>()).PassAs
<OutputSurface
>();
2403 return output_surface
.Pass();
2406 virtual void SetupTree() OVERRIDE
{
2407 LayerTreeHostTest::SetupTree();
2409 layer_tree_host()->root_layer()->SetIsDrawable(false);
2412 io_surface_size_
= gfx::Size(6, 7);
2414 scoped_refptr
<IOSurfaceLayer
> io_surface_layer
= IOSurfaceLayer::Create();
2415 io_surface_layer
->SetBounds(gfx::Size(10, 10));
2416 io_surface_layer
->SetAnchorPoint(gfx::PointF());
2417 io_surface_layer
->SetIsDrawable(true);
2418 io_surface_layer
->SetIOSurfaceProperties(io_surface_id_
, io_surface_size_
);
2419 layer_tree_host()->root_layer()->AddChild(io_surface_layer
);
2422 virtual void BeginTest() OVERRIDE
{
2423 PostSetNeedsCommitToMainThread();
2426 virtual void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2427 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2429 EXPECT_CALL(*mock_context_
, activeTexture(_
))
2431 EXPECT_CALL(*mock_context_
, bindTexture(GL_TEXTURE_RECTANGLE_ARB
, 1))
2433 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2434 GL_TEXTURE_MIN_FILTER
,
2437 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2438 GL_TEXTURE_MAG_FILTER
,
2441 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2445 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2450 EXPECT_CALL(*mock_context_
, texImageIOSurface2DCHROMIUM(
2451 GL_TEXTURE_RECTANGLE_ARB
,
2452 io_surface_size_
.width(),
2453 io_surface_size_
.height(),
2458 EXPECT_CALL(*mock_context_
, bindTexture(_
, 0))
2459 .Times(AnyNumber());
2462 virtual bool PrepareToDrawOnThread(
2463 LayerTreeHostImpl
* host_impl
,
2464 LayerTreeHostImpl::FrameData
* frame
,
2465 bool result
) OVERRIDE
{
2466 Mock::VerifyAndClearExpectations(&mock_context_
);
2468 // The io surface layer's texture is drawn.
2469 EXPECT_CALL(*mock_context_
, activeTexture(GL_TEXTURE0
))
2471 EXPECT_CALL(*mock_context_
, bindTexture(GL_TEXTURE_RECTANGLE_ARB
, 1))
2473 EXPECT_CALL(*mock_context_
, drawElements(GL_TRIANGLES
, 6, _
, _
))
2479 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2480 Mock::VerifyAndClearExpectations(&mock_context_
);
2484 virtual void AfterTest() OVERRIDE
{}
2487 MockIOSurfaceWebGraphicsContext3D
* mock_context_
;
2488 gfx::Size io_surface_size_
;
2491 // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2492 SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2493 LayerTreeHostTestIOSurfaceDrawing
);
2495 class LayerTreeHostTestAsyncReadback
: public LayerTreeHostTest
{
2497 virtual void SetupTree() OVERRIDE
{
2498 root
= FakeContentLayer::Create(&client_
);
2499 root
->SetBounds(gfx::Size(20, 20));
2501 child
= FakeContentLayer::Create(&client_
);
2502 child
->SetBounds(gfx::Size(10, 10));
2503 root
->AddChild(child
);
2505 layer_tree_host()->SetRootLayer(root
);
2506 LayerTreeHostTest::SetupTree();
2509 virtual void BeginTest() OVERRIDE
{
2510 PostSetNeedsCommitToMainThread();
2513 virtual void DidCommitAndDrawFrame() OVERRIDE
{
2517 void WaitForCallback() {
2518 base::MessageLoop::current()->PostTask(
2521 &LayerTreeHostTestAsyncReadback::NextStep
,
2522 base::Unretained(this)));
2526 int frame
= layer_tree_host()->commit_number();
2529 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2530 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback
,
2531 base::Unretained(this))));
2532 EXPECT_EQ(0u, callbacks_
.size());
2535 if (callbacks_
.size() < 1u) {
2539 EXPECT_EQ(1u, callbacks_
.size());
2540 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[0].ToString());
2542 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2543 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback
,
2544 base::Unretained(this))));
2545 root
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2546 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback
,
2547 base::Unretained(this))));
2548 child
->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2549 base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback
,
2550 base::Unretained(this))));
2551 EXPECT_EQ(1u, callbacks_
.size());
2554 if (callbacks_
.size() < 4u) {
2558 EXPECT_EQ(4u, callbacks_
.size());
2559 // The child was copied to a bitmap and passed back twice.
2560 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[1].ToString());
2561 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[2].ToString());
2562 // The root was copied to a bitmap and passed back also.
2563 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_
[3].ToString());
2569 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
2570 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2571 EXPECT_TRUE(result
->HasBitmap());
2572 scoped_ptr
<SkBitmap
> bitmap
= result
->TakeBitmap().Pass();
2573 EXPECT_EQ(result
->size().ToString(),
2574 gfx::Size(bitmap
->width(), bitmap
->height()).ToString());
2575 callbacks_
.push_back(result
->size());
2578 virtual void AfterTest() OVERRIDE
{
2579 EXPECT_EQ(4u, callbacks_
.size());
2582 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
2583 if (use_gl_renderer_
)
2584 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
2585 return FakeOutputSurface::CreateSoftware(
2586 make_scoped_ptr(new SoftwareOutputDevice
)).PassAs
<OutputSurface
>();
2589 bool use_gl_renderer_
;
2590 std::vector
<gfx::Size
> callbacks_
;
2591 FakeContentLayerClient client_
;
2592 scoped_refptr
<FakeContentLayer
> root
;
2593 scoped_refptr
<FakeContentLayer
> child
;
2596 // Readback can't be done with a delegating renderer.
2597 TEST_F(LayerTreeHostTestAsyncReadback
, GLRenderer_RunSingleThread
) {
2598 use_gl_renderer_
= true;
2599 RunTest(false, false, false);
2602 TEST_F(LayerTreeHostTestAsyncReadback
,
2603 GLRenderer_RunMultiThread_MainThreadPainting
) {
2604 use_gl_renderer_
= true;
2605 RunTest(true, false, false);
2608 TEST_F(LayerTreeHostTestAsyncReadback
,
2609 GLRenderer_RunMultiThread_ImplSidePainting
) {
2610 use_gl_renderer_
= true;
2611 RunTest(true, false, true);
2614 TEST_F(LayerTreeHostTestAsyncReadback
, SoftwareRenderer_RunSingleThread
) {
2615 use_gl_renderer_
= false;
2616 RunTest(false, false, false);
2619 TEST_F(LayerTreeHostTestAsyncReadback
,
2620 SoftwareRenderer_RunMultiThread_MainThreadPainting
) {
2621 use_gl_renderer_
= false;
2622 RunTest(true, false, false);
2625 TEST_F(LayerTreeHostTestAsyncReadback
,
2626 SoftwareRenderer_RunMultiThread_ImplSidePainting
) {
2627 use_gl_renderer_
= false;
2628 RunTest(true, false, true);
2631 class LayerTreeHostTestAsyncReadbackLayerDestroyed
: public LayerTreeHostTest
{
2633 virtual void SetupTree() OVERRIDE
{
2634 root_
= FakeContentLayer::Create(&client_
);
2635 root_
->SetBounds(gfx::Size(20, 20));
2637 main_destroyed_
= FakeContentLayer::Create(&client_
);
2638 main_destroyed_
->SetBounds(gfx::Size(15, 15));
2639 root_
->AddChild(main_destroyed_
);
2641 impl_destroyed_
= FakeContentLayer::Create(&client_
);
2642 impl_destroyed_
->SetBounds(gfx::Size(10, 10));
2643 root_
->AddChild(impl_destroyed_
);
2645 layer_tree_host()->SetRootLayer(root_
);
2646 LayerTreeHostTest::SetupTree();
2649 virtual void BeginTest() OVERRIDE
{
2650 callback_count_
= 0;
2651 PostSetNeedsCommitToMainThread();
2654 virtual void DidCommit() OVERRIDE
{
2655 int frame
= layer_tree_host()->commit_number();
2658 main_destroyed_
->RequestCopyOfOutput(
2659 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2660 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2662 base::Unretained(this))));
2663 impl_destroyed_
->RequestCopyOfOutput(
2664 CopyOutputRequest::CreateBitmapRequest(base::Bind(
2665 &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2667 base::Unretained(this))));
2668 EXPECT_EQ(0, callback_count_
);
2670 // Destroy the main thread layer right away.
2671 main_destroyed_
->RemoveFromParent();
2672 main_destroyed_
= NULL
;
2674 // Should callback with a NULL bitmap.
2675 EXPECT_EQ(1, callback_count_
);
2677 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
2678 layer_tree_host()->SetViewportSize(gfx::Size());
2681 // Flush the message loops and make sure the callbacks run.
2682 layer_tree_host()->SetNeedsCommit();
2685 // No drawing means no readback yet.
2686 EXPECT_EQ(1, callback_count_
);
2688 // Destroy the impl thread layer.
2689 impl_destroyed_
->RemoveFromParent();
2690 impl_destroyed_
= NULL
;
2692 // No callback yet because it's on the impl side.
2693 EXPECT_EQ(1, callback_count_
);
2696 // Flush the message loops and make sure the callbacks run.
2697 layer_tree_host()->SetNeedsCommit();
2700 // We should get another callback with a NULL bitmap.
2701 EXPECT_EQ(2, callback_count_
);
2707 void CopyOutputCallback(scoped_ptr
<CopyOutputResult
> result
) {
2708 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2709 EXPECT_TRUE(result
->IsEmpty());
2713 virtual void AfterTest() OVERRIDE
{}
2715 int callback_count_
;
2716 FakeContentLayerClient client_
;
2717 scoped_refptr
<FakeContentLayer
> root_
;
2718 scoped_refptr
<FakeContentLayer
> main_destroyed_
;
2719 scoped_refptr
<FakeContentLayer
> impl_destroyed_
;
2722 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed
);
2724 class LayerTreeHostTestNumFramesPending
: public LayerTreeHostTest
{
2726 virtual void BeginTest() OVERRIDE
{
2728 PostSetNeedsCommitToMainThread();
2731 // Round 1: commit + draw
2732 // Round 2: commit only (no draw/swap)
2733 // Round 3: draw only (no commit)
2734 // Round 4: composite & readback (2 commits, no draw/swap)
2735 // Round 5: commit + draw
2737 virtual void DidCommit() OVERRIDE
{
2738 int commit
= layer_tree_host()->commit_number();
2742 EXPECT_EQ(1, frame_
);
2743 layer_tree_host()->SetNeedsRedraw();
2746 // CompositeAndReadback in Round 4, first commit.
2747 EXPECT_EQ(2, frame_
);
2751 EXPECT_EQ(2, frame_
);
2752 layer_tree_host()->SetNeedsCommit();
2753 layer_tree_host()->SetNeedsRedraw();
2758 virtual void DidCompleteSwapBuffers() OVERRIDE
{
2759 int commit
= layer_tree_host()->commit_number();
2761 char pixels
[4] = {0};
2765 EXPECT_EQ(1, commit
);
2766 layer_tree_host()->SetNeedsCommit();
2770 EXPECT_EQ(2, commit
);
2771 layer_tree_host()->CompositeAndReadback(pixels
, gfx::Rect(0, 0, 1, 1));
2775 EXPECT_EQ(5, commit
);
2781 virtual void AfterTest() OVERRIDE
{}
2787 TEST_F(LayerTreeHostTestNumFramesPending
, DelegatingRenderer
) {
2788 RunTest(true, true, true);
2791 TEST_F(LayerTreeHostTestNumFramesPending
, GLRenderer
) {
2792 RunTest(true, false, true);
2795 class LayerTreeHostTestDeferredInitialize
: public LayerTreeHostTest
{
2797 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2798 // PictureLayer can only be used with impl side painting enabled.
2799 settings
->impl_side_painting
= true;
2800 settings
->solid_color_scrollbars
= true;
2803 virtual void SetupTree() OVERRIDE
{
2804 layer_
= FakePictureLayer::Create(&client_
);
2805 layer_tree_host()->SetRootLayer(layer_
);
2806 LayerTreeHostTest::SetupTree();
2809 virtual void BeginTest() OVERRIDE
{
2810 initialized_gl_
= false;
2811 PostSetNeedsCommitToMainThread();
2814 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
2815 scoped_ptr
<TestWebGraphicsContext3D
> context3d(
2816 TestWebGraphicsContext3D::Create());
2817 context3d
->set_support_swapbuffers_complete_callback(false);
2819 return FakeOutputSurface::CreateDeferredGL(
2820 scoped_ptr
<SoftwareOutputDevice
>(new SoftwareOutputDevice
))
2821 .PassAs
<OutputSurface
>();
2824 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2825 ASSERT_TRUE(host_impl
->RootLayer());
2826 FakePictureLayerImpl
* layer_impl
=
2827 static_cast<FakePictureLayerImpl
*>(host_impl
->RootLayer());
2828 if (!initialized_gl_
) {
2829 EXPECT_EQ(1u, layer_impl
->append_quads_count());
2830 ImplThreadTaskRunner()->PostTask(FROM_HERE
, base::Bind(
2831 &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw
,
2832 base::Unretained(this),
2833 base::Unretained(host_impl
)));
2835 EXPECT_EQ(2u, layer_impl
->append_quads_count());
2840 void DeferredInitializeAndRedraw(LayerTreeHostImpl
* host_impl
) {
2841 EXPECT_TRUE(static_cast<FakeOutputSurface
*>(host_impl
->output_surface())
2842 ->SetAndInitializeContext3D(
2843 scoped_ptr
<WebKit::WebGraphicsContext3D
>(
2844 TestWebGraphicsContext3D::Create())));
2845 initialized_gl_
= true;
2847 // Force redraw again.
2848 host_impl
->SetNeedsRedrawRect(gfx::Rect(1, 1));
2850 // If we didn't swap this begin frame, we need to request another one.
2851 host_impl
->SetNeedsBeginFrame(true);
2854 virtual void AfterTest() OVERRIDE
{
2855 EXPECT_TRUE(initialized_gl_
);
2859 FakeContentLayerClient client_
;
2860 scoped_refptr
<FakePictureLayer
> layer_
;
2861 bool initialized_gl_
;
2864 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize
);