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