[chromium] Early out in a new prepareToDraw() step if checkerboarding an accelerated...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Mar 2012 22:59:36 +0000 (22:59 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Mar 2012 22:59:36 +0000 (22:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=81437

Patch by Dana Jansens <danakj@chromium.org> on 2012-03-21
Reviewed by Adrienne Walker.

Source/WebCore:

Split CCLayerTreeHostImpl::drawLayers() into two phases:
prepareToDraw() and drawLayers().

When calculating a RenderPass, and we checkerboard a quad on a
layer, bubble this info back up to CCLayerTreeHostImpl. If the
layer is transforming in an animation, then abort the prepareToDraw()
phase and cause it to return false back to the thread proxy.

Unit test: CCLayerTreeHostImplTest.prepareToDrawFailsWhenAnimationUsesCheckerboard

* platform/graphics/chromium/cc/CCLayerImpl.cpp:
(WebCore::CCLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCLayerImpl.h:
(CCLayerImpl):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::calculateRenderPasses):
(WebCore::CCLayerTreeHostImpl::prepareToDraw):
(WebCore):
(WebCore::CCLayerTreeHostImpl::drawLayers):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
(CCLayerTreeHostImpl):
(FrameData):
* platform/graphics/chromium/cc/CCQuadCuller.cpp:
(WebCore::CCQuadCuller::append):
* platform/graphics/chromium/cc/CCQuadCuller.h:
(CCQuadCuller):
* platform/graphics/chromium/cc/CCRenderPass.cpp:
(WebCore::CCRenderPass::appendQuadsForLayer):
* platform/graphics/chromium/cc/CCRenderPass.h:
(CCRenderPass):
* platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:
(WebCore::CCScrollbarLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCScrollbarLayerImpl.h:
(CCScrollbarLayerImpl):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::doComposite):
* platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp:
(WebCore::CCSolidColorLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCSolidColorLayerImpl.h:
(CCSolidColorLayerImpl):
* platform/graphics/chromium/cc/CCTextureLayerImpl.cpp:
(WebCore::CCTextureLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCTextureLayerImpl.h:
(CCTextureLayerImpl):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::scheduledActionDrawAndSwap):
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::CCTiledLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:
(CCTiledLayerImpl):
* platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
(WebCore::CCVideoLayerImpl::appendQuads):
* platform/graphics/chromium/cc/CCVideoLayerImpl.h:
(CCVideoLayerImpl):

Source/WebKit/chromium:

* tests/CCAnimationTestCommon.cpp:
(WebCore):
(WebCore::addAnimatedTransform):
(WebKitTests::addOpacityTransitionToLayer):
(WebKitTests):
(WebKitTests::addAnimatedTransformToLayer):
* tests/CCAnimationTestCommon.h:
(WebCore):
(WebKitTests):
* tests/CCLayerTreeHostImplTest.cpp:
(WebKitTests::TEST_F):
(DidDrawCheckLayer):
(WebKitTests::DidDrawCheckLayer::DidDrawCheckLayer):
(MissingTextureAnimatingLayer):
(WebKitTests::MissingTextureAnimatingLayer::create):
(WebKitTests::MissingTextureAnimatingLayer::MissingTextureAnimatingLayer):
(WebKitTests):
(WebKitTests::BlendStateCheckLayer::appendQuads):
* tests/CCLayerTreeHostTest.cpp:
(WTF::TestHooks::prepareToDrawOnCCThread):
(WTF::MockLayerTreeHostImpl::prepareToDraw):
(MockLayerTreeHostImpl):
(WTF::MockLayerTreeHostImpl::drawLayers):
* tests/CCQuadCullerTest.cpp:
(WebCore::appendQuads):
* tests/CCSolidColorLayerImplTest.cpp:
(CCLayerTestCommon::TEST):
* tests/CCTiledLayerImplTest.cpp:
(CCLayerTestCommon::TEST):
(CCLayerTestCommon::getQuads):
* tests/MockCCQuadCuller.h:
(WebCore::MockCCQuadCuller::append):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@111616 268f45cc-cd09-0410-ab3c-d52691b4dbfc

30 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp
Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h
Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp
Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h
Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCScrollbarLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCAnimationTestCommon.cpp
Source/WebKit/chromium/tests/CCAnimationTestCommon.h
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
Source/WebKit/chromium/tests/CCQuadCullerTest.cpp
Source/WebKit/chromium/tests/CCSolidColorLayerImplTest.cpp
Source/WebKit/chromium/tests/CCTiledLayerImplTest.cpp
Source/WebKit/chromium/tests/MockCCQuadCuller.h

index 33959ea65aaf6c557f93ccd2a14430473763907b..cb17e8f331bd428ddff19f513fd912347425da0c 100644 (file)
@@ -1,3 +1,65 @@
+2012-03-21  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Early out in a new prepareToDraw() step if checkerboarding an accelerated animation in order to skip the frame
+        https://bugs.webkit.org/show_bug.cgi?id=81437
+
+        Reviewed by Adrienne Walker.
+
+        Split CCLayerTreeHostImpl::drawLayers() into two phases:
+        prepareToDraw() and drawLayers().
+
+        When calculating a RenderPass, and we checkerboard a quad on a
+        layer, bubble this info back up to CCLayerTreeHostImpl. If the
+        layer is transforming in an animation, then abort the prepareToDraw()
+        phase and cause it to return false back to the thread proxy.
+
+        Unit test: CCLayerTreeHostImplTest.prepareToDrawFailsWhenAnimationUsesCheckerboard
+
+        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+        (WebCore::CCLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCLayerImpl.h:
+        (CCLayerImpl):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::calculateRenderPasses):
+        (WebCore::CCLayerTreeHostImpl::prepareToDraw):
+        (WebCore):
+        (WebCore::CCLayerTreeHostImpl::drawLayers):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+        (CCLayerTreeHostImpl):
+        (FrameData):
+        * platform/graphics/chromium/cc/CCQuadCuller.cpp:
+        (WebCore::CCQuadCuller::append):
+        * platform/graphics/chromium/cc/CCQuadCuller.h:
+        (CCQuadCuller):
+        * platform/graphics/chromium/cc/CCRenderPass.cpp:
+        (WebCore::CCRenderPass::appendQuadsForLayer):
+        * platform/graphics/chromium/cc/CCRenderPass.h:
+        (CCRenderPass):
+        * platform/graphics/chromium/cc/CCScrollbarLayerImpl.cpp:
+        (WebCore::CCScrollbarLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCScrollbarLayerImpl.h:
+        (CCScrollbarLayerImpl):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+        (WebCore::CCSingleThreadProxy::doComposite):
+        * platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp:
+        (WebCore::CCSolidColorLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCSolidColorLayerImpl.h:
+        (CCSolidColorLayerImpl):
+        * platform/graphics/chromium/cc/CCTextureLayerImpl.cpp:
+        (WebCore::CCTextureLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCTextureLayerImpl.h:
+        (CCTextureLayerImpl):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::scheduledActionDrawAndSwap):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
+        (WebCore::CCTiledLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.h:
+        (CCTiledLayerImpl):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
+        (WebCore::CCVideoLayerImpl::appendQuads):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.h:
+        (CCVideoLayerImpl):
+
 2012-03-21  Enrica Casucci  <enrica@apple.com>
 
         WebKitURLWithTitles pasteboard format should support URLs containing Emoji characters.
index 69f061f00dd4c2d68cf56877659cb8a37c571b66..2afb9d8ff741f93359566a169fd43729702a7969 100644 (file)
@@ -136,7 +136,7 @@ PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const
     return CCSharedQuadState::create(quadTransform(), drawTransform(), visibleLayerRect(), layerClipRect, drawOpacity(), opaque());
 }
 
-void CCLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+void CCLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
 {
     appendGutterQuads(quadList, sharedQuadState);
 }
index bee9f1bb5cf0155bd07d8d38d00901d03752637b..74a039efb0e43a90da7261521f0a038375c91fc8 100644 (file)
@@ -84,7 +84,7 @@ public:
 
     PassOwnPtr<CCSharedQuadState> createSharedQuadState() const;
     virtual void willDraw(LayerRendererChromium*) { }
-    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*);
+    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& usedCheckerboard);
     virtual void didDraw() { }
     void appendDebugBorderQuad(CCQuadCuller&, const CCSharedQuadState*) const;
 
index 0abfae188db9fe23e7e3335564f3032eb59569ae..443a1ffaa77ba0ee52029df0e3ab14967f4c52db 100644 (file)
@@ -220,9 +220,10 @@ static FloatRect damageInSurfaceSpace(CCLayerImpl* renderSurfaceLayer, const Flo
     return surfaceDamageRect;
 }
 
-void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLayerList& renderSurfaceLayerList)
+bool CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLayerList& renderSurfaceLayerList)
 {
-    TRACE_EVENT1("webkit", "CCLayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(renderSurfaceLayerList.size()));
+    ASSERT(passes.isEmpty());
+    ASSERT(renderSurfaceLayerList.isEmpty());
 
     renderSurfaceLayerList.append(rootLayer());
 
@@ -239,6 +240,8 @@ void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye
         CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootLayer(), rootLayer(), identityMatrix, identityMatrix, renderSurfaceLayerList, rootLayer()->renderSurface()->layerList(), &m_layerSorter, layerRendererCapabilities().maxTextureSize);
     }
 
+    TRACE_EVENT1("webkit", "CCLayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(renderSurfaceLayerList.size()));
+
     if (layerRendererCapabilities().usingPartialSwap)
         trackDamageForAllSurfaces(rootLayer(), renderSurfaceLayerList);
     m_rootDamageRect = rootLayer()->renderSurface()->damageTracker()->currentDamageRect();
@@ -272,6 +275,9 @@ void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye
     // Add quads to the Render passes in FrontToBack order to allow for testing occlusion and performing culling during the tree walk.
     typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
 
+    // If we are unable to draw an animation on some layer, then we abort the entire frame.
+    bool drawFrame = true;
+
     CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
     for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
         CCRenderSurface* renderSurface = it.targetRenderSurfaceLayer()->renderSurface();
@@ -295,11 +301,23 @@ void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye
         }
 
         it->willDraw(m_layerRenderer.get());
-        pass->appendQuadsForLayer(*it, &occlusionTracker);
+
+        bool usedCheckerboard = false;
+        pass->appendQuadsForLayer(*it, &occlusionTracker, usedCheckerboard);
+        if (usedCheckerboard) {
+            bool layerHasAnimatingTransform = it->screenSpaceTransformIsAnimating() || it->drawTransformIsAnimating();
+            if (layerHasAnimatingTransform) {
+                drawFrame = false;
+                break;
+            }
+        }
+
         occlusionTracker.markOccludedBehindLayer(*it);
     }
 
