diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 20:03:38 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 20:03:38 +0000 |
commit | 23bbb41cbfef41530bd637d7fe46c1fb8f571133 (patch) | |
tree | 3118d3763fe490d57a47c3e938ad84b466bd595a /cc | |
parent | 6de743ab3928a797cc16e97b8f8091f408b4a127 (diff) | |
download | chromium_src-23bbb41cbfef41530bd637d7fe46c1fb8f571133.zip chromium_src-23bbb41cbfef41530bd637d7fe46c1fb8f571133.tar.gz chromium_src-23bbb41cbfef41530bd637d7fe46c1fb8f571133.tar.bz2 |
Roll CC snapshot up to WK r127064
TBR=nduca@chromium.org
BUG=
Review URL: https://chromiumcodereview.appspot.com/10889048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154239 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/CCFrameRateController.cpp | 2 | ||||
-rw-r--r-- | cc/CCHeadsUpDisplayTest.cpp | 110 | ||||
-rw-r--r-- | cc/CCLayerSorter.cpp | 2 | ||||
-rw-r--r-- | cc/CCLayerTreeHost.cpp | 14 | ||||
-rw-r--r-- | cc/CCLayerTreeHost.h | 2 | ||||
-rw-r--r-- | cc/CCLayerTreeHostCommon.cpp | 7 | ||||
-rw-r--r-- | cc/CCLayerTreeHostCommonTest.cpp | 307 | ||||
-rw-r--r-- | cc/CCLayerTreeHostImpl.cpp | 4 | ||||
-rw-r--r-- | cc/CCLayerTreeHostTest.cpp | 6 | ||||
-rw-r--r-- | cc/CCOcclusionTrackerTest.cpp | 10 | ||||
-rw-r--r-- | cc/CCScheduler.cpp | 20 | ||||
-rw-r--r-- | cc/CCScheduler.h | 6 | ||||
-rw-r--r-- | cc/CCSchedulerTest.cpp | 17 | ||||
-rw-r--r-- | cc/CCTextureUpdateController.cpp | 40 | ||||
-rw-r--r-- | cc/CCTextureUpdateController.h | 22 | ||||
-rw-r--r-- | cc/CCTextureUpdateControllerTest.cpp | 71 | ||||
-rw-r--r-- | cc/CCThreadProxy.cpp | 26 | ||||
-rw-r--r-- | cc/CCThreadProxy.h | 8 | ||||
-rw-r--r-- | cc/CCThreadedTest.cpp | 3 | ||||
-rw-r--r-- | cc/CCThreadedTest.h | 7 | ||||
-rw-r--r-- | cc/cc_tests.gyp | 1 |
21 files changed, 581 insertions, 104 deletions
diff --git a/cc/CCFrameRateController.cpp b/cc/CCFrameRateController.cpp index 6f021f1..b264bc2 100644 --- a/cc/CCFrameRateController.cpp +++ b/cc/CCFrameRateController.cpp @@ -59,9 +59,9 @@ CCFrameRateController::~CCFrameRateController() void CCFrameRateController::setActive(bool active) { - TRACE_EVENT1("cc", "CCFrameRateController::setActive", "active", active); if (m_active == active) return; + TRACE_EVENT1("cc", "CCFrameRateController::setActive", "active", active); m_active = active; if (m_isTimeSourceThrottling) diff --git a/cc/CCHeadsUpDisplayTest.cpp b/cc/CCHeadsUpDisplayTest.cpp new file mode 100644 index 0000000..6c8500a --- /dev/null +++ b/cc/CCHeadsUpDisplayTest.cpp @@ -0,0 +1,110 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#include "CCLayerTreeHost.h" +#include "CCThreadedTest.h" +#include "HeadsUpDisplayLayerChromium.h" +#include "LayerChromium.h" + +using namespace WebCore; +using namespace WebKitTests; + +namespace { + +class CCHeadsUpDisplayTest : public CCThreadedTest { +protected: + virtual void initializeSettings(CCLayerTreeSettings& settings) OVERRIDE + { + // Enable the HUD without requiring text. + settings.showPropertyChangedRects = true; + } +}; + +class DrawsContentLayerChromium : public LayerChromium { +public: + static PassRefPtr<DrawsContentLayerChromium> create() { return adoptRef(new DrawsContentLayerChromium()); } + virtual bool drawsContent() const OVERRIDE { return true; } + +private: + DrawsContentLayerChromium() : LayerChromium() { } +}; + +class CCHudWithRootLayerChange : public CCHeadsUpDisplayTest { +public: + CCHudWithRootLayerChange() + : m_rootLayer1(DrawsContentLayerChromium::create()) + , m_rootLayer2(DrawsContentLayerChromium::create()) + , m_numCommits(0) + { + } + + virtual void beginTest() OVERRIDE + { + m_rootLayer1->setBounds(IntSize(30, 30)); + m_rootLayer2->setBounds(IntSize(30, 30)); + + postSetNeedsCommitToMainThread(); + } + + virtual void didCommit() OVERRIDE + { + ++m_numCommits; + + ASSERT_TRUE(m_layerTreeHost->hudLayer()); + + switch (m_numCommits) { + case 1: + // Change directly to a new root layer. + m_layerTreeHost->setRootLayer(m_rootLayer1); + break; + case 2: + EXPECT_EQ(m_rootLayer1.get(), m_layerTreeHost->hudLayer()->parent()); + // Unset the root layer. + m_layerTreeHost->setRootLayer(0); + break; + case 3: + EXPECT_EQ(0, m_layerTreeHost->hudLayer()->parent()); + // Change back to the previous root layer. + m_layerTreeHost->setRootLayer(m_rootLayer1); + break; + case 4: + EXPECT_EQ(m_rootLayer1.get(), m_layerTreeHost->hudLayer()->parent()); + // Unset the root layer. + m_layerTreeHost->setRootLayer(0); + break; + case 5: + EXPECT_EQ(0, m_layerTreeHost->hudLayer()->parent()); + // Change to a new root layer from a null root. + m_layerTreeHost->setRootLayer(m_rootLayer2); + break; + case 6: + EXPECT_EQ(m_rootLayer2.get(), m_layerTreeHost->hudLayer()->parent()); + // Change directly back to the last root layer/ + m_layerTreeHost->setRootLayer(m_rootLayer1); + break; + case 7: + EXPECT_EQ(m_rootLayer1.get(), m_layerTreeHost->hudLayer()->parent()); + endTest(); + break; + } + } + + virtual void afterTest() OVERRIDE + { + } + +private: + RefPtr<DrawsContentLayerChromium> m_rootLayer1; + RefPtr<DrawsContentLayerChromium> m_rootLayer2; + int m_numCommits; +}; + +TEST_F(CCHudWithRootLayerChange, runMultiThread) +{ + runTest(true); +} + +} // namespace diff --git a/cc/CCLayerSorter.cpp b/cc/CCLayerSorter.cpp index bf2818b..e8a14eb 100644 --- a/cc/CCLayerSorter.cpp +++ b/cc/CCLayerSorter.cpp @@ -244,7 +244,7 @@ void CCLayerSorter::createGraphEdges() #endif // Fraction of the total zRange below which z differences // are not considered reliable. - const float zThresholdFactor = 0.01; + const float zThresholdFactor = 0.01f; float zThreshold = m_zRange * zThresholdFactor; for (unsigned na = 0; na < m_nodes.size(); na++) { diff --git a/cc/CCLayerTreeHost.cpp b/cc/CCLayerTreeHost.cpp index aa8d441..10320a9 100644 --- a/cc/CCLayerTreeHost.cpp +++ b/cc/CCLayerTreeHost.cpp @@ -219,10 +219,10 @@ void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl) hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->detachLayerTree(), hostImpl)); - if (!m_hudLayer) - hostImpl->setHudLayer(0); - else + if (m_rootLayer && m_hudLayer) hostImpl->setHudLayer(static_cast<CCHeadsUpDisplayLayerImpl*>(CCLayerTreeHostCommon::findLayerInSubtree(hostImpl->rootLayer(), m_hudLayer->id()))); + else + hostImpl->setHudLayer(0); // We may have added an animation during the tree sync. This will cause both layer tree hosts // to visit their controllers. @@ -255,10 +255,8 @@ void CCLayerTreeHost::willCommit() if (m_fontAtlas) m_hudLayer->setFontAtlas(m_fontAtlas.release()); - if (m_hudLayer->parent() != m_rootLayer.get()) { - m_hudLayer->removeFromParent(); + if (!m_hudLayer->parent()) m_rootLayer->addChild(m_hudLayer); - } } } @@ -358,6 +356,10 @@ void CCLayerTreeHost::setRootLayer(PassRefPtr<LayerChromium> rootLayer) m_rootLayer = rootLayer; if (m_rootLayer) m_rootLayer->setLayerTreeHost(this); + + if (m_hudLayer) + m_hudLayer->removeFromParent(); + setNeedsCommit(); } diff --git a/cc/CCLayerTreeHost.h b/cc/CCLayerTreeHost.h index 11e1f9b..0bddc46 100644 --- a/cc/CCLayerTreeHost.h +++ b/cc/CCLayerTreeHost.h @@ -241,6 +241,8 @@ public: void setFontAtlas(PassOwnPtr<CCFontAtlas>); + HeadsUpDisplayLayerChromium* hudLayer() const { return m_hudLayer.get(); } + protected: CCLayerTreeHost(CCLayerTreeHostClient*, const CCLayerTreeSettings&); bool initialize(); diff --git a/cc/CCLayerTreeHostCommon.cpp b/cc/CCLayerTreeHostCommon.cpp index 146f796..4afae01 100644 --- a/cc/CCLayerTreeHostCommon.cpp +++ b/cc/CCLayerTreeHostCommon.cpp @@ -593,15 +593,12 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay // Layers that are not their own renderTarget will render into the target of their nearest ancestor. layer->setRenderTarget(layer->parent()->renderTarget()); } else { - // FIXME: This root layer special case code should eventually go away. But before that is truly possible, - // tests (or code) related to CCOcclusionTracker need to be adjusted so that they do not require - // the rootLayer to clip; the root layer's RenderSurface would already clip and should be enough. + // FIXME: This root layer special case code should eventually go away. https://bugs.webkit.org/show_bug.cgi?id=92290 ASSERT(!layer->parent()); ASSERT(layer->renderSurface()); ASSERT(ancestorClipsSubtree); layer->renderSurface()->setClipRect(clipRectFromAncestor); - subtreeShouldBeClipped = true; - clipRectForSubtree = clipRectFromAncestor; + subtreeShouldBeClipped = false; } } diff --git a/cc/CCLayerTreeHostCommonTest.cpp b/cc/CCLayerTreeHostCommonTest.cpp index 2fef05d..ee9077a 100644 --- a/cc/CCLayerTreeHostCommonTest.cpp +++ b/cc/CCLayerTreeHostCommonTest.cpp @@ -652,6 +652,7 @@ TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForRenderSurfaceWithClipp setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint(30, 30), IntSize(10, 10), false); parent->addChild(renderSurface1); + parent->setMasksToBounds(true); renderSurface1->addChild(child); renderSurface1->setForceRenderSurface(true); @@ -1933,6 +1934,312 @@ TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForPerspectiveUnprojection) EXPECT_INT_RECT_EQ(expected, actual); } +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForSimpleLayers) +{ + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child3 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(child1); + root->addChild(child2); + root->addChild(child3); + + WebTransformationMatrix identityMatrix; + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(50, 50), false); + setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); + setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); + + executeCalculateDrawTransformsAndVisibility(root.get()); + + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); + + // Layers that do not draw content should have empty visibleContentRects. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); + + // layer visibleContentRects are clipped by their targetSurface + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 25, 25), child2->visibleContentRect()); + EXPECT_TRUE(child3->visibleContentRect().isEmpty()); + + // layer drawableContentRects are not clipped. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child1->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); +} + +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForLayersClippedByLayer) +{ + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromium> child = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> grandChild1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> grandChild2 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> grandChild3 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(child); + child->addChild(grandChild1); + child->addChild(grandChild2); + child->addChild(grandChild3); + + WebTransformationMatrix identityMatrix; + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); + setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); + setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); + + child->setMasksToBounds(true); + executeCalculateDrawTransformsAndVisibility(root.get()); + + ASSERT_FALSE(child->renderSurface()); + + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); + + // Layers that do not draw content should have empty visibleContentRects. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), child->visibleContentRect()); + + // All grandchild visibleContentRects should be clipped by child. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), grandChild1->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 25, 25), grandChild2->visibleContentRect()); + EXPECT_TRUE(grandChild3->visibleContentRect().isEmpty()); + + // All grandchild drawableContentRects should also be clipped by child. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 50, 50), grandChild1->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(75, 75, 25, 25), grandChild2->drawableContentRect()); + EXPECT_TRUE(grandChild3->drawableContentRect().isEmpty()); +} + +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) +{ + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromium> renderSurface1 = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child3 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(renderSurface1); + renderSurface1->addChild(child1); + renderSurface1->addChild(child2); + renderSurface1->addChild(child3); + + WebTransformationMatrix identityMatrix; + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); + setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); + setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); + setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); + + renderSurface1->setForceRenderSurface(true); + executeCalculateDrawTransformsAndVisibility(root.get()); + + ASSERT_TRUE(renderSurface1->renderSurface()); + + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); + + // Layers that do not draw content should have empty visibleContentRects. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); + + // An unclipped surface grows its drawableContentRect to include all drawable regions of the subtree. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 170, 170), renderSurface1->renderSurface()->drawableContentRect()); + + // All layers that draw content into the unclipped surface are also unclipped. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child2->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child3->visibleContentRect()); + + EXPECT_INT_RECT_EQ(IntRect(5, 5, 50, 50), child1->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); +} + +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForLayersInClippedRenderSurface) +{ + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromium> renderSurface1 = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child3 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(renderSurface1); + renderSurface1->addChild(child1); + renderSurface1->addChild(child2); + renderSurface1->addChild(child3); + + WebTransformationMatrix identityMatrix; + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); + setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); + setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); + setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); + + root->setMasksToBounds(true); + renderSurface1->setForceRenderSurface(true); + executeCalculateDrawTransformsAndVisibility(root.get()); + + ASSERT_TRUE(renderSurface1->renderSurface()); + + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); + + // Layers that do not draw content should have empty visibleContentRects. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); + + // A clipped surface grows its drawableContentRect to include all drawable regions of the subtree, + // but also gets clamped by the ancestor's clip. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 95, 95), renderSurface1->renderSurface()->drawableContentRect()); + + // All layers that draw content into the surface have their visibleContentRect clipped by the surface clipRect. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 25, 25), child2->visibleContentRect()); + EXPECT_TRUE(child3->visibleContentRect().isEmpty()); + + // But the drawableContentRects are unclipped. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 50, 50), child1->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); +} + +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForSurfaceHierarchy) +{ + // Check that clipping does not propagate down surfaces. + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromium> renderSurface1 = LayerChromium::create(); + RefPtr<LayerChromium> renderSurface2 = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + RefPtr<LayerChromiumWithForcedDrawsContent> child3 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(renderSurface1); + renderSurface1->addChild(renderSurface2); + renderSurface2->addChild(child1); + renderSurface2->addChild(child2); + renderSurface2->addChild(child3); + + WebTransformationMatrix identityMatrix; + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); + setLayerPropertiesForTesting(renderSurface2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(7, 13), false); + setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); + setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); + setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); + + root->setMasksToBounds(true); + renderSurface1->setForceRenderSurface(true); + renderSurface2->setForceRenderSurface(true); + executeCalculateDrawTransformsAndVisibility(root.get()); + + ASSERT_TRUE(renderSurface1->renderSurface()); + ASSERT_TRUE(renderSurface2->renderSurface()); + + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); + + // Layers that do not draw content should have empty visibleContentRects. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface2->visibleContentRect()); + + // A clipped surface grows its drawableContentRect to include all drawable regions of the subtree, + // but also gets clamped by the ancestor's clip. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 95, 95), renderSurface1->renderSurface()->drawableContentRect()); + + // renderSurface1 lives in the "unclipped universe" of renderSurface1, and is only + // implicitly clipped by renderSurface1's contentRect. So, renderSurface2 grows to + // enclose all drawable content of its subtree. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 170, 170), renderSurface2->renderSurface()->drawableContentRect()); + + // All layers that draw content into renderSurface2 think they are unclipped. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child2->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child3->visibleContentRect()); + + // drawableContentRects are also unclipped. + EXPECT_INT_RECT_EQ(IntRect(5, 5, 50, 50), child1->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); +} + +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) +{ + // Layers that have non-axis aligned bounds (due to transforms) have an expanded, + // axis-aligned drawableContentRect and visibleContentRect. + + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromium> renderSurface1 = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(renderSurface1); + renderSurface1->addChild(child1); + + WebTransformationMatrix identityMatrix; + WebTransformationMatrix childRotation; + childRotation.rotate(45); + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); + setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); + setLayerPropertiesForTesting(child1.get(), childRotation, identityMatrix, FloatPoint(0.5, 0.5), FloatPoint(25, 25), IntSize(50, 50), false); + + renderSurface1->setForceRenderSurface(true); + executeCalculateDrawTransformsAndVisibility(root.get()); + + ASSERT_TRUE(renderSurface1->renderSurface()); + + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); + + // Layers that do not draw content should have empty visibleContentRects. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); + + // The unclipped surface grows its drawableContentRect to include all drawable regions of the subtree. + int diagonalRadius = ceil(sqrt(2.0) * 25); + IntRect expectedSurfaceDrawableContent = IntRect(50 - diagonalRadius, 50 - diagonalRadius, diagonalRadius * 2, diagonalRadius * 2); + EXPECT_INT_RECT_EQ(expectedSurfaceDrawableContent, renderSurface1->renderSurface()->drawableContentRect()); + + // All layers that draw content into the unclipped surface are also unclipped. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); + EXPECT_INT_RECT_EQ(expectedSurfaceDrawableContent, child1->drawableContentRect()); +} + +TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsWithTransformOnClippedSurface) +{ + // Layers that have non-axis aligned bounds (due to transforms) have an expanded, + // axis-aligned drawableContentRect and visibleContentRect. + + RefPtr<LayerChromium> root = LayerChromium::create(); + RefPtr<LayerChromium> renderSurface1 = LayerChromium::create(); + RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent()); + root->addChild(renderSurface1); + renderSurface1->addChild(child1); + + WebTransformationMatrix identityMatrix; + WebTransformationMatrix childRotation; + childRotation.rotate(45); + setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(50, 50), false); + setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); + setLayerPropertiesForTesting(child1.get(), childRotation, identityMatrix, FloatPoint(0.5, 0.5), FloatPoint(25, 25), IntSize(50, 50), false); + + root->setMasksToBounds(true); + renderSurface1->setForceRenderSurface(true); + executeCalculateDrawTransformsAndVisibility(root.get()); + + ASSERT_TRUE(renderSurface1->renderSurface()); + + // The clipped surface clamps the drawableContentRect that encloses the rotated layer. + int diagonalRadius = ceil(sqrt(2.0) * 25); + IntRect unclippedSurfaceContent = IntRect(50 - diagonalRadius, 50 - diagonalRadius, diagonalRadius * 2, diagonalRadius * 2); + IntRect expectedSurfaceDrawableContent = intersection(unclippedSurfaceContent, IntRect(0, 0, 50, 50)); + EXPECT_INT_RECT_EQ(expectedSurfaceDrawableContent, renderSurface1->renderSurface()->drawableContentRect()); + + // On the clipped surface, only a quarter of the child1 is visible, but when rotating + // it back to child1's content space, the actual enclosing rect ends up covering the + // full left half of child1. + EXPECT_INT_RECT_EQ(IntRect(0, 0, 26, 50), child1->visibleContentRect()); + + // The child's drawableContentRect is unclipped. + EXPECT_INT_RECT_EQ(unclippedSurfaceContent, child1->drawableContentRect()); +} + TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d) { // Verify the behavior of back-face culling when there are no preserve-3d layers. Note diff --git a/cc/CCLayerTreeHostImpl.cpp b/cc/CCLayerTreeHostImpl.cpp index 1d67042..9b11289 100644 --- a/cc/CCLayerTreeHostImpl.cpp +++ b/cc/CCLayerTreeHostImpl.cpp @@ -956,7 +956,7 @@ void CCLayerTreeHostImpl::scrollBy(const IntPoint& viewportPoint, const IntSize& appliedDelta = scrollLayerWithLocalDelta(*layerImpl, pendingDelta); // If the layer wasn't able to move, try the next one in the hierarchy. - float moveThresholdSquared = 0.1 * 0.1; + float moveThresholdSquared = 0.1f * 0.1f; if (appliedDelta.diagonalLengthSquared() < moveThresholdSquared) continue; @@ -1058,7 +1058,7 @@ void CCLayerTreeHostImpl::computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo // Only send fake scroll/zoom deltas if we're pinch zooming out by a // significant amount. This also ensures only one fake delta set will be // sent. - const float pinchZoomOutSensitivity = 0.95; + const float pinchZoomOutSensitivity = 0.95f; if (m_pageScaleDelta > pinchZoomOutSensitivity) return; diff --git a/cc/CCLayerTreeHostTest.cpp b/cc/CCLayerTreeHostTest.cpp index 23607f7..d03388f 100644 --- a/cc/CCLayerTreeHostTest.cpp +++ b/cc/CCLayerTreeHostTest.cpp @@ -18,16 +18,13 @@ #include "Extensions3DChromium.h" #include "FakeWebCompositorOutputSurface.h" #include <gmock/gmock.h> -#include <gtest/gtest.h> #include <public/Platform.h> -#include <public/WebThread.h> #include <wtf/MainThread.h> #include <wtf/OwnArrayPtr.h> using namespace WebCore; using namespace WebKit; using namespace WebKitTests; -using namespace WTF; #define EXPECT_EQ_RECT(a, b) \ EXPECT_EQ(a.x(), b.x()); \ @@ -2221,7 +2218,8 @@ private: RefPtr<LayerChromium> m_rootScrollLayer; }; -TEST_F(CCLayerTreeHostTestScrollChildLayer, runMultiThread) +// https://bugs.webkit.org/show_bug.cgi?id=95358 +TEST_F(CCLayerTreeHostTestScrollChildLayer, DISABLED_runMultiThread) { runTest(true); } diff --git a/cc/CCOcclusionTrackerTest.cpp b/cc/CCOcclusionTrackerTest.cpp index cb0eefe6..f52ce09 100644 --- a/cc/CCOcclusionTrackerTest.cpp +++ b/cc/CCOcclusionTrackerTest.cpp @@ -586,6 +586,7 @@ protected: childTransform.translate(-250, -250); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500)); child->setMasksToBounds(true); typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true); @@ -665,6 +666,7 @@ protected: childTransform.translate(-250, -250); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500)); child->setMasksToBounds(true); typename Types::ContentLayerType* layer = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true); @@ -842,6 +844,7 @@ protected: childTransform.translate(-250, -250); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::LayerType* child = this->createLayer(parent, childTransform, FloatPoint(30, 30), IntSize(500, 500)); child->setMasksToBounds(true); typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child, this->identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true); @@ -930,6 +933,7 @@ protected: childTransform.translate(-250, -250); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::LayerType* child1 = this->createSurface(parent, childTransform, FloatPoint(30, 30), IntSize(10, 10)); typename Types::LayerType* child2 = this->createSurface(parent, childTransform, FloatPoint(20, 40), IntSize(10, 10)); typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true); @@ -1044,6 +1048,7 @@ protected: child2Transform.translate(-250, -250); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::LayerType* child1 = this->createSurface(parent, child1Transform, FloatPoint(30, 20), IntSize(10, 10)); typename Types::LayerType* child2 = this->createDrawingSurface(parent, child2Transform, FloatPoint(20, 40), IntSize(10, 10), false); typename Types::ContentLayerType* layer1 = this->createDrawingLayer(child1, this->identityMatrix, FloatPoint(-10, -20), IntSize(510, 510), true); @@ -1146,6 +1151,7 @@ protected: layerTransform.translate(-250, -250); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::ContentLayerType* blurLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true); typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true); typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true); @@ -1255,6 +1261,7 @@ protected: void runMyTest() { typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 170)); + parent->setMasksToBounds(true); typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 50), true); this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(50, 50), IntSize()); this->calcDrawEtc(parent); @@ -1935,6 +1942,7 @@ protected: transform.translate(-50, -50); typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); + parent->setMasksToBounds(true); typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true); parent->setPreserves3D(true); layer->setPreserves3D(true); @@ -2201,6 +2209,7 @@ protected: void runMyTest() { typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300)); + parent->setMasksToBounds(true); typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 300), false); surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200)); this->calcDrawEtc(parent); @@ -2442,6 +2451,7 @@ protected: // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect. typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(80, 200)); + parent->setMasksToBounds(true); typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true); typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false); typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true); diff --git a/cc/CCScheduler.cpp b/cc/CCScheduler.cpp index 1840b4a..5bfad37 100644 --- a/cc/CCScheduler.cpp +++ b/cc/CCScheduler.cpp @@ -13,6 +13,7 @@ namespace WebCore { CCScheduler::CCScheduler(CCSchedulerClient* client, PassOwnPtr<CCFrameRateController> frameRateController) : m_client(client) , m_frameRateController(frameRateController) + , m_hasMoreResourceUpdates(false) , m_updateMoreResourcesPending(false) { ASSERT(m_client); @@ -67,9 +68,10 @@ void CCScheduler::setMainThreadNeedsLayerTextures() processScheduledActions(); } -void CCScheduler::beginFrameComplete() +void CCScheduler::beginFrameComplete(bool hasResourceUpdates) { TRACE_EVENT0("cc", "CCScheduler::beginFrameComplete"); + m_hasMoreResourceUpdates = hasResourceUpdates; m_stateMachine.beginFrameComplete(); processScheduledActions(); } @@ -116,7 +118,8 @@ void CCScheduler::vsyncTick() { if (m_updateMoreResourcesPending) { m_updateMoreResourcesPending = false; - m_stateMachine.beginUpdateMoreResourcesComplete(m_client->hasMoreResourceUpdates()); + ASSERT(m_hasMoreResourceUpdates); + m_stateMachine.beginUpdateMoreResourcesComplete(true); } TRACE_EVENT0("cc", "CCScheduler::vsyncTick"); @@ -125,6 +128,17 @@ void CCScheduler::vsyncTick() m_stateMachine.didLeaveVSync(); } +void CCScheduler::updateResourcesComplete() +{ + TRACE_EVENT0("cc", "CCScheduler::updateResourcesComplete"); + if (m_updateMoreResourcesPending) { + m_updateMoreResourcesPending = false; + m_stateMachine.beginUpdateMoreResourcesComplete(false); + } + m_hasMoreResourceUpdates = false; + processScheduledActions(); +} + CCSchedulerStateMachine::Action CCScheduler::nextAction() { m_stateMachine.setCanDraw(m_client->canDraw()); @@ -154,7 +168,7 @@ void CCScheduler::processScheduledActions() m_client->scheduledActionBeginFrame(); break; case CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES: - if (m_client->hasMoreResourceUpdates()) { + if (m_hasMoreResourceUpdates) { m_client->scheduledActionUpdateMoreResources(m_frameRateController->nextTickTimeIfActivated()); m_updateMoreResourcesPending = true; } else diff --git a/cc/CCScheduler.h b/cc/CCScheduler.h index 10fce73..3e2614b 100644 --- a/cc/CCScheduler.h +++ b/cc/CCScheduler.h @@ -33,7 +33,6 @@ struct CCScheduledActionDrawAndSwapResult { class CCSchedulerClient { public: virtual bool canDraw() = 0; - virtual bool hasMoreResourceUpdates() const = 0; virtual void scheduledActionBeginFrame() = 0; virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() = 0; @@ -73,7 +72,7 @@ public: // Like setNeedsRedraw(), but ensures the draw will definitely happen even if we are not visible. void setNeedsForcedRedraw(); - void beginFrameComplete(); + void beginFrameComplete(bool hasResourceUpdates); void beginFrameAborted(); void setMaxFramesPending(int); @@ -90,6 +89,8 @@ public: // CCFrameRateControllerClient implementation virtual void vsyncTick() OVERRIDE; + void updateResourcesComplete(); + private: CCScheduler(CCSchedulerClient*, PassOwnPtr<CCFrameRateController>); @@ -99,6 +100,7 @@ private: CCSchedulerClient* m_client; OwnPtr<CCFrameRateController> m_frameRateController; CCSchedulerStateMachine m_stateMachine; + bool m_hasMoreResourceUpdates; bool m_updateMoreResourcesPending; }; diff --git a/cc/CCSchedulerTest.cpp b/cc/CCSchedulerTest.cpp index ec68c71..12702bd 100644 --- a/cc/CCSchedulerTest.cpp +++ b/cc/CCSchedulerTest.cpp @@ -23,14 +23,12 @@ public: void reset() { m_actions.clear(); - m_hasMoreResourceUpdates = false; m_canDraw = true; m_drawWillHappen = true; m_swapWillHappenIfDrawHappens = true; m_numDraws = 0; } - void setHasMoreResourceUpdates(bool b) { m_hasMoreResourceUpdates = b; } void setCanDraw(bool b) { m_canDraw = b; } int numDraws() const { return m_numDraws; } @@ -46,7 +44,6 @@ public: } virtual bool canDraw() OVERRIDE { return m_canDraw; } - virtual bool hasMoreResourceUpdates() const OVERRIDE { return m_hasMoreResourceUpdates; } virtual void scheduledActionBeginFrame() OVERRIDE { m_actions.push_back("scheduledActionBeginFrame"); } virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE { @@ -93,9 +90,9 @@ TEST(CCSchedulerTest, RequestCommit) EXPECT_FALSE(timeSource->active()); client.reset(); - // Since, hasMoreResourceUpdates is set to false, + // Since, hasResourceUpdates is false, // beginFrameComplete should commit - scheduler->beginFrameComplete(); + scheduler->beginFrameComplete(false); EXPECT_EQ(1, client.numActions()); EXPECT_STREQ("scheduledActionCommit", client.action(0)); EXPECT_TRUE(timeSource->active()); @@ -129,9 +126,9 @@ TEST(CCSchedulerTest, RequestCommitAfterBeginFrame) // Now setNeedsCommit again. Calling here means we need a second frame. scheduler->setNeedsCommit(); - // Since, hasMoreResourceUpdates is set to false, and another commit is + // Since, hasResourceUpdates is false, and another commit is // needed, beginFrameComplete should commit, then begin another frame. - scheduler->beginFrameComplete(); + scheduler->beginFrameComplete(false); EXPECT_EQ(1, client.numActions()); EXPECT_STREQ("scheduledActionCommit", client.action(0)); client.reset(); @@ -164,7 +161,7 @@ TEST(CCSchedulerTest, TextureAcquisitionCollision) EXPECT_FALSE(timeSource->active()); // Trigger the commit - scheduler->beginFrameComplete(); + scheduler->beginFrameComplete(false); EXPECT_TRUE(timeSource->active()); client.reset(); @@ -192,7 +189,7 @@ TEST(CCSchedulerTest, VisibilitySwitchWithTextureAcquisition) scheduler->setVisible(true); scheduler->setNeedsCommit(); - scheduler->beginFrameComplete(); + scheduler->beginFrameComplete(false); scheduler->setMainThreadNeedsLayerTextures(); client.reset(); // Verify that pending texture acquisition fires when visibility @@ -361,7 +358,7 @@ TEST(CCSchedulerTest, RequestCommitInsideDraw) EXPECT_FALSE(timeSource->active()); EXPECT_EQ(1, client.numDraws()); EXPECT_TRUE(scheduler->commitPending()); - scheduler->beginFrameComplete(); + scheduler->beginFrameComplete(false); timeSource->tick(); EXPECT_EQ(2, client.numDraws()); diff --git a/cc/CCTextureUpdateController.cpp b/cc/CCTextureUpdateController.cpp index 25d41cc..9c448be 100644 --- a/cc/CCTextureUpdateController.cpp +++ b/cc/CCTextureUpdateController.cpp @@ -92,8 +92,9 @@ void CCTextureUpdateController::updateTextures(CCResourceProvider* resourceProvi copier->flush(); } -CCTextureUpdateController::CCTextureUpdateController(CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) - : m_timer(adoptPtr(new CCTimer(thread, this))) +CCTextureUpdateController::CCTextureUpdateController(CCTextureUpdateControllerClient* client, CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) + : m_client(client) + , m_timer(adoptPtr(new CCTimer(thread, this))) , m_queue(queue) , m_resourceProvider(resourceProvider) , m_copier(copier) @@ -107,34 +108,40 @@ CCTextureUpdateController::~CCTextureUpdateController() { } -bool CCTextureUpdateController::hasMoreUpdates() const -{ - return m_queue->hasMoreUpdates(); -} - void CCTextureUpdateController::updateMoreTextures(double monotonicTimeLimit) { + ASSERT(monotonicTimeLimit >= m_monotonicTimeLimit); m_monotonicTimeLimit = monotonicTimeLimit; - if (!m_queue->hasMoreUpdates()) + // Update already in progress. + if (m_timer->isActive()) return; // Call updateMoreTexturesNow() directly unless it's the first update // attempt. This ensures that we empty the update queue in a finite // amount of time. if (m_firstUpdateAttempt) { - updateMoreTexturesIfEnoughTimeRemaining(); + // Post a 0-delay task when no updates were left. When it runs, + // updateTexturesCompleted() will be called. + if (!updateMoreTexturesIfEnoughTimeRemaining()) + m_timer->startOneShot(0); + m_firstUpdateAttempt = false; } else updateMoreTexturesNow(); } -void CCTextureUpdateController::onTimerFired() +void CCTextureUpdateController::discardUploads() { - if (!m_queue->hasMoreUpdates()) - return; + // CCTextureUpdateControllerClient::updateTexturesCompleted will be + // called when all remaining texture copies are done. + m_queue->clearUploads(); +} - updateMoreTexturesIfEnoughTimeRemaining(); +void CCTextureUpdateController::onTimerFired() +{ + if (!updateMoreTexturesIfEnoughTimeRemaining()) + m_client->updateTexturesCompleted(); } double CCTextureUpdateController::monotonicTimeNow() const @@ -152,11 +159,16 @@ size_t CCTextureUpdateController::updateMoreTexturesSize() const return textureUpdatesPerTick; } -void CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() +bool CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() { + if (!m_queue->hasMoreUpdates()) + return false; + bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMoreTexturesTime(); if (hasTimeRemaining) updateMoreTexturesNow(); + + return true; } void CCTextureUpdateController::updateMoreTexturesNow() diff --git a/cc/CCTextureUpdateController.h b/cc/CCTextureUpdateController.h index 6fc8db3..72929c4 100644 --- a/cc/CCTextureUpdateController.h +++ b/cc/CCTextureUpdateController.h @@ -15,21 +15,31 @@ namespace WebCore { class TextureCopier; class TextureUploader; +class CCTextureUpdateControllerClient { +public: + virtual void updateTexturesCompleted() = 0; + +protected: + virtual ~CCTextureUpdateControllerClient() { } +}; + class CCTextureUpdateController : public CCTimerClient { WTF_MAKE_NONCOPYABLE(CCTextureUpdateController); public: - static PassOwnPtr<CCTextureUpdateController> create(CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) + static PassOwnPtr<CCTextureUpdateController> create(CCTextureUpdateControllerClient* client, CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) { - return adoptPtr(new CCTextureUpdateController(thread, queue, resourceProvider, copier, uploader)); + return adoptPtr(new CCTextureUpdateController(client, thread, queue, resourceProvider, copier, uploader)); } static size_t maxPartialTextureUpdates(); static void updateTextures(CCResourceProvider*, TextureCopier*, TextureUploader*, CCTextureUpdateQueue*, size_t count); virtual ~CCTextureUpdateController(); - bool hasMoreUpdates() const; void updateMoreTextures(double monotonicTimeLimit); + // Discard all remaining uploads. + void discardUploads(); + // CCTimerClient implementation. virtual void onTimerFired() OVERRIDE; @@ -39,11 +49,13 @@ public: virtual size_t updateMoreTexturesSize() const; protected: - CCTextureUpdateController(CCThread*, PassOwnPtr<CCTextureUpdateQueue>, CCResourceProvider*, TextureCopier*, TextureUploader*); + CCTextureUpdateController(CCTextureUpdateControllerClient*, CCThread*, PassOwnPtr<CCTextureUpdateQueue>, CCResourceProvider*, TextureCopier*, TextureUploader*); - void updateMoreTexturesIfEnoughTimeRemaining(); + // This returns true when there were textures left to update. + bool updateMoreTexturesIfEnoughTimeRemaining(); void updateMoreTexturesNow(); + CCTextureUpdateControllerClient* m_client; OwnPtr<CCTimer> m_timer; OwnPtr<CCTextureUpdateQueue> m_queue; bool m_contentsTexturesPurged; diff --git a/cc/CCTextureUpdateControllerTest.cpp b/cc/CCTextureUpdateControllerTest.cpp index 2ed0e59..d2a6fcf6 100644 --- a/cc/CCTextureUpdateControllerTest.cpp +++ b/cc/CCTextureUpdateControllerTest.cpp @@ -521,11 +521,23 @@ TEST_F(CCTextureUpdateControllerTest, TripleUpdateFinalUpdateAllPartial) EXPECT_EQ(kFullUploads + kPartialUploads, m_numTotalUploads); } +class FakeCCTextureUpdateControllerClient : public WebCore::CCTextureUpdateControllerClient { +public: + FakeCCTextureUpdateControllerClient() { reset(); } + void reset() { m_completedCalled = false; } + bool completedCalled() const { return m_completedCalled; } + + virtual void updateTexturesCompleted() OVERRIDE { m_completedCalled = true; } + +protected: + bool m_completedCalled; +}; + class FakeCCTextureUpdateController : public WebCore::CCTextureUpdateController { public: - static PassOwnPtr<FakeCCTextureUpdateController> create(WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) + static PassOwnPtr<FakeCCTextureUpdateController> create(WebCore::CCTextureUpdateControllerClient* client, WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) { - return adoptPtr(new FakeCCTextureUpdateController(thread, queue, resourceProvider, copier, uploader)); + return adoptPtr(new FakeCCTextureUpdateController(client, thread, queue, resourceProvider, copier, uploader)); } void setMonotonicTimeNow(double time) { m_monotonicTimeNow = time; } @@ -536,8 +548,8 @@ public: virtual size_t updateMoreTexturesSize() const OVERRIDE { return m_updateMoreTexturesSize; } protected: - FakeCCTextureUpdateController(WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) - : WebCore::CCTextureUpdateController(thread, queue, resourceProvider, copier, uploader) + FakeCCTextureUpdateController(WebCore::CCTextureUpdateControllerClient* client, WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader) + : WebCore::CCTextureUpdateController(client, thread, queue, resourceProvider, copier, uploader) , m_monotonicTimeNow(0) , m_updateMoreTexturesTime(0) , m_updateMoreTexturesSize(0) { } @@ -547,8 +559,17 @@ protected: size_t m_updateMoreTexturesSize; }; +static void runPendingTasks(FakeCCThread* thread, FakeCCTextureUpdateController* controller) +{ + while (thread->hasPendingTask()) { + controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread->pendingDelayMs() / 1000.0); + thread->runPendingTask(); + } +} + TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures) { + FakeCCTextureUpdateControllerClient client; FakeCCThread thread; setMaxUploadCountPerUpdate(1); @@ -556,39 +577,34 @@ TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures) appendPartialUploadsToUpdateQueue(0); DebugScopedSetImplThread implThread; - OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader)); + OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&client, &thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader)); controller->setMonotonicTimeNow(0); controller->setUpdateMoreTexturesTime(0.1); controller->setUpdateMoreTexturesSize(1); // Not enough time for any updates. controller->updateMoreTextures(0.09); - EXPECT_FALSE(thread.hasPendingTask()); + runPendingTasks(&thread, controller.get()); EXPECT_EQ(0, m_numBeginUploads); EXPECT_EQ(0, m_numEndUploads); - thread.reset(); controller->setMonotonicTimeNow(0); controller->setUpdateMoreTexturesTime(0.1); controller->setUpdateMoreTexturesSize(1); // Only enough time for 1 update. controller->updateMoreTextures(0.12); - EXPECT_TRUE(thread.hasPendingTask()); - controller->setMonotonicTimeNow(thread.pendingDelayMs() / 1000.0); - thread.runPendingTask(); + runPendingTasks(&thread, controller.get()); EXPECT_EQ(1, m_numBeginUploads); EXPECT_EQ(1, m_numEndUploads); EXPECT_EQ(1, m_numTotalUploads); - thread.reset(); controller->setMonotonicTimeNow(0); controller->setUpdateMoreTexturesTime(0.1); controller->setUpdateMoreTexturesSize(1); // Enough time for 2 updates. controller->updateMoreTextures(0.22); - EXPECT_TRUE(thread.hasPendingTask()); - controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0); - thread.runPendingTask(); + runPendingTasks(&thread, controller.get()); + EXPECT_TRUE(client.completedCalled()); EXPECT_EQ(3, m_numBeginUploads); EXPECT_EQ(3, m_numEndUploads); EXPECT_EQ(3, m_numTotalUploads); @@ -596,6 +612,7 @@ TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures) TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates) { + FakeCCTextureUpdateControllerClient client; FakeCCThread thread; setMaxUploadCountPerUpdate(1); @@ -603,30 +620,26 @@ TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates) appendPartialUploadsToUpdateQueue(0); DebugScopedSetImplThread implThread; - OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader)); + OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&client, &thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader)); controller->setMonotonicTimeNow(0); controller->setUpdateMoreTexturesTime(0.1); controller->setUpdateMoreTexturesSize(1); // Enough time for 3 updates but only 2 necessary. controller->updateMoreTextures(0.31); - EXPECT_TRUE(thread.hasPendingTask()); - controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0); - thread.runPendingTask(); - EXPECT_TRUE(thread.hasPendingTask()); - controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0); - thread.runPendingTask(); + runPendingTasks(&thread, controller.get()); + EXPECT_TRUE(client.completedCalled()); EXPECT_EQ(2, m_numBeginUploads); EXPECT_EQ(2, m_numEndUploads); EXPECT_EQ(2, m_numTotalUploads); - thread.reset(); controller->setMonotonicTimeNow(0); controller->setUpdateMoreTexturesTime(0.1); controller->setUpdateMoreTexturesSize(1); // Enough time for updates but no more updates left. controller->updateMoreTextures(0.31); - EXPECT_FALSE(thread.hasPendingTask()); + runPendingTasks(&thread, controller.get()); + EXPECT_TRUE(client.completedCalled()); EXPECT_EQ(2, m_numBeginUploads); EXPECT_EQ(2, m_numEndUploads); EXPECT_EQ(2, m_numTotalUploads); @@ -634,6 +647,7 @@ TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates) TEST_F(CCTextureUpdateControllerTest, UpdatesCompleteInFiniteTime) { + FakeCCTextureUpdateControllerClient client; FakeCCThread thread; setMaxUploadCountPerUpdate(1); @@ -641,25 +655,22 @@ TEST_F(CCTextureUpdateControllerTest, UpdatesCompleteInFiniteTime) appendPartialUploadsToUpdateQueue(0); DebugScopedSetImplThread implThread; - OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader)); + OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&client, &thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader)); controller->setMonotonicTimeNow(0); controller->setUpdateMoreTexturesTime(0.5); controller->setUpdateMoreTexturesSize(1); for (int i = 0; i < 100; i++) { - if (!controller->hasMoreUpdates()) + if (client.completedCalled()) break; // Not enough time for any updates. controller->updateMoreTextures(0.4); - - if (thread.hasPendingTask()) { - controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0); - thread.runPendingTask(); - } + runPendingTasks(&thread, controller.get()); } + EXPECT_TRUE(client.completedCalled()); EXPECT_EQ(2, m_numBeginUploads); EXPECT_EQ(2, m_numEndUploads); EXPECT_EQ(2, m_numTotalUploads); diff --git a/cc/CCThreadProxy.cpp b/cc/CCThreadProxy.cpp index e90f3fe..0984b3c 100644 --- a/cc/CCThreadProxy.cpp +++ b/cc/CCThreadProxy.cpp @@ -14,7 +14,6 @@ #include "CCLayerTreeHost.h" #include "CCScheduler.h" #include "CCScopedThreadProxy.h" -#include "CCTextureUpdateController.h" #include "CCThreadTask.h" #include "TraceEvent.h" #include <public/WebSharedGraphicsContext3D.h> @@ -294,7 +293,8 @@ void CCThreadProxy::didLoseContextOnImplThread() { ASSERT(isImplThread()); TRACE_EVENT0("cc", "CCThreadProxy::didLoseContextOnImplThread"); - m_currentTextureUpdateControllerOnImplThread.clear(); + if (m_currentTextureUpdateControllerOnImplThread) + m_currentTextureUpdateControllerOnImplThread->discardUploads(); m_schedulerOnImplThread->didLoseContext(); } @@ -309,7 +309,7 @@ void CCThreadProxy::onSwapBuffersCompleteOnImplThread() void CCThreadProxy::onVSyncParametersChanged(double monotonicTimebase, double intervalInSeconds) { ASSERT(isImplThread()); - TRACE_EVENT0("cc", "CCThreadProxy::onVSyncParametersChanged"); + TRACE_EVENT2("cc", "CCThreadProxy::onVSyncParametersChanged", "monotonicTimebase", monotonicTimebase, "intervalInSeconds", intervalInSeconds); m_schedulerOnImplThread->setTimebaseAndInterval(monotonicTimebase, intervalInSeconds); } @@ -558,10 +558,12 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion } else m_resetContentsTexturesPurgedAfterCommitOnImplThread = true; - m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->renderer()->textureCopier(), m_layerTreeHostImpl->renderer()->textureUploader()); + bool hasResourceUpdates = queue->hasMoreUpdates(); + if (hasResourceUpdates) + m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(this, CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->renderer()->textureCopier(), m_layerTreeHostImpl->renderer()->textureUploader()); m_commitCompletionEventOnImplThread = completion; - m_schedulerOnImplThread->beginFrameComplete(); + m_schedulerOnImplThread->beginFrameComplete(hasResourceUpdates); } void CCThreadProxy::beginFrameAbortedOnImplThread() @@ -574,13 +576,6 @@ void CCThreadProxy::beginFrameAbortedOnImplThread() m_schedulerOnImplThread->beginFrameAborted(); } -bool CCThreadProxy::hasMoreResourceUpdates() const -{ - if (!m_currentTextureUpdateControllerOnImplThread) - return false; - return m_currentTextureUpdateControllerOnImplThread->hasMoreUpdates(); -} - bool CCThreadProxy::canDraw() { ASSERT(isImplThread()); @@ -600,7 +595,6 @@ void CCThreadProxy::scheduledActionCommit() { TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionCommit"); ASSERT(isImplThread()); - ASSERT(!hasMoreResourceUpdates()); ASSERT(m_commitCompletionEventOnImplThread); m_currentTextureUpdateControllerOnImplThread.clear(); @@ -738,6 +732,12 @@ CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapForc return scheduledActionDrawAndSwapInternal(true); } +void CCThreadProxy::updateTexturesCompleted() +{ + ASSERT(isImplThread()); + m_schedulerOnImplThread->updateResourcesComplete(); +} + void CCThreadProxy::didCommitAndDrawFrame() { ASSERT(isMainThread()); diff --git a/cc/CCThreadProxy.h b/cc/CCThreadProxy.h index cc80ebd..0d5f8d9 100644 --- a/cc/CCThreadProxy.h +++ b/cc/CCThreadProxy.h @@ -10,6 +10,7 @@ #include "CCLayerTreeHostImpl.h" #include "CCProxy.h" #include "CCScheduler.h" +#include "CCTextureUpdateController.h" #include <wtf/OwnPtr.h> namespace WebCore { @@ -19,11 +20,10 @@ class CCLayerTreeHost; class CCScheduler; class CCScopedThreadProxy; class CCTextureUpdateQueue; -class CCTextureUpdateController; class CCThread; class CCThreadProxyContextRecreationTimer; -class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClient { +class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClient, CCTextureUpdateControllerClient { public: static PassOwnPtr<CCProxy> create(CCLayerTreeHost*); @@ -64,7 +64,6 @@ public: // CCSchedulerClient implementation virtual bool canDraw() OVERRIDE; - virtual bool hasMoreResourceUpdates() const OVERRIDE; virtual void scheduledActionBeginFrame() OVERRIDE; virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE; virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() OVERRIDE; @@ -73,6 +72,9 @@ public: virtual void scheduledActionBeginContextRecreation() OVERRIDE; virtual void scheduledActionAcquireLayerTexturesForMainThread() OVERRIDE; + // CCTextureUpdateControllerClient implementation + virtual void updateTexturesCompleted() OVERRIDE; + private: explicit CCThreadProxy(CCLayerTreeHost*); friend class CCThreadProxyContextRecreationTimer; diff --git a/cc/CCThreadedTest.cpp b/cc/CCThreadedTest.cpp index 09526ac..617614b 100644 --- a/cc/CCThreadedTest.cpp +++ b/cc/CCThreadedTest.cpp @@ -36,7 +36,6 @@ using namespace WebCore; using namespace WebKit; -using namespace WTF; namespace WebKitTests { @@ -592,6 +591,8 @@ void CCThreadedTest::runTest(bool threaded) ASSERT(CCProxy::isMainThread()); m_mainThreadProxy = CCScopedThreadProxy::create(CCProxy::mainThread()); + initializeSettings(m_settings); + m_beginTask = new BeginTask(this); WebKit::Platform::current()->currentThread()->postDelayedTask(m_beginTask, 0); // postDelayedTask takes ownership of the task m_timeoutTask = new TimeoutTask(this); diff --git a/cc/CCThreadedTest.h b/cc/CCThreadedTest.h index 6971c42..55840ed 100644 --- a/cc/CCThreadedTest.h +++ b/cc/CCThreadedTest.h @@ -11,6 +11,7 @@ #include "CompositorFakeWebGraphicsContext3D.h" #include <gtest/gtest.h> #include <public/WebAnimationDelegate.h> +#include <public/WebThread.h> namespace WebCore { class CCLayerImpl; @@ -20,10 +21,6 @@ class CCLayerTreeHostImpl; class GraphicsContext3D; } -namespace WebKit { -class WebThread; -} - namespace WebKitTests { // Used by test stubs to notify the test when something interesting happens. @@ -97,6 +94,8 @@ public: protected: CCThreadedTest(); + virtual void initializeSettings(WebCore::CCLayerTreeSettings&) { } + virtual void scheduleComposite(); static void onEndTest(void* self); diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 5e873f8..f4b0334 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -11,6 +11,7 @@ 'CCDamageTrackerTest.cpp', 'CCDelayBasedTimeSourceTest.cpp', 'CCFrameRateControllerTest.cpp', + 'CCHeadsUpDisplayTest.cpp', 'CCKeyframedAnimationCurveTest.cpp', 'CCLayerAnimationControllerTest.cpp', 'CCLayerImplTest.cpp', |