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/layer_tree_host.h"
7 #include "base/synchronization/lock.h"
8 #include "cc/content_layer.h"
9 #include "cc/content_layer_client.h"
10 #include "cc/frame_rate_controller.h"
11 #include "cc/layer_impl.h"
12 #include "cc/layer_tree_host_impl.h"
13 #include "cc/layer_tree_impl.h"
14 #include "cc/output_surface.h"
15 #include "cc/picture_layer.h"
16 #include "cc/prioritized_resource.h"
17 #include "cc/resource_update_queue.h"
18 #include "cc/single_thread_proxy.h"
19 #include "cc/test/fake_content_layer.h"
20 #include "cc/test/fake_content_layer_client.h"
21 #include "cc/test/fake_layer_tree_host_client.h"
22 #include "cc/test/fake_output_surface.h"
23 #include "cc/test/fake_proxy.h"
24 #include "cc/test/fake_scrollbar_layer.h"
25 #include "cc/test/geometry_test_utils.h"
26 #include "cc/test/layer_tree_test_common.h"
27 #include "cc/test/occlusion_tracker_test_common.h"
28 #include "cc/thread_proxy.h"
29 #include "cc/timing_function.h"
30 #include "skia/ext/refptr.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
33 #include "third_party/khronos/GLES2/gl2.h"
34 #include "third_party/khronos/GLES2/gl2ext.h"
35 #include "third_party/skia/include/core/SkPicture.h"
36 #include "ui/gfx/point_conversions.h"
37 #include "ui/gfx/size_conversions.h"
38 #include "ui/gfx/vector2d_conversions.h"
43 class LayerTreeHostTest
: public ThreadedTest
{ };
45 // Shortlived layerTreeHosts shouldn't die.
46 class LayerTreeHostTestShortlived1
: public LayerTreeHostTest
{
48 LayerTreeHostTestShortlived1() { }
50 virtual void beginTest() OVERRIDE
52 // Kill the layerTreeHost immediately.
53 m_layerTreeHost
->setRootLayer(0);
54 m_layerTreeHost
.reset();
59 virtual void afterTest() OVERRIDE
64 // Shortlived layerTreeHosts shouldn't die with a commit in flight.
65 class LayerTreeHostTestShortlived2
: public LayerTreeHostTest
{
67 LayerTreeHostTestShortlived2() { }
69 virtual void beginTest() OVERRIDE
71 postSetNeedsCommitToMainThread();
73 // Kill the layerTreeHost immediately.
74 m_layerTreeHost
->setRootLayer(0);
75 m_layerTreeHost
.reset();
80 virtual void afterTest() OVERRIDE
85 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestShortlived2
)
87 // Shortlived layerTreeHosts shouldn't die with a redraw in flight.
88 class LayerTreeHostTestShortlived3
: public LayerTreeHostTest
{
90 LayerTreeHostTestShortlived3() { }
92 virtual void beginTest() OVERRIDE
94 postSetNeedsRedrawToMainThread();
96 // Kill the layerTreeHost immediately.
97 m_layerTreeHost
->setRootLayer(0);
98 m_layerTreeHost
.reset();
103 virtual void afterTest() OVERRIDE
108 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestShortlived3
)
110 // Test interleaving of redraws and commits
111 class LayerTreeHostTestCommitingWithContinuousRedraw
: public LayerTreeHostTest
{
113 LayerTreeHostTestCommitingWithContinuousRedraw()
114 : m_numCompleteCommits(0)
119 virtual void beginTest() OVERRIDE
121 postSetNeedsCommitToMainThread();
124 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
126 m_numCompleteCommits
++;
127 if (m_numCompleteCommits
== 2)
131 virtual void drawLayersOnThread(LayerTreeHostImpl
*) OVERRIDE
134 postSetNeedsCommitToMainThread();
136 postSetNeedsRedrawToMainThread();
139 virtual void afterTest() OVERRIDE
144 int m_numCompleteCommits
;
148 TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw
, runMultiThread
)
153 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
154 // draw with frame 0.
155 class LayerTreeHostTestSetNeedsCommit1
: public LayerTreeHostTest
{
157 LayerTreeHostTestSetNeedsCommit1()
163 virtual void beginTest() OVERRIDE
165 postSetNeedsCommitToMainThread();
166 postSetNeedsCommitToMainThread();
169 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
172 if (!impl
->activeTree()->source_frame_number())
176 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
181 virtual void afterTest() OVERRIDE
183 EXPECT_GE(1, m_numCommits
);
184 EXPECT_GE(1, m_numDraws
);
192 TEST_F(LayerTreeHostTestSetNeedsCommit1
, DISABLED_runMultiThread
)
197 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
198 // first committed frame draws should lead to another commit.
199 class LayerTreeHostTestSetNeedsCommit2
: public LayerTreeHostTest
{
201 LayerTreeHostTestSetNeedsCommit2()
207 virtual void beginTest() OVERRIDE
209 postSetNeedsCommitToMainThread();
212 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
214 if (impl
->activeTree()->source_frame_number() == 0)
215 postSetNeedsCommitToMainThread();
216 else if (impl
->activeTree()->source_frame_number() == 1)
220 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
225 virtual void afterTest() OVERRIDE
227 EXPECT_EQ(2, m_numCommits
);
228 EXPECT_GE(2, m_numDraws
);
236 TEST_F(LayerTreeHostTestSetNeedsCommit2
, runMultiThread
)
241 // 1 setNeedsRedraw after the first commit has completed should lead to 1
243 class LayerTreeHostTestSetNeedsRedraw
: public LayerTreeHostTest
{
245 LayerTreeHostTestSetNeedsRedraw()
251 virtual void beginTest() OVERRIDE
253 postSetNeedsCommitToMainThread();
256 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
258 EXPECT_EQ(0, impl
->activeTree()->source_frame_number());
260 postSetNeedsRedrawToMainThread(); // Redraw again to verify that the second redraw doesn't commit.
266 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
268 EXPECT_EQ(0, m_numDraws
);
272 virtual void afterTest() OVERRIDE
274 EXPECT_GE(2, m_numDraws
);
275 EXPECT_EQ(1, m_numCommits
);
283 TEST_F(LayerTreeHostTestSetNeedsRedraw
, runMultiThread
)
288 class LayerTreeHostTestNoExtraCommitFromInvalidate
: public LayerTreeHostTest
{
290 LayerTreeHostTestNoExtraCommitFromInvalidate()
291 : m_rootLayer(ContentLayer::create(&m_client
))
295 virtual void beginTest() OVERRIDE
297 m_rootLayer
->setAutomaticallyComputeRasterScale(false);
298 m_rootLayer
->setIsDrawable(true);
299 m_rootLayer
->setBounds(gfx::Size(1, 1));
300 m_layerTreeHost
->setRootLayer(m_rootLayer
);
301 postSetNeedsCommitToMainThread();
304 virtual void didCommit() OVERRIDE
306 switch (m_layerTreeHost
->commitNumber()) {
308 // Changing the content bounds will cause a single commit!
309 m_rootLayer
->setRasterScale(4.0f
);
313 EXPECT_EQ(2, m_layerTreeHost
->commitNumber());
318 virtual void afterTest() OVERRIDE
323 FakeContentLayerClient m_client
;
324 scoped_refptr
<ContentLayer
> m_rootLayer
;
327 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate
)
329 class LayerTreeHostTestCompositeAndReadback
: public LayerTreeHostTest
{
331 LayerTreeHostTestCompositeAndReadback()
336 virtual void beginTest() OVERRIDE
338 postSetNeedsCommitToMainThread();
341 virtual void didCommit() OVERRIDE
344 if (m_numCommits
== 1) {
346 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
347 } else if (m_numCommits
== 2) {
348 // This is inside the readback. We should get another commit after it.
349 } else if (m_numCommits
== 3) {
356 virtual void afterTest() OVERRIDE
364 TEST_F(LayerTreeHostTestCompositeAndReadback
, runMultiThread
)
369 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
: public LayerTreeHostTest
{
371 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
376 virtual void beginTest() OVERRIDE
378 postSetNeedsCommitToMainThread();
381 virtual void didCommit() OVERRIDE
384 if (m_numCommits
== 1) {
385 m_layerTreeHost
->setNeedsCommit();
386 } else if (m_numCommits
== 2) {
388 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
389 } else if (m_numCommits
== 3) {
390 // This is inside the readback. We should get another commit after it.
391 } else if (m_numCommits
== 4) {
398 virtual void afterTest() OVERRIDE
406 TEST_F(LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
, runMultiThread
)
411 // If the layerTreeHost says it can't draw, then we should not try to draw.
412 class LayerTreeHostTestCanDrawBlocksDrawing
: public LayerTreeHostTest
{
414 LayerTreeHostTestCanDrawBlocksDrawing()
420 virtual void beginTest() OVERRIDE
422 postSetNeedsCommitToMainThread();
425 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
429 // Only the initial draw should bring us here.
430 EXPECT_TRUE(impl
->canDraw());
431 EXPECT_EQ(0, impl
->activeTree()->source_frame_number());
434 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
438 if (m_numCommits
>= 1) {
439 // After the first commit, we should not be able to draw.
440 EXPECT_FALSE(impl
->canDraw());
444 virtual void didCommit() OVERRIDE
447 if (m_numCommits
== 1) {
448 // Make the viewport empty so the host says it can't draw.
449 m_layerTreeHost
->setViewportSize(gfx::Size(0, 0), gfx::Size(0, 0));
450 } else if (m_numCommits
== 2) {
452 m_layerTreeHost
->compositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
453 } else if (m_numCommits
== 3) {
454 // Let it draw so we go idle and end the test.
455 m_layerTreeHost
->setViewportSize(gfx::Size(1, 1), gfx::Size(1, 1));
461 virtual void afterTest() OVERRIDE
470 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing
)
472 // beginLayerWrite should prevent draws from executing until a commit occurs
473 class LayerTreeHostTestWriteLayersRedraw
: public LayerTreeHostTest
{
475 LayerTreeHostTestWriteLayersRedraw()
481 virtual void beginTest() OVERRIDE
483 postAcquireLayerTextures();
484 postSetNeedsRedrawToMainThread(); // should be inhibited without blocking
485 postSetNeedsCommitToMainThread();
488 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
491 EXPECT_EQ(m_numDraws
, m_numCommits
);
494 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
500 virtual void afterTest() OVERRIDE
502 EXPECT_EQ(1, m_numCommits
);
510 TEST_F(LayerTreeHostTestWriteLayersRedraw
, runMultiThread
)
515 // Verify that when resuming visibility, requesting layer write permission
516 // will not deadlock the main thread even though there are not yet any
517 // scheduled redraws. This behavior is critical for reliably surviving tab
518 // switching. There are no failure conditions to this test, it just passes
519 // by not timing out.
520 class LayerTreeHostTestWriteLayersAfterVisible
: public LayerTreeHostTest
{
522 LayerTreeHostTestWriteLayersAfterVisible()
527 virtual void beginTest() OVERRIDE
529 postSetNeedsCommitToMainThread();
532 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
535 if (m_numCommits
== 2)
537 else if (m_numCommits
< 2) {
538 postSetVisibleToMainThread(false);
539 postSetVisibleToMainThread(true);
540 postAcquireLayerTextures();
541 postSetNeedsCommitToMainThread();
545 virtual void afterTest() OVERRIDE
553 TEST_F(LayerTreeHostTestWriteLayersAfterVisible
, runMultiThread
)
558 // A compositeAndReadback while invisible should force a normal commit without assertion.
559 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
: public LayerTreeHostTest
{
561 LayerTreeHostTestCompositeAndReadbackWhileInvisible()
566 virtual void beginTest() OVERRIDE
568 postSetNeedsCommitToMainThread();
571 virtual void didCommitAndDrawFrame() OVERRIDE
574 if (m_numCommits
== 1) {
575 m_layerTreeHost
->setVisible(false);
576 m_layerTreeHost
->setNeedsCommit();
577 m_layerTreeHost
->setNeedsCommit();
579 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
585 virtual void afterTest() OVERRIDE
593 TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible
, runMultiThread
)
598 class LayerTreeHostTestAbortFrameWhenInvisible
: public LayerTreeHostTest
{
600 LayerTreeHostTestAbortFrameWhenInvisible()
604 virtual void beginTest() OVERRIDE
606 // Request a commit (from the main thread), which will trigger the commit flow from the impl side.
607 m_layerTreeHost
->setNeedsCommit();
608 // Then mark ourselves as not visible before processing any more messages on the main thread.
609 m_layerTreeHost
->setVisible(false);
610 // If we make it without kicking a frame, we pass!
611 endTestAfterDelay(1);
614 virtual void layout() OVERRIDE
620 virtual void afterTest() OVERRIDE
627 TEST_F(LayerTreeHostTestAbortFrameWhenInvisible
, runMultiThread
)
632 // This test verifies that properties on the layer tree host are commited to the impl side.
633 class LayerTreeHostTestCommit
: public LayerTreeHostTest
{
636 LayerTreeHostTestCommit() { }
638 virtual void beginTest() OVERRIDE
640 m_layerTreeHost
->setViewportSize(gfx::Size(20, 20), gfx::Size(20, 20));
641 m_layerTreeHost
->setBackgroundColor(SK_ColorGRAY
);
642 m_layerTreeHost
->setPageScaleFactorAndLimits(5, 5, 5);
644 postSetNeedsCommitToMainThread();
647 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
649 EXPECT_EQ(gfx::Size(20, 20), impl
->layoutViewportSize());
650 EXPECT_EQ(SK_ColorGRAY
, impl
->activeTree()->background_color());
651 EXPECT_EQ(5, impl
->activeTree()->page_scale_factor());
656 virtual void afterTest() OVERRIDE
{ }
659 TEST_F(LayerTreeHostTestCommit
, runTest
)
664 // Verifies that startPageScaleAnimation events propagate correctly from LayerTreeHost to
665 // LayerTreeHostImpl in the MT compositor.
666 class LayerTreeHostTestStartPageScaleAnimation
: public LayerTreeHostTest
{
669 LayerTreeHostTestStartPageScaleAnimation()
670 : m_animationRequested(false)
674 virtual void beginTest() OVERRIDE
676 m_layerTreeHost
->rootLayer()->setScrollable(true);
677 m_layerTreeHost
->rootLayer()->setScrollOffset(gfx::Vector2d());
678 postSetNeedsCommitToMainThread();
679 postSetNeedsRedrawToMainThread();
682 void requestStartPageScaleAnimation()
684 layerTreeHost()->startPageScaleAnimation(gfx::Vector2d(), false, 1.25, base::TimeDelta());
687 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
689 impl
->rootLayer()->setScrollable(true);
690 impl
->rootLayer()->setScrollOffset(gfx::Vector2d());
691 impl
->activeTree()->SetPageScaleFactorAndLimits(impl
->activeTree()->page_scale_factor(), 0.5, 2);
693 // We request animation only once.
694 if (!m_animationRequested
) {
695 impl
->proxy()->mainThread()->postTask(base::Bind(&LayerTreeHostTestStartPageScaleAnimation::requestStartPageScaleAnimation
, base::Unretained(this)));
696 m_animationRequested
= true;
700 virtual void applyScrollAndScale(gfx::Vector2d scrollDelta
, float scale
) OVERRIDE
702 gfx::Vector2d offset
= m_layerTreeHost
->rootLayer()->scrollOffset();
703 m_layerTreeHost
->rootLayer()->setScrollOffset(offset
+ scrollDelta
);
704 m_layerTreeHost
->setPageScaleFactorAndLimits(scale
, 0.5, 2);
707 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
709 impl
->processScrollDeltas();
710 // We get one commit before the first draw, and the animation doesn't happen until the second draw.
711 if (impl
->activeTree()->source_frame_number() == 1) {
712 EXPECT_EQ(1.25, impl
->activeTree()->page_scale_factor());
715 postSetNeedsRedrawToMainThread();
718 virtual void afterTest() OVERRIDE
723 bool m_animationRequested
;
726 // TODO(aelias): This test is currently broken: http://crbug.com/178295
727 TEST_F(LayerTreeHostTestStartPageScaleAnimation
, DISABLED_runTest
)
732 class LayerTreeHostTestSetVisible
: public LayerTreeHostTest
{
735 LayerTreeHostTestSetVisible()
740 virtual void beginTest() OVERRIDE
742 postSetNeedsCommitToMainThread();
743 postSetVisibleToMainThread(false);
744 postSetNeedsRedrawToMainThread(); // This is suppressed while we're invisible.
745 postSetVisibleToMainThread(true); // Triggers the redraw.
748 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
750 EXPECT_TRUE(impl
->visible());
755 virtual void afterTest() OVERRIDE
757 EXPECT_EQ(1, m_numDraws
);
764 TEST_F(LayerTreeHostTestSetVisible
, runMultiThread
)
769 class TestOpacityChangeLayerDelegate
: public ContentLayerClient
{
771 TestOpacityChangeLayerDelegate()
776 void setTestLayer(Layer
* testLayer
)
778 m_testLayer
= testLayer
;
781 virtual void paintContents(SkCanvas
*, const gfx::Rect
&, gfx::RectF
&) OVERRIDE
783 // Set layer opacity to 0.
785 m_testLayer
->setOpacity(0);
792 class ContentLayerWithUpdateTracking
: public ContentLayer
{
794 static scoped_refptr
<ContentLayerWithUpdateTracking
> create(ContentLayerClient
* client
) { return make_scoped_refptr(new ContentLayerWithUpdateTracking(client
)); }
796 int paintContentsCount() { return m_paintContentsCount
; }
797 void resetPaintContentsCount() { m_paintContentsCount
= 0; }
799 virtual void update(ResourceUpdateQueue
& queue
, const OcclusionTracker
* occlusion
, RenderingStats
* stats
) OVERRIDE
801 ContentLayer::update(queue
, occlusion
, stats
);
802 m_paintContentsCount
++;
806 explicit ContentLayerWithUpdateTracking(ContentLayerClient
* client
)
807 : ContentLayer(client
)
808 , m_paintContentsCount(0)
810 setAnchorPoint(gfx::PointF(0, 0));
811 setBounds(gfx::Size(10, 10));
814 virtual ~ContentLayerWithUpdateTracking()
818 int m_paintContentsCount
;
821 // Layer opacity change during paint should not prevent compositor resources from being updated during commit.
822 class LayerTreeHostTestOpacityChange
: public LayerTreeHostTest
{
824 LayerTreeHostTestOpacityChange()
825 : m_testOpacityChangeDelegate()
826 , m_updateCheckLayer(ContentLayerWithUpdateTracking::create(&m_testOpacityChangeDelegate
))
828 m_testOpacityChangeDelegate
.setTestLayer(m_updateCheckLayer
.get());
831 virtual void beginTest() OVERRIDE
833 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
834 m_layerTreeHost
->rootLayer()->addChild(m_updateCheckLayer
);
836 postSetNeedsCommitToMainThread();
839 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
844 virtual void afterTest() OVERRIDE
846 // update() should have been called once.
847 EXPECT_EQ(1, m_updateCheckLayer
->paintContentsCount());
849 // clear m_updateCheckLayer so LayerTreeHost dies.
850 m_updateCheckLayer
= NULL
;
854 TestOpacityChangeLayerDelegate m_testOpacityChangeDelegate
;
855 scoped_refptr
<ContentLayerWithUpdateTracking
> m_updateCheckLayer
;
858 TEST_F(LayerTreeHostTestOpacityChange
, runMultiThread
)
863 class NoScaleContentLayer
: public ContentLayer
{
865 static scoped_refptr
<NoScaleContentLayer
> create(ContentLayerClient
* client
) { return make_scoped_refptr(new NoScaleContentLayer(client
)); }
867 virtual void calculateContentsScale(
868 float idealContentsScale
,
869 bool animatingTransformToScreen
,
870 float* contentsScaleX
,
871 float* contentsScaleY
,
872 gfx::Size
* contentBounds
) OVERRIDE
874 // Skip over the ContentLayer's method to the base Layer class.
875 Layer::calculateContentsScale(
877 animatingTransformToScreen
,
884 explicit NoScaleContentLayer(ContentLayerClient
* client
)
885 : ContentLayer(client
) { }
886 virtual ~NoScaleContentLayer() { }
889 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
: public LayerTreeHostTest
{
892 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
893 : m_rootLayer(NoScaleContentLayer::create(&m_client
))
894 , m_childLayer(ContentLayer::create(&m_client
))
898 virtual void beginTest() OVERRIDE
900 m_layerTreeHost
->setViewportSize(gfx::Size(40, 40), gfx::Size(60, 60));
901 m_layerTreeHost
->setDeviceScaleFactor(1.5);
902 EXPECT_EQ(gfx::Size(40, 40), m_layerTreeHost
->layoutViewportSize());
903 EXPECT_EQ(gfx::Size(60, 60), m_layerTreeHost
->deviceViewportSize());
905 m_rootLayer
->addChild(m_childLayer
);
907 m_rootLayer
->setIsDrawable(true);
908 m_rootLayer
->setBounds(gfx::Size(30, 30));
909 m_rootLayer
->setAnchorPoint(gfx::PointF(0, 0));
911 m_childLayer
->setIsDrawable(true);
912 m_childLayer
->setPosition(gfx::Point(2, 2));
913 m_childLayer
->setBounds(gfx::Size(10, 10));
914 m_childLayer
->setAnchorPoint(gfx::PointF(0, 0));
916 m_layerTreeHost
->setRootLayer(m_rootLayer
);
918 ASSERT_TRUE(m_layerTreeHost
->initializeRendererIfNeeded());
919 ResourceUpdateQueue queue
;
920 m_layerTreeHost
->updateLayers(queue
, std::numeric_limits
<size_t>::max());
921 postSetNeedsCommitToMainThread();
924 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
926 // Get access to protected methods.
927 MockLayerTreeHostImpl
* mockImpl
= static_cast<MockLayerTreeHostImpl
*>(impl
);
929 // Should only do one commit.
930 EXPECT_EQ(0, impl
->activeTree()->source_frame_number());
931 // Device scale factor should come over to impl.
932 EXPECT_NEAR(impl
->deviceScaleFactor(), 1.5, 0.00001);
934 // Both layers are on impl.
935 ASSERT_EQ(1u, impl
->rootLayer()->children().size());
937 // Device viewport is scaled.
938 EXPECT_EQ(gfx::Size(40, 40), impl
->layoutViewportSize());
939 EXPECT_EQ(gfx::Size(60, 60), impl
->deviceViewportSize());
941 LayerImpl
* root
= impl
->rootLayer();
942 LayerImpl
* child
= impl
->rootLayer()->children()[0];
944 // Positions remain in layout pixels.
945 EXPECT_EQ(gfx::Point(0, 0), root
->position());
946 EXPECT_EQ(gfx::Point(2, 2), child
->position());
948 // Compute all the layer transforms for the frame.
949 LayerTreeHostImpl::FrameData frameData
;
950 mockImpl
->prepareToDraw(frameData
);
951 mockImpl
->didDrawAllLayers(frameData
);
953 const MockLayerTreeHostImpl::LayerList
& renderSurfaceLayerList
=
954 *frameData
.renderSurfaceLayerList
;
956 // Both layers should be drawing into the root render surface.
957 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
958 ASSERT_EQ(root
->renderSurface(), renderSurfaceLayerList
[0]->renderSurface());
959 ASSERT_EQ(2u, root
->renderSurface()->layerList().size());
961 // The root render surface is the size of the viewport.
962 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60), root
->renderSurface()->contentRect());
964 // The content bounds of the child should be scaled.
965 gfx::Size childBoundsScaled
= gfx::ToCeiledSize(gfx::ScaleSize(child
->bounds(), 1.5));
966 EXPECT_EQ(childBoundsScaled
, child
->contentBounds());
968 gfx::Transform scaleTransform
;
969 scaleTransform
.Scale(impl
->deviceScaleFactor(), impl
->deviceScaleFactor());
971 // The root layer is scaled by 2x.
972 gfx::Transform rootScreenSpaceTransform
= scaleTransform
;
973 gfx::Transform rootDrawTransform
= scaleTransform
;
975 EXPECT_EQ(rootDrawTransform
, root
->drawTransform());
976 EXPECT_EQ(rootScreenSpaceTransform
, root
->screenSpaceTransform());
978 // The child is at position 2,2, which is transformed to 3,3 after the scale
979 gfx::Transform childScreenSpaceTransform
;
980 childScreenSpaceTransform
.Translate(3, 3);
981 gfx::Transform childDrawTransform
= childScreenSpaceTransform
;
983 EXPECT_TRANSFORMATION_MATRIX_EQ(childDrawTransform
, child
->drawTransform());
984 EXPECT_TRANSFORMATION_MATRIX_EQ(childScreenSpaceTransform
, child
->screenSpaceTransform());
989 virtual void afterTest() OVERRIDE
996 FakeContentLayerClient m_client
;
997 scoped_refptr
<NoScaleContentLayer
> m_rootLayer
;
998 scoped_refptr
<ContentLayer
> m_childLayer
;
1001 TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
, runMultiThread
)
1006 // Verify atomicity of commits and reuse of textures.
1007 class LayerTreeHostTestAtomicCommit
: public LayerTreeHostTest
{
1009 LayerTreeHostTestAtomicCommit()
1011 // Make sure partial texture updates are turned off.
1012 m_settings
.maxPartialTextureUpdates
= 0;
1013 // Linear fade animator prevents scrollbars from drawing immediately.
1014 m_settings
.useLinearFadeScrollbarAnimator
= false;
1017 virtual void setupTree() OVERRIDE
1019 m_layer
= FakeContentLayer::Create(&m_client
);
1020 m_layer
->setBounds(gfx::Size(10, 20));
1022 bool paint_scrollbar
= true;
1023 bool has_thumb
= false;
1024 m_scrollbar
= FakeScrollbarLayer::Create(
1025 paint_scrollbar
, has_thumb
, m_layer
->id());
1026 m_scrollbar
->setPosition(gfx::Point(0, 10));
1027 m_scrollbar
->setBounds(gfx::Size(10, 10));
1029 m_layer
->addChild(m_scrollbar
);
1031 m_layerTreeHost
->setRootLayer(m_layer
);
1032 LayerTreeHostTest::setupTree();
1035 virtual void beginTest() OVERRIDE
1037 postSetNeedsCommitToMainThread();
1040 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1042 ASSERT_EQ(0u, m_layerTreeHost
->settings().maxPartialTextureUpdates
);
1044 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(impl
->outputSurface()->context3d());
1046 switch (impl
->activeTree()->source_frame_number()) {
1048 // Number of textures should be one for each layer
1049 ASSERT_EQ(2, context
->NumTextures());
1050 // Number of textures used for commit should be one for each layer.
1051 EXPECT_EQ(2, context
->NumUsedTextures());
1052 // Verify that used texture is correct.
1053 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1054 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1056 context
->ResetUsedTextures();
1057 postSetNeedsCommitToMainThread();
1060 // Number of textures should be doubled as the first textures
1061 // are used by impl thread and cannot by used for update.
1062 ASSERT_EQ(4, context
->NumTextures());
1063 // Number of textures used for commit should still be one for each layer.
1064 EXPECT_EQ(2, context
->NumUsedTextures());
1065 // First textures should not have been used.
1066 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1067 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1068 // New textures should have been used.
1069 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1070 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1072 context
->ResetUsedTextures();
1073 postSetNeedsCommitToMainThread();
1084 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1086 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(impl
->outputSurface()->context3d());
1088 // Number of textures used for draw should always be one for each layer.
1089 EXPECT_EQ(2, context
->NumUsedTextures());
1090 context
->ResetUsedTextures();
1093 virtual void layout() OVERRIDE
1095 m_layer
->setNeedsDisplay();
1096 m_scrollbar
->setNeedsDisplay();
1099 virtual void afterTest() OVERRIDE
1104 FakeContentLayerClient m_client
;
1105 scoped_refptr
<FakeContentLayer
> m_layer
;
1106 scoped_refptr
<FakeScrollbarLayer
> m_scrollbar
;
1109 TEST_F(LayerTreeHostTestAtomicCommit
, runMultiThread
)
1114 static void setLayerPropertiesForTesting(Layer
* layer
, Layer
* parent
, const gfx::Transform
& transform
, const gfx::PointF
& anchor
, const gfx::PointF
& position
, const gfx::Size
& bounds
, bool opaque
)
1116 layer
->removeAllChildren();
1118 parent
->addChild(layer
);
1119 layer
->setTransform(transform
);
1120 layer
->setAnchorPoint(anchor
);
1121 layer
->setPosition(position
);
1122 layer
->setBounds(bounds
);
1123 layer
->setContentsOpaque(opaque
);
1126 class LayerTreeHostTestAtomicCommitWithPartialUpdate
: public LayerTreeHostTest
{
1128 LayerTreeHostTestAtomicCommitWithPartialUpdate()
1131 // Allow one partial texture update.
1132 m_settings
.maxPartialTextureUpdates
= 1;
1133 // Linear fade animator prevents scrollbars from drawing immediately.
1134 m_settings
.useLinearFadeScrollbarAnimator
= false;
1137 virtual void setupTree() OVERRIDE
1139 m_parent
= FakeContentLayer::Create(&m_client
);
1140 m_parent
->setBounds(gfx::Size(10, 20));
1142 m_child
= FakeContentLayer::Create(&m_client
);
1143 m_child
->setPosition(gfx::Point(0, 10));
1144 m_child
->setBounds(gfx::Size(3, 10));
1146 bool paint_scrollbar
= true;
1147 bool has_thumb
= false;
1148 m_scrollbarWithPaints
= FakeScrollbarLayer::Create(
1149 paint_scrollbar
, has_thumb
, m_parent
->id());
1150 m_scrollbarWithPaints
->setPosition(gfx::Point(3, 10));
1151 m_scrollbarWithPaints
->setBounds(gfx::Size(3, 10));
1153 paint_scrollbar
= false;
1154 m_scrollbarWithoutPaints
= FakeScrollbarLayer::Create(
1155 paint_scrollbar
, has_thumb
, m_parent
->id());
1156 m_scrollbarWithoutPaints
->setPosition(gfx::Point(6, 10));
1157 m_scrollbarWithoutPaints
->setBounds(gfx::Size(3, 10));
1159 m_parent
->addChild(m_child
);
1160 m_parent
->addChild(m_scrollbarWithPaints
);
1161 m_parent
->addChild(m_scrollbarWithoutPaints
);
1163 m_layerTreeHost
->setRootLayer(m_parent
);
1164 LayerTreeHostTest::setupTree();
1167 virtual void beginTest() OVERRIDE
1169 postSetNeedsCommitToMainThread();
1172 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1174 ASSERT_EQ(1u, m_layerTreeHost
->settings().maxPartialTextureUpdates
);
1176 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(impl
->outputSurface()->context3d());
1178 switch (impl
->activeTree()->source_frame_number()) {
1180 // Number of textures should be one for each layer.
1181 ASSERT_EQ(4, context
->NumTextures());
1182 // Number of textures used for commit should be one for each layer.
1183 EXPECT_EQ(4, context
->NumUsedTextures());
1184 // Verify that used textures are correct.
1185 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1186 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1187 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1188 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1190 context
->ResetUsedTextures();
1191 postSetNeedsCommitToMainThread();
1194 // Number of textures should be two for each content layer and one
1195 // for each scrollbar, since they always do a partial update.
1196 ASSERT_EQ(6, context
->NumTextures());
1197 // Number of textures used for commit should be one for each content
1198 // layer, and one for the scrollbar layer that paints.
1199 EXPECT_EQ(3, context
->NumUsedTextures());
1201 // First content textures should not have been used.
1202 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1203 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1204 // The non-painting scrollbar's texture wasn't updated.
1205 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1206 // The painting scrollbar's partial update texture was used.
1207 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1208 // New textures should have been used.
1209 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1210 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(5)));
1212 context
->ResetUsedTextures();
1213 postSetNeedsCommitToMainThread();
1216 // Number of textures should be two for each content layer and one
1217 // for each scrollbar, since they always do a partial update.
1218 ASSERT_EQ(6, context
->NumTextures());
1219 // Number of textures used for commit should be one for each content
1220 // layer, and one for the scrollbar layer that paints.
1221 EXPECT_EQ(3, context
->NumUsedTextures());
1223 // The non-painting scrollbar's texture wasn't updated.
1224 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1225 // The painting scrollbar does a partial update.
1226 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1227 // One content layer does a partial update also.
1228 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1229 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(5)));
1231 context
->ResetUsedTextures();
1232 postSetNeedsCommitToMainThread();
1235 // No textures should be used for commit.
1236 EXPECT_EQ(0, context
->NumUsedTextures());
1238 context
->ResetUsedTextures();
1239 postSetNeedsCommitToMainThread();
1242 // Number of textures used for commit should be two. One for the
1243 // content layer, and one for the painting scrollbar. The
1244 // non-painting scrollbar doesn't update its texture.
1245 EXPECT_EQ(2, context
->NumUsedTextures());
1247 context
->ResetUsedTextures();
1248 postSetNeedsCommitToMainThread();
1259 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1261 TestWebGraphicsContext3D
* context
= static_cast<TestWebGraphicsContext3D
*>(impl
->outputSurface()->context3d());
1263 // Number of textures used for drawing should one per layer except for
1264 // frame 3 where the viewport only contains one layer.
1265 if (impl
->activeTree()->source_frame_number() == 3)
1266 EXPECT_EQ(1, context
->NumUsedTextures());
1268 EXPECT_EQ(4, context
->NumUsedTextures());
1270 context
->ResetUsedTextures();
1273 virtual void layout() OVERRIDE
1275 switch (m_numCommits
++) {
1278 m_parent
->setNeedsDisplay();
1279 m_child
->setNeedsDisplay();
1280 m_scrollbarWithPaints
->setNeedsDisplay();
1281 m_scrollbarWithoutPaints
->setNeedsDisplay();
1284 // Damage part of layers.
1285 m_parent
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1286 m_child
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1287 m_scrollbarWithPaints
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1288 m_scrollbarWithoutPaints
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1291 m_child
->setNeedsDisplay();
1292 m_scrollbarWithPaints
->setNeedsDisplay();
1293 m_scrollbarWithoutPaints
->setNeedsDisplay();
1294 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1297 m_layerTreeHost
->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));
1307 virtual void afterTest() OVERRIDE
1312 FakeContentLayerClient m_client
;
1313 scoped_refptr
<FakeContentLayer
> m_parent
;
1314 scoped_refptr
<FakeContentLayer
> m_child
;
1315 scoped_refptr
<FakeScrollbarLayer
> m_scrollbarWithPaints
;
1316 scoped_refptr
<FakeScrollbarLayer
> m_scrollbarWithoutPaints
;
1320 TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate
, runMultiThread
)
1325 class LayerTreeHostTestFinishAllRendering
: public LayerTreeHostTest
{
1327 LayerTreeHostTestFinishAllRendering()
1333 virtual void beginTest() OVERRIDE
1335 m_layerTreeHost
->setNeedsRedraw();
1336 postSetNeedsCommitToMainThread();
1339 virtual void didCommitAndDrawFrame() OVERRIDE
1344 m_layerTreeHost
->setNeedsRedraw();
1345 m_layerTreeHost
->acquireLayerTextures();
1347 base::AutoLock
lock(m_lock
);
1350 m_layerTreeHost
->finishAllRendering();
1352 base::AutoLock
lock(m_lock
);
1353 EXPECT_EQ(0, m_drawCount
);
1358 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1360 base::AutoLock
lock(m_lock
);
1364 virtual void afterTest() OVERRIDE
1374 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering
)
1376 class LayerTreeHostTestCompositeAndReadbackCleanup
: public LayerTreeHostTest
{
1378 LayerTreeHostTestCompositeAndReadbackCleanup() { }
1380 virtual void beginTest() OVERRIDE
1382 Layer
* rootLayer
= m_layerTreeHost
->rootLayer();
1385 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
1386 EXPECT_FALSE(rootLayer
->renderSurface());
1391 virtual void afterTest() OVERRIDE
1396 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup
)
1398 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
: public LayerTreeHostTest
{
1400 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1401 : m_rootLayer(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1402 , m_surfaceLayer1(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1403 , m_replicaLayer1(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1404 , m_surfaceLayer2(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1405 , m_replicaLayer2(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1409 virtual void initializeSettings(LayerTreeSettings
& settings
) OVERRIDE
1411 settings
.cacheRenderPassContents
= true;
1414 virtual void beginTest() OVERRIDE
1416 m_layerTreeHost
->setViewportSize(gfx::Size(100, 100), gfx::Size(100, 100));
1418 m_rootLayer
->setBounds(gfx::Size(100, 100));
1419 m_surfaceLayer1
->setBounds(gfx::Size(100, 100));
1420 m_surfaceLayer1
->setForceRenderSurface(true);
1421 m_surfaceLayer1
->setOpacity(0.5);
1422 m_surfaceLayer2
->setBounds(gfx::Size(100, 100));
1423 m_surfaceLayer2
->setForceRenderSurface(true);
1424 m_surfaceLayer2
->setOpacity(0.5);
1426 m_surfaceLayer1
->setReplicaLayer(m_replicaLayer1
.get());
1427 m_surfaceLayer2
->setReplicaLayer(m_replicaLayer2
.get());
1429 m_rootLayer
->addChild(m_surfaceLayer1
);
1430 m_surfaceLayer1
->addChild(m_surfaceLayer2
);
1431 m_layerTreeHost
->setRootLayer(m_rootLayer
);
1433 postSetNeedsCommitToMainThread();
1436 virtual void drawLayersOnThread(LayerTreeHostImpl
* hostImpl
) OVERRIDE
1438 Renderer
* renderer
= hostImpl
->renderer();
1439 RenderPass::Id surface1RenderPassId
= hostImpl
->rootLayer()->children()[0]->renderSurface()->renderPassId();
1440 RenderPass::Id surface2RenderPassId
= hostImpl
->rootLayer()->children()[0]->children()[0]->renderSurface()->renderPassId();
1442 switch (hostImpl
->activeTree()->source_frame_number()) {
1444 EXPECT_TRUE(renderer
->haveCachedResourcesForRenderPassId(surface1RenderPassId
));
1445 EXPECT_TRUE(renderer
->haveCachedResourcesForRenderPassId(surface2RenderPassId
));
1447 // Reduce the memory limit to only fit the root layer and one render surface. This
1448 // prevents any contents drawing into surfaces from being allocated.
1449 hostImpl
->setManagedMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1452 EXPECT_FALSE(renderer
->haveCachedResourcesForRenderPassId(surface1RenderPassId
));
1453 EXPECT_FALSE(renderer
->haveCachedResourcesForRenderPassId(surface2RenderPassId
));
1460 virtual void afterTest() OVERRIDE
1462 EXPECT_EQ(2, m_rootLayer
->paintContentsCount());
1463 EXPECT_EQ(2, m_surfaceLayer1
->paintContentsCount());
1464 EXPECT_EQ(2, m_surfaceLayer2
->paintContentsCount());
1466 // Clear layer references so LayerTreeHost dies.
1468 m_surfaceLayer1
= NULL
;
1469 m_replicaLayer1
= NULL
;
1470 m_surfaceLayer2
= NULL
;
1471 m_replicaLayer2
= NULL
;
1475 FakeContentLayerClient m_fakeDelegate
;
1476 scoped_refptr
<ContentLayerWithUpdateTracking
> m_rootLayer
;
1477 scoped_refptr
<ContentLayerWithUpdateTracking
> m_surfaceLayer1
;
1478 scoped_refptr
<ContentLayerWithUpdateTracking
> m_replicaLayer1
;
1479 scoped_refptr
<ContentLayerWithUpdateTracking
> m_surfaceLayer2
;
1480 scoped_refptr
<ContentLayerWithUpdateTracking
> m_replicaLayer2
;
1483 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
)
1485 class EvictionTestLayer
: public Layer
{
1487 static scoped_refptr
<EvictionTestLayer
> create() { return make_scoped_refptr(new EvictionTestLayer()); }
1489 virtual void update(ResourceUpdateQueue
&, const OcclusionTracker
*, RenderingStats
*) OVERRIDE
;
1490 virtual bool drawsContent() const OVERRIDE
{ return true; }
1492 virtual scoped_ptr
<LayerImpl
> createLayerImpl(LayerTreeImpl
* treeImpl
) OVERRIDE
;
1493 virtual void pushPropertiesTo(LayerImpl
*) OVERRIDE
;
1494 virtual void setTexturePriorities(const PriorityCalculator
&) OVERRIDE
;
1496 bool haveBackingTexture() const { return m_texture
.get() ? m_texture
->haveBackingTexture() : false; }
1499 EvictionTestLayer() : Layer() { }
1500 virtual ~EvictionTestLayer() { }
1502 void createTextureIfNeeded()
1504 if (m_texture
.get())
1506 m_texture
= PrioritizedResource::create(layerTreeHost()->contentsTextureManager());
1507 m_texture
->setDimensions(gfx::Size(10, 10), GL_RGBA
);
1508 m_bitmap
.setConfig(SkBitmap::kARGB_8888_Config
, 10, 10);
1511 scoped_ptr
<PrioritizedResource
> m_texture
;
1515 class EvictionTestLayerImpl
: public LayerImpl
{
1517 static scoped_ptr
<EvictionTestLayerImpl
> create(LayerTreeImpl
* treeImpl
, int id
)
1519 return make_scoped_ptr(new EvictionTestLayerImpl(treeImpl
, id
));
1521 virtual ~EvictionTestLayerImpl() { }
1523 virtual void appendQuads(QuadSink
& quadSink
, AppendQuadsData
&) OVERRIDE
1525 ASSERT_TRUE(m_hasTexture
);
1526 ASSERT_NE(0u, layerTreeImpl()->resource_provider()->numResources());
1529 void setHasTexture(bool hasTexture
) { m_hasTexture
= hasTexture
; }
1532 EvictionTestLayerImpl(LayerTreeImpl
* treeImpl
, int id
)
1533 : LayerImpl(treeImpl
, id
)
1534 , m_hasTexture(false) { }
1539 void EvictionTestLayer::setTexturePriorities(const PriorityCalculator
&)
1541 createTextureIfNeeded();
1542 if (!m_texture
.get())
1544 m_texture
->setRequestPriority(PriorityCalculator::uiPriority(true));
1547 void EvictionTestLayer::update(ResourceUpdateQueue
& queue
, const OcclusionTracker
*, RenderingStats
*)
1549 createTextureIfNeeded();
1550 if (!m_texture
.get())
1553 gfx::Rect
fullRect(0, 0, 10, 10);
1554 ResourceUpdate upload
= ResourceUpdate::Create(
1555 m_texture
.get(), &m_bitmap
, fullRect
, fullRect
, gfx::Vector2d());
1556 queue
.appendFullUpload(upload
);
1559 scoped_ptr
<LayerImpl
> EvictionTestLayer::createLayerImpl(LayerTreeImpl
* treeImpl
)
1561 return EvictionTestLayerImpl::create(treeImpl
, m_layerId
).PassAs
<LayerImpl
>();
1564 void EvictionTestLayer::pushPropertiesTo(LayerImpl
* layerImpl
)
1566 Layer::pushPropertiesTo(layerImpl
);
1568 EvictionTestLayerImpl
* testLayerImpl
= static_cast<EvictionTestLayerImpl
*>(layerImpl
);
1569 testLayerImpl
->setHasTexture(m_texture
->haveBackingTexture());
1572 class LayerTreeHostTestEvictTextures
: public LayerTreeHostTest
{
1574 LayerTreeHostTestEvictTextures()
1575 : m_layer(EvictionTestLayer::create())
1576 , m_implForEvictTextures(0)
1581 virtual void beginTest() OVERRIDE
1583 m_layerTreeHost
->setRootLayer(m_layer
);
1584 m_layerTreeHost
->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));
1586 gfx::Transform identityMatrix
;
1587 setLayerPropertiesForTesting(m_layer
.get(), 0, identityMatrix
, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(10, 20), true);
1589 postSetNeedsCommitToMainThread();
1592 void postEvictTextures()
1594 DCHECK(implThread());
1595 implThread()->postTask(base::Bind(&LayerTreeHostTestEvictTextures::evictTexturesOnImplThread
,
1596 base::Unretained(this)));
1599 void evictTexturesOnImplThread()
1601 DCHECK(m_implForEvictTextures
);
1602 m_implForEvictTextures
->enforceManagedMemoryPolicy(ManagedMemoryPolicy(0));
1605 // Commit 1: Just commit and draw normally, then post an eviction at the end
1606 // that will trigger a commit.
1607 // Commit 2: Triggered by the eviction, let it go through and then set
1609 // Commit 3: Triggered by the setNeedsCommit. In layout(), post an eviction
1610 // task, which will be handled before the commit. Don't set needsCommit, it
1611 // should have been posted. A frame should not be drawn (note,
1612 // didCommitAndDrawFrame may be called anyway).
1613 // Commit 4: Triggered by the eviction, let it go through and then set
1615 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1616 // layout(), a frame should not be drawn but a commit will be posted.
1617 // Commit 6: Triggered by the eviction, post an eviction task in
1618 // layout(), which will be a noop, letting the commit (which recreates the
1619 // textures) go through and draw a frame, then end the test.
1621 // Commits 1+2 test the eviction recovery path where eviction happens outside
1622 // of the beginFrame/commit pair.
1623 // Commits 3+4 test the eviction recovery path where eviction happens inside
1624 // the beginFrame/commit pair.
1625 // Commits 5+6 test the path where an eviction happens during the eviction
1627 virtual void didCommitAndDrawFrame() OVERRIDE
1629 switch (m_numCommits
) {
1631 EXPECT_TRUE(m_layer
->haveBackingTexture());
1632 postEvictTextures();
1635 EXPECT_TRUE(m_layer
->haveBackingTexture());
1636 m_layerTreeHost
->setNeedsCommit();
1641 EXPECT_TRUE(m_layer
->haveBackingTexture());
1642 m_layerTreeHost
->setNeedsCommit();
1647 EXPECT_TRUE(m_layer
->haveBackingTexture());
1656 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1658 m_implForEvictTextures
= impl
;
1661 virtual void layout() OVERRIDE
1664 switch (m_numCommits
) {
1669 postEvictTextures();
1672 // We couldn't check in didCommitAndDrawFrame on commit 3, so check here.
1673 EXPECT_FALSE(m_layer
->haveBackingTexture());
1676 postEvictTextures();
1679 // We couldn't check in didCommitAndDrawFrame on commit 5, so check here.
1680 EXPECT_FALSE(m_layer
->haveBackingTexture());
1681 postEvictTextures();
1689 virtual void afterTest() OVERRIDE
1694 FakeContentLayerClient m_client
;
1695 scoped_refptr
<EvictionTestLayer
> m_layer
;
1696 LayerTreeHostImpl
* m_implForEvictTextures
;
1700 TEST_F(LayerTreeHostTestEvictTextures
, runMultiThread
)
1705 class LayerTreeHostTestContinuousCommit
: public LayerTreeHostTest
{
1707 LayerTreeHostTestContinuousCommit()
1708 : m_numCommitComplete(0)
1709 , m_numDrawLayers(0)
1713 virtual void beginTest() OVERRIDE
1715 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1716 m_layerTreeHost
->rootLayer()->setBounds(gfx::Size(10, 10));
1718 postSetNeedsCommitToMainThread();
1721 virtual void didCommit() OVERRIDE
1723 if (m_numDrawLayers
== 2)
1725 postSetNeedsCommitToMainThread();
1728 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
1730 if (m_numDrawLayers
== 1)
1731 m_numCommitComplete
++;
1734 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1737 if (m_numDrawLayers
== 2)
1741 virtual void afterTest() OVERRIDE
1743 // Check that we didn't commit twice between first and second draw.
1744 EXPECT_EQ(1, m_numCommitComplete
);
1748 int m_numCommitComplete
;
1749 int m_numDrawLayers
;
1752 TEST_F(LayerTreeHostTestContinuousCommit
, runMultiThread
)
1757 class LayerTreeHostTestContinuousInvalidate
: public LayerTreeHostTest
{
1759 LayerTreeHostTestContinuousInvalidate()
1760 : m_numCommitComplete(0)
1761 , m_numDrawLayers(0)
1765 virtual void beginTest() OVERRIDE
1767 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1768 m_layerTreeHost
->rootLayer()->setBounds(gfx::Size(10, 10));
1770 m_contentLayer
= ContentLayer::create(&m_fakeDelegate
);
1771 m_contentLayer
->setBounds(gfx::Size(10, 10));
1772 m_contentLayer
->setPosition(gfx::PointF(0, 0));
1773 m_contentLayer
->setAnchorPoint(gfx::PointF(0, 0));
1774 m_contentLayer
->setIsDrawable(true);
1775 m_layerTreeHost
->rootLayer()->addChild(m_contentLayer
);
1777 postSetNeedsCommitToMainThread();
1780 virtual void didCommit() OVERRIDE
1782 if (m_numDrawLayers
== 2)
1784 m_contentLayer
->setNeedsDisplay();
1787 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
1789 if (m_numDrawLayers
== 1)
1790 m_numCommitComplete
++;
1793 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1796 if (m_numDrawLayers
== 2)
1800 virtual void afterTest() OVERRIDE
1802 // Check that we didn't commit twice between first and second draw.
1803 EXPECT_EQ(1, m_numCommitComplete
);
1805 // Clear layer references so LayerTreeHost dies.
1806 m_contentLayer
= NULL
;
1810 FakeContentLayerClient m_fakeDelegate
;
1811 scoped_refptr
<Layer
> m_contentLayer
;
1812 int m_numCommitComplete
;
1813 int m_numDrawLayers
;
1816 TEST_F(LayerTreeHostTestContinuousInvalidate
, runMultiThread
)
1821 class LayerTreeHostTestDeferCommits
: public LayerTreeHostTest
{
1823 LayerTreeHostTestDeferCommits()
1824 : m_numCommitsDeferred(0)
1825 , m_numCompleteCommits(0)
1829 virtual void beginTest() OVERRIDE
1831 postSetNeedsCommitToMainThread();
1834 virtual void didDeferCommit() OVERRIDE
1836 m_numCommitsDeferred
++;
1837 m_layerTreeHost
->setDeferCommits(false);
1840 virtual void didCommit() OVERRIDE
1842 m_numCompleteCommits
++;
1843 switch (m_numCompleteCommits
) {
1845 EXPECT_EQ(0, m_numCommitsDeferred
);
1846 m_layerTreeHost
->setDeferCommits(true);
1847 postSetNeedsCommitToMainThread();
1858 virtual void afterTest() OVERRIDE
1860 EXPECT_EQ(1, m_numCommitsDeferred
);
1861 EXPECT_EQ(2, m_numCompleteCommits
);
1865 int m_numCommitsDeferred
;
1866 int m_numCompleteCommits
;
1869 TEST_F(LayerTreeHostTestDeferCommits
, runMultiThread
)
1874 class LayerTreeHostWithProxy
: public LayerTreeHost
{
1876 LayerTreeHostWithProxy(FakeLayerImplTreeHostClient
* client
, const LayerTreeSettings
& settings
, scoped_ptr
<Proxy
> proxy
)
1877 : LayerTreeHost(client
, settings
)
1879 EXPECT_TRUE(initializeForTesting(proxy
.Pass()));
1883 FakeLayerImplTreeHostClient m_client
;
1886 TEST(LayerTreeHostTest
, LimitPartialUpdates
)
1888 // When partial updates are not allowed, max updates should be 0.
1890 FakeLayerImplTreeHostClient client
;
1892 scoped_ptr
<FakeProxy
> proxy
= make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1893 proxy
->rendererCapabilities().allowPartialTextureUpdates
= false;
1894 proxy
->setMaxPartialTextureUpdates(5);
1896 LayerTreeSettings settings
;
1897 settings
.maxPartialTextureUpdates
= 10;
1899 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1900 EXPECT_TRUE(host
.initializeRendererIfNeeded());
1902 EXPECT_EQ(0u, host
.settings().maxPartialTextureUpdates
);
1905 // When partial updates are allowed, max updates should be limited by the proxy.
1907 FakeLayerImplTreeHostClient client
;
1909 scoped_ptr
<FakeProxy
> proxy
= make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1910 proxy
->rendererCapabilities().allowPartialTextureUpdates
= true;
1911 proxy
->setMaxPartialTextureUpdates(5);
1913 LayerTreeSettings settings
;
1914 settings
.maxPartialTextureUpdates
= 10;
1916 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1917 EXPECT_TRUE(host
.initializeRendererIfNeeded());
1919 EXPECT_EQ(5u, host
.settings().maxPartialTextureUpdates
);
1922 // When partial updates are allowed, max updates should also be limited by the settings.
1924 FakeLayerImplTreeHostClient client
;
1926 scoped_ptr
<FakeProxy
> proxy
= make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1927 proxy
->rendererCapabilities().allowPartialTextureUpdates
= true;
1928 proxy
->setMaxPartialTextureUpdates(20);
1930 LayerTreeSettings settings
;
1931 settings
.maxPartialTextureUpdates
= 10;
1933 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1934 EXPECT_TRUE(host
.initializeRendererIfNeeded());
1936 EXPECT_EQ(10u, host
.settings().maxPartialTextureUpdates
);
1940 TEST(LayerTreeHostTest
, PartialUpdatesWithGLRenderer
)
1942 bool useSoftwareRendering
= false;
1943 bool useDelegatingRenderer
= false;
1944 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
1946 LayerTreeSettings settings
;
1947 settings
.maxPartialTextureUpdates
= 4;
1949 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
1950 EXPECT_TRUE(host
->initializeRendererIfNeeded());
1951 EXPECT_EQ(4u, host
->settings().maxPartialTextureUpdates
);
1954 TEST(LayerTreeHostTest
, PartialUpdatesWithSoftwareRenderer
)
1956 bool useSoftwareRendering
= true;
1957 bool useDelegatingRenderer
= false;
1958 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
1960 LayerTreeSettings settings
;
1961 settings
.maxPartialTextureUpdates
= 4;
1963 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
1964 EXPECT_TRUE(host
->initializeRendererIfNeeded());
1965 EXPECT_EQ(4u, host
->settings().maxPartialTextureUpdates
);
1968 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndGLContent
)
1970 bool useSoftwareRendering
= false;
1971 bool useDelegatingRenderer
= true;
1972 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
1974 LayerTreeSettings settings
;
1975 settings
.maxPartialTextureUpdates
= 4;
1977 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
1978 EXPECT_TRUE(host
->initializeRendererIfNeeded());
1979 EXPECT_EQ(0u, host
->settings().maxPartialTextureUpdates
);
1982 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndSoftwareContent
)
1984 bool useSoftwareRendering
= true;
1985 bool useDelegatingRenderer
= true;
1986 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
1988 LayerTreeSettings settings
;
1989 settings
.maxPartialTextureUpdates
= 4;
1991 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
1992 EXPECT_TRUE(host
->initializeRendererIfNeeded());
1993 EXPECT_EQ(0u, host
->settings().maxPartialTextureUpdates
);
1996 class LayerTreeHostTestCapturePicture
: public LayerTreeHostTest
{
1998 LayerTreeHostTestCapturePicture()
1999 : m_bounds(gfx::Size(100, 100))
2000 , m_layer(PictureLayer::create(&m_contentClient
))
2002 m_settings
.implSidePainting
= true;
2005 class FillRectContentLayerClient
: public ContentLayerClient
{
2007 virtual void paintContents(SkCanvas
* canvas
, const gfx::Rect
& clip
, gfx::RectF
& opaque
) OVERRIDE
2010 paint
.setColor(SK_ColorGREEN
);
2012 SkRect rect
= SkRect::MakeWH(canvas
->getDeviceSize().width(), canvas
->getDeviceSize().height());
2013 opaque
= gfx::RectF(rect
.width(), rect
.height());
2014 canvas
->drawRect(rect
, paint
);
2018 virtual void beginTest() OVERRIDE
2020 m_layer
->setIsDrawable(true);
2021 m_layer
->setBounds(m_bounds
);
2022 m_layerTreeHost
->setViewportSize(m_bounds
, m_bounds
);
2023 m_layerTreeHost
->setRootLayer(m_layer
);
2025 EXPECT_TRUE(m_layerTreeHost
->initializeRendererIfNeeded());
2026 postSetNeedsCommitToMainThread();
2029 virtual void didCommitAndDrawFrame() OVERRIDE
2031 m_picture
= m_layerTreeHost
->capturePicture();
2035 virtual void afterTest() OVERRIDE
2037 EXPECT_EQ(m_bounds
, gfx::Size(m_picture
->width(), m_picture
->height()));
2040 bitmap
.setConfig(SkBitmap::kARGB_8888_Config
, m_bounds
.width(), m_bounds
.height());
2041 bitmap
.allocPixels();
2042 bitmap
.eraseARGB(0, 0, 0, 0);
2043 SkCanvas
canvas(bitmap
);
2045 m_picture
->draw(&canvas
);
2047 bitmap
.lockPixels();
2048 SkColor
* pixels
= reinterpret_cast<SkColor
*>(bitmap
.getPixels());
2049 EXPECT_EQ(SK_ColorGREEN
, pixels
[0]);
2050 bitmap
.unlockPixels();
2055 FillRectContentLayerClient m_contentClient
;
2056 scoped_refptr
<PictureLayer
> m_layer
;
2057 skia::RefPtr
<SkPicture
> m_picture
;
2060 MULTI_THREAD_TEST_F(LayerTreeHostTestCapturePicture
);
2062 class LayerTreeHostTestMaxPendingFrames
: public LayerTreeHostTest
{
2064 LayerTreeHostTestMaxPendingFrames()
2065 : LayerTreeHostTest()
2069 virtual scoped_ptr
<OutputSurface
> createOutputSurface() OVERRIDE
2071 if (m_delegatingRenderer
)
2072 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
2073 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
2076 virtual void beginTest() OVERRIDE
2078 postSetNeedsCommitToMainThread();
2081 virtual void drawLayersOnThread(LayerTreeHostImpl
* hostImpl
) OVERRIDE
2083 DCHECK(hostImpl
->proxy()->hasImplThread());
2085 const ThreadProxy
* proxy
= static_cast<ThreadProxy
*>(hostImpl
->proxy());
2086 if (m_delegatingRenderer
)
2087 EXPECT_EQ(1, proxy
->maxFramesPendingForTesting());
2089 EXPECT_EQ(FrameRateController::kDefaultMaxFramesPending
, proxy
->maxFramesPendingForTesting());
2093 virtual void afterTest() OVERRIDE
2098 bool m_delegatingRenderer
;
2101 TEST_F(LayerTreeHostTestMaxPendingFrames
, DelegatingRenderer
)
2103 m_delegatingRenderer
= true;
2107 TEST_F(LayerTreeHostTestMaxPendingFrames
, GLRenderer
)
2109 m_delegatingRenderer
= false;