-    occlusionTracker.overdrawMetrics().recordMetrics(this);
+    if (drawFrame)
+        occlusionTracker.overdrawMetrics().recordMetrics(this);
+    return drawFrame;
 }
 
 void CCLayerTreeHostImpl::animateLayersRecursive(CCLayerImpl* current, double monotonicTime, double wallClockTime, CCAnimationEventsVector* events, bool& didAnimate, bool& needsAnimateLayers)
@@ -339,26 +357,39 @@ IntSize CCLayerTreeHostImpl::contentSize() const
     return m_scrollLayerImpl->children()[0]->contentBounds();
 }
 
-void CCLayerTreeHostImpl::drawLayers()
+bool CCLayerTreeHostImpl::prepareToDraw(FrameData& frame)
 {
-    TRACE_EVENT("CCLayerTreeHostImpl::drawLayers", this, 0);
-    ASSERT(m_layerRenderer);
+    TRACE_EVENT("CCLayerTreeHostImpl::prepareToDraw", this, 0);
+
+    frame.renderPasses.clear();
+    frame.renderSurfaceLayerList.clear();
 
     if (!rootLayer())
-        return;
+        return false;
 
-    CCRenderPassList passes;
-    CCLayerList renderSurfaceLayerList;
-    calculateRenderPasses(passes, renderSurfaceLayerList);
+    if (!calculateRenderPasses(frame.renderPasses, frame.renderSurfaceLayerList)) {
+        frame.renderPasses.clear();
+        frame.renderSurfaceLayerList.clear();
+        return false;
+    }
+
+    // If we return true, then we expect drawLayers() to be called before this function is called again.
+    return true;
+}
+
+void CCLayerTreeHostImpl::drawLayers(const FrameData& frame)
+{
+    TRACE_EVENT("CCLayerTreeHostImpl::drawLayers", this, 0);
+    ASSERT(m_layerRenderer);
 
     m_layerRenderer->beginDrawingFrame();
-    for (size_t i = 0; i < passes.size(); ++i)
-        m_layerRenderer->drawRenderPass(passes[i].get());
+    for (size_t i = 0; i < frame.renderPasses.size(); ++i)
+        m_layerRenderer->drawRenderPass(frame.renderPasses[i].get());
 
     typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
 
-    CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
-    for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
+    CCLayerIteratorType end = CCLayerIteratorType::end(&frame.renderSurfaceLayerList);
+    for (CCLayerIteratorType it = CCLayerIteratorType::begin(&frame.renderSurfaceLayerList); it != end; ++it) {
         if (it.representsItself() && !it->visibleLayerRect().isEmpty())
             it->didDraw();
     }
index 3149474c4b58a5c5d0ee70b63a611ae2e82c12c6..e0c6e73a33420dd47d09542862cb9a48a0ad1cb0 100644 (file)
@@ -60,6 +60,8 @@ public:
 // CCLayerTreeHostImpl owns the CCLayerImpl tree as well as associated rendering state
 class CCLayerTreeHostImpl : public CCInputHandlerClient, LayerRendererChromiumClient {
     WTF_MAKE_NONCOPYABLE(CCLayerTreeHostImpl);
+    typedef Vector<CCLayerImpl*> CCLayerList;
+
 public:
     static PassOwnPtr<CCLayerTreeHostImpl> create(const CCSettings&, CCLayerTreeHostImplClient*);
     virtual ~CCLayerTreeHostImpl();
@@ -77,11 +79,17 @@ public:
     virtual void setActiveGestureAnimation(PassOwnPtr<CCActiveGestureAnimation>);
     virtual void scheduleAnimation();
 
+    struct FrameData {
+        CCRenderPassList renderPasses;
+        CCLayerList renderSurfaceLayerList;
+    };
+
     // Virtual for testing.
     virtual void beginCommit();
     virtual void commitComplete();
     virtual void animate(double monotonicTime, double wallClockTime);
-    virtual void drawLayers();
+    virtual bool prepareToDraw(FrameData&);
+    virtual void drawLayers(const FrameData&);
 
     // LayerRendererChromiumClient implementation
     virtual const IntSize& viewportSize() const { return m_viewportSize; }
@@ -151,8 +159,6 @@ protected:
     int m_frameNumber;
 
 private:
-    typedef Vector<CCLayerImpl*> CCLayerList;
-
     void computeDoubleTapZoomDeltas(CCScrollAndScaleSet* scrollInfo);
     void computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo);
     void makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale);
