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/output_surface.h"
19 #include "cc/resources/prioritized_resource.h"
20 #include "cc/resources/prioritized_resource_manager.h"
21 #include "cc/resources/resource_update_queue.h"
22 #include "cc/scheduler/frame_rate_controller.h"
23 #include "cc/test/fake_content_layer.h"
24 #include "cc/test/fake_content_layer_client.h"
25 #include "cc/test/fake_layer_tree_host_client.h"
26 #include "cc/test/fake_output_surface.h"
27 #include "cc/test/fake_proxy.h"
28 #include "cc/test/fake_scrollbar_layer.h"
29 #include "cc/test/geometry_test_utils.h"
30 #include "cc/test/layer_tree_test.h"
31 #include "cc/test/occlusion_tracker_test_common.h"
32 #include "cc/trees/layer_tree_host_impl.h"
33 #include "cc/trees/layer_tree_impl.h"
34 #include "cc/trees/single_thread_proxy.h"
35 #include "cc/trees/thread_proxy.h"
36 #include "gpu/GLES2/gl2extchromium.h"
37 #include "skia/ext/refptr.h"
38 #include "testing/gmock/include/gmock/gmock.h"
39 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
40 #include "third_party/khronos/GLES2/gl2.h"
41 #include "third_party/khronos/GLES2/gl2ext.h"
42 #include "third_party/skia/include/core/SkPicture.h"
43 #include "ui/gfx/point_conversions.h"
44 #include "ui/gfx/size_conversions.h"
45 #include "ui/gfx/vector2d_conversions.h"
48 using testing::AnyNumber
;
49 using testing::AtLeast
;
55 class LayerTreeHostTest
: public LayerTreeTest
{
58 // Test interleaving of redraws and commits
59 class LayerTreeHostTestCommitingWithContinuousRedraw
60 : public LayerTreeHostTest
{
62 LayerTreeHostTestCommitingWithContinuousRedraw()
63 : num_complete_commits_(0), num_draws_(0) {}
65 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
67 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
68 num_complete_commits_
++;
69 if (num_complete_commits_
== 2)
73 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
75 PostSetNeedsCommitToMainThread();
77 PostSetNeedsRedrawToMainThread();
80 virtual void AfterTest() OVERRIDE
{}
83 int num_complete_commits_
;
87 MULTI_THREAD_TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw
);
89 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
91 class LayerTreeHostTestSetNeedsCommit1
: public LayerTreeHostTest
{
93 LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
95 virtual void BeginTest() OVERRIDE
{
96 PostSetNeedsCommitToMainThread();
97 PostSetNeedsCommitToMainThread();
100 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
102 if (!impl
->active_tree()->source_frame_number())
106 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
110 virtual void AfterTest() OVERRIDE
{
111 EXPECT_GE(1, num_commits_
);
112 EXPECT_GE(1, num_draws_
);
120 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1
);
122 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
123 // first committed frame draws should lead to another commit.
124 class LayerTreeHostTestSetNeedsCommit2
: public LayerTreeHostTest
{
126 LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
128 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
130 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
134 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
136 if (impl
->active_tree()->source_frame_number() == 0)
137 PostSetNeedsCommitToMainThread();
138 else if (impl
->active_tree()->source_frame_number() == 1)
142 virtual void AfterTest() OVERRIDE
{
143 EXPECT_EQ(2, num_commits_
);
144 EXPECT_LE(1, num_draws_
);
152 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2
);
154 // 1 setNeedsRedraw after the first commit has completed should lead to 1
156 class LayerTreeHostTestSetNeedsRedraw
: public LayerTreeHostTest
{
158 LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
160 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
162 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
163 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
165 // Redraw again to verify that the second redraw doesn't commit.
166 PostSetNeedsRedrawToMainThread();
173 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
174 EXPECT_EQ(0, num_draws_
);
178 virtual void AfterTest() OVERRIDE
{
179 EXPECT_GE(2, num_draws_
);
180 EXPECT_EQ(1, num_commits_
);
188 MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw
);
190 // After setNeedsRedrawRect(invalid_rect) the final damage_rect
191 // must contain invalid_rect.
192 class LayerTreeHostTestSetNeedsRedrawRect
: public LayerTreeHostTest
{
194 LayerTreeHostTestSetNeedsRedrawRect()
197 invalid_rect_(10, 10, 20, 20),
198 root_layer_(ContentLayer::Create(&client_
)) {
201 virtual void BeginTest() OVERRIDE
{
202 root_layer_
->SetIsDrawable(true);
203 root_layer_
->SetBounds(bounds_
);
204 layer_tree_host()->SetRootLayer(root_layer_
);
205 layer_tree_host()->SetViewportSize(bounds_
);
206 PostSetNeedsCommitToMainThread();
209 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
210 LayerTreeHostImpl::FrameData
* frame_data
,
211 bool result
) OVERRIDE
{
214 gfx::RectF root_damage_rect
;
215 if (!frame_data
->render_passes
.empty())
216 root_damage_rect
= frame_data
->render_passes
.back()->damage_rect
;
219 // If this is the first frame, expect full frame damage.
220 EXPECT_RECT_EQ(root_damage_rect
, gfx::Rect(bounds_
));
222 // Check that invalid_rect_ is indeed repainted.
223 EXPECT_TRUE(root_damage_rect
.Contains(invalid_rect_
));
229 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
231 PostSetNeedsRedrawRectToMainThread(invalid_rect_
);
238 virtual void AfterTest() OVERRIDE
{
239 EXPECT_EQ(2, num_draws_
);
244 const gfx::Size bounds_
;
245 const gfx::Rect invalid_rect_
;
246 FakeContentLayerClient client_
;
247 scoped_refptr
<ContentLayer
> root_layer_
;
250 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect
);
252 class LayerTreeHostTestNoExtraCommitFromInvalidate
: public LayerTreeHostTest
{
254 LayerTreeHostTestNoExtraCommitFromInvalidate()
255 : root_layer_(ContentLayer::Create(&client_
)) {}
257 virtual void BeginTest() OVERRIDE
{
258 root_layer_
->SetAutomaticallyComputeRasterScale(false);
259 root_layer_
->SetIsDrawable(true);
260 root_layer_
->SetBounds(gfx::Size(1, 1));
261 layer_tree_host()->SetRootLayer(root_layer_
);
262 PostSetNeedsCommitToMainThread();
265 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
266 if (host_impl
->active_tree()->source_frame_number() == 1)
270 virtual void DidCommit() OVERRIDE
{
271 switch (layer_tree_host()->commit_number()) {
273 // Changing the content bounds will cause a single commit!
274 root_layer_
->SetRasterScale(4.f
);
278 EXPECT_EQ(2, layer_tree_host()->commit_number());
282 virtual void AfterTest() OVERRIDE
{}
285 FakeContentLayerClient client_
;
286 scoped_refptr
<ContentLayer
> root_layer_
;
289 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate
);
291 class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
292 : public LayerTreeHostTest
{
294 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate()
295 : root_layer_(FakeContentLayer::Create(&client_
)) {}
297 virtual void SetupTree() OVERRIDE
{
298 root_layer_
->SetBounds(gfx::Size(10, 20));
300 bool paint_scrollbar
= true;
301 bool has_thumb
= false;
302 scrollbar_
= FakeScrollbarLayer::Create(paint_scrollbar
,
305 scrollbar_
->SetPosition(gfx::Point(0, 10));
306 scrollbar_
->SetBounds(gfx::Size(10, 10));
308 root_layer_
->AddChild(scrollbar_
);
310 layer_tree_host()->SetRootLayer(root_layer_
);
311 LayerTreeHostTest::SetupTree();
314 virtual void BeginTest() OVERRIDE
{
315 PostSetNeedsCommitToMainThread();
318 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
319 if (host_impl
->active_tree()->source_frame_number() == 1)
323 virtual void DidCommit() OVERRIDE
{
324 switch (layer_tree_host()->commit_number()) {
326 // This should cause a single commit.
327 scrollbar_
->SetRasterScale(4.0f
);
331 EXPECT_EQ(2, layer_tree_host()->commit_number());
335 virtual void AfterTest() OVERRIDE
{}
338 FakeContentLayerClient client_
;
339 scoped_refptr
<FakeContentLayer
> root_layer_
;
340 scoped_refptr
<FakeScrollbarLayer
> scrollbar_
;
343 SINGLE_AND_MULTI_THREAD_TEST_F(
344 LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
);
346 class LayerTreeHostTestCompositeAndReadback
: public LayerTreeHostTest
{
348 LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
350 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
352 virtual void DidCommit() OVERRIDE
{
354 if (num_commits_
== 1) {
356 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
357 } else if (num_commits_
== 2) {
358 // This is inside the readback. We should get another commit after it.
359 } else if (num_commits_
== 3) {
366 virtual void AfterTest() OVERRIDE
{}
372 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback
);
374 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
375 : public LayerTreeHostTest
{
377 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
380 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
382 virtual void DidCommit() OVERRIDE
{
384 if (num_commits_
== 1) {
385 layer_tree_host()->SetNeedsCommit();
386 } else if (num_commits_
== 2) {
388 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
389 } else if (num_commits_
== 3) {
390 // This is inside the readback. We should get another commit after it.
391 } else if (num_commits_
== 4) {
398 virtual void AfterTest() OVERRIDE
{}
405 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
);
407 // If the layerTreeHost says it can't draw, Then we should not try to draw.
408 class LayerTreeHostTestCanDrawBlocksDrawing
: public LayerTreeHostTest
{
410 LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
412 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
414 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
417 // Only the initial draw should bring us here.
418 EXPECT_TRUE(impl
->CanDraw());
419 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
422 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
425 if (num_commits_
>= 1) {
426 // After the first commit, we should not be able to draw.
427 EXPECT_FALSE(impl
->CanDraw());
431 virtual void DidCommit() OVERRIDE
{
433 if (num_commits_
== 1) {
434 // Make the viewport empty so the host says it can't draw.
435 layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
436 } else if (num_commits_
== 2) {
438 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
439 } else if (num_commits_
== 3) {
440 // Let it draw so we go idle and end the test.
441 layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
447 virtual void AfterTest() OVERRIDE
{}
454 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing
);
456 // beginLayerWrite should prevent draws from executing until a commit occurs
457 class LayerTreeHostTestWriteLayersRedraw
: public LayerTreeHostTest
{
459 LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
461 virtual void BeginTest() OVERRIDE
{
462 PostAcquireLayerTextures();
463 PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
464 PostSetNeedsCommitToMainThread();
467 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
469 EXPECT_EQ(num_draws_
, num_commits_
);
472 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
477 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_commits_
); }
484 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw
);
486 // Verify that when resuming visibility, Requesting layer write permission
487 // will not deadlock the main thread even though there are not yet any
488 // scheduled redraws. This behavior is critical for reliably surviving tab
489 // switching. There are no failure conditions to this test, it just passes
490 // by not timing out.
491 class LayerTreeHostTestWriteLayersAfterVisible
: public LayerTreeHostTest
{
493 LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
495 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
497 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
499 if (num_commits_
== 2)
501 else if (num_commits_
< 2) {
502 PostSetVisibleToMainThread(false);
503 PostSetVisibleToMainThread(true);
504 PostAcquireLayerTextures();
505 PostSetNeedsCommitToMainThread();
509 virtual void AfterTest() OVERRIDE
{}
515 MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible
);
517 // A compositeAndReadback while invisible should force a normal commit without
519 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
520 : public LayerTreeHostTest
{
522 LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
524 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
526 virtual void DidCommitAndDrawFrame() OVERRIDE
{
528 if (num_commits_
== 1) {
529 layer_tree_host()->SetVisible(false);
530 layer_tree_host()->SetNeedsCommit();
531 layer_tree_host()->SetNeedsCommit();
533 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
539 virtual void AfterTest() OVERRIDE
{}
545 MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible
);
547 class LayerTreeHostTestAbortFrameWhenInvisible
: public LayerTreeHostTest
{
549 LayerTreeHostTestAbortFrameWhenInvisible() {}
551 virtual void BeginTest() OVERRIDE
{
552 // Request a commit (from the main thread), Which will trigger the commit
553 // flow from the impl side.
554 layer_tree_host()->SetNeedsCommit();
555 // Then mark ourselves as not visible before processing any more messages
556 // on the main thread.
557 layer_tree_host()->SetVisible(false);
558 // If we make it without kicking a frame, we pass!
559 EndTestAfterDelay(1);
562 virtual void Layout() OVERRIDE
{
567 virtual void AfterTest() OVERRIDE
{}
572 MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible
);
574 // This test verifies that properties on the layer tree host are commited
576 class LayerTreeHostTestCommit
: public LayerTreeHostTest
{
578 LayerTreeHostTestCommit() {}
580 virtual void BeginTest() OVERRIDE
{
581 layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
582 layer_tree_host()->set_background_color(SK_ColorGRAY
);
583 layer_tree_host()->SetPageScaleFactorAndLimits(5.f
, 5.f
, 5.f
);
585 PostSetNeedsCommitToMainThread();
588 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
589 EXPECT_EQ(gfx::Size(20, 20), impl
->device_viewport_size());
590 EXPECT_EQ(SK_ColorGRAY
, impl
->active_tree()->background_color());
591 EXPECT_EQ(5.f
, impl
->active_tree()->page_scale_factor());
596 virtual void AfterTest() OVERRIDE
{}
599 MULTI_THREAD_TEST_F(LayerTreeHostTestCommit
);
601 // Verifies that StartPageScaleAnimation events propagate correctly
602 // from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
603 class LayerTreeHostTestStartPageScaleAnimation
: public LayerTreeHostTest
{
605 LayerTreeHostTestStartPageScaleAnimation() {}
607 virtual void BeginTest() OVERRIDE
{
608 layer_tree_host()->root_layer()->SetScrollable(true);
609 layer_tree_host()->root_layer()->SetScrollOffset(gfx::Vector2d());
610 layer_tree_host()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 2.f
);
611 layer_tree_host()->StartPageScaleAnimation(
612 gfx::Vector2d(), false, 1.25f
, base::TimeDelta());
613 PostSetNeedsCommitToMainThread();
614 PostSetNeedsRedrawToMainThread();
617 virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta
, float scale
)
619 gfx::Vector2d offset
= layer_tree_host()->root_layer()->scroll_offset();
620 layer_tree_host()->root_layer()->SetScrollOffset(offset
+ scroll_delta
);
621 layer_tree_host()->SetPageScaleFactorAndLimits(scale
, 0.5f
, 2.f
);
624 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
625 impl
->ProcessScrollDeltas();
626 // We get one commit before the first draw, and the animation doesn't happen
627 // until the second draw.
628 if (impl
->active_tree()->source_frame_number() == 1) {
629 EXPECT_EQ(1.25f
, impl
->active_tree()->page_scale_factor());
632 PostSetNeedsRedrawToMainThread();
636 virtual void AfterTest() OVERRIDE
{}
639 MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation
);
641 class LayerTreeHostTestSetVisible
: public LayerTreeHostTest
{
643 LayerTreeHostTestSetVisible() : num_draws_(0) {}
645 virtual void BeginTest() OVERRIDE
{
646 PostSetNeedsCommitToMainThread();
647 PostSetVisibleToMainThread(false);
648 // This is suppressed while we're invisible.
649 PostSetNeedsRedrawToMainThread();
650 // Triggers the redraw.
651 PostSetVisibleToMainThread(true);
654 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
655 EXPECT_TRUE(impl
->visible());
660 virtual void AfterTest() OVERRIDE
{ EXPECT_EQ(1, num_draws_
); }
666 MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible
);
668 class TestOpacityChangeLayerDelegate
: public ContentLayerClient
{
670 TestOpacityChangeLayerDelegate() : test_layer_(0) {}
672 void SetTestLayer(Layer
* test_layer
) { test_layer_
= test_layer
; }
674 virtual void PaintContents(SkCanvas
*, gfx::Rect
, gfx::RectF
*) OVERRIDE
{
675 // Set layer opacity to 0.
677 test_layer_
->SetOpacity(0.f
);
679 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
685 class ContentLayerWithUpdateTracking
: public ContentLayer
{
687 static scoped_refptr
<ContentLayerWithUpdateTracking
> Create(
688 ContentLayerClient
* client
) {
689 return make_scoped_refptr(new ContentLayerWithUpdateTracking(client
));
692 int PaintContentsCount() { return paint_contents_count_
; }
693 void ResetPaintContentsCount() { paint_contents_count_
= 0; }
695 virtual void Update(ResourceUpdateQueue
* queue
,
696 const OcclusionTracker
* occlusion
,
697 RenderingStats
* stats
) OVERRIDE
{
698 ContentLayer::Update(queue
, occlusion
, stats
);
699 paint_contents_count_
++;
703 explicit ContentLayerWithUpdateTracking(ContentLayerClient
* client
)
704 : ContentLayer(client
), paint_contents_count_(0) {
705 SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
706 SetBounds(gfx::Size(10, 10));
709 virtual ~ContentLayerWithUpdateTracking() {}
711 int paint_contents_count_
;
714 // Layer opacity change during paint should not prevent compositor resources
715 // from being updated during commit.
716 class LayerTreeHostTestOpacityChange
: public LayerTreeHostTest
{
718 LayerTreeHostTestOpacityChange()
719 : test_opacity_change_delegate_(),
720 update_check_layer_(ContentLayerWithUpdateTracking::Create(
721 &test_opacity_change_delegate_
)) {
722 test_opacity_change_delegate_
.SetTestLayer(update_check_layer_
.get());
725 virtual void BeginTest() OVERRIDE
{
726 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
727 layer_tree_host()->root_layer()->AddChild(update_check_layer_
);
729 PostSetNeedsCommitToMainThread();
732 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
736 virtual void AfterTest() OVERRIDE
{
737 // Update() should have been called once.
738 EXPECT_EQ(1, update_check_layer_
->PaintContentsCount());
742 TestOpacityChangeLayerDelegate test_opacity_change_delegate_
;
743 scoped_refptr
<ContentLayerWithUpdateTracking
> update_check_layer_
;
746 MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange
);
748 class NoScaleContentLayer
: public ContentLayer
{
750 static scoped_refptr
<NoScaleContentLayer
> Create(ContentLayerClient
* client
) {
751 return make_scoped_refptr(new NoScaleContentLayer(client
));
754 virtual void CalculateContentsScale(float ideal_contents_scale
,
755 bool animating_transform_to_screen
,
756 float* contents_scale_x
,
757 float* contents_scale_y
,
758 gfx::Size
* contentBounds
) OVERRIDE
{
759 // Skip over the ContentLayer's method to the base Layer class.
760 Layer::CalculateContentsScale(ideal_contents_scale
,
761 animating_transform_to_screen
,
768 explicit NoScaleContentLayer(ContentLayerClient
* client
)
769 : ContentLayer(client
) {}
770 virtual ~NoScaleContentLayer() {}
773 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
774 : public LayerTreeHostTest
{
776 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
777 : root_layer_(NoScaleContentLayer::Create(&client_
)),
778 child_layer_(ContentLayer::Create(&client_
)) {}
780 virtual void BeginTest() OVERRIDE
{
781 layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
782 layer_tree_host()->SetDeviceScaleFactor(1.5);
783 EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
785 root_layer_
->AddChild(child_layer_
);
787 root_layer_
->SetIsDrawable(true);
788 root_layer_
->SetBounds(gfx::Size(30, 30));
789 root_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
791 child_layer_
->SetIsDrawable(true);
792 child_layer_
->SetPosition(gfx::Point(2, 2));
793 child_layer_
->SetBounds(gfx::Size(10, 10));
794 child_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
796 layer_tree_host()->SetRootLayer(root_layer_
);
798 PostSetNeedsCommitToMainThread();
801 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
802 // Should only do one commit.
803 EXPECT_EQ(0, impl
->active_tree()->source_frame_number());
804 // Device scale factor should come over to impl.
805 EXPECT_NEAR(impl
->device_scale_factor(), 1.5f
, 0.00001f
);
807 // Both layers are on impl.
808 ASSERT_EQ(1u, impl
->active_tree()->root_layer()->children().size());
810 // Device viewport is scaled.
811 EXPECT_EQ(gfx::Size(60, 60), impl
->device_viewport_size());
813 LayerImpl
* root
= impl
->active_tree()->root_layer();
814 LayerImpl
* child
= impl
->active_tree()->root_layer()->children()[0];
816 // Positions remain in layout pixels.
817 EXPECT_EQ(gfx::Point(0, 0), root
->position());
818 EXPECT_EQ(gfx::Point(2, 2), child
->position());
820 // Compute all the layer transforms for the frame.
821 LayerTreeHostImpl::FrameData frame_data
;
822 impl
->PrepareToDraw(&frame_data
, gfx::Rect());
823 impl
->DidDrawAllLayers(frame_data
);
825 const LayerImplList
& render_surface_layer_list
=
826 *frame_data
.render_surface_layer_list
;
828 // Both layers should be drawing into the root render surface.
829 ASSERT_EQ(1u, render_surface_layer_list
.size());
830 ASSERT_EQ(root
->render_surface(),
831 render_surface_layer_list
[0]->render_surface());
832 ASSERT_EQ(2u, root
->render_surface()->layer_list().size());
834 // The root render surface is the size of the viewport.
835 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
836 root
->render_surface()->content_rect());
838 // The content bounds of the child should be scaled.
839 gfx::Size child_bounds_scaled
=
840 gfx::ToCeiledSize(gfx::ScaleSize(child
->bounds(), 1.5));
841 EXPECT_EQ(child_bounds_scaled
, child
->content_bounds());
843 gfx::Transform scale_transform
;
844 scale_transform
.Scale(impl
->device_scale_factor(),
845 impl
->device_scale_factor());
847 // The root layer is scaled by 2x.
848 gfx::Transform root_screen_space_transform
= scale_transform
;
849 gfx::Transform root_draw_transform
= scale_transform
;
851 EXPECT_EQ(root_draw_transform
, root
->draw_transform());
852 EXPECT_EQ(root_screen_space_transform
, root
->screen_space_transform());
854 // The child is at position 2,2, which is transformed to 3,3 after the scale
855 gfx::Transform child_screen_space_transform
;
856 child_screen_space_transform
.Translate(3.f
, 3.f
);
857 gfx::Transform child_draw_transform
= child_screen_space_transform
;
859 EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform
,
860 child
->draw_transform());
861 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform
,
862 child
->screen_space_transform());
867 virtual void AfterTest() OVERRIDE
{}
870 FakeContentLayerClient client_
;
871 scoped_refptr
<NoScaleContentLayer
> root_layer_
;
872 scoped_refptr
<ContentLayer
> child_layer_
;
875 MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
);
877 // Verify atomicity of commits and reuse of textures.
878 class LayerTreeHostTestAtomicCommit
: public LayerTreeHostTest
{
880 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
881 // Make sure partial texture updates are turned off.
882 settings
->max_partial_texture_updates
= 0;
883 // Linear fade animator prevents scrollbars from drawing immediately.
884 settings
->use_linear_fade_scrollbar_animator
= false;
887 virtual void SetupTree() OVERRIDE
{
888 layer_
= FakeContentLayer::Create(&client_
);
889 layer_
->SetBounds(gfx::Size(10, 20));
891 bool paint_scrollbar
= true;
892 bool has_thumb
= false;
894 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, layer_
->id());
895 scrollbar_
->SetPosition(gfx::Point(0, 10));
896 scrollbar_
->SetBounds(gfx::Size(10, 10));
898 layer_
->AddChild(scrollbar_
);
900 layer_tree_host()->SetRootLayer(layer_
);
901 LayerTreeHostTest::SetupTree();
904 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
906 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
907 ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates
);
909 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
910 impl
->output_surface()->context3d());
912 switch (impl
->active_tree()->source_frame_number()) {
914 // Number of textures should be one for each layer
915 ASSERT_EQ(2u, context
->NumTextures());
916 // Number of textures used for commit should be one for each layer.
917 EXPECT_EQ(2u, context
->NumUsedTextures());
918 // Verify that used texture is correct.
919 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
920 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
922 context
->ResetUsedTextures();
923 PostSetNeedsCommitToMainThread();
926 // Number of textures should be doubled as the first textures
927 // are used by impl thread and cannot by used for update.
928 ASSERT_EQ(4u, context
->NumTextures());
929 // Number of textures used for commit should still be
930 // one for each layer.
931 EXPECT_EQ(2u, context
->NumUsedTextures());
932 // First textures should not have been used.
933 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
934 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
935 // New textures should have been used.
936 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
937 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
939 context
->ResetUsedTextures();
940 PostSetNeedsCommitToMainThread();
951 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
952 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
953 impl
->output_surface()->context3d());
955 // Number of textures used for draw should always be one for each layer.
956 EXPECT_EQ(2u, context
->NumUsedTextures());
957 context
->ResetUsedTextures();
960 virtual void Layout() OVERRIDE
{
961 layer_
->SetNeedsDisplay();
962 scrollbar_
->SetNeedsDisplay();
965 virtual void AfterTest() OVERRIDE
{}
968 FakeContentLayerClient client_
;
969 scoped_refptr
<FakeContentLayer
> layer_
;
970 scoped_refptr
<FakeScrollbarLayer
> scrollbar_
;
973 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit
);
975 static void SetLayerPropertiesForTesting(Layer
* layer
,
977 const gfx::Transform
& transform
,
979 gfx::PointF position
,
982 layer
->RemoveAllChildren();
984 parent
->AddChild(layer
);
985 layer
->SetTransform(transform
);
986 layer
->SetAnchorPoint(anchor
);
987 layer
->SetPosition(position
);
988 layer
->SetBounds(bounds
);
989 layer
->SetContentsOpaque(opaque
);
992 class LayerTreeHostTestAtomicCommitWithPartialUpdate
993 : public LayerTreeHostTest
{
995 LayerTreeHostTestAtomicCommitWithPartialUpdate() : num_commits_(0) {}
997 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
998 // Allow one partial texture update.
999 settings
->max_partial_texture_updates
= 1;
1000 // Linear fade animator prevents scrollbars from drawing immediately.
1001 settings
->use_linear_fade_scrollbar_animator
= false;
1004 virtual void SetupTree() OVERRIDE
{
1005 parent_
= FakeContentLayer::Create(&client_
);
1006 parent_
->SetBounds(gfx::Size(10, 20));
1008 child_
= FakeContentLayer::Create(&client_
);
1009 child_
->SetPosition(gfx::Point(0, 10));
1010 child_
->SetBounds(gfx::Size(3, 10));
1012 bool paint_scrollbar
= true;
1013 bool has_thumb
= false;
1014 scrollbar_with_paints_
=
1015 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, parent_
->id());
1016 scrollbar_with_paints_
->SetPosition(gfx::Point(3, 10));
1017 scrollbar_with_paints_
->SetBounds(gfx::Size(3, 10));
1019 paint_scrollbar
= false;
1020 scrollbar_without_paints_
=
1021 FakeScrollbarLayer::Create(paint_scrollbar
, has_thumb
, parent_
->id());
1022 scrollbar_without_paints_
->SetPosition(gfx::Point(6, 10));
1023 scrollbar_without_paints_
->SetBounds(gfx::Size(3, 10));
1025 parent_
->AddChild(child_
);
1026 parent_
->AddChild(scrollbar_with_paints_
);
1027 parent_
->AddChild(scrollbar_without_paints_
);
1029 layer_tree_host()->SetRootLayer(parent_
);
1030 LayerTreeHostTest::SetupTree();
1033 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1035 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1036 ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates
);
1038 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1039 impl
->output_surface()->context3d());
1041 switch (impl
->active_tree()->source_frame_number()) {
1043 // Number of textures should be one for each layer.
1044 ASSERT_EQ(4u, context
->NumTextures());
1045 // Number of textures used for commit should be one for each layer.
1046 EXPECT_EQ(4u, context
->NumUsedTextures());
1047 // Verify that used textures are correct.
1048 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1049 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1050 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1051 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1053 context
->ResetUsedTextures();
1054 PostSetNeedsCommitToMainThread();
1057 // Number of textures should be two for each content layer and one
1058 // for each scrollbar, since they always do a partial update.
1059 ASSERT_EQ(6u, context
->NumTextures());
1060 // Number of textures used for commit should be one for each content
1061 // layer, and one for the scrollbar layer that paints.
1062 EXPECT_EQ(3u, context
->NumUsedTextures());
1064 // First content textures should not have been used.
1065 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1066 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1067 // The non-painting scrollbar's texture wasn't updated.
1068 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1069 // The painting scrollbar's partial update texture was used.
1070 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1071 // New textures should have been used.
1072 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1073 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(5)));
1075 context
->ResetUsedTextures();
1076 PostSetNeedsCommitToMainThread();
1079 // Number of textures should be two for each content layer and one
1080 // for each scrollbar, since they always do a partial update.
1081 ASSERT_EQ(6u, context
->NumTextures());
1082 // Number of textures used for commit should be one for each content
1083 // layer, and one for the scrollbar layer that paints.
1084 EXPECT_EQ(3u, context
->NumUsedTextures());
1086 // The non-painting scrollbar's texture wasn't updated.
1087 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1088 // The painting scrollbar does a partial update.
1089 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1090 // One content layer does a partial update also.
1091 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1092 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(5)));
1094 context
->ResetUsedTextures();
1095 PostSetNeedsCommitToMainThread();
1098 // No textures should be used for commit.
1099 EXPECT_EQ(0u, context
->NumUsedTextures());
1101 context
->ResetUsedTextures();
1102 PostSetNeedsCommitToMainThread();
1105 // Number of textures used for commit should be two. One for the
1106 // content layer, and one for the painting scrollbar. The
1107 // non-painting scrollbar doesn't update its texture.
1108 EXPECT_EQ(2u, context
->NumUsedTextures());
1110 context
->ResetUsedTextures();
1111 PostSetNeedsCommitToMainThread();
1122 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1123 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(
1124 impl
->output_surface()->context3d());
1126 // Number of textures used for drawing should one per layer except for
1127 // frame 3 where the viewport only contains one layer.
1128 if (impl
->active_tree()->source_frame_number() == 3)
1129 EXPECT_EQ(1u, context
->NumUsedTextures());
1131 EXPECT_EQ(4u, context
->NumUsedTextures());
1133 context
->ResetUsedTextures();
1136 virtual void Layout() OVERRIDE
{
1137 switch (num_commits_
++) {
1140 parent_
->SetNeedsDisplay();
1141 child_
->SetNeedsDisplay();
1142 scrollbar_with_paints_
->SetNeedsDisplay();
1143 scrollbar_without_paints_
->SetNeedsDisplay();
1146 // Damage part of layers.
1147 parent_
->SetNeedsDisplayRect(gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1148 child_
->SetNeedsDisplayRect(gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1149 scrollbar_with_paints_
->SetNeedsDisplayRect(
1150 gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1151 scrollbar_without_paints_
->SetNeedsDisplayRect(
1152 gfx::RectF(0.f
, 0.f
, 5.f
, 5.f
));
1155 child_
->SetNeedsDisplay();
1156 scrollbar_with_paints_
->SetNeedsDisplay();
1157 scrollbar_without_paints_
->SetNeedsDisplay();
1158 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1161 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1171 virtual void AfterTest() OVERRIDE
{}
1174 FakeContentLayerClient client_
;
1175 scoped_refptr
<FakeContentLayer
> parent_
;
1176 scoped_refptr
<FakeContentLayer
> child_
;
1177 scoped_refptr
<FakeScrollbarLayer
> scrollbar_with_paints_
;
1178 scoped_refptr
<FakeScrollbarLayer
> scrollbar_without_paints_
;
1182 MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate
);
1184 class LayerTreeHostTestFinishAllRendering
: public LayerTreeHostTest
{
1186 LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1188 virtual void BeginTest() OVERRIDE
{
1189 layer_tree_host()->SetNeedsRedraw();
1190 PostSetNeedsCommitToMainThread();
1193 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1197 layer_tree_host()->SetNeedsRedraw();
1198 layer_tree_host()->AcquireLayerTextures();
1200 base::AutoLock
lock(lock_
);
1203 layer_tree_host()->FinishAllRendering();
1205 base::AutoLock
lock(lock_
);
1206 EXPECT_EQ(0, draw_count_
);
1211 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1212 base::AutoLock
lock(lock_
);
1216 virtual void AfterTest() OVERRIDE
{}
1224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering
);
1226 class LayerTreeHostTestCompositeAndReadbackCleanup
: public LayerTreeHostTest
{
1228 virtual void BeginTest() OVERRIDE
{
1229 Layer
* root_layer
= layer_tree_host()->root_layer();
1232 layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels
),
1233 gfx::Rect(0, 0, 1, 1));
1234 EXPECT_FALSE(root_layer
->render_surface());
1239 virtual void AfterTest() OVERRIDE
{}
1242 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup
);
1244 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1245 : public LayerTreeHostTest
{
1247 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1248 : root_layer_(FakeContentLayer::Create(&client_
)),
1250 FakeContentLayer::Create(&client_
)),
1252 FakeContentLayer::Create(&client_
)),
1254 FakeContentLayer::Create(&client_
)),
1256 FakeContentLayer::Create(&client_
)) {}
1258 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1259 settings
->cache_render_pass_contents
= true;
1262 virtual void BeginTest() OVERRIDE
{
1263 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1265 root_layer_
->SetBounds(gfx::Size(100, 100));
1266 surface_layer1_
->SetBounds(gfx::Size(100, 100));
1267 surface_layer1_
->SetForceRenderSurface(true);
1268 surface_layer1_
->SetOpacity(0.5f
);
1269 surface_layer2_
->SetBounds(gfx::Size(100, 100));
1270 surface_layer2_
->SetForceRenderSurface(true);
1271 surface_layer2_
->SetOpacity(0.5f
);
1273 surface_layer1_
->SetReplicaLayer(replica_layer1_
.get());
1274 surface_layer2_
->SetReplicaLayer(replica_layer2_
.get());
1276 root_layer_
->AddChild(surface_layer1_
);
1277 surface_layer1_
->AddChild(surface_layer2_
);
1278 layer_tree_host()->SetRootLayer(root_layer_
);
1280 PostSetNeedsCommitToMainThread();
1283 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1284 Renderer
* renderer
= host_impl
->renderer();
1285 RenderPass::Id surface1_render_pass_id
= host_impl
->active_tree()
1286 ->root_layer()->children()[0]->render_surface()->RenderPassId();
1287 RenderPass::Id surface2_render_pass_id
=
1288 host_impl
->active_tree()->root_layer()->children()[0]->children()[0]
1289 ->render_surface()->RenderPassId();
1291 switch (host_impl
->active_tree()->source_frame_number()) {
1293 EXPECT_TRUE(renderer
->HaveCachedResourcesForRenderPassId(
1294 surface1_render_pass_id
));
1295 EXPECT_TRUE(renderer
->HaveCachedResourcesForRenderPassId(
1296 surface2_render_pass_id
));
1298 // Reduce the memory limit to only fit the root layer and one render
1299 // surface. This prevents any contents drawing into surfaces
1300 // from being allocated.
1301 host_impl
->SetManagedMemoryPolicy(
1302 ManagedMemoryPolicy(100 * 100 * 4 * 2));
1305 EXPECT_FALSE(renderer
->HaveCachedResourcesForRenderPassId(
1306 surface1_render_pass_id
));
1307 EXPECT_FALSE(renderer
->HaveCachedResourcesForRenderPassId(
1308 surface2_render_pass_id
));
1315 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1317 root_layer_
->SetNeedsDisplay();
1320 virtual void AfterTest() OVERRIDE
{
1321 EXPECT_EQ(3u, root_layer_
->update_count());
1322 EXPECT_EQ(3u, surface_layer1_
->update_count());
1323 EXPECT_EQ(3u, surface_layer2_
->update_count());
1327 FakeContentLayerClient client_
;
1328 scoped_refptr
<FakeContentLayer
> root_layer_
;
1329 scoped_refptr
<FakeContentLayer
> surface_layer1_
;
1330 scoped_refptr
<FakeContentLayer
> replica_layer1_
;
1331 scoped_refptr
<FakeContentLayer
> surface_layer2_
;
1332 scoped_refptr
<FakeContentLayer
> replica_layer2_
;
1335 SINGLE_AND_MULTI_THREAD_TEST_F(
1336 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
);
1338 class EvictionTestLayer
: public Layer
{
1340 static scoped_refptr
<EvictionTestLayer
> Create() {
1341 return make_scoped_refptr(new EvictionTestLayer());
1344 virtual void Update(ResourceUpdateQueue
*,
1345 const OcclusionTracker
*,
1346 RenderingStats
*) OVERRIDE
;
1347 virtual bool DrawsContent() const OVERRIDE
{ return true; }
1349 virtual scoped_ptr
<LayerImpl
> CreateLayerImpl(LayerTreeImpl
* tree_impl
)
1351 virtual void PushPropertiesTo(LayerImpl
* impl
) OVERRIDE
;
1352 virtual void SetTexturePriorities(const PriorityCalculator
&) OVERRIDE
;
1354 bool HaveBackingTexture() const {
1355 return texture_
.get() ? texture_
->have_backing_texture() : false;
1359 EvictionTestLayer() : Layer() {}
1360 virtual ~EvictionTestLayer() {}
1362 void CreateTextureIfNeeded() {
1365 texture_
= PrioritizedResource::Create(
1366 layer_tree_host()->contents_texture_manager());
1367 texture_
->SetDimensions(gfx::Size(10, 10), GL_RGBA
);
1368 bitmap_
.setConfig(SkBitmap::kARGB_8888_Config
, 10, 10);
1371 scoped_ptr
<PrioritizedResource
> texture_
;
1375 class EvictionTestLayerImpl
: public LayerImpl
{
1377 static scoped_ptr
<EvictionTestLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1379 return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl
, id
));
1381 virtual ~EvictionTestLayerImpl() {}
1383 virtual void AppendQuads(QuadSink
* quad_sink
,
1384 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1385 ASSERT_TRUE(has_texture_
);
1386 ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1389 void SetHasTexture(bool has_texture
) { has_texture_
= has_texture
; }
1392 EvictionTestLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
1393 : LayerImpl(tree_impl
, id
), has_texture_(false) {}
1398 void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator
&) {
1399 CreateTextureIfNeeded();
1402 texture_
->set_request_priority(PriorityCalculator::UIPriority(true));
1405 void EvictionTestLayer::Update(ResourceUpdateQueue
* queue
,
1406 const OcclusionTracker
*,
1408 CreateTextureIfNeeded();
1412 gfx::Rect
full_rect(0, 0, 10, 10);
1413 ResourceUpdate upload
= ResourceUpdate::Create(
1414 texture_
.get(), &bitmap_
, full_rect
, full_rect
, gfx::Vector2d());
1415 queue
->AppendFullUpload(upload
);
1418 scoped_ptr
<LayerImpl
> EvictionTestLayer::CreateLayerImpl(
1419 LayerTreeImpl
* tree_impl
) {
1420 return EvictionTestLayerImpl::Create(tree_impl
, layer_id_
)
1421 .PassAs
<LayerImpl
>();
1424 void EvictionTestLayer::PushPropertiesTo(LayerImpl
* layer_impl
) {
1425 Layer::PushPropertiesTo(layer_impl
);
1427 EvictionTestLayerImpl
* test_layer_impl
=
1428 static_cast<EvictionTestLayerImpl
*>(layer_impl
);
1429 test_layer_impl
->SetHasTexture(texture_
->have_backing_texture());
1432 class LayerTreeHostTestEvictTextures
: public LayerTreeHostTest
{
1434 LayerTreeHostTestEvictTextures()
1435 : layer_(EvictionTestLayer::Create()),
1436 impl_for_evict_textures_(0),
1439 virtual void BeginTest() OVERRIDE
{
1440 layer_tree_host()->SetRootLayer(layer_
);
1441 layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1443 gfx::Transform identity_matrix
;
1444 SetLayerPropertiesForTesting(layer_
.get(),
1447 gfx::PointF(0.f
, 0.f
),
1448 gfx::PointF(0.f
, 0.f
),
1452 PostSetNeedsCommitToMainThread();
1455 void PostEvictTextures() {
1456 DCHECK(ImplThread());
1457 ImplThread()->PostTask(
1458 base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread
,
1459 base::Unretained(this)));
1462 void EvictTexturesOnImplThread() {
1463 DCHECK(impl_for_evict_textures_
);
1464 impl_for_evict_textures_
->EnforceManagedMemoryPolicy(
1465 ManagedMemoryPolicy(0));
1468 // Commit 1: Just commit and draw normally, then post an eviction at the end
1469 // that will trigger a commit.
1470 // Commit 2: Triggered by the eviction, let it go through and then set
1472 // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1473 // task, which will be handled before the commit. Don't set needsCommit, it
1474 // should have been posted. A frame should not be drawn (note,
1475 // didCommitAndDrawFrame may be called anyway).
1476 // Commit 4: Triggered by the eviction, let it go through and then set
1478 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1479 // Layout(), a frame should not be drawn but a commit will be posted.
1480 // Commit 6: Triggered by the eviction, post an eviction task in
1481 // Layout(), which will be a noop, letting the commit (which recreates the
1482 // textures) go through and draw a frame, then end the test.
1484 // Commits 1+2 test the eviction recovery path where eviction happens outside
1485 // of the beginFrame/commit pair.
1486 // Commits 3+4 test the eviction recovery path where eviction happens inside
1487 // the beginFrame/commit pair.
1488 // Commits 5+6 test the path where an eviction happens during the eviction
1490 virtual void DidCommit() OVERRIDE
{
1491 switch (num_commits_
) {
1493 EXPECT_TRUE(layer_
->HaveBackingTexture());
1494 PostEvictTextures();
1497 EXPECT_TRUE(layer_
->HaveBackingTexture());
1498 layer_tree_host()->SetNeedsCommit();
1503 EXPECT_TRUE(layer_
->HaveBackingTexture());
1504 layer_tree_host()->SetNeedsCommit();
1509 EXPECT_TRUE(layer_
->HaveBackingTexture());
1518 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1519 impl_for_evict_textures_
= impl
;
1522 virtual void Layout() OVERRIDE
{
1524 switch (num_commits_
) {
1529 PostEvictTextures();
1532 // We couldn't check in didCommitAndDrawFrame on commit 3,
1534 EXPECT_FALSE(layer_
->HaveBackingTexture());
1537 PostEvictTextures();
1540 // We couldn't check in didCommitAndDrawFrame on commit 5,
1542 EXPECT_FALSE(layer_
->HaveBackingTexture());
1543 PostEvictTextures();
1551 virtual void AfterTest() OVERRIDE
{}
1554 FakeContentLayerClient client_
;
1555 scoped_refptr
<EvictionTestLayer
> layer_
;
1556 LayerTreeHostImpl
* impl_for_evict_textures_
;
1560 MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures
);
1562 class LayerTreeHostTestContinuousCommit
: public LayerTreeHostTest
{
1564 LayerTreeHostTestContinuousCommit()
1565 : num_commit_complete_(0), num_draw_layers_(0) {}
1567 virtual void BeginTest() OVERRIDE
{
1568 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1569 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1571 PostSetNeedsCommitToMainThread();
1574 virtual void DidCommit() OVERRIDE
{
1575 if (num_draw_layers_
== 2)
1577 layer_tree_host()->root_layer()->SetNeedsDisplay();
1580 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1581 if (num_draw_layers_
== 1)
1582 num_commit_complete_
++;
1585 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1587 if (num_draw_layers_
== 2)
1591 virtual void AfterTest() OVERRIDE
{
1592 // Check that we didn't commit twice between first and second draw.
1593 EXPECT_EQ(1, num_commit_complete_
);
1597 int num_commit_complete_
;
1598 int num_draw_layers_
;
1601 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit
);
1603 class LayerTreeHostTestContinuousInvalidate
: public LayerTreeHostTest
{
1605 LayerTreeHostTestContinuousInvalidate()
1606 : num_commit_complete_(0), num_draw_layers_(0) {}
1608 virtual void BeginTest() OVERRIDE
{
1609 layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1610 layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1612 content_layer_
= ContentLayer::Create(&client_
);
1613 content_layer_
->SetBounds(gfx::Size(10, 10));
1614 content_layer_
->SetPosition(gfx::PointF(0.f
, 0.f
));
1615 content_layer_
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
1616 content_layer_
->SetIsDrawable(true);
1617 layer_tree_host()->root_layer()->AddChild(content_layer_
);
1619 PostSetNeedsCommitToMainThread();
1622 virtual void DidCommit() OVERRIDE
{
1623 if (num_draw_layers_
== 2)
1625 content_layer_
->SetNeedsDisplay();
1628 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1629 if (num_draw_layers_
== 1)
1630 num_commit_complete_
++;
1633 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
1635 if (num_draw_layers_
== 2)
1639 virtual void AfterTest() OVERRIDE
{
1640 // Check that we didn't commit twice between first and second draw.
1641 EXPECT_EQ(1, num_commit_complete_
);
1645 FakeContentLayerClient client_
;
1646 scoped_refptr
<Layer
> content_layer_
;
1647 int num_commit_complete_
;
1648 int num_draw_layers_
;
1651 MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate
);
1653 class LayerTreeHostTestDeferCommits
: public LayerTreeHostTest
{
1655 LayerTreeHostTestDeferCommits()
1656 : num_commits_deferred_(0), num_complete_commits_(0) {}
1658 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1660 virtual void DidDeferCommit() OVERRIDE
{
1661 num_commits_deferred_
++;
1662 layer_tree_host()->SetDeferCommits(false);
1665 virtual void DidCommit() OVERRIDE
{
1666 num_complete_commits_
++;
1667 switch (num_complete_commits_
) {
1669 EXPECT_EQ(0, num_commits_deferred_
);
1670 layer_tree_host()->SetDeferCommits(true);
1671 PostSetNeedsCommitToMainThread();
1682 virtual void AfterTest() OVERRIDE
{
1683 EXPECT_EQ(1, num_commits_deferred_
);
1684 EXPECT_EQ(2, num_complete_commits_
);
1688 int num_commits_deferred_
;
1689 int num_complete_commits_
;
1692 MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits
);
1694 class LayerTreeHostWithProxy
: public LayerTreeHost
{
1696 LayerTreeHostWithProxy(FakeLayerTreeHostClient
* client
,
1697 const LayerTreeSettings
& settings
,
1698 scoped_ptr
<FakeProxy
> proxy
)
1699 : LayerTreeHost(client
, settings
) {
1700 proxy
->SetLayerTreeHost(this);
1701 EXPECT_TRUE(InitializeForTesting(proxy
.PassAs
<Proxy
>()));
1705 TEST(LayerTreeHostTest
, LimitPartialUpdates
) {
1706 // When partial updates are not allowed, max updates should be 0.
1708 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1710 scoped_ptr
<FakeProxy
> proxy
=
1711 make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1712 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= false;
1713 proxy
->SetMaxPartialTextureUpdates(5);
1715 LayerTreeSettings settings
;
1716 settings
.max_partial_texture_updates
= 10;
1718 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.Pass());
1719 EXPECT_TRUE(host
.InitializeOutputSurfaceIfNeeded());
1721 EXPECT_EQ(0u, host
.settings().max_partial_texture_updates
);
1724 // When partial updates are allowed,
1725 // max updates should be limited by the proxy.
1727 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1729 scoped_ptr
<FakeProxy
> proxy
=
1730 make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1731 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= true;
1732 proxy
->SetMaxPartialTextureUpdates(5);
1734 LayerTreeSettings settings
;
1735 settings
.max_partial_texture_updates
= 10;
1737 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.Pass());
1738 EXPECT_TRUE(host
.InitializeOutputSurfaceIfNeeded());
1740 EXPECT_EQ(5u, host
.settings().max_partial_texture_updates
);
1743 // When partial updates are allowed,
1744 // max updates should also be limited by the settings.
1746 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1748 scoped_ptr
<FakeProxy
> proxy
=
1749 make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1750 proxy
->GetRendererCapabilities().allow_partial_texture_updates
= true;
1751 proxy
->SetMaxPartialTextureUpdates(20);
1753 LayerTreeSettings settings
;
1754 settings
.max_partial_texture_updates
= 10;
1756 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.Pass());
1757 EXPECT_TRUE(host
.InitializeOutputSurfaceIfNeeded());
1759 EXPECT_EQ(10u, host
.settings().max_partial_texture_updates
);
1763 TEST(LayerTreeHostTest
, PartialUpdatesWithGLRenderer
) {
1764 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_3D
);
1766 LayerTreeSettings settings
;
1767 settings
.max_partial_texture_updates
= 4;
1769 scoped_ptr
<LayerTreeHost
> host
=
1770 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1771 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1772 EXPECT_EQ(4u, host
->settings().max_partial_texture_updates
);
1775 TEST(LayerTreeHostTest
, PartialUpdatesWithSoftwareRenderer
) {
1776 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DIRECT_SOFTWARE
);
1778 LayerTreeSettings settings
;
1779 settings
.max_partial_texture_updates
= 4;
1781 scoped_ptr
<LayerTreeHost
> host
=
1782 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1783 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1784 EXPECT_EQ(4u, host
->settings().max_partial_texture_updates
);
1787 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndGLContent
) {
1788 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DELEGATED_3D
);
1790 LayerTreeSettings settings
;
1791 settings
.max_partial_texture_updates
= 4;
1793 scoped_ptr
<LayerTreeHost
> host
=
1794 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1795 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1796 EXPECT_EQ(0u, host
->settings().max_partial_texture_updates
);
1799 TEST(LayerTreeHostTest
,
1800 PartialUpdatesWithDelegatingRendererAndSoftwareContent
) {
1801 FakeLayerTreeHostClient
client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE
);
1803 LayerTreeSettings settings
;
1804 settings
.max_partial_texture_updates
= 4;
1806 scoped_ptr
<LayerTreeHost
> host
=
1807 LayerTreeHost::Create(&client
, settings
, scoped_ptr
<Thread
>());
1808 EXPECT_TRUE(host
->InitializeOutputSurfaceIfNeeded());
1809 EXPECT_EQ(0u, host
->settings().max_partial_texture_updates
);
1812 class LayerTreeHostTestCapturePicture
: public LayerTreeHostTest
{
1814 LayerTreeHostTestCapturePicture()
1815 : bounds_(gfx::Size(100, 100)),
1816 layer_(PictureLayer::Create(&content_client_
)) {}
1818 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
1819 settings
->impl_side_painting
= true;
1822 class FillRectContentLayerClient
: public ContentLayerClient
{
1824 virtual void PaintContents(SkCanvas
* canvas
,
1826 gfx::RectF
* opaque
) OVERRIDE
{
1828 paint
.setColor(SK_ColorGREEN
);
1830 SkRect rect
= SkRect::MakeWH(canvas
->getDeviceSize().width(),
1831 canvas
->getDeviceSize().height());
1832 *opaque
= gfx::RectF(rect
.width(), rect
.height());
1833 canvas
->drawRect(rect
, paint
);
1835 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
1838 virtual void BeginTest() OVERRIDE
{
1839 layer_
->SetIsDrawable(true);
1840 layer_
->SetBounds(bounds_
);
1841 // Outside viewport so tiles don't have to be initialized for commit.
1842 layer_
->SetPosition(gfx::Point(100, 100));
1843 layer_tree_host()->SetViewportSize(bounds_
);
1844 layer_tree_host()->SetRootLayer(layer_
);
1846 PostSetNeedsCommitToMainThread();
1849 virtual void DidCommitAndDrawFrame() OVERRIDE
{
1850 picture_
= layer_tree_host()->CapturePicture();
1854 virtual void AfterTest() OVERRIDE
{
1855 EXPECT_EQ(bounds_
, gfx::Size(picture_
->width(), picture_
->height()));
1859 SkBitmap::kARGB_8888_Config
, bounds_
.width(), bounds_
.height());
1860 bitmap
.allocPixels();
1861 bitmap
.eraseARGB(0, 0, 0, 0);
1862 SkCanvas
canvas(bitmap
);
1864 picture_
->draw(&canvas
);
1866 bitmap
.lockPixels();
1867 SkColor
* pixels
= reinterpret_cast<SkColor
*>(bitmap
.getPixels());
1868 EXPECT_EQ(SK_ColorGREEN
, pixels
[0]);
1869 bitmap
.unlockPixels();
1874 FillRectContentLayerClient content_client_
;
1875 scoped_refptr
<PictureLayer
> layer_
;
1876 skia::RefPtr
<SkPicture
> picture_
;
1879 MULTI_THREAD_TEST_F(LayerTreeHostTestCapturePicture
);
1881 class LayerTreeHostTestMaxPendingFrames
: public LayerTreeHostTest
{
1883 LayerTreeHostTestMaxPendingFrames() : LayerTreeHostTest() {}
1885 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
1886 if (delegating_renderer_
)
1887 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
1888 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
1891 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
1893 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1894 DCHECK(host_impl
->proxy()->HasImplThread());
1896 const ThreadProxy
* proxy
= static_cast<ThreadProxy
*>(host_impl
->proxy());
1897 if (delegating_renderer_
) {
1898 EXPECT_EQ(1, proxy
->MaxFramesPendingForTesting());
1900 EXPECT_EQ(FrameRateController::DEFAULT_MAX_FRAMES_PENDING
,
1901 proxy
->MaxFramesPendingForTesting());
1906 virtual void AfterTest() OVERRIDE
{}
1909 bool delegating_renderer_
;
1912 TEST_F(LayerTreeHostTestMaxPendingFrames
, DelegatingRenderer
) {
1913 delegating_renderer_
= true;
1917 TEST_F(LayerTreeHostTestMaxPendingFrames
, GLRenderer
) {
1918 delegating_renderer_
= false;
1922 class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
1923 : public LayerTreeHostTest
{
1925 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
1926 : root_layer_(FakeContentLayer::Create(&client_
)),
1927 child_layer1_(FakeContentLayer::Create(&client_
)),
1928 child_layer2_(FakeContentLayer::Create(&client_
)),
1931 virtual void BeginTest() OVERRIDE
{
1932 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
1933 root_layer_
->SetBounds(gfx::Size(100, 100));
1934 child_layer1_
->SetBounds(gfx::Size(100, 100));
1935 child_layer2_
->SetBounds(gfx::Size(100, 100));
1936 root_layer_
->AddChild(child_layer1_
);
1937 root_layer_
->AddChild(child_layer2_
);
1938 layer_tree_host()->SetRootLayer(root_layer_
);
1939 PostSetNeedsCommitToMainThread();
1942 virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl
* host_impl
,
1943 bool visible
) OVERRIDE
{
1944 // One backing should remain unevicted.
1945 EXPECT_EQ(100u * 100u * 4u * 1u,
1946 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1947 // Make sure that contents textures are marked as having been
1949 EXPECT_TRUE(host_impl
->active_tree()->ContentsTexturesPurged());
1950 // End the test in this state.
1954 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
1956 switch (num_commits_
) {
1958 // All three backings should have memory.
1960 100u * 100u * 4u * 3u,
1961 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1962 // Set a new policy that will kick out 1 of the 3 resources.
1963 // Because a resource was evicted, a commit will be kicked off.
1964 host_impl
->SetManagedMemoryPolicy(
1965 ManagedMemoryPolicy(100 * 100 * 4 * 2,
1966 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
,
1968 ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING
));
1971 // Only two backings should have memory.
1973 100u * 100u * 4u * 2u,
1974 layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
1975 // Become backgrounded, which will cause 1 more resource to be
1977 PostSetVisibleToMainThread(false);
1980 // No further commits should happen because this is not visible
1987 virtual void AfterTest() OVERRIDE
{}
1990 FakeContentLayerClient client_
;
1991 scoped_refptr
<FakeContentLayer
> root_layer_
;
1992 scoped_refptr
<FakeContentLayer
> child_layer1_
;
1993 scoped_refptr
<FakeContentLayer
> child_layer2_
;
1997 SINGLE_AND_MULTI_THREAD_TEST_F(
1998 LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
);
2000 class LayerTreeHostTestPinchZoomScrollbarCreation
: public LayerTreeHostTest
{
2002 LayerTreeHostTestPinchZoomScrollbarCreation()
2003 : root_layer_(ContentLayer::Create(&client_
)) {}
2005 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2006 settings
->use_pinch_zoom_scrollbars
= true;
2009 virtual void BeginTest() OVERRIDE
{
2010 root_layer_
->SetIsDrawable(true);
2011 root_layer_
->SetBounds(gfx::Size(100, 100));
2012 layer_tree_host()->SetRootLayer(root_layer_
);
2013 PostSetNeedsCommitToMainThread();
2016 virtual void DidCommit() OVERRIDE
{
2017 // We always expect two pinch-zoom scrollbar layers.
2018 ASSERT_EQ(2u, root_layer_
->children().size());
2020 // Pinch-zoom scrollbar layers always have invalid scrollLayerIds.
2021 ScrollbarLayer
* layer1
= root_layer_
->children()[0]->ToScrollbarLayer();
2022 ASSERT_TRUE(layer1
);
2023 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
2024 layer1
->scroll_layer_id());
2025 EXPECT_EQ(0.f
, layer1
->opacity());
2026 EXPECT_TRUE(layer1
->OpacityCanAnimateOnImplThread());
2027 EXPECT_TRUE(layer1
->DrawsContent());
2029 ScrollbarLayer
* layer2
= root_layer_
->children()[1]->ToScrollbarLayer();
2030 ASSERT_TRUE(layer2
);
2031 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
2032 layer2
->scroll_layer_id());
2033 EXPECT_EQ(0.f
, layer2
->opacity());
2034 EXPECT_TRUE(layer2
->OpacityCanAnimateOnImplThread());
2035 EXPECT_TRUE(layer2
->DrawsContent());
2040 virtual void AfterTest() OVERRIDE
{}
2043 FakeContentLayerClient client_
;
2044 scoped_refptr
<ContentLayer
> root_layer_
;
2047 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarCreation
);
2049 class LayerTreeHostTestPinchZoomScrollbarResize
: public LayerTreeHostTest
{
2051 LayerTreeHostTestPinchZoomScrollbarResize()
2052 : root_layer_(ContentLayer::Create(&client_
)), num_commits_(0) {}
2054 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2055 settings
->use_pinch_zoom_scrollbars
= true;
2058 virtual void BeginTest() OVERRIDE
{
2059 root_layer_
->SetIsDrawable(true);
2060 root_layer_
->SetBounds(gfx::Size(100, 100));
2061 layer_tree_host()->SetRootLayer(root_layer_
);
2062 layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2063 PostSetNeedsCommitToMainThread();
2066 virtual void DidCommit() OVERRIDE
{
2069 ScrollbarLayer
* layer1
= root_layer_
->children()[0]->ToScrollbarLayer();
2070 ASSERT_TRUE(layer1
);
2071 ScrollbarLayer
* layer2
= root_layer_
->children()[1]->ToScrollbarLayer();
2072 ASSERT_TRUE(layer2
);
2074 // Get scrollbar thickness from horizontal scrollbar's height.
2075 int thickness
= layer1
->bounds().height();
2077 if (!layer1
->Orientation() == WebKit::WebScrollbar::Horizontal
)
2078 std::swap(layer1
, layer2
);
2080 gfx::Size viewport_size
= layer_tree_host()->device_viewport_size();
2081 EXPECT_EQ(viewport_size
.width() - thickness
, layer1
->bounds().width());
2082 EXPECT_EQ(viewport_size
.height() - thickness
, layer2
->bounds().height());
2084 switch (num_commits_
) {
2086 // Resizing the viewport should also resize the pinch-zoom scrollbars.
2087 layer_tree_host()->SetViewportSize(gfx::Size(120, 150));
2094 virtual void AfterTest() OVERRIDE
{}
2097 FakeContentLayerClient client_
;
2098 scoped_refptr
<ContentLayer
> root_layer_
;
2102 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarResize
);
2104 class LayerTreeHostTestPinchZoomScrollbarNewRootLayer
2105 : public LayerTreeHostTest
{
2107 LayerTreeHostTestPinchZoomScrollbarNewRootLayer()
2108 : root_layer_(ContentLayer::Create(&client_
)), num_commits_(0) {}
2110 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2111 settings
->use_pinch_zoom_scrollbars
= true;
2114 virtual void BeginTest() OVERRIDE
{
2115 root_layer_
->SetIsDrawable(true);
2116 root_layer_
->SetBounds(gfx::Size(100, 100));
2117 layer_tree_host()->SetRootLayer(root_layer_
);
2118 PostSetNeedsCommitToMainThread();
2121 virtual void DidCommit() OVERRIDE
{
2124 // We always expect two pinch-zoom scrollbar layers.
2125 ASSERT_EQ(2u, root_layer_
->children().size());
2127 // Pinch-zoom scrollbar layers always have invalid scrollLayerIds.
2128 ScrollbarLayer
* layer1
= root_layer_
->children()[0]->ToScrollbarLayer();
2129 ASSERT_TRUE(layer1
);
2130 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
2131 layer1
->scroll_layer_id());
2132 EXPECT_EQ(0.f
, layer1
->opacity());
2133 EXPECT_TRUE(layer1
->DrawsContent());
2135 ScrollbarLayer
* layer2
= root_layer_
->children()[1]->ToScrollbarLayer();
2136 ASSERT_TRUE(layer2
);
2137 EXPECT_EQ(Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID
,
2138 layer2
->scroll_layer_id());
2139 EXPECT_EQ(0.f
, layer2
->opacity());
2140 EXPECT_TRUE(layer2
->DrawsContent());
2142 if (num_commits_
== 1) {
2143 // Create a new root layer and attach to tree to verify the pinch
2144 // zoom scrollbars get correctly re-attached.
2145 root_layer_
= ContentLayer::Create(&client_
);
2146 root_layer_
->SetIsDrawable(true);
2147 root_layer_
->SetBounds(gfx::Size(100, 100));
2148 layer_tree_host()->SetRootLayer(root_layer_
);
2149 PostSetNeedsCommitToMainThread();
2155 virtual void AfterTest() OVERRIDE
{}
2158 FakeContentLayerClient client_
;
2159 scoped_refptr
<ContentLayer
> root_layer_
;
2163 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarNewRootLayer
);
2165 class LayerTreeHostTestLCDNotification
: public LayerTreeHostTest
{
2167 class NotificationClient
: public ContentLayerClient
{
2169 NotificationClient()
2170 : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2172 void set_layer(Layer
* layer
) { layer_
= layer
; }
2173 int paint_count() const { return paint_count_
; }
2174 int lcd_notification_count() const { return lcd_notification_count_
; }
2176 virtual void PaintContents(SkCanvas
* canvas
,
2178 gfx::RectF
* opaque
) OVERRIDE
{
2181 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{
2182 ++lcd_notification_count_
;
2183 layer_
->SetNeedsDisplay();
2189 int lcd_notification_count_
;
2192 virtual void SetupTree() OVERRIDE
{
2193 scoped_refptr
<ContentLayer
> root_layer
= ContentLayer::Create(&client_
);
2194 root_layer
->SetIsDrawable(true);
2195 root_layer
->SetBounds(gfx::Size(1, 1));
2197 layer_tree_host()->SetRootLayer(root_layer
);
2198 client_
.set_layer(root_layer
.get());
2200 // The expecations are based on the assumption that the default
2201 // LCD settings are:
2202 EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text
);
2203 EXPECT_FALSE(root_layer
->can_use_lcd_text());
2205 LayerTreeHostTest::SetupTree();
2208 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2209 virtual void AfterTest() OVERRIDE
{}
2211 virtual void DidCommit() OVERRIDE
{
2212 switch (layer_tree_host()->commit_number()) {
2214 // The first update consists one LCD notification and one paint.
2215 EXPECT_EQ(1, client_
.lcd_notification_count());
2216 EXPECT_EQ(1, client_
.paint_count());
2217 // LCD text must have been enabled on the layer.
2218 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2219 PostSetNeedsCommitToMainThread();
2222 // Since nothing changed on layer, there should be no notification
2223 // or paint on the second update.
2224 EXPECT_EQ(1, client_
.lcd_notification_count());
2225 EXPECT_EQ(1, client_
.paint_count());
2226 // LCD text must not have changed.
2227 EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2228 // Change layer opacity that should trigger lcd notification.
2229 layer_tree_host()->root_layer()->SetOpacity(.5f
);
2230 // No need to request a commit - setting opacity will do it.
2233 // Verify that there is not extra commit due to layer invalidation.
2234 EXPECT_EQ(3, layer_tree_host()->commit_number());
2235 // LCD notification count should have incremented due to
2236 // change in layer opacity.
2237 EXPECT_EQ(2, client_
.lcd_notification_count());
2238 // Paint count should be incremented due to invalidation.
2239 EXPECT_EQ(2, client_
.paint_count());
2240 // LCD text must have been disabled on the layer due to opacity.
2241 EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2248 NotificationClient client_
;
2251 SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification
);
2253 // Verify that the vsync notification is used to initiate rendering.
2254 class LayerTreeHostTestVSyncNotification
: public LayerTreeHostTest
{
2256 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2257 settings
->render_vsync_notification_enabled
= true;
2260 virtual void BeginTest() OVERRIDE
{
2261 PostSetNeedsCommitToMainThread();
2264 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2265 FakeOutputSurface
* fake_output_surface
=
2266 reinterpret_cast<FakeOutputSurface
*>(host_impl
->output_surface());
2268 // The vsync notification is turned off now but will get enabled once we
2269 // return, so post a task to trigger it.
2270 ASSERT_FALSE(fake_output_surface
->vsync_notification_enabled());
2271 PostVSyncOnImplThread(fake_output_surface
);
2274 void PostVSyncOnImplThread(FakeOutputSurface
* fake_output_surface
) {
2275 DCHECK(ImplThread());
2276 ImplThread()->PostTask(
2277 base::Bind(&LayerTreeHostTestVSyncNotification::DidVSync
,
2278 base::Unretained(this),
2279 base::Unretained(fake_output_surface
)));
2282 void DidVSync(FakeOutputSurface
* fake_output_surface
) {
2283 ASSERT_TRUE(fake_output_surface
->vsync_notification_enabled());
2284 fake_output_surface
->DidVSync(frame_time_
);
2287 virtual bool PrepareToDrawOnThread(
2288 LayerTreeHostImpl
* host_impl
,
2289 LayerTreeHostImpl::FrameData
* frame
,
2290 bool result
) OVERRIDE
{
2295 virtual void AfterTest() OVERRIDE
{}
2298 base::TimeTicks frame_time_
;
2301 MULTI_THREAD_TEST_F(LayerTreeHostTestVSyncNotification
);
2303 class LayerTreeHostTestInputDrivenRendering
: public LayerTreeHostTest
{
2305 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2306 settings
->render_vsync_notification_enabled
= true;
2309 virtual void BeginTest() OVERRIDE
{
2310 frame_time_
= base::TimeTicks::Now();
2311 PostSetNeedsCommitToMainThread();
2314 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2315 // Post a task to send the final input event for the current vsync; it
2316 // should trigger rendering.
2317 ImplThread()->PostTask(
2318 base::Bind(&LayerTreeHostTestInputDrivenRendering::SendFinalInputEvent
,
2319 base::Unretained(this),
2320 base::Unretained(host_impl
)));
2323 void SendFinalInputEvent(LayerTreeHostImpl
* host_impl
) {
2324 host_impl
->DidReceiveLastInputEventForVSync(frame_time_
);
2327 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2328 EXPECT_EQ(frame_time_
, **host_impl
->fps_counter()->begin());
2332 virtual void AfterTest() OVERRIDE
{}
2335 base::TimeTicks frame_time_
;
2338 MULTI_THREAD_TEST_F(LayerTreeHostTestInputDrivenRendering
);
2340 class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2341 : public LayerTreeHostTest
{
2343 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
2344 settings
->impl_side_painting
= true;
2347 virtual void SetupTree() OVERRIDE
{
2348 LayerTreeHostTest::SetupTree();
2350 scoped_refptr
<Layer
> layer
= PictureLayer::Create(&client_
);
2351 layer
->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2352 layer
->SetBounds(gfx::Size(10, 10));
2353 layer_tree_host()->root_layer()->AddChild(layer
);
2356 virtual void BeginTest() OVERRIDE
{
2357 PostSetNeedsCommitToMainThread();
2360 virtual void TreeActivatedOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2364 virtual void AfterTest() OVERRIDE
{
2367 FakeContentLayerClient client_
;
2370 MULTI_THREAD_TEST_F(
2371 LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
);
2373 class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2374 : public LayerTreeHostTest
{
2376 class SetBoundsClient
: public ContentLayerClient
{
2378 SetBoundsClient() : layer_(0) {}
2380 void set_layer(Layer
* layer
) { layer_
= layer
; }
2382 virtual void PaintContents(SkCanvas
* canvas
,
2384 gfx::RectF
* opaque
) OVERRIDE
{
2385 layer_
->SetBounds(gfx::Size(2, 2));
2388 virtual void DidChangeLayerCanUseLCDText() OVERRIDE
{}
2394 LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2396 virtual void SetupTree() OVERRIDE
{
2397 scoped_refptr
<ContentLayer
> root_layer
= ContentLayer::Create(&client_
);
2398 root_layer
->SetIsDrawable(true);
2399 root_layer
->SetBounds(gfx::Size(1, 1));
2401 layer_tree_host()->SetRootLayer(root_layer
);
2402 client_
.set_layer(root_layer
.get());
2404 LayerTreeHostTest::SetupTree();
2407 virtual void BeginTest() OVERRIDE
{ PostSetNeedsCommitToMainThread(); }
2408 virtual void AfterTest() OVERRIDE
{}
2410 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2412 if (num_commits_
== 1) {
2413 LayerImpl
* root_layer
= host_impl
->active_tree()->root_layer();
2414 EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer
->bounds());
2416 LayerImpl
* root_layer
= host_impl
->active_tree()->root_layer();
2417 EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer
->bounds());
2423 SetBoundsClient client_
;
2427 SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents
);
2429 class MockIOSurfaceWebGraphicsContext3D
: public FakeWebGraphicsContext3D
{
2431 MockIOSurfaceWebGraphicsContext3D()
2432 : FakeWebGraphicsContext3D() {}
2434 virtual WebKit::WebGLId
createTexture() OVERRIDE
{
2438 virtual WebKit::WebString
getString(WebKit::WGC3Denum name
) OVERRIDE
{
2439 if (name
== GL_EXTENSIONS
) {
2440 return WebKit::WebString(
2441 "GL_CHROMIUM_iosurface GL_ARB_texture_rectangle");
2443 return WebKit::WebString();
2446 MOCK_METHOD1(activeTexture
, void(WebKit::WGC3Denum texture
));
2447 MOCK_METHOD2(bindTexture
, void(WebKit::WGC3Denum target
,
2448 WebKit::WebGLId texture_id
));
2449 MOCK_METHOD3(texParameteri
, void(WebKit::WGC3Denum target
,
2450 WebKit::WGC3Denum pname
,
2451 WebKit::WGC3Dint param
));
2452 MOCK_METHOD5(texImageIOSurface2DCHROMIUM
, void(WebKit::WGC3Denum target
,
2453 WebKit::WGC3Dint width
,
2454 WebKit::WGC3Dint height
,
2455 WebKit::WGC3Duint ioSurfaceId
,
2456 WebKit::WGC3Duint plane
));
2457 MOCK_METHOD4(drawElements
, void(WebKit::WGC3Denum mode
,
2458 WebKit::WGC3Dsizei count
,
2459 WebKit::WGC3Denum type
,
2460 WebKit::WGC3Dintptr offset
));
2464 class LayerTreeHostTestIOSurfaceDrawing
: public LayerTreeHostTest
{
2466 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
2467 scoped_ptr
<MockIOSurfaceWebGraphicsContext3D
> context(
2468 new MockIOSurfaceWebGraphicsContext3D
);
2469 mock_context_
= context
.get();
2470 scoped_ptr
<OutputSurface
> output_surface
= FakeOutputSurface::Create3d(
2471 context
.PassAs
<WebKit::WebGraphicsContext3D
>()).PassAs
<OutputSurface
>();
2472 return output_surface
.Pass();
2475 virtual void SetupTree() OVERRIDE
{
2476 LayerTreeHostTest::SetupTree();
2478 layer_tree_host()->root_layer()->SetIsDrawable(false);
2481 io_surface_size_
= gfx::Size(6, 7);
2483 scoped_refptr
<IOSurfaceLayer
> io_surface_layer
= IOSurfaceLayer::Create();
2484 io_surface_layer
->SetBounds(gfx::Size(10, 10));
2485 io_surface_layer
->SetAnchorPoint(gfx::PointF());
2486 io_surface_layer
->SetIsDrawable(true);
2487 io_surface_layer
->SetIOSurfaceProperties(io_surface_id_
, io_surface_size_
);
2488 layer_tree_host()->root_layer()->AddChild(io_surface_layer
);
2491 virtual void BeginTest() OVERRIDE
{
2492 PostSetNeedsCommitToMainThread();
2495 virtual void TreeActivatedOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2496 // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2498 EXPECT_CALL(*mock_context_
, activeTexture(_
))
2500 EXPECT_CALL(*mock_context_
, bindTexture(GL_TEXTURE_RECTANGLE_ARB
, 1))
2502 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2503 GL_TEXTURE_MIN_FILTER
,
2506 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2507 GL_TEXTURE_MAG_FILTER
,
2510 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2514 EXPECT_CALL(*mock_context_
, texParameteri(GL_TEXTURE_RECTANGLE_ARB
,
2519 EXPECT_CALL(*mock_context_
, texImageIOSurface2DCHROMIUM(
2520 GL_TEXTURE_RECTANGLE_ARB
,
2521 io_surface_size_
.width(),
2522 io_surface_size_
.height(),
2527 EXPECT_CALL(*mock_context_
, bindTexture(_
, 0))
2528 .Times(AnyNumber());
2531 virtual bool PrepareToDrawOnThread(
2532 LayerTreeHostImpl
* host_impl
,
2533 LayerTreeHostImpl::FrameData
* frame
,
2534 bool result
) OVERRIDE
{
2535 Mock::VerifyAndClearExpectations(&mock_context_
);
2537 // The io surface layer's texture is drawn.
2538 EXPECT_CALL(*mock_context_
, activeTexture(GL_TEXTURE0
))
2540 EXPECT_CALL(*mock_context_
, bindTexture(GL_TEXTURE_RECTANGLE_ARB
, 1))
2542 EXPECT_CALL(*mock_context_
, drawElements(GL_TRIANGLES
, 6, _
, _
))
2548 virtual void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
2549 Mock::VerifyAndClearExpectations(&mock_context_
);
2553 virtual void AfterTest() OVERRIDE
{}
2556 MockIOSurfaceWebGraphicsContext3D
* mock_context_
;
2557 gfx::Size io_surface_size_
;
2560 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing
);
2562 class LayerTreeHostTestAsyncReadback
: public LayerTreeHostTest
{
2564 virtual void SetupTree() OVERRIDE
{
2565 root
= FakeContentLayer::Create(&client_
);
2566 root
->SetBounds(gfx::Size(20, 20));
2568 child
= FakeContentLayer::Create(&client_
);
2569 child
->SetBounds(gfx::Size(10, 10));
2570 root
->AddChild(child
);
2572 layer_tree_host()->SetRootLayer(root
);
2573 LayerTreeHostTest::SetupTree();
2576 virtual void BeginTest() OVERRIDE
{
2577 PostSetNeedsCommitToMainThread();
2580 virtual void DidCommitAndDrawFrame() OVERRIDE
{
2584 void WaitForCallback() {
2585 base::MessageLoop::current()->PostTask(
2588 &LayerTreeHostTestAsyncReadback::NextStep
,
2589 base::Unretained(this)));
2593 int frame
= layer_tree_host()->commit_number();
2596 child
->RequestCopyAsBitmap(base::Bind(
2597 &LayerTreeHostTestAsyncReadback::BitmapCallback
,
2598 base::Unretained(this)));
2599 EXPECT_EQ(0u, callbacks_
.size());
2602 if (callbacks_
.size() < 1u) {
2606 EXPECT_EQ(1u, callbacks_
.size());
2607 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[0].ToString());
2609 child
->RequestCopyAsBitmap(base::Bind(
2610 &LayerTreeHostTestAsyncReadback::BitmapCallback
,
2611 base::Unretained(this)));
2612 root
->RequestCopyAsBitmap(base::Bind(
2613 &LayerTreeHostTestAsyncReadback::BitmapCallback
,
2614 base::Unretained(this)));
2615 child
->RequestCopyAsBitmap(base::Bind(
2616 &LayerTreeHostTestAsyncReadback::BitmapCallback
,
2617 base::Unretained(this)));
2618 EXPECT_EQ(1u, callbacks_
.size());
2621 if (callbacks_
.size() < 4u) {
2625 EXPECT_EQ(4u, callbacks_
.size());
2626 // The child was copied to a bitmap and passed back twice.
2627 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[1].ToString());
2628 EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_
[2].ToString());
2629 // The root was copied to a bitmap and passed back also.
2630 EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_
[3].ToString());
2636 void BitmapCallback(scoped_ptr
<SkBitmap
> bitmap
) {
2637 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2638 EXPECT_TRUE(bitmap
);
2639 callbacks_
.push_back(gfx::Size(bitmap
->width(), bitmap
->height()));
2642 virtual void AfterTest() OVERRIDE
{
2643 EXPECT_EQ(4u, callbacks_
.size());
2646 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
2647 if (use_gl_renderer_
)
2648 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
2649 return FakeOutputSurface::CreateSoftware(
2650 make_scoped_ptr(new SoftwareOutputDevice
)).PassAs
<OutputSurface
>();
2653 bool use_gl_renderer_
;
2654 std::vector
<gfx::Size
> callbacks_
;
2655 FakeContentLayerClient client_
;
2656 scoped_refptr
<FakeContentLayer
> root
;
2657 scoped_refptr
<FakeContentLayer
> child
;
2660 TEST_F(LayerTreeHostTestAsyncReadback
, GLRenderer_RunSingleThread
) {
2661 use_gl_renderer_
= true;
2665 TEST_F(LayerTreeHostTestAsyncReadback
, GLRenderer_RunMultiThread
) {
2666 use_gl_renderer_
= true;
2670 TEST_F(LayerTreeHostTestAsyncReadback
, SoftwareRenderer_RunSingleThread
) {
2671 use_gl_renderer_
= false;
2675 TEST_F(LayerTreeHostTestAsyncReadback
, SoftwareRenderer_RunMultiThread
) {
2676 use_gl_renderer_
= false;
2680 class LayerTreeHostTestAsyncReadbackLayerDestroyed
: public LayerTreeHostTest
{
2682 virtual void SetupTree() OVERRIDE
{
2683 root_
= FakeContentLayer::Create(&client_
);
2684 root_
->SetBounds(gfx::Size(20, 20));
2686 main_destroyed_
= FakeContentLayer::Create(&client_
);
2687 main_destroyed_
->SetBounds(gfx::Size(15, 15));
2688 root_
->AddChild(main_destroyed_
);
2690 impl_destroyed_
= FakeContentLayer::Create(&client_
);
2691 impl_destroyed_
->SetBounds(gfx::Size(10, 10));
2692 root_
->AddChild(impl_destroyed_
);
2694 layer_tree_host()->SetRootLayer(root_
);
2695 LayerTreeHostTest::SetupTree();
2698 virtual void BeginTest() OVERRIDE
{
2699 callback_count_
= 0;
2700 PostSetNeedsCommitToMainThread();
2703 virtual void DidCommit() OVERRIDE
{
2704 int frame
= layer_tree_host()->commit_number();
2707 main_destroyed_
->RequestCopyAsBitmap(base::Bind(
2708 &LayerTreeHostTestAsyncReadbackLayerDestroyed::BitmapCallback
,
2709 base::Unretained(this)));
2710 impl_destroyed_
->RequestCopyAsBitmap(base::Bind(
2711 &LayerTreeHostTestAsyncReadbackLayerDestroyed::BitmapCallback
,
2712 base::Unretained(this)));
2713 EXPECT_EQ(0, callback_count_
);
2715 // Destroy the main thread layer right away.
2716 main_destroyed_
->RemoveFromParent();
2717 main_destroyed_
= NULL
;
2719 // Should callback with a NULL bitmap.
2720 EXPECT_EQ(1, callback_count_
);
2722 // Prevent drawing so we can't make a copy of the impl_destroyed layer.
2723 layer_tree_host()->SetViewportSize(gfx::Size());
2726 // Flush the message loops and make sure the callbacks run.
2727 layer_tree_host()->SetNeedsCommit();
2730 // No drawing means no readback yet.
2731 EXPECT_EQ(1, callback_count_
);
2733 // Destroy the impl thread layer.
2734 impl_destroyed_
->RemoveFromParent();
2735 impl_destroyed_
= NULL
;
2737 // No callback yet because it's on the impl side.
2738 EXPECT_EQ(1, callback_count_
);
2741 // Flush the message loops and make sure the callbacks run.
2742 layer_tree_host()->SetNeedsCommit();
2745 // We should get another callback with a NULL bitmap.
2746 EXPECT_EQ(2, callback_count_
);
2752 void BitmapCallback(scoped_ptr
<SkBitmap
> bitmap
) {
2753 EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2754 EXPECT_FALSE(bitmap
);
2758 virtual void AfterTest() OVERRIDE
{}
2760 int callback_count_
;
2761 FakeContentLayerClient client_
;
2762 scoped_refptr
<FakeContentLayer
> root_
;
2763 scoped_refptr
<FakeContentLayer
> main_destroyed_
;
2764 scoped_refptr
<FakeContentLayer
> impl_destroyed_
;
2767 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed
);