Enabling tests which should be fixed by r173829.
[chromium-blink-merge.git] / cc / layer_tree_host_unittest.cc
blobe8d86ccb35d3274c97d3b8ef15313fd16c53282f
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"
36 namespace cc {
37 namespace {
39 class LayerTreeHostTest : public ThreadedTest { };
41 // Shortlived layerTreeHosts shouldn't die.
42 class LayerTreeHostTestShortlived1 : public LayerTreeHostTest {
43 public:
44 LayerTreeHostTestShortlived1() { }
46 virtual void beginTest() OVERRIDE
48 // Kill the layerTreeHost immediately.
49 m_layerTreeHost->setRootLayer(0);
50 m_layerTreeHost.reset();
52 endTest();
55 virtual void afterTest() OVERRIDE
60 // Shortlived layerTreeHosts shouldn't die with a commit in flight.
61 class LayerTreeHostTestShortlived2 : public LayerTreeHostTest {
62 public:
63 LayerTreeHostTestShortlived2() { }
65 virtual void beginTest() OVERRIDE
67 postSetNeedsCommitToMainThread();
69 // Kill the layerTreeHost immediately.
70 m_layerTreeHost->setRootLayer(0);
71 m_layerTreeHost.reset();
73 endTest();
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 {
85 public:
86 LayerTreeHostTestShortlived3() { }
88 virtual void beginTest() OVERRIDE
90 postSetNeedsRedrawToMainThread();
92 // Kill the layerTreeHost immediately.
93 m_layerTreeHost->setRootLayer(0);
94 m_layerTreeHost.reset();
96 endTest();
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 {
108 public:
109 LayerTreeHostTestCommitingWithContinuousRedraw()
110 : m_numCompleteCommits(0)
111 , m_numDraws(0)
115 virtual void beginTest() OVERRIDE
117 postSetNeedsCommitToMainThread();
120 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
122 m_numCompleteCommits++;
123 if (m_numCompleteCommits == 2)
124 endTest();
127 virtual void drawLayersOnThread(LayerTreeHostImpl*) OVERRIDE
129 if (m_numDraws == 1)
130 postSetNeedsCommitToMainThread();
131 m_numDraws++;
132 postSetNeedsRedrawToMainThread();
135 virtual void afterTest() OVERRIDE
139 private:
140 int m_numCompleteCommits;
141 int m_numDraws;
144 TEST_F(LayerTreeHostTestCommitingWithContinuousRedraw, runMultiThread)
146 runTest(true);
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 {
152 public:
153 LayerTreeHostTestSetNeedsCommit1()
154 : m_numCommits(0)
155 , m_numDraws(0)
159 virtual void beginTest() OVERRIDE
161 postSetNeedsCommitToMainThread();
162 postSetNeedsCommitToMainThread();
165 virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
167 m_numDraws++;
168 if (!impl->activeTree()->source_frame_number())
169 endTest();
172 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
174 m_numCommits++;
177 virtual void afterTest() OVERRIDE
179 EXPECT_GE(1, m_numCommits);
180 EXPECT_GE(1, m_numDraws);
183 private:
184 int m_numCommits;
185 int m_numDraws;
188 TEST_F(LayerTreeHostTestSetNeedsCommit1, DISABLED_runMultiThread)
190 runTest(true);
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 {
196 public:
197 LayerTreeHostTestSetNeedsCommit2()
198 : m_numCommits(0)
199 , m_numDraws(0)
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)
213 endTest();
216 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
218 m_numCommits++;
221 virtual void afterTest() OVERRIDE
223 EXPECT_EQ(2, m_numCommits);
224 EXPECT_GE(2, m_numDraws);
227 private:
228 int m_numCommits;
229 int m_numDraws;
232 TEST_F(LayerTreeHostTestSetNeedsCommit2, runMultiThread)
234 runTest(true);
237 // 1 setNeedsRedraw after the first commit has completed should lead to 1
238 // additional draw.
239 class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
240 public:
241 LayerTreeHostTestSetNeedsRedraw()
242 : m_numCommits(0)
243 , m_numDraws(0)
247 virtual void beginTest() OVERRIDE
249 postSetNeedsCommitToMainThread();
252 virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
254 EXPECT_EQ(0, impl->activeTree()->source_frame_number());
255 if (!m_numDraws)
256 postSetNeedsRedrawToMainThread(); // Redraw again to verify that the second redraw doesn't commit.
257 else
258 endTest();
259 m_numDraws++;
262 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
264 EXPECT_EQ(0, m_numDraws);
265 m_numCommits++;
268 virtual void afterTest() OVERRIDE
270 EXPECT_GE(2, m_numDraws);
271 EXPECT_EQ(1, m_numCommits);
274 private:
275 int m_numCommits;
276 int m_numDraws;
279 TEST_F(LayerTreeHostTestSetNeedsRedraw, runMultiThread)
281 runTest(true);
284 class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
285 public:
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()) {
303 case 1:
304 // Changing the content bounds will cause a single commit!
305 m_rootLayer->setRasterScale(4.0f);
306 break;
307 default:
308 // No extra commits.
309 EXPECT_EQ(2, m_layerTreeHost->commitNumber());
310 endTest();
314 virtual void afterTest() OVERRIDE
318 private:
319 FakeContentLayerClient m_client;
320 scoped_refptr<ContentLayer> m_rootLayer;
323 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate)
325 class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
326 public:
327 LayerTreeHostTestCompositeAndReadback()
328 : m_numCommits(0)
332 virtual void beginTest() OVERRIDE
334 postSetNeedsCommitToMainThread();
337 virtual void didCommit() OVERRIDE
339 m_numCommits++;
340 if (m_numCommits == 1) {
341 char pixels[4];
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) {
346 endTest();
347 } else {
348 NOTREACHED();
352 virtual void afterTest() OVERRIDE
356 private:
357 int m_numCommits;
360 TEST_F(LayerTreeHostTestCompositeAndReadback, runMultiThread)
362 runTest(true);
365 class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws : public LayerTreeHostTest {
366 public:
367 LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
368 : m_numCommits(0)
372 virtual void beginTest() OVERRIDE
374 postSetNeedsCommitToMainThread();
377 virtual void didCommit() OVERRIDE
379 m_numCommits++;
380 if (m_numCommits == 1) {
381 m_layerTreeHost->setNeedsCommit();
382 } else if (m_numCommits == 2) {
383 char pixels[4];
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) {
388 endTest();
389 } else {
390 NOTREACHED();
394 virtual void afterTest() OVERRIDE
398 private:
399 int m_numCommits;
402 TEST_F(LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws, runMultiThread)
404 runTest(true);
407 // If the layerTreeHost says it can't draw, then we should not try to draw.
408 class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
409 public:
410 LayerTreeHostTestCanDrawBlocksDrawing()
411 : m_numCommits(0)
412 , m_done(false)
416 virtual void beginTest() OVERRIDE
418 postSetNeedsCommitToMainThread();
421 virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
423 if (m_done)
424 return;
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
432 if (m_done)
433 return;
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
442 m_numCommits++;
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) {
447 char pixels[4];
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));
452 m_done = true;
453 endTest();
457 virtual void afterTest() OVERRIDE
461 private:
462 int m_numCommits;
463 bool m_done;
466 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing)
468 // beginLayerWrite should prevent draws from executing until a commit occurs
469 class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
470 public:
471 LayerTreeHostTestWriteLayersRedraw()
472 : m_numCommits(0)
473 , m_numDraws(0)
477 virtual void beginTest() OVERRIDE
479 postAcquireLayerTextures();
480 postSetNeedsRedrawToMainThread(); // should be inhibited without blocking
481 postSetNeedsCommitToMainThread();
484 virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
486 m_numDraws++;
487 EXPECT_EQ(m_numDraws, m_numCommits);
490 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
492 m_numCommits++;
493 endTest();
496 virtual void afterTest() OVERRIDE
498 EXPECT_EQ(1, m_numCommits);
501 private:
502 int m_numCommits;
503 int m_numDraws;
506 TEST_F(LayerTreeHostTestWriteLayersRedraw, runMultiThread)
508 runTest(true);
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 {
517 public:
518 LayerTreeHostTestWriteLayersAfterVisible()
519 : m_numCommits(0)
523 virtual void beginTest() OVERRIDE
525 postSetNeedsCommitToMainThread();
528 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
530 m_numCommits++;
531 if (m_numCommits == 2)
532 endTest();
533 else if (m_numCommits < 2) {
534 postSetVisibleToMainThread(false);
535 postSetVisibleToMainThread(true);
536 postAcquireLayerTextures();
537 postSetNeedsCommitToMainThread();
541 virtual void afterTest() OVERRIDE
545 private:
546 int m_numCommits;
549 TEST_F(LayerTreeHostTestWriteLayersAfterVisible, runMultiThread)
551 runTest(true);
554 // A compositeAndReadback while invisible should force a normal commit without assertion.
555 class LayerTreeHostTestCompositeAndReadbackWhileInvisible : public LayerTreeHostTest {
556 public:
557 LayerTreeHostTestCompositeAndReadbackWhileInvisible()
558 : m_numCommits(0)
562 virtual void beginTest() OVERRIDE
564 postSetNeedsCommitToMainThread();
567 virtual void didCommitAndDrawFrame() OVERRIDE
569 m_numCommits++;
570 if (m_numCommits == 1) {
571 m_layerTreeHost->setVisible(false);
572 m_layerTreeHost->setNeedsCommit();
573 m_layerTreeHost->setNeedsCommit();
574 char pixels[4];
575 m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
576 } else
577 endTest();
581 virtual void afterTest() OVERRIDE
585 private:
586 int m_numCommits;
589 TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible, runMultiThread)
591 runTest(true);
594 class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
595 public:
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
612 ASSERT_FALSE(true);
613 endTest();
616 virtual void afterTest() OVERRIDE
620 private:
623 TEST_F(LayerTreeHostTestAbortFrameWhenInvisible, runMultiThread)
625 runTest(true);
628 // This test verifies that properties on the layer tree host are commited to the impl side.
629 class LayerTreeHostTestCommit : public LayerTreeHostTest {
630 public:
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());
649 endTest();
652 virtual void afterTest() OVERRIDE { }
655 TEST_F(LayerTreeHostTestCommit, runTest)
657 runTest(true);
660 // Verifies that startPageScaleAnimation events propagate correctly from LayerTreeHost to
661 // LayerTreeHostImpl in the MT compositor.
662 class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
663 public:
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());
709 endTest();
710 } else
711 postSetNeedsRedrawToMainThread();
714 virtual void afterTest() OVERRIDE
718 private:
719 bool m_animationRequested;
722 TEST_F(LayerTreeHostTestStartPageScaleAnimation, runTest)
724 runTest(true);
727 class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
728 public:
730 LayerTreeHostTestSetVisible()
731 : m_numDraws(0)
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());
746 ++m_numDraws;
747 endTest();
750 virtual void afterTest() OVERRIDE
752 EXPECT_EQ(1, m_numDraws);
755 private:
756 int m_numDraws;
759 TEST_F(LayerTreeHostTestSetVisible, runMultiThread)
761 runTest(true);
764 class TestOpacityChangeLayerDelegate : public ContentLayerClient {
765 public:
766 TestOpacityChangeLayerDelegate()
767 : m_testLayer(0)
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.
779 if (m_testLayer)
780 m_testLayer->setOpacity(0);
783 private:
784 Layer* m_testLayer;
787 class ContentLayerWithUpdateTracking : public ContentLayer {
788 public:
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++;
800 private:
801 explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
802 : ContentLayer(client)
803 , m_paintContentsCount(0)
805 setAnchorPoint(gfx::PointF(0, 0));
806 setBounds(gfx::Size(10, 10));
807 setIsDrawable(true);
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 {
818 public:
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
836 endTest();
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;
848 private:
849 TestOpacityChangeLayerDelegate m_testOpacityChangeDelegate;
850 scoped_refptr<ContentLayerWithUpdateTracking> m_updateCheckLayer;
853 TEST_F(LayerTreeHostTestOpacityChange, runMultiThread)
855 runTest(true);
858 class NoScaleContentLayer : public ContentLayer {
859 public:
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(
869 idealContentsScale,
870 contentsScaleX,
871 contentsScaleY,
872 contentBounds);
875 private:
876 explicit NoScaleContentLayer(ContentLayerClient* client)
877 : ContentLayer(client) { }
878 virtual ~NoScaleContentLayer() { }
881 class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : public LayerTreeHostTest {
882 public:
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());
978 endTest();
981 virtual void afterTest() OVERRIDE
983 m_rootLayer = NULL;
984 m_childLayer = NULL;
987 private:
988 FakeContentLayerClient m_client;
989 scoped_refptr<NoScaleContentLayer> m_rootLayer;
990 scoped_refptr<ContentLayer> m_childLayer;
993 TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers, runMultiThread)
995 runTest(true);
998 // Verify atomicity of commits and reuse of textures.
999 class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest {
1000 public:
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()) {
1039 case 0:
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();
1050 break;
1051 case 1:
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();
1066 break;
1067 case 2:
1068 endTest();
1069 break;
1070 default:
1071 NOTREACHED();
1072 break;
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
1095 private:
1096 FakeContentLayerClient m_client;
1097 scoped_refptr<FakeContentLayer> m_layer;
1098 scoped_refptr<FakeScrollbarLayer> m_scrollbar;
1101 TEST_F(LayerTreeHostTestAtomicCommit, runMultiThread)
1103 runTest(true);
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();
1109 if (parent)
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 {
1119 public:
1120 LayerTreeHostTestAtomicCommitWithPartialUpdate()
1121 : m_numCommits(0)
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()) {
1171 case 0:
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();
1184 break;
1185 case 1:
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();
1206 break;
1207 case 2:
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();
1225 break;
1226 case 3:
1227 // No textures should be used for commit.
1228 EXPECT_EQ(0, context->NumUsedTextures());
1230 context->ResetUsedTextures();
1231 postSetNeedsCommitToMainThread();
1232 break;
1233 case 4:
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();
1241 break;
1242 case 5:
1243 endTest();
1244 break;
1245 default:
1246 NOTREACHED();
1247 break;
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());
1259 else
1260 EXPECT_EQ(4, context->NumUsedTextures());
1262 context->ResetUsedTextures();
1265 virtual void layout() OVERRIDE
1267 switch (m_numCommits++) {
1268 case 0:
1269 case 1:
1270 m_parent->setNeedsDisplay();
1271 m_child->setNeedsDisplay();
1272 m_scrollbarWithPaints->setNeedsDisplay();
1273 m_scrollbarWithoutPaints->setNeedsDisplay();
1274 break;
1275 case 2:
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));
1281 break;
1282 case 3:
1283 m_child->setNeedsDisplay();
1284 m_scrollbarWithPaints->setNeedsDisplay();
1285 m_scrollbarWithoutPaints->setNeedsDisplay();
1286 m_layerTreeHost->setViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
1287 break;
1288 case 4:
1289 m_layerTreeHost->setViewportSize(gfx::Size(10, 20), gfx::Size(10, 20));
1290 break;
1291 case 5:
1292 break;
1293 default:
1294 NOTREACHED();
1295 break;
1299 virtual void afterTest() OVERRIDE
1303 private:
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;
1309 int m_numCommits;
1312 TEST_F(LayerTreeHostTestAtomicCommitWithPartialUpdate, runMultiThread)
1314 runTest(true);
1317 class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1318 public:
1319 LayerTreeHostTestFinishAllRendering()
1320 : m_once(false)
1321 , m_drawCount(0)
1325 virtual void beginTest() OVERRIDE
1327 m_layerTreeHost->setNeedsRedraw();
1328 postSetNeedsCommitToMainThread();
1331 virtual void didCommitAndDrawFrame() OVERRIDE
1333 if (m_once)
1334 return;
1335 m_once = true;
1336 m_layerTreeHost->setNeedsRedraw();
1337 m_layerTreeHost->acquireLayerTextures();
1339 base::AutoLock lock(m_lock);
1340 m_drawCount = 0;
1342 m_layerTreeHost->finishAllRendering();
1344 base::AutoLock lock(m_lock);
1345 EXPECT_EQ(0, m_drawCount);
1347 endTest();
1350 virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
1352 base::AutoLock lock(m_lock);
1353 ++m_drawCount;
1356 virtual void afterTest() OVERRIDE
1359 private:
1361 bool m_once;
1362 base::Lock m_lock;
1363 int m_drawCount;
1366 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering)
1368 class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1369 public:
1370 LayerTreeHostTestCompositeAndReadbackCleanup() { }
1372 virtual void beginTest() OVERRIDE
1374 Layer* rootLayer = m_layerTreeHost->rootLayer();
1376 char pixels[4];
1377 m_layerTreeHost->compositeAndReadback(static_cast<void*>(&pixels), gfx::Rect(0, 0, 1, 1));
1378 EXPECT_FALSE(rootLayer->renderSurface());
1380 endTest();
1383 virtual void afterTest() OVERRIDE
1388 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup)
1390 class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit : public LayerTreeHostTest {
1391 public:
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()) {
1430 case 0:
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));
1437 break;
1438 case 1:
1439 EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId));
1440 EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId));
1442 endTest();
1443 break;
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.
1454 m_rootLayer = NULL;
1455 m_surfaceLayer1 = NULL;
1456 m_replicaLayer1 = NULL;
1457 m_surfaceLayer2 = NULL;
1458 m_replicaLayer2 = NULL;
1461 private:
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 {
1473 public:
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; }
1485 private:
1486 EvictionTestLayer() : Layer() { }
1487 virtual ~EvictionTestLayer() { }
1489 void createTextureIfNeeded()
1491 if (m_texture.get())
1492 return;
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;
1499 SkBitmap m_bitmap;
1502 class EvictionTestLayerImpl : public LayerImpl {
1503 public:
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; }
1518 private:
1519 EvictionTestLayerImpl(LayerTreeImpl* treeImpl, int id)
1520 : LayerImpl(treeImpl, id)
1521 , m_hasTexture(false) { }
1523 bool m_hasTexture;
1526 void EvictionTestLayer::setTexturePriorities(const PriorityCalculator&)
1528 createTextureIfNeeded();
1529 if (!m_texture.get())
1530 return;
1531 m_texture->setRequestPriority(PriorityCalculator::uiPriority(true));
1534 void EvictionTestLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker*, RenderingStats&)
1536 createTextureIfNeeded();
1537 if (!m_texture.get())
1538 return;
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 {
1560 public:
1561 LayerTreeHostTestEvictTextures()
1562 : m_layer(EvictionTestLayer::create())
1563 , m_implForEvictTextures(0)
1564 , m_numCommits(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
1595 // needsCommit.
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
1601 // needsCommit.
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
1613 // recovery path.
1614 virtual void didCommitAndDrawFrame() OVERRIDE
1616 switch (m_numCommits) {
1617 case 1:
1618 EXPECT_TRUE(m_layer->haveBackingTexture());
1619 postEvictTextures();
1620 break;
1621 case 2:
1622 EXPECT_TRUE(m_layer->haveBackingTexture());
1623 m_layerTreeHost->setNeedsCommit();
1624 break;
1625 case 3:
1626 break;
1627 case 4:
1628 EXPECT_TRUE(m_layer->haveBackingTexture());
1629 m_layerTreeHost->setNeedsCommit();
1630 break;
1631 case 5:
1632 break;
1633 case 6:
1634 EXPECT_TRUE(m_layer->haveBackingTexture());
1635 endTest();
1636 break;
1637 default:
1638 NOTREACHED();
1639 break;
1643 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE
1645 m_implForEvictTextures = impl;
1648 virtual void layout() OVERRIDE
1650 ++m_numCommits;
1651 switch (m_numCommits) {
1652 case 1:
1653 case 2:
1654 break;
1655 case 3:
1656 postEvictTextures();
1657 break;
1658 case 4:
1659 // We couldn't check in didCommitAndDrawFrame on commit 3, so check here.
1660 EXPECT_FALSE(m_layer->haveBackingTexture());
1661 break;
1662 case 5:
1663 postEvictTextures();
1664 break;
1665 case 6:
1666 // We couldn't check in didCommitAndDrawFrame on commit 5, so check here.
1667 EXPECT_FALSE(m_layer->haveBackingTexture());
1668 postEvictTextures();
1669 break;
1670 default:
1671 NOTREACHED();
1672 break;
1676 virtual void afterTest() OVERRIDE
1680 private:
1681 FakeContentLayerClient m_client;
1682 scoped_refptr<EvictionTestLayer> m_layer;
1683 LayerTreeHostImpl* m_implForEvictTextures;
1684 int m_numCommits;
1687 TEST_F(LayerTreeHostTestEvictTextures, runMultiThread)
1689 runTest(true);
1692 class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1693 public:
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)
1711 return;
1712 postSetNeedsCommitToMainThread();
1715 virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
1717 if (m_numDrawLayers == 1)
1718 m_numCommitComplete++;
1721 virtual void drawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE
1723 m_numDrawLayers++;
1724 if (m_numDrawLayers == 2)
1725 endTest();
1728 virtual void afterTest() OVERRIDE
1730 // Check that we didn't commit twice between first and second draw.
1731 EXPECT_EQ(1, m_numCommitComplete);
1734 private:
1735 int m_numCommitComplete;
1736 int m_numDrawLayers;
1739 TEST_F(LayerTreeHostTestContinuousCommit, runMultiThread)
1741 runTest(true);
1744 class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1745 public:
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)
1770 return;
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
1782 m_numDrawLayers++;
1783 if (m_numDrawLayers == 2)
1784 endTest();
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;
1796 private:
1797 FakeContentLayerClient m_fakeDelegate;
1798 scoped_refptr<Layer> m_contentLayer;
1799 int m_numCommitComplete;
1800 int m_numDrawLayers;
1803 TEST_F(LayerTreeHostTestContinuousInvalidate, runMultiThread)
1805 runTest(true);
1808 class LayerTreeHostTestAdjustPointForZoom : public LayerTreeHostTest {
1809 public:
1810 LayerTreeHostTestAdjustPointForZoom()
1814 virtual void beginTest() OVERRIDE
1816 gfx::Transform m;
1817 m.Translate(250, 360);
1818 m.Scale(2, 2);
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());
1835 endTest();
1838 virtual void afterTest() OVERRIDE
1843 TEST_F(LayerTreeHostTestAdjustPointForZoom, runMultiThread)
1845 runTest(true);
1848 class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1849 public:
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) {
1871 case 1:
1872 EXPECT_EQ(0, m_numCommitsDeferred);
1873 m_layerTreeHost->setDeferCommits(true);
1874 postSetNeedsCommitToMainThread();
1875 break;
1876 case 2:
1877 endTest();
1878 break;
1879 default:
1880 NOTREACHED();
1881 break;
1885 virtual void afterTest() OVERRIDE
1887 EXPECT_EQ(1, m_numCommitsDeferred);
1888 EXPECT_EQ(2, m_numCompleteCommits);
1891 private:
1892 int m_numCommitsDeferred;
1893 int m_numCompleteCommits;
1896 TEST_F(LayerTreeHostTestDeferCommits, runMultiThread)
1898 runTest(true);
1901 class LayerTreeHostWithProxy : public LayerTreeHost {
1902 public:
1903 LayerTreeHostWithProxy(FakeLayerImplTreeHostClient* client, const LayerTreeSettings& settings, scoped_ptr<Proxy> proxy)
1904 : LayerTreeHost(client, settings)
1906 EXPECT_TRUE(initializeForTesting(proxy.Pass()));
1909 private:
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 {
2024 public:
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());
2049 else
2050 EXPECT_EQ(FrameRateController::kDefaultMaxFramesPending, proxy->maxFramesPendingForTesting());
2051 endTest();
2054 virtual void afterTest() OVERRIDE
2058 protected:
2059 bool m_delegatingRenderer;
2062 TEST_F(LayerTreeHostTestMaxPendingFrames, DelegatingRenderer)
2064 m_delegatingRenderer = true;
2065 runTest(true);
2068 TEST_F(LayerTreeHostTestMaxPendingFrames, GLRenderer)
2070 m_delegatingRenderer = false;
2071 runTest(true);
2074 } // namespace
2075 } // namespace cc