@@ -162,7 +168,8 @@ private:
     void adjustScrollsForPageScaleChange(float);
     void updateMaxScrollPosition();
     void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
-    void calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList);
+    // Returns false if the frame should not be displayed.
+    bool calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList);
     void animateLayersRecursive(CCLayerImpl*, double monotonicTime, double wallClockTime, CCAnimationEventsVector*, bool& didAnimate, bool& needsAnimateLayers);
     IntSize contentSize() const;
     void sendDidLoseContextRecursive(CCLayerImpl*);
index f2a8587170c3ba5ae22e1b388f3f8826d0efd3ac..35d19461779592feb4ef8471b38fe0d5ef9c8440 100644 (file)
@@ -47,7 +47,7 @@ CCQuadCuller::CCQuadCuller(CCQuadList& quadList, CCLayerImpl* layer, CCOcclusion
 {
 }
 
-void CCQuadCuller::append(PassOwnPtr<CCDrawQuad> passDrawQuad)
+bool CCQuadCuller::append(PassOwnPtr<CCDrawQuad> passDrawQuad)
 {
     OwnPtr<CCDrawQuad> drawQuad(passDrawQuad);
     IntRect culledRect = m_occlusionTracker->unoccludedContentRect(m_layer, drawQuad->quadRect());
@@ -61,6 +61,7 @@ void CCQuadCuller::append(PassOwnPtr<CCDrawQuad> passDrawQuad)
     // Release the quad after we're done using it.
     if (keepQuad)
         m_quadList.append(drawQuad.release());
+    return keepQuad;
 }
 
 } // namespace WebCore
index 1f4b920562ae95c56df70693d8b9c1708fc99720..3435b72f5d3503b9e99e50f8248826c1c98ee081 100644 (file)
@@ -38,7 +38,8 @@ public:
     // done to estimate over draw statistics.
     CCQuadCuller(CCQuadList&, CCLayerImpl*, CCOcclusionTrackerImpl*);
 
-    virtual void append(PassOwnPtr<CCDrawQuad> passDrawQuad);
+    // Returns true if the quad is added to the list, and false if the quad is entirely culled.
+    virtual bool append(PassOwnPtr<CCDrawQuad> passDrawQuad);
 
 private:
     CCQuadList& m_quadList;
index a12bfbb59f4a7b93963d2434ec60cbe85005634a..cf47b6cb87a43760210307dcdf9069071e4a4e0c 100644 (file)
@@ -46,12 +46,12 @@ CCRenderPass::CCRenderPass(CCRenderSurface* targetSurface)
     ASSERT(m_targetSurface);
 }
 
-void CCRenderPass::appendQuadsForLayer(CCLayerImpl* layer, CCOcclusionTrackerImpl* occlusionTracker)
+void CCRenderPass::appendQuadsForLayer(CCLayerImpl* layer, CCOcclusionTrackerImpl* occlusionTracker, bool& usedCheckerboard)
 {
     CCQuadCuller quadCuller(m_quadList, layer, occlusionTracker);
 
     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-    layer->appendQuads(quadCuller, sharedQuadState.get());
+    layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
     layer->appendDebugBorderQuad(quadCuller, sharedQuadState.get());
     m_sharedQuadStateList.append(sharedQuadState.release());
 }
index ac8dbc1a0d26a8476657fb672c2f15aab24c8ee1..59901c8c58cf376a0c1f0cc09c578ee04d3162e3 100644 (file)
@@ -54,7 +54,7 @@ class CCRenderPass {
 public:
     static PassOwnPtr<CCRenderPass> create(CCRenderSurface*);
 
-    void appendQuadsForLayer(CCLayerImpl*, CCOcclusionTrackerImpl*);
+    void appendQuadsForLayer(CCLayerImpl*, CCOcclusionTrackerImpl*, bool& usedCheckerboard);
     void appendQuadsForRenderSurfaceLayer(CCLayerImpl*);
 
     const CCQuadList& quadList() const { return m_quadList; }
index 437f4f776d8b07d5b9afcd1c0c503dd8c89142a5..152065d08e111d9ae1cdb5fd6331e8194010c5da 100644 (file)
@@ -79,7 +79,7 @@ void CCScrollbarLayerImpl::willDraw(LayerRendererChromium* layerRenderer)
     }
 }
 
