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/resource_update_queue.h"
16 #include "cc/single_thread_proxy.h"
17 #include "cc/test/fake_content_layer.h"
18 #include "cc/test/fake_content_layer_client.h"
19 #include "cc/test/fake_layer_tree_host_client.h"
20 #include "cc/test/fake_output_surface.h"
21 #include "cc/test/fake_proxy.h"
22 #include "cc/test/fake_scrollbar_layer.h"
23 #include "cc/test/geometry_test_utils.h"
24 #include "cc/test/layer_tree_test_common.h"
25 #include "cc/test/occlusion_tracker_test_common.h"
26 #include "cc/thread_proxy.h"
27 #include "cc/timing_function.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
30 #include "third_party/khronos/GLES2/gl2.h"
31 #include "third_party/khronos/GLES2/gl2ext.h"
32 #include "ui/gfx/point_conversions.h"
33 #include "ui/gfx/size_conversions.h"
34 #include "ui/gfx/vector2d_conversions.h"
39 class LayerTreeHostTest
: public ThreadedTest
{ };
41 // Shortlived layerTreeHosts shouldn't die.
42 class LayerTreeHostTestShortlived1
: public LayerTreeHostTest
{
44 LayerTreeHostTestShortlived1() { }
46 virtual void beginTest() OVERRIDE
48 // Kill the layerTreeHost immediately.
49 m_layerTreeHost
->setRootLayer(0);
50 m_layerTreeHost
.reset();
55 virtual void afterTest() OVERRIDE
60 // Shortlived layerTreeHosts shouldn't die with a commit in flight.
61 class LayerTreeHostTestShortlived2
: public LayerTreeHostTest
{
63 LayerTreeHostTestShortlived2() { }
65 virtual void beginTest() OVERRIDE
67 postSetNeedsCommitToMainThread();
69 // Kill the layerTreeHost immediately.
70 m_layerTreeHost
->setRootLayer(0);
71 m_layerTreeHost
.reset();
76 virtual void afterTest() OVERRIDE
81 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestShortlived2
)
83 // Shortlived layerTreeHosts shouldn't die with a redraw in flight.
84 class LayerTreeHostTestShortlived3
: public LayerTreeHostTest
{
86 LayerTreeHostTestShortlived3() { }
88 virtual void beginTest() OVERRIDE
90 postSetNeedsRedrawToMainThread();
92 // Kill the layerTreeHost immediately.
93 m_layerTreeHost
->setRootLayer(0);
94 m_layerTreeHost
.reset();
99 virtual void afterTest() OVERRIDE
104 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestShortlived3
)
106 // Test interleaving of redraws and commits
107 class LayerTreeHostTestCommitingWithContinuousRedraw
: public LayerTreeHostTest
{
109 LayerTreeHostTestCommitingWithContinuousRedraw()
110 : m_numCompleteCommits(0)
115 virtual void beginTest() OVERRIDE
117 postSetNeedsCommitToMainThread();
120 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
122 m_numCompleteCommits
++;
123 if (m_numCompleteCommits
== 2)
127 virtual void drawLayersOnThread(LayerTreeHostImpl
*) OVERRIDE
130 postSetNeedsCommitToMainThread();
132 postSetNeedsRedrawToMainThread();
135 virtual void afterTest() OVERRIDE
140 int m_numCompleteCommits
;
144 TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw
, runMultiThread
)
149 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
150 // draw with frame 0.
151 class LayerTreeHostTestSetNeedsCommit1
: public LayerTreeHostTest
{
153 LayerTreeHostTestSetNeedsCommit1()
159 virtual void beginTest() OVERRIDE
161 postSetNeedsCommitToMainThread();
162 postSetNeedsCommitToMainThread();
165 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
168 if (!impl
->activeTree()->source_frame_number())
172 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
177 virtual void afterTest() OVERRIDE
179 EXPECT_GE(1, m_numCommits
);
180 EXPECT_GE(1, m_numDraws
);
188 TEST_F(LayerTreeHostTestSetNeedsCommit1
, DISABLED_runMultiThread
)
193 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
194 // first committed frame draws should lead to another commit.
195 class LayerTreeHostTestSetNeedsCommit2
: public LayerTreeHostTest
{
197 LayerTreeHostTestSetNeedsCommit2()
203 virtual void beginTest() OVERRIDE
205 postSetNeedsCommitToMainThread();
208 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
210 if (impl
->activeTree()->source_frame_number() == 0)
211 postSetNeedsCommitToMainThread();
212 else if (impl
->activeTree()->source_frame_number() == 1)
216 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
221 virtual void afterTest() OVERRIDE
223 EXPECT_EQ(2, m_numCommits
);
224 EXPECT_GE(2, m_numDraws
);
232 TEST_F(LayerTreeHostTestSetNeedsCommit2
, runMultiThread
)
237 // 1 setNeedsRedraw after the first commit has completed should lead to 1
239 class LayerTreeHostTestSetNeedsRedraw
: public LayerTreeHostTest
{
241 LayerTreeHostTestSetNeedsRedraw()
247 virtual void beginTest() OVERRIDE
249 postSetNeedsCommitToMainThread();
252 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
254 EXPECT_EQ(0, impl
->activeTree()->source_frame_number());
256 postSetNeedsRedrawToMainThread(); // Redraw again to verify that the second redraw doesn't commit.
262 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
264 EXPECT_EQ(0, m_numDraws
);
268 virtual void afterTest() OVERRIDE
270 EXPECT_GE(2, m_numDraws
);
271 EXPECT_EQ(1, m_numCommits
);
279 TEST_F(LayerTreeHostTestSetNeedsRedraw
, runMultiThread
)
284 class LayerTreeHostTestNoExtraCommitFromInvalidate
: public LayerTreeHostTest
{
286 LayerTreeHostTestNoExtraCommitFromInvalidate()
287 : m_rootLayer(ContentLayer::create(&m_client
))
291 virtual void beginTest() OVERRIDE
293 m_rootLayer
->setAutomaticallyComputeRasterScale(false);
294 m_rootLayer
->setIsDrawable(true);
295 m_rootLayer
->setBounds(gfx::Size(1, 1));
296 m_layerTreeHost
->setRootLayer(m_rootLayer
);
297 postSetNeedsCommitToMainThread();
300 virtual void didCommit() OVERRIDE
302 switch (m_layerTreeHost
->commitNumber()) {
304 // Changing the content bounds will cause a single commit!
305 m_rootLayer
->setRasterScale(4.0f
);
309 EXPECT_EQ(2, m_layerTreeHost
->commitNumber());
314 virtual void afterTest() OVERRIDE
319 FakeContentLayerClient m_client
;
320 scoped_refptr
<ContentLayer
> m_rootLayer
;
323 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate
)
325 class LayerTreeHostTestCompositeAndReadback
: public LayerTreeHostTest
{
327 LayerTreeHostTestCompositeAndReadback()
332 virtual void beginTest() OVERRIDE
334 postSetNeedsCommitToMainThread();
337 virtual void didCommit() OVERRIDE
340 if (m_numCommits
== 1) {
342 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
343 } else if (m_numCommits
== 2) {
344 // This is inside the readback. We should get another commit after it.
345 } else if (m_numCommits
== 3) {
352 virtual void afterTest() OVERRIDE
360 TEST_F(LayerTreeHostTestCompositeAndReadback
, runMultiThread
)
365 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
: public LayerTreeHostTest
{
367 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
372 virtual void beginTest() OVERRIDE
374 postSetNeedsCommitToMainThread();
377 virtual void didCommit() OVERRIDE
380 if (m_numCommits
== 1) {
381 m_layerTreeHost
->setNeedsCommit();
382 } else if (m_numCommits
== 2) {
384 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
385 } else if (m_numCommits
== 3) {
386 // This is inside the readback. We should get another commit after it.
387 } else if (m_numCommits
== 4) {
394 virtual void afterTest() OVERRIDE
402 TEST_F(LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
, runMultiThread
)
407 // If the layerTreeHost says it can't draw, then we should not try to draw.
408 class LayerTreeHostTestCanDrawBlocksDrawing
: public LayerTreeHostTest
{
410 LayerTreeHostTestCanDrawBlocksDrawing()
416 virtual void beginTest() OVERRIDE
418 postSetNeedsCommitToMainThread();
421 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
425 // Only the initial draw should bring us here.
426 EXPECT_TRUE(impl
->canDraw());
427 EXPECT_EQ(0, impl
->activeTree()->source_frame_number());
430 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
434 if (m_numCommits
>= 1) {
435 // After the first commit, we should not be able to draw.
436 EXPECT_FALSE(impl
->canDraw());
440 virtual void didCommit() OVERRIDE
443 if (m_numCommits
== 1) {
444 // Make the viewport empty so the host says it can't draw.
445 m_layerTreeHost
->setViewportSize(gfx::Size(0, 0), gfx::Size(0, 0));
446 } else if (m_numCommits
== 2) {
448 m_layerTreeHost
->compositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
449 } else if (m_numCommits
== 3) {
450 // Let it draw so we go idle and end the test.
451 m_layerTreeHost
->setViewportSize(gfx::Size(1, 1), gfx::Size(1, 1));
457 virtual void afterTest() OVERRIDE
466 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing
)
468 // beginLayerWrite should prevent draws from executing until a commit occurs
469 class LayerTreeHostTestWriteLayersRedraw
: public LayerTreeHostTest
{
471 LayerTreeHostTestWriteLayersRedraw()
477 virtual void beginTest() OVERRIDE
479 postAcquireLayerTextures();
480 postSetNeedsRedrawToMainThread(); // should be inhibited without blocking
481 postSetNeedsCommitToMainThread();
484 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
487 EXPECT_EQ(m_numDraws
, m_numCommits
);
490 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
496 virtual void afterTest() OVERRIDE
498 EXPECT_EQ(1, m_numCommits
);
506 TEST_F(LayerTreeHostTestWriteLayersRedraw
, runMultiThread
)
511 // Verify that when resuming visibility, requesting layer write permission
512 // will not deadlock the main thread even though there are not yet any
513 // scheduled redraws. This behavior is critical for reliably surviving tab
514 // switching. There are no failure conditions to this test, it just passes
515 // by not timing out.
516 class LayerTreeHostTestWriteLayersAfterVisible
: public LayerTreeHostTest
{
518 LayerTreeHostTestWriteLayersAfterVisible()
523 virtual void beginTest() OVERRIDE
525 postSetNeedsCommitToMainThread();
528 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
531 if (m_numCommits
== 2)
533 else if (m_numCommits
< 2) {
534 postSetVisibleToMainThread(false);
535 postSetVisibleToMainThread(true);
536 postAcquireLayerTextures();
537 postSetNeedsCommitToMainThread();
541 virtual void afterTest() OVERRIDE
549 TEST_F(LayerTreeHostTestWriteLayersAfterVisible
, runMultiThread
)
554 // A compositeAndReadback while invisible should force a normal commit without assertion.
555 class LayerTreeHostTestCompositeAndReadbackWhileInvisible
: public LayerTreeHostTest
{
557 LayerTreeHostTestCompositeAndReadbackWhileInvisible()
562 virtual void beginTest() OVERRIDE
564 postSetNeedsCommitToMainThread();
567 virtual void didCommitAndDrawFrame() OVERRIDE
570 if (m_numCommits
== 1) {
571 m_layerTreeHost
->setVisible(false);
572 m_layerTreeHost
->setNeedsCommit();
573 m_layerTreeHost
->setNeedsCommit();
575 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
581 virtual void afterTest() OVERRIDE
589 TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible
, runMultiThread
)
594 class LayerTreeHostTestAbortFrameWhenInvisible
: public LayerTreeHostTest
{
596 LayerTreeHostTestAbortFrameWhenInvisible()
600 virtual void beginTest() OVERRIDE
602 // Request a commit (from the main thread), which will trigger the commit flow from the impl side.
603 m_layerTreeHost
->setNeedsCommit();
604 // Then mark ourselves as not visible before processing any more messages on the main thread.
605 m_layerTreeHost
->setVisible(false);
606 // If we make it without kicking a frame, we pass!
607 endTestAfterDelay(1);
610 virtual void layout() OVERRIDE
616 virtual void afterTest() OVERRIDE
623 TEST_F(LayerTreeHostTestAbortFrameWhenInvisible
, runMultiThread
)
628 // This test verifies that properties on the layer tree host are commited to the impl side.
629 class LayerTreeHostTestCommit
: public LayerTreeHostTest
{
632 LayerTreeHostTestCommit() { }
634 virtual void beginTest() OVERRIDE
636 m_layerTreeHost
->setViewportSize(gfx::Size(20, 20), gfx::Size(20, 20));
637 m_layerTreeHost
->setBackgroundColor(SK_ColorGRAY
);
638 m_layerTreeHost
->setPageScaleFactorAndLimits(5, 5, 5);
640 postSetNeedsCommitToMainThread();
643 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
645 EXPECT_EQ(gfx::Size(20, 20), impl
->layoutViewportSize());
646 EXPECT_EQ(SK_ColorGRAY
, impl
->activeTree()->background_color());
647 EXPECT_EQ(5, impl
->pageScaleFactor());
652 virtual void afterTest() OVERRIDE
{ }
655 TEST_F(LayerTreeHostTestCommit
, runTest
)
660 // Verifies that startPageScaleAnimation events propagate correctly from LayerTreeHost to
661 // LayerTreeHostImpl in the MT compositor.
662 class LayerTreeHostTestStartPageScaleAnimation
: public LayerTreeHostTest
{
665 LayerTreeHostTestStartPageScaleAnimation()
666 : m_animationRequested(false)
670 virtual void beginTest() OVERRIDE
672 m_layerTreeHost
->rootLayer()->setScrollable(true);
673 m_layerTreeHost
->rootLayer()->setScrollOffset(gfx::Vector2d());
674 postSetNeedsCommitToMainThread();
675 postSetNeedsRedrawToMainThread();
678 void requestStartPageScaleAnimation()
680 layerTreeHost()->startPageScaleAnimation(gfx::Vector2d(), false, 1.25, base::TimeDelta());
683 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
685 impl
->rootLayer()->setScrollable(true);
686 impl
->rootLayer()->setScrollOffset(gfx::Vector2d());
687 impl
->setPageScaleFactorAndLimits(impl
->pageScaleFactor(), 0.5, 2);
689 // We request animation only once.
690 if (!m_animationRequested
) {
691 impl
->proxy()->mainThread()->postTask(base::Bind(&LayerTreeHostTestStartPageScaleAnimation::requestStartPageScaleAnimation
, base::Unretained(this)));
692 m_animationRequested
= true;
696 virtual void applyScrollAndScale(gfx::Vector2d scrollDelta
, float scale
) OVERRIDE
698 gfx::Vector2d offset
= m_layerTreeHost
->rootLayer()->scrollOffset();
699 m_layerTreeHost
->rootLayer()->setScrollOffset(offset
+ scrollDelta
);
700 m_layerTreeHost
->setPageScaleFactorAndLimits(scale
, 0.5, 2);
703 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
705 impl
->processScrollDeltas();
706 // We get one commit before the first draw, and the animation doesn't happen until the second draw.
707 if (impl
->activeTree()->source_frame_number() == 1) {
708 EXPECT_EQ(1.25, impl
->pageScaleFactor());
711 postSetNeedsRedrawToMainThread();
714 virtual void afterTest() OVERRIDE
719 bool m_animationRequested
;
722 TEST_F(LayerTreeHostTestStartPageScaleAnimation
, runTest
)
727 class LayerTreeHostTestSetVisible
: public LayerTreeHostTest
{
730 LayerTreeHostTestSetVisible()
735 virtual void beginTest() OVERRIDE
737 postSetNeedsCommitToMainThread();
738 postSetVisibleToMainThread(false);
739 postSetNeedsRedrawToMainThread(); // This is suppressed while we're invisible.
740 postSetVisibleToMainThread(true); // Triggers the redraw.
743 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
745 EXPECT_TRUE(impl
->visible());
750 virtual void afterTest() OVERRIDE
752 EXPECT_EQ(1, m_numDraws
);
759 TEST_F(LayerTreeHostTestSetVisible
, runMultiThread
)
764 class TestOpacityChangeLayerDelegate
: public ContentLayerClient
{
766 TestOpacityChangeLayerDelegate()
771 void setTestLayer(Layer
* testLayer
)
773 m_testLayer
= testLayer
;
776 virtual void paintContents(SkCanvas
*, const gfx::Rect
&, gfx::RectF
&) OVERRIDE
778 // Set layer opacity to 0.
780 m_testLayer
->setOpacity(0);
787 class ContentLayerWithUpdateTracking
: public ContentLayer
{
789 static scoped_refptr
<ContentLayerWithUpdateTracking
> create(ContentLayerClient
* client
) { return make_scoped_refptr(new ContentLayerWithUpdateTracking(client
)); }
791 int paintContentsCount() { return m_paintContentsCount
; }
792 void resetPaintContentsCount() { m_paintContentsCount
= 0; }
794 virtual void update(ResourceUpdateQueue
& queue
, const OcclusionTracker
* occlusion
, RenderingStats
& stats
) OVERRIDE
796 ContentLayer::update(queue
, occlusion
, stats
);
797 m_paintContentsCount
++;
801 explicit ContentLayerWithUpdateTracking(ContentLayerClient
* client
)
802 : ContentLayer(client
)
803 , m_paintContentsCount(0)
805 setAnchorPoint(gfx::PointF(0, 0));
806 setBounds(gfx::Size(10, 10));
809 virtual ~ContentLayerWithUpdateTracking()
813 int m_paintContentsCount
;
816 // Layer opacity change during paint should not prevent compositor resources from being updated during commit.
817 class LayerTreeHostTestOpacityChange
: public LayerTreeHostTest
{
819 LayerTreeHostTestOpacityChange()
820 : m_testOpacityChangeDelegate()
821 , m_updateCheckLayer(ContentLayerWithUpdateTracking::create(&m_testOpacityChangeDelegate
))
823 m_testOpacityChangeDelegate
.setTestLayer(m_updateCheckLayer
.get());
826 virtual void beginTest() OVERRIDE
828 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
829 m_layerTreeHost
->rootLayer()->addChild(m_updateCheckLayer
);
831 postSetNeedsCommitToMainThread();
834 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
839 virtual void afterTest() OVERRIDE
841 // update() should have been called once.
842 EXPECT_EQ(1, m_updateCheckLayer
->paintContentsCount());
844 // clear m_updateCheckLayer so LayerTreeHost dies.
845 m_updateCheckLayer
= NULL
;
849 TestOpacityChangeLayerDelegate m_testOpacityChangeDelegate
;
850 scoped_refptr
<ContentLayerWithUpdateTracking
> m_updateCheckLayer
;
853 TEST_F(LayerTreeHostTestOpacityChange
, runMultiThread
)
858 class NoScaleContentLayer
: public ContentLayer
{
860 static scoped_refptr
<NoScaleContentLayer
> create(ContentLayerClient
* client
) { return make_scoped_refptr(new NoScaleContentLayer(client
)); }
862 virtual void calculateContentsScale(
863 float idealContentsScale
,
864 float* contentsScaleX
,
865 float* contentsScaleY
,
866 gfx::Size
* contentBounds
) OVERRIDE
868 Layer::calculateContentsScale(
876 explicit NoScaleContentLayer(ContentLayerClient
* client
)
877 : ContentLayer(client
) { }
878 virtual ~NoScaleContentLayer() { }
881 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
: public LayerTreeHostTest
{
884 LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
885 : m_rootLayer(NoScaleContentLayer::create(&m_client
))
886 , m_childLayer(ContentLayer::create(&m_client
))
890 virtual void beginTest() OVERRIDE
892 m_layerTreeHost
->setViewportSize(gfx::Size(40, 40), gfx::Size(60, 60));
893 m_layerTreeHost
->setDeviceScaleFactor(1.5);
894 EXPECT_EQ(gfx::Size(40, 40), m_layerTreeHost
->layoutViewportSize());
895 EXPECT_EQ(gfx::Size(60, 60), m_layerTreeHost
->deviceViewportSize());
897 m_rootLayer
->addChild(m_childLayer
);
899 m_rootLayer
->setIsDrawable(true);
900 m_rootLayer
->setBounds(gfx::Size(30, 30));
901 m_rootLayer
->setAnchorPoint(gfx::PointF(0, 0));
903 m_childLayer
->setIsDrawable(true);
904 m_childLayer
->setPosition(gfx::Point(2, 2));
905 m_childLayer
->setBounds(gfx::Size(10, 10));
906 m_childLayer
->setAnchorPoint(gfx::PointF(0, 0));
908 m_layerTreeHost
->setRootLayer(m_rootLayer
);
910 ASSERT_TRUE(m_layerTreeHost
->initializeRendererIfNeeded());
911 ResourceUpdateQueue queue
;
912 m_layerTreeHost
->updateLayers(queue
, std::numeric_limits
<size_t>::max());
913 postSetNeedsCommitToMainThread();
916 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
918 // Get access to protected methods.
919 MockLayerTreeHostImpl
* mockImpl
= static_cast<MockLayerTreeHostImpl
*>(impl
);
921 // Should only do one commit.
922 EXPECT_EQ(0, impl
->activeTree()->source_frame_number());
923 // Device scale factor should come over to impl.
924 EXPECT_NEAR(impl
->deviceScaleFactor(), 1.5, 0.00001);
926 // Both layers are on impl.
927 ASSERT_EQ(1u, impl
->rootLayer()->children().size());
929 // Device viewport is scaled.
930 EXPECT_EQ(gfx::Size(40, 40), impl
->layoutViewportSize());
931 EXPECT_EQ(gfx::Size(60, 60), impl
->deviceViewportSize());
933 LayerImpl
* root
= impl
->rootLayer();
934 LayerImpl
* child
= impl
->rootLayer()->children()[0];
936 // Positions remain in layout pixels.
937 EXPECT_EQ(gfx::Point(0, 0), root
->position());
938 EXPECT_EQ(gfx::Point(2, 2), child
->position());
940 // Compute all the layer transforms for the frame.
941 LayerTreeHostImpl::FrameData frameData
;
942 mockImpl
->prepareToDraw(frameData
);
943 mockImpl
->didDrawAllLayers(frameData
);
945 const MockLayerTreeHostImpl::LayerList
& renderSurfaceLayerList
=
946 *frameData
.renderSurfaceLayerList
;
948 // Both layers should be drawing into the root render surface.
949 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
950 ASSERT_EQ(root
->renderSurface(), renderSurfaceLayerList
[0]->renderSurface());
951 ASSERT_EQ(2u, root
->renderSurface()->layerList().size());
953 // The root render surface is the size of the viewport.
954 EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60), root
->renderSurface()->contentRect());
956 // The content bounds of the child should be scaled.
957 gfx::Size childBoundsScaled
= gfx::ToCeiledSize(gfx::ScaleSize(child
->bounds(), 1.5));
958 EXPECT_EQ(childBoundsScaled
, child
->contentBounds());
960 gfx::Transform scaleTransform
;
961 scaleTransform
.Scale(impl
->deviceScaleFactor(), impl
->deviceScaleFactor());
963 // The root layer is scaled by 2x.
964 gfx::Transform rootScreenSpaceTransform
= scaleTransform
;
965 gfx::Transform rootDrawTransform
= scaleTransform
;
967 EXPECT_EQ(rootDrawTransform
, root
->drawTransform());
968 EXPECT_EQ(rootScreenSpaceTransform
, root
->screenSpaceTransform());
970 // The child is at position 2,2, which is transformed to 3,3 after the scale
971 gfx::Transform childScreenSpaceTransform
;
972 childScreenSpaceTransform
.Translate(3, 3);
973 gfx::Transform childDrawTransform
= childScreenSpaceTransform
;
975 EXPECT_TRANSFORMATION_MATRIX_EQ(childDrawTransform
, child
->drawTransform());
976 EXPECT_TRANSFORMATION_MATRIX_EQ(childScreenSpaceTransform
, child
->screenSpaceTransform());
981 virtual void afterTest() OVERRIDE
988 FakeContentLayerClient m_client
;
989 scoped_refptr
<NoScaleContentLayer
> m_rootLayer
;
990 scoped_refptr
<ContentLayer
> m_childLayer
;
993 TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
, runMultiThread
)
998 // Verify atomicity of commits and reuse of textures.
999 class LayerTreeHostTestAtomicCommit
: public LayerTreeHostTest
{
1001 LayerTreeHostTestAtomicCommit()
1003 // Make sure partial texture updates are turned off.
1004 m_settings
.maxPartialTextureUpdates
= 0;
1005 // Linear fade animator prevents scrollbars from drawing immediately.
1006 m_settings
.useLinearFadeScrollbarAnimator
= false;
1009 virtual void setupTree() OVERRIDE
1011 m_layer
= FakeContentLayer::Create(&m_client
);
1012 m_layer
->setBounds(gfx::Size(10, 20));
1014 bool paint_scrollbar
= true;
1015 bool has_thumb
= false;
1016 m_scrollbar
= FakeScrollbarLayer::Create(
1017 paint_scrollbar
, has_thumb
, m_layer
->id());
1018 m_scrollbar
->setPosition(gfx::Point(0, 10));
1019 m_scrollbar
->setBounds(gfx::Size(10, 10));
1021 m_layer
->addChild(m_scrollbar
);
1023 m_layerTreeHost
->setRootLayer(m_layer
);
1024 LayerTreeHostTest::setupTree();
1027 virtual void beginTest() OVERRIDE
1029 postSetNeedsCommitToMainThread();
1032 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1034 ASSERT_EQ(0u, m_layerTreeHost
->settings().maxPartialTextureUpdates
);
1036 FakeWebGraphicsContext3D
* context
= static_cast<FakeWebGraphicsContext3D
*>(impl
->outputSurface()->Context3D());
1038 switch (impl
->activeTree()->source_frame_number()) {
1040 // Number of textures should be one for each layer
1041 ASSERT_EQ(2, context
->NumTextures());
1042 // Number of textures used for commit should be one for each layer.
1043 EXPECT_EQ(2, context
->NumUsedTextures());
1044 // Verify that used texture is correct.
1045 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1046 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1048 context
->ResetUsedTextures();
1049 postSetNeedsCommitToMainThread();
1052 // Number of textures should be doubled as the first textures
1053 // are used by impl thread and cannot by used for update.
1054 ASSERT_EQ(4, context
->NumTextures());
1055 // Number of textures used for commit should still be one for each layer.
1056 EXPECT_EQ(2, context
->NumUsedTextures());
1057 // First textures should not have been used.
1058 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1059 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1060 // New textures should have been used.
1061 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1062 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1064 context
->ResetUsedTextures();
1065 postSetNeedsCommitToMainThread();
1076 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1078 FakeWebGraphicsContext3D
* context
= static_cast<FakeWebGraphicsContext3D
*>(impl
->outputSurface()->Context3D());
1080 // Number of textures used for draw should always be one for each layer.
1081 EXPECT_EQ(2, context
->NumUsedTextures());
1082 context
->ResetUsedTextures();
1085 virtual void layout() OVERRIDE
1087 m_layer
->setNeedsDisplay();
1088 m_scrollbar
->setNeedsDisplay();
1091 virtual void afterTest() OVERRIDE
1096 FakeContentLayerClient m_client
;
1097 scoped_refptr
<FakeContentLayer
> m_layer
;
1098 scoped_refptr
<FakeScrollbarLayer
> m_scrollbar
;
1101 TEST_F(LayerTreeHostTestAtomicCommit
, runMultiThread
)
1106 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
)
1108 layer
->removeAllChildren();
1110 parent
->addChild(layer
);
1111 layer
->setTransform(transform
);
1112 layer
->setAnchorPoint(anchor
);
1113 layer
->setPosition(position
);
1114 layer
->setBounds(bounds
);
1115 layer
->setContentsOpaque(opaque
);
1118 class LayerTreeHostTestAtomicCommitWithPartialUpdate
: public LayerTreeHostTest
{
1120 LayerTreeHostTestAtomicCommitWithPartialUpdate()
1123 // Allow one partial texture update.
1124 m_settings
.maxPartialTextureUpdates
= 1;
1125 // Linear fade animator prevents scrollbars from drawing immediately.
1126 m_settings
.useLinearFadeScrollbarAnimator
= false;
1129 virtual void setupTree() OVERRIDE
1131 m_parent
= FakeContentLayer::Create(&m_client
);
1132 m_parent
->setBounds(gfx::Size(10, 20));
1134 m_child
= FakeContentLayer::Create(&m_client
);
1135 m_child
->setPosition(gfx::Point(0, 10));
1136 m_child
->setBounds(gfx::Size(3, 10));
1138 bool paint_scrollbar
= true;
1139 bool has_thumb
= false;
1140 m_scrollbarWithPaints
= FakeScrollbarLayer::Create(
1141 paint_scrollbar
, has_thumb
, m_parent
->id());
1142 m_scrollbarWithPaints
->setPosition(gfx::Point(3, 10));
1143 m_scrollbarWithPaints
->setBounds(gfx::Size(3, 10));
1145 paint_scrollbar
= false;
1146 m_scrollbarWithoutPaints
= FakeScrollbarLayer::Create(
1147 paint_scrollbar
, has_thumb
, m_parent
->id());
1148 m_scrollbarWithoutPaints
->setPosition(gfx::Point(6, 10));
1149 m_scrollbarWithoutPaints
->setBounds(gfx::Size(3, 10));
1151 m_parent
->addChild(m_child
);
1152 m_parent
->addChild(m_scrollbarWithPaints
);
1153 m_parent
->addChild(m_scrollbarWithoutPaints
);
1155 m_layerTreeHost
->setRootLayer(m_parent
);
1156 LayerTreeHostTest::setupTree();
1159 virtual void beginTest() OVERRIDE
1161 postSetNeedsCommitToMainThread();
1164 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1166 ASSERT_EQ(1u, m_layerTreeHost
->settings().maxPartialTextureUpdates
);
1168 FakeWebGraphicsContext3D
* context
= static_cast<FakeWebGraphicsContext3D
*>(impl
->outputSurface()->Context3D());
1170 switch (impl
->activeTree()->source_frame_number()) {
1172 // Number of textures should be one for each layer.
1173 ASSERT_EQ(4, context
->NumTextures());
1174 // Number of textures used for commit should be one for each layer.
1175 EXPECT_EQ(4, context
->NumUsedTextures());
1176 // Verify that used textures are correct.
1177 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(0)));
1178 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(1)));
1179 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(2)));
1180 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1182 context
->ResetUsedTextures();
1183 postSetNeedsCommitToMainThread();
1186 // Number of textures should be two for each content layer and one
1187 // for each scrollbar, since they always do a partial update.
1188 ASSERT_EQ(6, context
->NumTextures());
1189 // Number of textures used for commit should be one for each content
1190 // layer, and one for the scrollbar layer that paints.
1191 EXPECT_EQ(3, context
->NumUsedTextures());
1193 // First content textures should not have been used.
1194 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(0)));
1195 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(1)));
1196 // The non-painting scrollbar's texture wasn't updated.
1197 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1198 // The painting scrollbar's partial update texture was used.
1199 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1200 // New textures should have been used.
1201 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1202 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(5)));
1204 context
->ResetUsedTextures();
1205 postSetNeedsCommitToMainThread();
1208 // Number of textures should be two for each content layer and one
1209 // for each scrollbar, since they always do a partial update.
1210 ASSERT_EQ(6, context
->NumTextures());
1211 // Number of textures used for commit should be one for each content
1212 // layer, and one for the scrollbar layer that paints.
1213 EXPECT_EQ(3, context
->NumUsedTextures());
1215 // The non-painting scrollbar's texture wasn't updated.
1216 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(2)));
1217 // The painting scrollbar does a partial update.
1218 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(3)));
1219 // One content layer does a partial update also.
1220 EXPECT_TRUE(context
->UsedTexture(context
->TextureAt(4)));
1221 EXPECT_FALSE(context
->UsedTexture(context
->TextureAt(5)));
1223 context
->ResetUsedTextures();
1224 postSetNeedsCommitToMainThread();
1227 // No textures should be used for commit.
1228 EXPECT_EQ(0, context
->NumUsedTextures());
1230 context
->ResetUsedTextures();
1231 postSetNeedsCommitToMainThread();
1234 // Number of textures used for commit should be two. One for the
1235 // content layer, and one for the painting scrollbar. The
1236 // non-painting scrollbar doesn't update its texture.
1237 EXPECT_EQ(2, context
->NumUsedTextures());
1239 context
->ResetUsedTextures();
1240 postSetNeedsCommitToMainThread();
1251 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1253 FakeWebGraphicsContext3D
* context
= static_cast<FakeWebGraphicsContext3D
*>(impl
->outputSurface()->Context3D());
1255 // Number of textures used for drawing should one per layer except for
1256 // frame 3 where the viewport only contains one layer.
1257 if (impl
->activeTree()->source_frame_number() == 3)
1258 EXPECT_EQ(1, context
->NumUsedTextures());
1260 EXPECT_EQ(4, context
->NumUsedTextures());
1262 context
->ResetUsedTextures();
1265 virtual void layout() OVERRIDE
1267 switch (m_numCommits
++) {
1270 m_parent
->setNeedsDisplay();
1271 m_child
->setNeedsDisplay();
1272 m_scrollbarWithPaints
->setNeedsDisplay();
1273 m_scrollbarWithoutPaints
->setNeedsDisplay();
1276 // Damage part of layers.
1277 m_parent
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1278 m_child
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1279 m_scrollbarWithPaints
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1280 m_scrollbarWithoutPaints
->setNeedsDisplayRect(gfx::RectF(0, 0, 5, 5));
1283 m_child
->setNeedsDisplay();
1284 m_scrollbarWithPaints
->setNeedsDisplay();
1285 m_scrollbarWithoutPaints
->setNeedsDisplay();
1286 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1289 m_layerTreeHost
->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));
1299 virtual void afterTest() OVERRIDE
1304 FakeContentLayerClient m_client
;
1305 scoped_refptr
<FakeContentLayer
> m_parent
;
1306 scoped_refptr
<FakeContentLayer
> m_child
;
1307 scoped_refptr
<FakeScrollbarLayer
> m_scrollbarWithPaints
;
1308 scoped_refptr
<FakeScrollbarLayer
> m_scrollbarWithoutPaints
;
1312 TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate
, runMultiThread
)
1317 class LayerTreeHostTestFinishAllRendering
: public LayerTreeHostTest
{
1319 LayerTreeHostTestFinishAllRendering()
1325 virtual void beginTest() OVERRIDE
1327 m_layerTreeHost
->setNeedsRedraw();
1328 postSetNeedsCommitToMainThread();
1331 virtual void didCommitAndDrawFrame() OVERRIDE
1336 m_layerTreeHost
->setNeedsRedraw();
1337 m_layerTreeHost
->acquireLayerTextures();
1339 base::AutoLock
lock(m_lock
);
1342 m_layerTreeHost
->finishAllRendering();
1344 base::AutoLock
lock(m_lock
);
1345 EXPECT_EQ(0, m_drawCount
);
1350 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1352 base::AutoLock
lock(m_lock
);
1356 virtual void afterTest() OVERRIDE
1366 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering
)
1368 class LayerTreeHostTestCompositeAndReadbackCleanup
: public LayerTreeHostTest
{
1370 LayerTreeHostTestCompositeAndReadbackCleanup() { }
1372 virtual void beginTest() OVERRIDE
1374 Layer
* rootLayer
= m_layerTreeHost
->rootLayer();
1377 m_layerTreeHost
->compositeAndReadback(static_cast<void*>(&pixels
), gfx::Rect(0, 0, 1, 1));
1378 EXPECT_FALSE(rootLayer
->renderSurface());
1383 virtual void afterTest() OVERRIDE
1388 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup
)
1390 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
: public LayerTreeHostTest
{
1392 LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
1393 : m_rootLayer(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1394 , m_surfaceLayer1(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1395 , m_replicaLayer1(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1396 , m_surfaceLayer2(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1397 , m_replicaLayer2(ContentLayerWithUpdateTracking::create(&m_fakeDelegate
))
1401 virtual void beginTest() OVERRIDE
1403 m_layerTreeHost
->setViewportSize(gfx::Size(100, 100), gfx::Size(100, 100));
1405 m_rootLayer
->setBounds(gfx::Size(100, 100));
1406 m_surfaceLayer1
->setBounds(gfx::Size(100, 100));
1407 m_surfaceLayer1
->setForceRenderSurface(true);
1408 m_surfaceLayer1
->setOpacity(0.5);
1409 m_surfaceLayer2
->setBounds(gfx::Size(100, 100));
1410 m_surfaceLayer2
->setForceRenderSurface(true);
1411 m_surfaceLayer2
->setOpacity(0.5);
1413 m_surfaceLayer1
->setReplicaLayer(m_replicaLayer1
.get());
1414 m_surfaceLayer2
->setReplicaLayer(m_replicaLayer2
.get());
1416 m_rootLayer
->addChild(m_surfaceLayer1
);
1417 m_surfaceLayer1
->addChild(m_surfaceLayer2
);
1418 m_layerTreeHost
->setRootLayer(m_rootLayer
);
1420 postSetNeedsCommitToMainThread();
1423 virtual void drawLayersOnThread(LayerTreeHostImpl
* hostImpl
) OVERRIDE
1425 Renderer
* renderer
= hostImpl
->renderer();
1426 RenderPass::Id surface1RenderPassId
= hostImpl
->rootLayer()->children()[0]->renderSurface()->renderPassId();
1427 RenderPass::Id surface2RenderPassId
= hostImpl
->rootLayer()->children()[0]->children()[0]->renderSurface()->renderPassId();
1429 switch (hostImpl
->activeTree()->source_frame_number()) {
1431 EXPECT_TRUE(renderer
->haveCachedResourcesForRenderPassId(surface1RenderPassId
));
1432 EXPECT_TRUE(renderer
->haveCachedResourcesForRenderPassId(surface2RenderPassId
));
1434 // Reduce the memory limit to only fit the root layer and one render surface. This
1435 // prevents any contents drawing into surfaces from being allocated.
1436 hostImpl
->setManagedMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1439 EXPECT_FALSE(renderer
->haveCachedResourcesForRenderPassId(surface1RenderPassId
));
1440 EXPECT_FALSE(renderer
->haveCachedResourcesForRenderPassId(surface2RenderPassId
));
1447 virtual void afterTest() OVERRIDE
1449 EXPECT_EQ(2, m_rootLayer
->paintContentsCount());
1450 EXPECT_EQ(2, m_surfaceLayer1
->paintContentsCount());
1451 EXPECT_EQ(2, m_surfaceLayer2
->paintContentsCount());
1453 // Clear layer references so LayerTreeHost dies.
1455 m_surfaceLayer1
= NULL
;
1456 m_replicaLayer1
= NULL
;
1457 m_surfaceLayer2
= NULL
;
1458 m_replicaLayer2
= NULL
;
1462 FakeContentLayerClient m_fakeDelegate
;
1463 scoped_refptr
<ContentLayerWithUpdateTracking
> m_rootLayer
;
1464 scoped_refptr
<ContentLayerWithUpdateTracking
> m_surfaceLayer1
;
1465 scoped_refptr
<ContentLayerWithUpdateTracking
> m_replicaLayer1
;
1466 scoped_refptr
<ContentLayerWithUpdateTracking
> m_surfaceLayer2
;
1467 scoped_refptr
<ContentLayerWithUpdateTracking
> m_replicaLayer2
;
1470 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
)
1472 class EvictionTestLayer
: public Layer
{
1474 static scoped_refptr
<EvictionTestLayer
> create() { return make_scoped_refptr(new EvictionTestLayer()); }
1476 virtual void update(ResourceUpdateQueue
&, const OcclusionTracker
*, RenderingStats
&) OVERRIDE
;
1477 virtual bool drawsContent() const OVERRIDE
{ return true; }
1479 virtual scoped_ptr
<LayerImpl
> createLayerImpl(LayerTreeImpl
* treeImpl
) OVERRIDE
;
1480 virtual void pushPropertiesTo(LayerImpl
*) OVERRIDE
;
1481 virtual void setTexturePriorities(const PriorityCalculator
&) OVERRIDE
;
1483 bool haveBackingTexture() const { return m_texture
.get() ? m_texture
->haveBackingTexture() : false; }
1486 EvictionTestLayer() : Layer() { }
1487 virtual ~EvictionTestLayer() { }
1489 void createTextureIfNeeded()
1491 if (m_texture
.get())
1493 m_texture
= PrioritizedResource::create(layerTreeHost()->contentsTextureManager());
1494 m_texture
->setDimensions(gfx::Size(10, 10), GL_RGBA
);
1495 m_bitmap
.setConfig(SkBitmap::kARGB_8888_Config
, 10, 10);
1498 scoped_ptr
<PrioritizedResource
> m_texture
;
1502 class EvictionTestLayerImpl
: public LayerImpl
{
1504 static scoped_ptr
<EvictionTestLayerImpl
> create(LayerTreeImpl
* treeImpl
, int id
)
1506 return make_scoped_ptr(new EvictionTestLayerImpl(treeImpl
, id
));
1508 virtual ~EvictionTestLayerImpl() { }
1510 virtual void appendQuads(QuadSink
& quadSink
, AppendQuadsData
&) OVERRIDE
1512 ASSERT_TRUE(m_hasTexture
);
1513 ASSERT_NE(0u, layerTreeImpl()->resource_provider()->numResources());
1516 void setHasTexture(bool hasTexture
) { m_hasTexture
= hasTexture
; }
1519 EvictionTestLayerImpl(LayerTreeImpl
* treeImpl
, int id
)
1520 : LayerImpl(treeImpl
, id
)
1521 , m_hasTexture(false) { }
1526 void EvictionTestLayer::setTexturePriorities(const PriorityCalculator
&)
1528 createTextureIfNeeded();
1529 if (!m_texture
.get())
1531 m_texture
->setRequestPriority(PriorityCalculator::uiPriority(true));
1534 void EvictionTestLayer::update(ResourceUpdateQueue
& queue
, const OcclusionTracker
*, RenderingStats
&)
1536 createTextureIfNeeded();
1537 if (!m_texture
.get())
1540 gfx::Rect
fullRect(0, 0, 10, 10);
1541 ResourceUpdate upload
= ResourceUpdate::Create(
1542 m_texture
.get(), &m_bitmap
, fullRect
, fullRect
, gfx::Vector2d());
1543 queue
.appendFullUpload(upload
);
1546 scoped_ptr
<LayerImpl
> EvictionTestLayer::createLayerImpl(LayerTreeImpl
* treeImpl
)
1548 return EvictionTestLayerImpl::create(treeImpl
, m_layerId
).PassAs
<LayerImpl
>();
1551 void EvictionTestLayer::pushPropertiesTo(LayerImpl
* layerImpl
)
1553 Layer::pushPropertiesTo(layerImpl
);
1555 EvictionTestLayerImpl
* testLayerImpl
= static_cast<EvictionTestLayerImpl
*>(layerImpl
);
1556 testLayerImpl
->setHasTexture(m_texture
->haveBackingTexture());
1559 class LayerTreeHostTestEvictTextures
: public LayerTreeHostTest
{
1561 LayerTreeHostTestEvictTextures()
1562 : m_layer(EvictionTestLayer::create())
1563 , m_implForEvictTextures(0)
1568 virtual void beginTest() OVERRIDE
1570 m_layerTreeHost
->setRootLayer(m_layer
);
1571 m_layerTreeHost
->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));
1573 gfx::Transform identityMatrix
;
1574 setLayerPropertiesForTesting(m_layer
.get(), 0, identityMatrix
, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(10, 20), true);
1576 postSetNeedsCommitToMainThread();
1579 void postEvictTextures()
1581 DCHECK(implThread());
1582 implThread()->postTask(base::Bind(&LayerTreeHostTestEvictTextures::evictTexturesOnImplThread
,
1583 base::Unretained(this)));
1586 void evictTexturesOnImplThread()
1588 DCHECK(m_implForEvictTextures
);
1589 m_implForEvictTextures
->enforceManagedMemoryPolicy(ManagedMemoryPolicy(0));
1592 // Commit 1: Just commit and draw normally, then post an eviction at the end
1593 // that will trigger a commit.
1594 // Commit 2: Triggered by the eviction, let it go through and then set
1596 // Commit 3: Triggered by the setNeedsCommit. In layout(), post an eviction
1597 // task, which will be handled before the commit. Don't set needsCommit, it
1598 // should have been posted. A frame should not be drawn (note,
1599 // didCommitAndDrawFrame may be called anyway).
1600 // Commit 4: Triggered by the eviction, let it go through and then set
1602 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1603 // layout(), a frame should not be drawn but a commit will be posted.
1604 // Commit 6: Triggered by the eviction, post an eviction task in
1605 // layout(), which will be a noop, letting the commit (which recreates the
1606 // textures) go through and draw a frame, then end the test.
1608 // Commits 1+2 test the eviction recovery path where eviction happens outside
1609 // of the beginFrame/commit pair.
1610 // Commits 3+4 test the eviction recovery path where eviction happens inside
1611 // the beginFrame/commit pair.
1612 // Commits 5+6 test the path where an eviction happens during the eviction
1614 virtual void didCommitAndDrawFrame() OVERRIDE
1616 switch (m_numCommits
) {
1618 EXPECT_TRUE(m_layer
->haveBackingTexture());
1619 postEvictTextures();
1622 EXPECT_TRUE(m_layer
->haveBackingTexture());
1623 m_layerTreeHost
->setNeedsCommit();
1628 EXPECT_TRUE(m_layer
->haveBackingTexture());
1629 m_layerTreeHost
->setNeedsCommit();
1634 EXPECT_TRUE(m_layer
->haveBackingTexture());
1643 virtual void commitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1645 m_implForEvictTextures
= impl
;
1648 virtual void layout() OVERRIDE
1651 switch (m_numCommits
) {
1656 postEvictTextures();
1659 // We couldn't check in didCommitAndDrawFrame on commit 3, so check here.
1660 EXPECT_FALSE(m_layer
->haveBackingTexture());
1663 postEvictTextures();
1666 // We couldn't check in didCommitAndDrawFrame on commit 5, so check here.
1667 EXPECT_FALSE(m_layer
->haveBackingTexture());
1668 postEvictTextures();
1676 virtual void afterTest() OVERRIDE
1681 FakeContentLayerClient m_client
;
1682 scoped_refptr
<EvictionTestLayer
> m_layer
;
1683 LayerTreeHostImpl
* m_implForEvictTextures
;
1687 TEST_F(LayerTreeHostTestEvictTextures
, runMultiThread
)
1692 class LayerTreeHostTestContinuousCommit
: public LayerTreeHostTest
{
1694 LayerTreeHostTestContinuousCommit()
1695 : m_numCommitComplete(0)
1696 , m_numDrawLayers(0)
1700 virtual void beginTest() OVERRIDE
1702 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1703 m_layerTreeHost
->rootLayer()->setBounds(gfx::Size(10, 10));
1705 postSetNeedsCommitToMainThread();
1708 virtual void didCommit() OVERRIDE
1710 if (m_numDrawLayers
== 2)
1712 postSetNeedsCommitToMainThread();
1715 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
1717 if (m_numDrawLayers
== 1)
1718 m_numCommitComplete
++;
1721 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1724 if (m_numDrawLayers
== 2)
1728 virtual void afterTest() OVERRIDE
1730 // Check that we didn't commit twice between first and second draw.
1731 EXPECT_EQ(1, m_numCommitComplete
);
1735 int m_numCommitComplete
;
1736 int m_numDrawLayers
;
1739 TEST_F(LayerTreeHostTestContinuousCommit
, runMultiThread
)
1744 class LayerTreeHostTestContinuousInvalidate
: public LayerTreeHostTest
{
1746 LayerTreeHostTestContinuousInvalidate()
1747 : m_numCommitComplete(0)
1748 , m_numDrawLayers(0)
1752 virtual void beginTest() OVERRIDE
1754 m_layerTreeHost
->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1755 m_layerTreeHost
->rootLayer()->setBounds(gfx::Size(10, 10));
1757 m_contentLayer
= ContentLayer::create(&m_fakeDelegate
);
1758 m_contentLayer
->setBounds(gfx::Size(10, 10));
1759 m_contentLayer
->setPosition(gfx::PointF(0, 0));
1760 m_contentLayer
->setAnchorPoint(gfx::PointF(0, 0));
1761 m_contentLayer
->setIsDrawable(true);
1762 m_layerTreeHost
->rootLayer()->addChild(m_contentLayer
);
1764 postSetNeedsCommitToMainThread();
1767 virtual void didCommit() OVERRIDE
1769 if (m_numDrawLayers
== 2)
1771 m_contentLayer
->setNeedsDisplay();
1774 virtual void commitCompleteOnThread(LayerTreeHostImpl
*) OVERRIDE
1776 if (m_numDrawLayers
== 1)
1777 m_numCommitComplete
++;
1780 virtual void drawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
1783 if (m_numDrawLayers
== 2)
1787 virtual void afterTest() OVERRIDE
1789 // Check that we didn't commit twice between first and second draw.
1790 EXPECT_EQ(1, m_numCommitComplete
);
1792 // Clear layer references so LayerTreeHost dies.
1793 m_contentLayer
= NULL
;
1797 FakeContentLayerClient m_fakeDelegate
;
1798 scoped_refptr
<Layer
> m_contentLayer
;
1799 int m_numCommitComplete
;
1800 int m_numDrawLayers
;
1803 TEST_F(LayerTreeHostTestContinuousInvalidate
, runMultiThread
)
1808 class LayerTreeHostTestAdjustPointForZoom
: public LayerTreeHostTest
{
1810 LayerTreeHostTestAdjustPointForZoom()
1814 virtual void beginTest() OVERRIDE
1817 m
.Translate(250, 360);
1820 gfx::Point
point(400, 550);
1821 gfx::Point transformedPoint
;
1823 // Unit transform, no change expected.
1824 m_layerTreeHost
->setImplTransform(gfx::Transform());
1825 transformedPoint
= gfx::ToRoundedPoint(m_layerTreeHost
->adjustEventPointForPinchZoom(point
));
1826 EXPECT_EQ(point
.x(), transformedPoint
.x());
1827 EXPECT_EQ(point
.y(), transformedPoint
.y());
1829 m_layerTreeHost
->setImplTransform(m
);
1831 // Apply m^(-1): 75 = (400 - 250) / 2; 95 = (550 - 360) / 2.
1832 transformedPoint
= gfx::ToRoundedPoint(m_layerTreeHost
->adjustEventPointForPinchZoom(point
));
1833 EXPECT_EQ(75, transformedPoint
.x());
1834 EXPECT_EQ(95, transformedPoint
.y());
1838 virtual void afterTest() OVERRIDE
1843 TEST_F(LayerTreeHostTestAdjustPointForZoom
, runMultiThread
)
1848 class LayerTreeHostTestDeferCommits
: public LayerTreeHostTest
{
1850 LayerTreeHostTestDeferCommits()
1851 : m_numCommitsDeferred(0)
1852 , m_numCompleteCommits(0)
1856 virtual void beginTest() OVERRIDE
1858 postSetNeedsCommitToMainThread();
1861 virtual void didDeferCommit() OVERRIDE
1863 m_numCommitsDeferred
++;
1864 m_layerTreeHost
->setDeferCommits(false);
1867 virtual void didCommit() OVERRIDE
1869 m_numCompleteCommits
++;
1870 switch (m_numCompleteCommits
) {
1872 EXPECT_EQ(0, m_numCommitsDeferred
);
1873 m_layerTreeHost
->setDeferCommits(true);
1874 postSetNeedsCommitToMainThread();
1885 virtual void afterTest() OVERRIDE
1887 EXPECT_EQ(1, m_numCommitsDeferred
);
1888 EXPECT_EQ(2, m_numCompleteCommits
);
1892 int m_numCommitsDeferred
;
1893 int m_numCompleteCommits
;
1896 TEST_F(LayerTreeHostTestDeferCommits
, runMultiThread
)
1901 class LayerTreeHostWithProxy
: public LayerTreeHost
{
1903 LayerTreeHostWithProxy(FakeLayerImplTreeHostClient
* client
, const LayerTreeSettings
& settings
, scoped_ptr
<Proxy
> proxy
)
1904 : LayerTreeHost(client
, settings
)
1906 EXPECT_TRUE(initializeForTesting(proxy
.Pass()));
1910 FakeLayerImplTreeHostClient m_client
;
1913 TEST(LayerTreeHostTest
, LimitPartialUpdates
)
1915 // When partial updates are not allowed, max updates should be 0.
1917 FakeLayerImplTreeHostClient client
;
1919 scoped_ptr
<FakeProxy
> proxy
= make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1920 proxy
->rendererCapabilities().allowPartialTextureUpdates
= false;
1921 proxy
->setMaxPartialTextureUpdates(5);
1923 LayerTreeSettings settings
;
1924 settings
.maxPartialTextureUpdates
= 10;
1926 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1927 EXPECT_TRUE(host
.initializeRendererIfNeeded());
1929 EXPECT_EQ(0u, host
.settings().maxPartialTextureUpdates
);
1932 // When partial updates are allowed, max updates should be limited by the proxy.
1934 FakeLayerImplTreeHostClient client
;
1936 scoped_ptr
<FakeProxy
> proxy
= make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1937 proxy
->rendererCapabilities().allowPartialTextureUpdates
= true;
1938 proxy
->setMaxPartialTextureUpdates(5);
1940 LayerTreeSettings settings
;
1941 settings
.maxPartialTextureUpdates
= 10;
1943 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1944 EXPECT_TRUE(host
.initializeRendererIfNeeded());
1946 EXPECT_EQ(5u, host
.settings().maxPartialTextureUpdates
);
1949 // When partial updates are allowed, max updates should also be limited by the settings.
1951 FakeLayerImplTreeHostClient client
;
1953 scoped_ptr
<FakeProxy
> proxy
= make_scoped_ptr(new FakeProxy(scoped_ptr
<Thread
>()));
1954 proxy
->rendererCapabilities().allowPartialTextureUpdates
= true;
1955 proxy
->setMaxPartialTextureUpdates(20);
1957 LayerTreeSettings settings
;
1958 settings
.maxPartialTextureUpdates
= 10;
1960 LayerTreeHostWithProxy
host(&client
, settings
, proxy
.PassAs
<Proxy
>());
1961 EXPECT_TRUE(host
.initializeRendererIfNeeded());
1963 EXPECT_EQ(10u, host
.settings().maxPartialTextureUpdates
);
1967 TEST(LayerTreeHostTest
, PartialUpdatesWithGLRenderer
)
1969 bool useSoftwareRendering
= false;
1970 bool useDelegatingRenderer
= false;
1971 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
1973 LayerTreeSettings settings
;
1974 settings
.maxPartialTextureUpdates
= 4;
1976 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
1977 EXPECT_TRUE(host
->initializeRendererIfNeeded());
1978 EXPECT_EQ(4u, host
->settings().maxPartialTextureUpdates
);
1981 TEST(LayerTreeHostTest
, PartialUpdatesWithSoftwareRenderer
)
1983 bool useSoftwareRendering
= true;
1984 bool useDelegatingRenderer
= false;
1985 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
1987 LayerTreeSettings settings
;
1988 settings
.maxPartialTextureUpdates
= 4;
1990 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
1991 EXPECT_TRUE(host
->initializeRendererIfNeeded());
1992 EXPECT_EQ(4u, host
->settings().maxPartialTextureUpdates
);
1995 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndGLContent
)
1997 bool useSoftwareRendering
= false;
1998 bool useDelegatingRenderer
= true;
1999 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
2001 LayerTreeSettings settings
;
2002 settings
.maxPartialTextureUpdates
= 4;
2004 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
2005 EXPECT_TRUE(host
->initializeRendererIfNeeded());
2006 EXPECT_EQ(0u, host
->settings().maxPartialTextureUpdates
);
2009 TEST(LayerTreeHostTest
, PartialUpdatesWithDelegatingRendererAndSoftwareContent
)
2011 bool useSoftwareRendering
= true;
2012 bool useDelegatingRenderer
= true;
2013 FakeLayerImplTreeHostClient
client(useSoftwareRendering
, useDelegatingRenderer
);
2015 LayerTreeSettings settings
;
2016 settings
.maxPartialTextureUpdates
= 4;
2018 scoped_ptr
<LayerTreeHost
> host
= LayerTreeHost::create(&client
, settings
, scoped_ptr
<Thread
>());
2019 EXPECT_TRUE(host
->initializeRendererIfNeeded());
2020 EXPECT_EQ(0u, host
->settings().maxPartialTextureUpdates
);
2023 class LayerTreeHostTestMaxPendingFrames
: public LayerTreeHostTest
{
2025 LayerTreeHostTestMaxPendingFrames()
2026 : LayerTreeHostTest()
2030 virtual scoped_ptr
<OutputSurface
> createOutputSurface() OVERRIDE
2032 if (m_delegatingRenderer
)
2033 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
2034 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
2037 virtual void beginTest() OVERRIDE
2039 postSetNeedsCommitToMainThread();
2042 virtual void drawLayersOnThread(LayerTreeHostImpl
* hostImpl
) OVERRIDE
2044 DCHECK(hostImpl
->proxy()->hasImplThread());
2046 const ThreadProxy
* proxy
= static_cast<ThreadProxy
*>(hostImpl
->proxy());
2047 if (m_delegatingRenderer
)
2048 EXPECT_EQ(1, proxy
->maxFramesPendingForTesting());
2050 EXPECT_EQ(FrameRateController::kDefaultMaxFramesPending
, proxy
->maxFramesPendingForTesting());
2054 virtual void afterTest() OVERRIDE
2059 bool m_delegatingRenderer
;
2062 TEST_F(LayerTreeHostTestMaxPendingFrames
, DelegatingRenderer
)
2064 m_delegatingRenderer
= true;
2068 TEST_F(LayerTreeHostTestMaxPendingFrames
, GLRenderer
)
2070 m_delegatingRenderer
= false;