-void CCScrollbarLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+void CCScrollbarLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
 {
     if (!m_texture->isReserved())
         return;
index fcec110e241831bdb21f8672bbd0c737211d3fcc..b03e451eb3923501c2e6539fdcac6f4785a9c786 100644 (file)
@@ -60,7 +60,7 @@ public:
     void setScrollLayer(CCLayerImpl* scrollLayer) { m_scrollLayer = scrollLayer; }
 
     virtual void willDraw(LayerRendererChromium*);
-    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*);
+    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& usedCheckerboard);
     virtual void didDraw();
 
 protected:
index b6fc76b52e8bdf4fea97550a216ef132ff7b5bf5..607b38af7a22cc774ff6a172793d3de59e40368b 100644 (file)
@@ -298,7 +298,9 @@ bool CCSingleThreadProxy::doComposite()
       double wallClockTime = currentTime();
 
       m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
-      m_layerTreeHostImpl->drawLayers();
+      CCLayerTreeHostImpl::FrameData frame;
+      m_layerTreeHostImpl->prepareToDraw(frame);
+      m_layerTreeHostImpl->drawLayers(frame);
     }
 
     if (m_layerTreeHostImpl->isContextLost()) {
index bf670ecc89e1b0fa17fee7603839ec27cbfd4917..6ae3a17298e9c6c31827ad69eab46b9e8ed3e463 100644 (file)
@@ -57,7 +57,7 @@ TransformationMatrix CCSolidColorLayerImpl::quadTransform() const
     return solidColorTransform;
 }
 
-void CCSolidColorLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+void CCSolidColorLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
 {
     // We create a series of smaller quads instead of just one large one so that the
     // culler can reduce the total pixels drawn.
index 7d076738cf3a0cccc982b422eabd8da00b01beba..10c6ade3f473b54dbba790453f2c0de8a5b6ace9 100644 (file)
@@ -42,7 +42,7 @@ public:
     virtual ~CCSolidColorLayerImpl();
 
     virtual TransformationMatrix quadTransform() const;
-    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*);
+    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& usedCheckerboard);
 
 protected:
     explicit CCSolidColorLayerImpl(int id);
index e06f72f6f249b61c71aa3dad336431a8b2e62b3c..12cbab62570667c88dc87709668832388c24f94f 100644 (file)
@@ -90,7 +90,7 @@ void CCTextureLayerImpl::willDraw(LayerRendererChromium* layerRenderer)
     }
 }
 
-void CCTextureLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+void CCTextureLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
 {
     IntRect quadRect(IntPoint(), bounds());
     quadList.append(CCTextureDrawQuad::create(sharedQuadState, quadRect, m_textureId, m_hasAlpha, m_premultipliedAlpha, m_uvRect, m_flipped, m_ioSurfaceSize, m_ioSurfaceTextureId));
index a81c3616aedb645a21a7350b91bd93d607f8bc72..92d1a90b9ffcd548211bc8c651961cdab367c9f3 100644 (file)
@@ -40,7 +40,7 @@ public:
     }
     virtual ~CCTextureLayerImpl();
 
-    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*);
+    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& usedCheckerboard);
 
     typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> ProgramFlip;
     typedef ProgramBinding<VertexShaderPosTexStretch, FragmentShaderRGBATexAlpha> ProgramStretch;
index 879aabfccd1c68f0e3893f98b350dc89c00c655e..e4173a8ad6113f7edc4b902ab0a7f850863a145f 100644 (file)
@@ -555,7 +555,9 @@ void CCThreadProxy::scheduledActionDrawAndSwap()
 
     m_inputHandlerOnImplThread->animate(monotonicTime);
     m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
-    m_layerTreeHostImpl->drawLayers();
+    CCLayerTreeHostImpl::FrameData frame;
+    m_layerTreeHostImpl->prepareToDraw(frame);
+    m_layerTreeHostImpl->drawLayers(frame);
 
     // Check for a pending compositeAndReadback.
     if (m_readbackRequestOnImplThread) {
index a1877b987af65ecf7158b87285e6d8809aa57fe4..3f7b0b3ac219a760775a5ebf0018dfd894237779 100644 (file)
@@ -123,7 +123,7 @@ TransformationMatrix CCTiledLayerImpl::quadTransform() const
     return transform;
 }
 
-void CCTiledLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+void CCTiledLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool& usedCheckerboard)
 {
     const IntRect& layerRect = visibleLayerRect();
 
@@ -149,7 +149,7 @@ void CCTiledLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadSta
                 continue;
 
             if (!tile || !tile->textureId()) {
-                quadList.append(CCSolidColorDrawQuad::create(sharedQuadState, tileRect, backgroundColor()));
+                usedCheckerboard |= quadList.append(CCSolidColorDrawQuad::create(sharedQuadState, tileRect, backgroundColor()));
                 continue;
             }
 
index 0be6577438c003631744b77735ca69ad283854ad..30a4aa638fae28ab8b90fd510d4df8eccdc8aeba 100644 (file)
@@ -43,7 +43,7 @@ public:
     }
     virtual ~CCTiledLayerImpl();
 
-    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*);
+    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& usedCheckerboard);
 
     virtual void bindContentsTexture(LayerRendererChromium*);
 
index b5aa3e17150fe054f73e51ef002a6fdabf7fc647..a56cf58913d54d62ef8c34016e807ba86a8419b1 100644 (file)
@@ -154,7 +154,7 @@ void CCVideoLayerImpl::willDraw(LayerRendererChromium* layerRenderer)
     }
 }
 
-void CCVideoLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+void CCVideoLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
 {
     if (!m_frame)
         return;
index 4fb45ebd970fb3f9c939e90b69e04cdbda0add2f..ddb279c83afefd87df366761e11ce6a89f7ae3a2 100644 (file)
@@ -50,7 +50,7 @@ public:
     virtual ~CCVideoLayerImpl();
 
     virtual void willDraw(LayerRendererChromium*);
-    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*);
+    virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& usedCheckerboard);
     virtual void didDraw();
 
     typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
index d059730f3272b95ca02e313cce2aa437494ef2e3..8cb4ebc48cc496532559b899329dc97e7b41f5d7 100644 (file)
@@ -1,3 +1,43 @@
+2012-03-21  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Early out in a new prepareToDraw() step if checkerboarding an accelerated animation in order to skip the frame
+        https://bugs.webkit.org/show_bug.cgi?id=81437
+
+        Reviewed by Adrienne Walker.
+
+        * tests/CCAnimationTestCommon.cpp:
+        (WebCore):
+        (WebCore::addAnimatedTransform):
+        (WebKitTests::addOpacityTransitionToLayer):
+        (WebKitTests):
+        (WebKitTests::addAnimatedTransformToLayer):
+        * tests/CCAnimationTestCommon.h:
+        (WebCore):
+        (WebKitTests):
+        * tests/CCLayerTreeHostImplTest.cpp:
+        (WebKitTests::TEST_F):
+        (DidDrawCheckLayer):
+        (WebKitTests::DidDrawCheckLayer::DidDrawCheckLayer):
+        (MissingTextureAnimatingLayer):
+        (WebKitTests::MissingTextureAnimatingLayer::create):
+        (WebKitTests::MissingTextureAnimatingLayer::MissingTextureAnimatingLayer):
+        (WebKitTests):
+        (WebKitTests::BlendStateCheckLayer::appendQuads):
+        * tests/CCLayerTreeHostTest.cpp:
+        (WTF::TestHooks::prepareToDrawOnCCThread):
+        (WTF::MockLayerTreeHostImpl::prepareToDraw):
+        (MockLayerTreeHostImpl):
+        (WTF::MockLayerTreeHostImpl::drawLayers):
+        * tests/CCQuadCullerTest.cpp:
+        (WebCore::appendQuads):
+        * tests/CCSolidColorLayerImplTest.cpp:
+        (CCLayerTestCommon::TEST):
+        * tests/CCTiledLayerImplTest.cpp:
+        (CCLayerTestCommon::TEST):
+        (CCLayerTestCommon::getQuads):
+        * tests/MockCCQuadCuller.h:
+        (WebCore::MockCCQuadCuller::append):
+
 2012-03-21  Alexandru Chiculita  <achicu@adobe.com>
 
         [CSS Shaders] Make CSS Shaders compile on Chromium
index a1d97a51bb47314d0ba95c5491d7760052f7793d..7e9a81c9e13a04ffd43412276451169b8f8955a5 100644 (file)
@@ -28,7 +28,9 @@
 
 #include "GraphicsLayer.h"
 #include "LayerChromium.h"
+#include "TranslateTransformOperation.h"
 #include "cc/CCLayerAnimationController.h"
+#include "cc/CCLayerImpl.h"
 
 using namespace WebCore;
 
@@ -53,6 +55,24 @@ void addOpacityTransition(Target& target, double duration, float startOpacity, f
     target.addAnimation(values, boxSize, animation.get(), 0, 0, 0);
 }
 
+template <class Target>
+void addAnimatedTransform(Target& target, double duration, int deltaX, int deltaY)
+{
+    static int id = 0;
+    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
+
+    TransformOperations operations;
+    operations.operations().append(TranslateTransformOperation::create(Length(deltaX, Fixed), Length(deltaY, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(0, &operations));
+
+    RefPtr<Animation> animation = Animation::create();
+    animation->setDuration(duration);
+
+    IntSize boxSize;
+
+    target.addAnimation(values, boxSize, animation.get(), ++id, 0, 0);
+}
+
 } // namespace
 
 namespace WebKitTests {
@@ -133,4 +153,19 @@ void addOpacityTransitionToLayer(WebCore::LayerChromium& layer, double duration,
     addOpacityTransition(layer, duration, startOpacity, endOpacity, useTimingFunction);
 }
 
+void addOpacityTransitionToLayer(WebCore::CCLayerImpl& layer, double duration, float startOpacity, float endOpacity, bool useTimingFunction)
+{
+    addOpacityTransition(*layer.layerAnimationController(), duration, startOpacity, endOpacity, useTimingFunction);
+}
+
+void addAnimatedTransformToLayer(WebCore::LayerChromium& layer, double duration, int deltaX, int deltaY)
+{
+    addAnimatedTransform(layer, duration, deltaX, deltaY);
+}
+
+void addAnimatedTransformToLayer(WebCore::CCLayerImpl& layer, double duration, int deltaX, int deltaY)
+{
+    addAnimatedTransform(*layer.layerAnimationController(), duration, deltaX, deltaY);
+}
+
 } // namespace WebKitTests
index 11a76b8acb07cf8aba79952fe814603406e39da4..2033bf9d00e3ac90e771b19c389842c1458a1b1d 100644 (file)
@@ -31,6 +31,7 @@
 #include <wtf/OwnPtr.h>
 
 namespace WebCore {
+class CCLayerImpl;
 class LayerChromium;
 }
 
@@ -98,6 +99,10 @@ private:
 void addOpacityTransitionToController(WebCore::CCLayerAnimationController&, double duration, float startOpacity, float endOpacity, bool useTimingFunction);
 
 void addOpacityTransitionToLayer(WebCore::LayerChromium&, double duration, float startOpacity, float endOpacity, bool useTimingFunction);
+void addOpacityTransitionToLayer(WebCore::CCLayerImpl&, double duration, float startOpacity, float endOpacity, bool useTimingFunction);
+
+void addAnimatedTransformToLayer(WebCore::LayerChromium&, double duration, int deltaX, int deltaY);
+void addAnimatedTransformToLayer(WebCore::CCLayerImpl&, double duration, int deltaX, int deltaY);
 
 } // namespace WebKitTests
 
index a192ba557bf0ea16c21e4c04242cb25d090a1763..44dcd14242f5310facffff74a78ac7c2e3cea8ab 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "cc/CCLayerTreeHostImpl.h"
 
+#include "CCAnimationTestCommon.h"
 #include "FakeWebGraphicsContext3D.h"
 #include "GraphicsContext3DPrivate.h"
 #include "LayerRendererChromium.h"
@@ -36,6 +37,7 @@
 
 using namespace WebCore;
 using namespace WebKit;
+using namespace WebKitTests;
 
 namespace {
 
@@ -250,7 +252,9 @@ TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionWithOffset)
     root->setNonFastScrollableRegion(IntRect(0, 0, 50, 50));
     root->setPosition(FloatPoint(-25, 0));
     m_hostImpl->setRootLayer(root.release());
-    m_hostImpl->drawLayers(); // Update draw transforms so we can correctly map points into layer space.
+    CCLayerTreeHostImpl::FrameData frame;
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame); // Update draw transforms so we can correctly map points into layer space.
 
     // This point would fall into the non-fast scrollable region except that we've moved the layer down by 25 pixels.
     EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(40, 10), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted);
@@ -390,7 +394,7 @@ TEST_F(CCLayerTreeHostImplTest, pageScaleAnimation)
     }
 }
 
-class DidDrawCheckLayer : public CCLayerImpl {
+class DidDrawCheckLayer : public CCTiledLayerImpl {
 public:
     static PassOwnPtr<DidDrawCheckLayer> create(int id) { return adoptPtr(new DidDrawCheckLayer(id)); }
 
@@ -407,9 +411,9 @@ public:
     bool didDrawCalled() const { return m_didDrawCalled; }
     bool willDrawCalled() const { return m_willDrawCalled; }
 
-private:
+protected:
     explicit DidDrawCheckLayer(int id)
-        : CCLayerImpl(id)
+        : CCTiledLayerImpl(id)
         , m_didDrawCalled(false)
         , m_willDrawCalled(false)
     {
@@ -418,6 +422,7 @@ private:
         setDrawsContent(true);
     }
 
+private:
     bool m_didDrawCalled;
     bool m_willDrawCalled;
 };
@@ -432,10 +437,13 @@ TEST_F(CCLayerTreeHostImplTest, didDrawNotCalledOnHiddenLayer)
     m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));
     DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(m_hostImpl->rootLayer());
 
+    CCLayerTreeHostImpl::FrameData frame;
+
     EXPECT_FALSE(root->willDrawCalled());
     EXPECT_FALSE(root->didDrawCalled());
 
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
 
     EXPECT_FALSE(root->willDrawCalled());
     EXPECT_FALSE(root->didDrawCalled());
@@ -448,7 +456,8 @@ TEST_F(CCLayerTreeHostImplTest, didDrawNotCalledOnHiddenLayer)
     EXPECT_FALSE(root->willDrawCalled());
     EXPECT_FALSE(root->didDrawCalled());
 
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
 
     EXPECT_TRUE(root->willDrawCalled());
     EXPECT_TRUE(root->didDrawCalled());
@@ -477,7 +486,9 @@ TEST_F(CCLayerTreeHostImplTest, didDrawCalledOnAllLayers)
     EXPECT_FALSE(layer1->didDrawCalled());
     EXPECT_FALSE(layer2->didDrawCalled());
 
-    m_hostImpl->drawLayers();
+    CCLayerTreeHostImpl::FrameData frame;
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
 
     EXPECT_TRUE(root->didDrawCalled());
     EXPECT_TRUE(layer1->didDrawCalled());
@@ -487,6 +498,68 @@ TEST_F(CCLayerTreeHostImplTest, didDrawCalledOnAllLayers)
     EXPECT_TRUE(!!layer1->renderSurface());
 }
 
+class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
+public:
+    static PassOwnPtr<MissingTextureAnimatingLayer> create(int id, bool tileMissing, bool skipsDraw, bool animating) { return adoptPtr(new MissingTextureAnimatingLayer(id, tileMissing, skipsDraw, animating)); }
+
+private:
+    explicit MissingTextureAnimatingLayer(int id, bool tileMissing, bool skipsDraw, bool animating)
+        : DidDrawCheckLayer(id)
+    {
+        OwnPtr<CCLayerTilingData> tilingData = CCLayerTilingData::create(IntSize(10, 10), CCLayerTilingData::NoBorderTexels);
+        tilingData->setBounds(bounds());
+        setTilingData(*tilingData.get());
+        setSkipsDraw(skipsDraw);
+        if (!tileMissing)
+            pushTileProperties(0, 0, 1, IntRect());
+        if (animating)
+            addAnimatedTransformToLayer(*this, 10, 3, 0);
+    }
+};
+
+TEST_F(CCLayerTreeHostImplTest, prepareToDrawFailsWhenAnimationUsesCheckerboard)
+{
+    m_hostImpl->initializeLayerRenderer(createContext());
+    m_hostImpl->setViewportSize(IntSize(10, 10));
+
+    // When the texture is not missing, we draw as usual.
+    m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));
+    DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(m_hostImpl->rootLayer());
+    root->addChild(MissingTextureAnimatingLayer::create(1, false, false, true));
+    DidDrawCheckLayer* layer = static_cast<MissingTextureAnimatingLayer*>(root->children()[0].get());
+
+    CCLayerTreeHostImpl::FrameData frame;
+
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
+
+    // When a texture is missing and we're not animating, we draw as usual with checkerboarding.
+    m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));
+    root = static_cast<DidDrawCheckLayer*>(m_hostImpl->rootLayer());
+    root->addChild(MissingTextureAnimatingLayer::create(1, true, false, false));
+    layer = static_cast<MissingTextureAnimatingLayer*>(root->children()[0].get());
+
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
+
+    // When a texture is missing and we're animating, we don't draw anything.
+    m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));
+    root = static_cast<DidDrawCheckLayer*>(m_hostImpl->rootLayer());
+    root->addChild(MissingTextureAnimatingLayer::create(1, true, false, true));
+    layer = static_cast<MissingTextureAnimatingLayer*>(root->children()[0].get());
+
+    EXPECT_FALSE(m_hostImpl->prepareToDraw(frame));
+
+    // When the layer skips draw and we're animating, we still draw the frame.
+    m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));
+    root = static_cast<DidDrawCheckLayer*>(m_hostImpl->rootLayer());
+    root->addChild(MissingTextureAnimatingLayer::create(1, false, true, true));
+    layer = static_cast<MissingTextureAnimatingLayer*>(root->children()[0].get());
+
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
+}
+
 class BlendStateTrackerContext: public FakeWebGraphicsContext3D {
 public:
     BlendStateTrackerContext() : m_blend(false) { }
@@ -513,7 +586,7 @@ class BlendStateCheckLayer : public CCLayerImpl {
 public:
     static PassOwnPtr<BlendStateCheckLayer> create(int id) { return adoptPtr(new BlendStateCheckLayer(id)); }
 
-    virtual void appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState)
+    virtual void appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&)
     {
         m_quadsAppended = true;
 
@@ -584,25 +657,30 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     root->addChild(BlendStateCheckLayer::create(1));
     BlendStateCheckLayer* layer1 = static_cast<BlendStateCheckLayer*>(root->children()[0].get());
 
+    CCLayerTreeHostImpl::FrameData frame;
+
     // Opaque layer, drawn without blending.
     layer1->setOpaque(true);
     layer1->setOpaqueContents(true);
     layer1->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with translucent content, but opaque content, so drawn without blending.
     layer1->setOpaque(false);
     layer1->setOpaqueContents(true);
     layer1->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with translucent content and painting, so drawn with blending.
     layer1->setOpaque(false);
     layer1->setOpaqueContents(false);
     layer1->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with translucent opacity, drawn with blending.
@@ -610,7 +688,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(true);
     layer1->setOpacity(0.5);
     layer1->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with translucent opacity and painting, drawn with blending.
@@ -618,7 +697,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(false);
     layer1->setOpacity(0.5);
     layer1->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     layer1->addChild(BlendStateCheckLayer::create(2));
@@ -633,7 +713,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer2->setOpaqueContents(true);
     layer2->setOpacity(1);
     layer2->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -643,7 +724,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(false);
     layer1->setExpectation(true, false);
     layer2->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -653,7 +735,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(true);
     layer1->setExpectation(false, false);
     layer2->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -667,7 +750,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpacity(0.5);
     layer1->setExpectation(false, true);
     layer2->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -681,7 +765,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer2->setOpaqueContents(true);
     layer2->setOpacity(0.5);
     layer2->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -693,7 +778,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer2->setOpaqueContents(false);
     layer2->setOpacity(1);
     layer2->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -705,7 +791,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer2->setOpaqueContents(true);
     layer2->setOpacity(1);
     layer2->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
     EXPECT_TRUE(layer2->quadsAppended());
 
@@ -716,7 +803,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(false);
     layer1->setOpaqueContentRect(IntRect(5, 5, 2, 5));
     layer1->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with partially opaque contents partially culled, drawn with blending.
@@ -726,7 +814,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(false);
     layer1->setOpaqueContentRect(IntRect(5, 5, 2, 5));
     layer1->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with partially opaque contents culled, drawn with blending.
@@ -736,7 +825,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(false);
     layer1->setOpaqueContentRect(IntRect(5, 5, 2, 5));
     layer1->setExpectation(true, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
     // Layer with partially opaque contents and translucent contents culled, drawn without blending.
@@ -746,7 +836,8 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     layer1->setOpaqueContents(false);
     layer1->setOpaqueContentRect(IntRect(5, 5, 2, 5));
     layer1->setExpectation(false, false);
-    m_hostImpl->drawLayers();
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(layer1->quadsAppended());
 
 }
@@ -788,7 +879,9 @@ TEST_F(CCLayerTreeHostImplTest, reshapeNotCalledUntilDraw)
     m_hostImpl->setRootLayer(adoptPtr(root));
     EXPECT_FALSE(reshapeTracker->reshapeCalled());
 
-    m_hostImpl->drawLayers();
+    CCLayerTreeHostImpl::FrameData frame;
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
     EXPECT_TRUE(reshapeTracker->reshapeCalled());
 }
 
@@ -840,8 +933,11 @@ TEST_F(CCLayerTreeHostImplTest, partialSwapReceivesDamageRect)
     root->addChild(adoptPtr(child));
     layerTreeHostImpl->setRootLayer(adoptPtr(root));
 
+    CCLayerTreeHostImpl::FrameData frame;
+
     // First frame, the entire screen should get swapped.
-    layerTreeHostImpl->drawLayers();
+    EXPECT_TRUE(layerTreeHostImpl->prepareToDraw(frame));
+    layerTreeHostImpl->drawLayers(frame);
     layerTreeHostImpl->swapBuffers();
     IntRect actualSwapRect = partialSwapTracker->partialSwapRect();
     IntRect expectedSwapRect = IntRect(IntPoint::zero(), IntSize(500, 500));
@@ -855,7 +951,8 @@ TEST_F(CCLayerTreeHostImplTest, partialSwapReceivesDamageRect)
     // expected damage rect: IntRect(IntPoint::zero(), IntSize(26, 28));
     // expected swap rect: vertically flipped, with origin at bottom left corner.
     child->setPosition(FloatPoint(0, 0));
-    layerTreeHostImpl->drawLayers();
+    EXPECT_TRUE(layerTreeHostImpl->prepareToDraw(frame));
+    layerTreeHostImpl->drawLayers(frame);
     layerTreeHostImpl->swapBuffers();
     actualSwapRect = partialSwapTracker->partialSwapRect();
     expectedSwapRect = IntRect(IntPoint(0, 500-28), IntSize(26, 28));
@@ -869,7 +966,8 @@ TEST_F(CCLayerTreeHostImplTest, partialSwapReceivesDamageRect)
     // expected swap rect: flipped damage rect, but also clamped to viewport
     layerTreeHostImpl->setViewportSize(IntSize(10, 10));
     root->setOpacity(0.7); // this will damage everything
-    layerTreeHostImpl->drawLayers();
+    EXPECT_TRUE(layerTreeHostImpl->prepareToDraw(frame));
+    layerTreeHostImpl->drawLayers(frame);
     layerTreeHostImpl->swapBuffers();
     actualSwapRect = partialSwapTracker->partialSwapRect();
     expectedSwapRect = IntRect(IntPoint::zero(), IntSize(10, 10));
@@ -900,19 +998,24 @@ TEST_F(CCLayerTreeHostImplTest, visibilityChangeResetsDamage)
     root->setDrawsContent(true);
     layerTreeHostImpl->setRootLayer(adoptPtr(root));
 
+    CCLayerTreeHostImpl::FrameData frame;
+
     // First frame: ignore.
-    layerTreeHostImpl->drawLayers();
+    EXPECT_TRUE(layerTreeHostImpl->prepareToDraw(frame));
+    layerTreeHostImpl->drawLayers(frame);
     layerTreeHostImpl->swapBuffers();
 
     // Second frame: nothing has changed --- so we souldn't push anything with partial swap.
-    layerTreeHostImpl->drawLayers();
+    EXPECT_TRUE(layerTreeHostImpl->prepareToDraw(frame));
+    layerTreeHostImpl->drawLayers(frame);
     layerTreeHostImpl->swapBuffers();
     EXPECT_TRUE(partialSwapTracker->partialSwapRect().isEmpty());
 
     // Third frame: visibility change --- so we should push a full frame with partial swap.
     layerTreeHostImpl->setVisible(false);
     layerTreeHostImpl->setVisible(true);
-    layerTreeHostImpl->drawLayers();
+    EXPECT_TRUE(layerTreeHostImpl->prepareToDraw(frame));
+    layerTreeHostImpl->drawLayers(frame);
     layerTreeHostImpl->swapBuffers();
     IntRect actualSwapRect = partialSwapTracker->partialSwapRect();
     IntRect expectedSwapRect = IntRect(IntPoint::zero(), IntSize(500, 500));
index 5f7fbca0c0f6bd53b0776bbcc4809748417b25d8..c72383702c113e210c344267977d95a8931b4ee2 100644 (file)
@@ -63,6 +63,7 @@ class TestHooks : public CCLayerAnimationDelegate {
 public:
     virtual void beginCommitOnCCThread(CCLayerTreeHostImpl*) { }
     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) { }
+    virtual void prepareToDrawOnCCThread(CCLayerTreeHostImpl*) { }
     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*) { }
     virtual void animateLayers(CCLayerTreeHostImpl*, double monotonicTime) { }
     virtual void applyScrollAndScale(const IntSize&, float) { }
@@ -95,9 +96,16 @@ public:
         m_testHooks->commitCompleteOnCCThread(this);
     }
 
-    virtual void drawLayers()
+    virtual bool prepareToDraw(FrameData& frame)
     {
-        CCLayerTreeHostImpl::drawLayers();
+        bool result = CCLayerTreeHostImpl::prepareToDraw(frame);
+        m_testHooks->prepareToDrawOnCCThread(this);
+        return result;
+    }
+
+    virtual void drawLayers(const FrameData& frame)
+    {
+        CCLayerTreeHostImpl::drawLayers(frame);
         m_testHooks->drawLayersOnCCThread(this);
     }
 
index c1bbce62526d153be5829e5a9afaf997f8179d8a..aef0d6ef5a96c5741aaf5fbb354abcd0e6775d74 100644 (file)
@@ -82,7 +82,8 @@ static void appendQuads(CCQuadList& quadList, Vector<OwnPtr<CCSharedQuadState> >
 {
     CCQuadCuller quadCuller(quadList, layer, &occlusionTracker);
     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-    layer->appendQuads(quadCuller, sharedQuadState.get());
+    bool usedCheckerboard = false;
+    layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
     sharedStateList.append(sharedQuadState.release());
 }
 
index 7c743d2a766ac027567294657ad4f481fb8ac217..12f8c224de51fc79cec4ed4d94aa503b97b0d21d 100644 (file)
@@ -52,7 +52,8 @@ TEST(CCSolidColorLayerImplTest, verifyTilingCompleteAndNoOverlap)
     layer->setBounds(layerSize);
 
     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-    layer->appendQuads(quadCuller, sharedQuadState.get());
+    bool usedCheckerboard = false;
+    layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
 
     verifyQuadsExactlyCoverRect(quadCuller.quadList(), visibleLayerRect);
 }
@@ -73,7 +74,8 @@ TEST(CCSolidColorLayerImplTest, verifyCorrectBackgroundColorInQuad)
     layer->setBackgroundColor(testColor);
 
     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-    layer->appendQuads(quadCuller, sharedQuadState.get());
+    bool usedCheckerboard = false;
+    layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
 
     ASSERT_EQ(quadCuller.quadList().size(), 1U);
     EXPECT_EQ(quadCuller.quadList()[0]->toSolidColorDrawQuad()->color(), testColor);
index fe8ca8eb0217af523324e20cc74eaf1c53dda8ff..57caa7dc1714a1f9e52e521c58d4039253537bb9 100644 (file)
@@ -72,7 +72,8 @@ TEST(CCTiledLayerImplTest, emptyQuadList)
         OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
         MockCCQuadCuller quadCuller;
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
         const unsigned numTiles = numTilesX * numTilesY;
         EXPECT_EQ(quadCuller.quadList().size(), numTiles);
     }
@@ -84,7 +85,8 @@ TEST(CCTiledLayerImplTest, emptyQuadList)
 
         MockCCQuadCuller quadCuller;
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
         EXPECT_EQ(quadCuller.quadList().size(), 0u);
     }
 
@@ -97,7 +99,8 @@ TEST(CCTiledLayerImplTest, emptyQuadList)
 
         MockCCQuadCuller quadCuller;
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
         EXPECT_EQ(quadCuller.quadList().size(), 0u);
     }
 
@@ -108,7 +111,8 @@ TEST(CCTiledLayerImplTest, emptyQuadList)
 
         MockCCQuadCuller quadCuller;
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
         EXPECT_EQ(quadCuller.quadList().size(), 0u);
     }
 }
@@ -128,8 +132,10 @@ TEST(CCTiledLayerImplTest, checkerboarding)
     // No checkerboarding
     {
         MockCCQuadCuller quadCuller;
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
         EXPECT_EQ(quadCuller.quadList().size(), 4u);
+        EXPECT_FALSE(usedCheckerboard);
 
         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::TiledContent);
@@ -142,7 +148,9 @@ TEST(CCTiledLayerImplTest, checkerboarding)
     // All checkerboarding
     {
         MockCCQuadCuller quadCuller;
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
+        EXPECT_TRUE(usedCheckerboard);
         EXPECT_EQ(quadCuller.quadList().size(), 4u);
         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::SolidColor);
@@ -157,7 +165,8 @@ static PassOwnPtr<CCSharedQuadState> getQuads(CCQuadList& quads, IntSize tileSiz
 
     MockCCQuadCuller quadCuller(quads);
     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
-    layer->appendQuads(quadCuller, sharedQuadState.get());
+    bool usedCheckerboard = false;
+    layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
     return sharedQuadState.release(); // The shared data must be owned as long as the quad list exists.
 }
 
@@ -275,7 +284,8 @@ TEST(CCTiledLayerImplTest, backgroundCoversViewport)
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
 
         MockCCQuadCuller quadCuller;
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
         EXPECT_EQ(quadCuller.quadList().size(), numTiles);
 
         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
@@ -290,7 +300,8 @@ TEST(CCTiledLayerImplTest, backgroundCoversViewport)
 
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
         MockCCQuadCuller quadCuller;
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
 
         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::SolidColor);
@@ -306,7 +317,8 @@ TEST(CCTiledLayerImplTest, backgroundCoversViewport)
 
         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
         MockCCQuadCuller quadCuller;
-        layer->appendQuads(quadCuller, sharedQuadState.get());
+        bool usedCheckerboard = false;
+        layer->appendQuads(quadCuller, sharedQuadState.get(), usedCheckerboard);
 
         unsigned numContentTiles = 0, numGutterTiles = 0;
         for (size_t i = 0; i < quadCuller.quadList().size(); ++i) {
index 791af5033f78f6610aa26652b34bb8dfe07f8db9..d9cd31326830bd122031cf0c8e18edcd90ec95c7 100644 (file)
@@ -44,11 +44,14 @@ public:
         , m_activeQuadList(externalQuadList)
     { }
 
-    virtual void append(WTF::PassOwnPtr<WebCore::CCDrawQuad> newQuad)
+    virtual bool append(WTF::PassOwnPtr<WebCore::CCDrawQuad> newQuad)
     {
         OwnPtr<WebCore::CCDrawQuad> drawQuad = newQuad;
-        if (!drawQuad->quadRect().isEmpty())
+        if (!drawQuad->quadRect().isEmpty()) {
             m_activeQuadList.append(drawQuad.release());
+            return true;
+        }
+        return false;
     }
 
     const WebCore::CCQuadList& quadList() const { return m_activeQuadList; };