diff options
24 files changed, 855 insertions, 22 deletions
diff --git a/cc/CCAppendQuadsData.h b/cc/CCAppendQuadsData.h index 2a19967..b086de0 100644 --- a/cc/CCAppendQuadsData.h +++ b/cc/CCAppendQuadsData.h @@ -5,12 +5,22 @@ #ifndef CCAppendQuadsData_h #define CCAppendQuadsData_h +#include "CCRenderPass.h" + namespace cc { struct CCAppendQuadsData { CCAppendQuadsData() : hadOcclusionFromOutsideTargetSurface(false) , hadMissingTiles(false) + , renderPassId(0, 0) + { + } + + explicit CCAppendQuadsData(CCRenderPass::Id renderPassId) + : hadOcclusionFromOutsideTargetSurface(false) + , hadMissingTiles(false) + , renderPassId(renderPassId) { } @@ -18,6 +28,8 @@ struct CCAppendQuadsData { bool hadOcclusionFromOutsideTargetSurface; // Set by the layer appending quads. bool hadMissingTiles; + // Given to the layer appending quads. + const CCRenderPass::Id renderPassId; }; } diff --git a/cc/CCDamageTrackerTest.cpp b/cc/CCDamageTrackerTest.cpp index bf290f2..ee05a3a 100644 --- a/cc/CCDamageTrackerTest.cpp +++ b/cc/CCDamageTrackerTest.cpp @@ -1096,7 +1096,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForEmptyLayerList) ASSERT_TRUE(root == root->renderTarget()); CCRenderSurface* targetSurface = root->renderSurface(); - targetSurface->clearLayerList(); + targetSurface->clearLayerLists(); targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), false, IntRect(), 0, WebFilterOperations()); FloatRect damageRect = targetSurface->damageTracker()->currentDamageRect(); diff --git a/cc/CCDelegatedRendererLayerImpl.cpp b/cc/CCDelegatedRendererLayerImpl.cpp new file mode 100644 index 0000000..845b63f --- /dev/null +++ b/cc/CCDelegatedRendererLayerImpl.cpp @@ -0,0 +1,177 @@ +// 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 "CCDelegatedRendererLayerImpl.h" + +#include "CCAppendQuadsData.h" +#include "CCQuadSink.h" +#include "CCRenderPassDrawQuad.h" +#include "CCRenderPassSink.h" + +namespace cc { + +CCDelegatedRendererLayerImpl::CCDelegatedRendererLayerImpl(int id) + : CCLayerImpl(id) +{ +} + +CCDelegatedRendererLayerImpl::~CCDelegatedRendererLayerImpl() +{ + clearRenderPasses(); +} + +bool CCDelegatedRendererLayerImpl::descendantDrawsContent() +{ + // FIXME: This could possibly return false even though there are some + // quads present as they could all be from a single layer (or set of + // layers without children). If this happens, then make a test that + // ensures the opacity is being changed on quads in the root RenderPass + // when this layer doesn't own a RenderSurface. + return !m_renderPassesInDrawOrder.isEmpty(); +} + +bool CCDelegatedRendererLayerImpl::hasContributingDelegatedRenderPasses() const +{ + // The root RenderPass for the layer is merged with its target + // RenderPass in each frame. So we only have extra RenderPasses + // to merge when we have a non-root RenderPass present. + return m_renderPassesInDrawOrder.size() > 1; +} + +void CCDelegatedRendererLayerImpl::setRenderPasses(Vector<OwnPtr<CCRenderPass> >& renderPassesInDrawOrder) +{ + FloatRect oldRootDamage; + if (!m_renderPassesInDrawOrder.isEmpty()) + oldRootDamage = m_renderPassesInDrawOrder.last()->damageRect(); + + clearRenderPasses(); + + for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) { + m_renderPassesIndexById.set(renderPassesInDrawOrder[i]->id(), i); + m_renderPassesInDrawOrder.append(renderPassesInDrawOrder[i].release()); + } + renderPassesInDrawOrder.clear(); + + if (!m_renderPassesInDrawOrder.isEmpty()) { + FloatRect newRootDamage = m_renderPassesInDrawOrder.last()->damageRect(); + m_renderPassesInDrawOrder.last()->setDamageRect(unionRect(oldRootDamage, newRootDamage)); + } +} + +void CCDelegatedRendererLayerImpl::clearRenderPasses() +{ + // FIXME: Release the resources back to the nested compositor. + m_renderPassesIndexById.clear(); + m_renderPassesInDrawOrder.clear(); +} + +void CCDelegatedRendererLayerImpl::didLoseContext() +{ + clearRenderPasses(); +} + +static inline int indexToId(int index) { return index + 1; } +static inline int idToIndex(int id) { return id - 1; } + +CCRenderPass::Id CCDelegatedRendererLayerImpl::firstContributingRenderPassId() const +{ + return CCRenderPass::Id(id(), indexToId(0)); +} + +CCRenderPass::Id CCDelegatedRendererLayerImpl::nextContributingRenderPassId(CCRenderPass::Id previous) const +{ + return CCRenderPass::Id(previous.layerId, previous.index + 1); +} + +CCRenderPass::Id CCDelegatedRendererLayerImpl::convertDelegatedRenderPassId(CCRenderPass::Id delegatedRenderPassId) const +{ + unsigned delegatedRenderPassIndex = m_renderPassesIndexById.get(delegatedRenderPassId); + return CCRenderPass::Id(id(), indexToId(delegatedRenderPassIndex)); +} + +void CCDelegatedRendererLayerImpl::appendContributingRenderPasses(CCRenderPassSink& renderPassSink) +{ + ASSERT(hasContributingDelegatedRenderPasses()); + + for (size_t i = 0; i < m_renderPassesInDrawOrder.size() - 1; ++i) { + CCRenderPass::Id outputRenderPassId = convertDelegatedRenderPassId(m_renderPassesInDrawOrder[i]->id()); + + // Don't clash with the RenderPass we generate if we own a RenderSurface. + ASSERT(outputRenderPassId.index > 0); + + renderPassSink.appendRenderPass(m_renderPassesInDrawOrder[i]->copy(outputRenderPassId)); + } +} + +void CCDelegatedRendererLayerImpl::appendQuads(CCQuadSink& quadSink, CCAppendQuadsData& appendQuadsData) +{ + if (m_renderPassesInDrawOrder.isEmpty()) + return; + + CCRenderPass::Id targetRenderPassId = appendQuadsData.renderPassId; + + // If the index of the renderPassId is 0, then it is a renderPass generated for a layer + // in this compositor, not the delegated renderer. Then we want to merge our root renderPass with + // the target renderPass. Otherwise, it is some renderPass which we added from the delegated + // renderer. + bool shouldMergeRootRenderPassWithTarget = !targetRenderPassId.index; + if (shouldMergeRootRenderPassWithTarget) { + // Verify that the renderPass we are appending to is created our renderTarget. + ASSERT(targetRenderPassId.layerId == renderTarget()->id()); + + CCRenderPass* rootDelegatedRenderPass = m_renderPassesInDrawOrder.last().get(); + appendRenderPassQuads(quadSink, appendQuadsData, rootDelegatedRenderPass); + } else { + // Verify that the renderPass we are appending to was created by us. + ASSERT(targetRenderPassId.layerId == id()); + + int renderPassIndex = idToIndex(targetRenderPassId.index); + CCRenderPass* delegatedRenderPass = m_renderPassesInDrawOrder[renderPassIndex].get(); + appendRenderPassQuads(quadSink, appendQuadsData, delegatedRenderPass); + } +} + +void CCDelegatedRendererLayerImpl::appendRenderPassQuads(CCQuadSink& quadSink, CCAppendQuadsData& appendQuadsData, CCRenderPass* delegatedRenderPass) const +{ + const CCSharedQuadState* currentSharedQuadState = 0; + CCSharedQuadState* copiedSharedQuadState = 0; + for (size_t i = 0; i < delegatedRenderPass->quadList().size(); ++i) { + CCDrawQuad* quad = delegatedRenderPass->quadList()[i].get(); + + if (quad->sharedQuadState() != currentSharedQuadState) { + currentSharedQuadState = quad->sharedQuadState(); + copiedSharedQuadState = quadSink.useSharedQuadState(currentSharedQuadState->copy()); + } + ASSERT(copiedSharedQuadState); + + bool targetIsFromDelegatedRendererLayer = appendQuadsData.renderPassId.layerId == id(); + if (!targetIsFromDelegatedRendererLayer) { + // Should be the root render pass. + ASSERT(delegatedRenderPass == m_renderPassesInDrawOrder.last()); + // This layer must be drawing to a renderTarget other than itself. + ASSERT(renderTarget() != this); + + copiedSharedQuadState->quadTransform = copiedSharedQuadState->quadTransform * drawTransform(); + copiedSharedQuadState->opacity *= drawOpacity(); + } + + OwnPtr<CCDrawQuad> copyQuad; + if (quad->material() != CCDrawQuad::RenderPass) + copyQuad = quad->copy(copiedSharedQuadState); + else { + CCRenderPass::Id contributingDelegatedRenderPassId = CCRenderPassDrawQuad::materialCast(quad)->renderPassId(); + CCRenderPass::Id contributingRenderPassId = convertDelegatedRenderPassId(contributingDelegatedRenderPassId); + ASSERT(contributingRenderPassId != appendQuadsData.renderPassId); + + copyQuad = CCRenderPassDrawQuad::materialCast(quad)->copy(copiedSharedQuadState, contributingRenderPassId); + } + ASSERT(copyQuad); + + quadSink.append(copyQuad.release(), appendQuadsData); + } +} + +} diff --git a/cc/CCDelegatedRendererLayerImpl.h b/cc/CCDelegatedRendererLayerImpl.h new file mode 100644 index 0000000..52218a6 --- /dev/null +++ b/cc/CCDelegatedRendererLayerImpl.h @@ -0,0 +1,49 @@ +// 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. + +#ifndef CCDelegatedRendererLayerImpl_h +#define CCDelegatedRendererLayerImpl_h + +#include "CCLayerImpl.h" + +namespace cc { + +class CCDelegatedRendererLayerImpl : public CCLayerImpl { +public: + static PassOwnPtr<CCDelegatedRendererLayerImpl> create(int id) { return adoptPtr(new CCDelegatedRendererLayerImpl(id)); } + virtual ~CCDelegatedRendererLayerImpl(); + + virtual bool descendantDrawsContent() OVERRIDE; + virtual bool hasContributingDelegatedRenderPasses() const OVERRIDE; + + // This gives ownership of the RenderPasses to the layer. + void setRenderPasses(Vector<OwnPtr<CCRenderPass> >&); + void clearRenderPasses(); + + virtual void didLoseContext() OVERRIDE; + + virtual CCRenderPass::Id firstContributingRenderPassId() const OVERRIDE; + virtual CCRenderPass::Id nextContributingRenderPassId(CCRenderPass::Id) const OVERRIDE; + + void appendContributingRenderPasses(CCRenderPassSink&); + virtual void appendQuads(CCQuadSink&, CCAppendQuadsData&) OVERRIDE; + +private: + explicit CCDelegatedRendererLayerImpl(int); + + CCRenderPass::Id convertDelegatedRenderPassId(CCRenderPass::Id delegatedRenderPassId) const; + + void appendRenderPassQuads(CCQuadSink&, CCAppendQuadsData&, CCRenderPass* fromDelegatedRenderPass) const; + + PassOwnPtr<CCDrawQuad> createCopyOfQuad(const CCDrawQuad*); + + virtual const char* layerTypeAsString() const OVERRIDE { return "DelegatedRendererLayer"; } + + Vector<OwnPtr<CCRenderPass> > m_renderPassesInDrawOrder; + HashMap<CCRenderPass::Id, int> m_renderPassesIndexById; +}; + +} + +#endif // CCDelegatedRendererLayerImpl_h diff --git a/cc/CCDelegatedRendererLayerImplTest.cpp b/cc/CCDelegatedRendererLayerImplTest.cpp new file mode 100644 index 0000000..3d47c26 --- /dev/null +++ b/cc/CCDelegatedRendererLayerImplTest.cpp @@ -0,0 +1,379 @@ +// 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 "CCDelegatedRendererLayerImpl.h" + +#include "CCAppendQuadsData.h" +#include "CCGeometryTestUtils.h" +#include "CCLayerTreeHostImpl.h" +#include "CCQuadSink.h" +#include "CCRenderPassDrawQuad.h" +#include "CCRenderPassTestCommon.h" +#include "CCSingleThreadProxy.h" +#include "CCSolidColorDrawQuad.h" +#include "CCSolidColorLayerImpl.h" +#include "FakeWebCompositorOutputSurface.h" +#include "FakeWebGraphicsContext3D.h" +#include "MockCCQuadCuller.h" +#include <gtest/gtest.h> +#include <public/WebTransformationMatrix.h> + +using WebKit::FakeWebCompositorOutputSurface; +using WebKit::FakeWebGraphicsContext3D; +using WebKit::WebTransformationMatrix; + +using namespace cc; +using namespace WebKitTests; + +namespace { + +class CCDelegatedRendererLayerImplTest : public testing::Test, public CCLayerTreeHostImplClient { +public: + CCDelegatedRendererLayerImplTest() + { + CCLayerTreeSettings settings; + settings.minimumOcclusionTrackingSize = IntSize(); + + m_hostImpl = CCLayerTreeHostImpl::create(settings, this); + m_hostImpl->initializeRenderer(createContext(), UnthrottledUploader); + m_hostImpl->setViewportSize(IntSize(10, 10), IntSize(10, 10)); + } + + // CCLayerTreeHostImplClient implementation. + virtual void didLoseContextOnImplThread() OVERRIDE { } + virtual void onSwapBuffersCompleteOnImplThread() OVERRIDE { } + virtual void onVSyncParametersChanged(double, double) OVERRIDE { } + virtual void onCanDrawStateChanged(bool) OVERRIDE { } + virtual void setNeedsRedrawOnImplThread() OVERRIDE { } + virtual void setNeedsCommitOnImplThread() OVERRIDE { } + virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE { } + virtual void releaseContentsTexturesOnImplThread() OVERRIDE { } + +protected: + PassOwnPtr<CCGraphicsContext> createContext() + { + return FakeWebCompositorOutputSurface::create(adoptPtr(new FakeWebGraphicsContext3D)); + } + + DebugScopedSetImplThread m_alwaysImplThread; + DebugScopedSetMainThreadBlocked m_alwaysMainThreadBlocked; + + OwnPtr<CCLayerTreeHostImpl> m_hostImpl; +}; + +static CCTestRenderPass* addRenderPass(Vector<OwnPtr<CCRenderPass> >& passList, CCRenderPass::Id id, IntRect outputRect, WebTransformationMatrix rootTransform) +{ + OwnPtr<CCRenderPass> pass(CCRenderPass::create(id, outputRect, rootTransform)); + CCTestRenderPass* testPass = static_cast<CCTestRenderPass*>(pass.get()); + passList.append(pass.release()); + return testPass; +} + +static CCSolidColorDrawQuad* addQuad(CCTestRenderPass* pass, IntRect rect, SkColor color) +{ + MockCCQuadCuller quadSink(pass->quadList(), pass->sharedQuadStateList()); + CCAppendQuadsData data(pass->id()); + CCSharedQuadState* sharedState = quadSink.useSharedQuadState(CCSharedQuadState::create(WebTransformationMatrix(), rect, rect, 1, false)); + OwnPtr<CCSolidColorDrawQuad> quad(CCSolidColorDrawQuad::create(sharedState, rect, color)); + CCSolidColorDrawQuad* quadPtr = quad.get(); + quadSink.append(quad.release(), data); + return quadPtr; +} + +static void addRenderPassQuad(CCTestRenderPass* toPass, CCTestRenderPass* contributingPass) +{ + MockCCQuadCuller quadSink(toPass->quadList(), toPass->sharedQuadStateList()); + CCAppendQuadsData data(toPass->id()); + IntRect outputRect = contributingPass->outputRect(); + CCSharedQuadState* sharedState = quadSink.useSharedQuadState(CCSharedQuadState::create(WebTransformationMatrix(), outputRect, outputRect, 1, false)); + OwnPtr<CCRenderPassDrawQuad> quad(CCRenderPassDrawQuad::create(sharedState, outputRect, contributingPass->id(), false, 0, outputRect, 0, 0, 0, 0)); + quadSink.append(quad.release(), data); +} + +class CCDelegatedRendererLayerImplTestSimple : public CCDelegatedRendererLayerImplTest { +public: + CCDelegatedRendererLayerImplTestSimple() + : CCDelegatedRendererLayerImplTest() + { + OwnPtr<CCSolidColorLayerImpl> rootLayer = CCSolidColorLayerImpl::create(1); + OwnPtr<CCSolidColorLayerImpl> layerBefore = CCSolidColorLayerImpl::create(2); + OwnPtr<CCSolidColorLayerImpl> layerAfter = CCSolidColorLayerImpl::create(3); + OwnPtr<CCDelegatedRendererLayerImpl> delegatedRendererLayer = CCDelegatedRendererLayerImpl::create(4); + + m_hostImpl->setViewportSize(IntSize(100, 100), IntSize(100, 100)); + rootLayer->setBounds(IntSize(100, 100)); + + layerBefore->setPosition(IntPoint(20, 20)); + layerBefore->setBounds(IntSize(14, 14)); + layerBefore->setContentBounds(IntSize(14, 14)); + layerBefore->setDrawsContent(true); + layerBefore->setForceRenderSurface(true); + + layerAfter->setPosition(IntPoint(5, 5)); + layerAfter->setBounds(IntSize(15, 15)); + layerAfter->setContentBounds(IntSize(15, 15)); + layerAfter->setDrawsContent(true); + layerAfter->setForceRenderSurface(true); + + delegatedRendererLayer->setPosition(IntPoint(3, 3)); + delegatedRendererLayer->setBounds(IntSize(10, 10)); + delegatedRendererLayer->setContentBounds(IntSize(10, 10)); + delegatedRendererLayer->setDrawsContent(true); + WebTransformationMatrix transform; + transform.translate(1, 1); + delegatedRendererLayer->setTransform(transform); + + Vector<OwnPtr<CCRenderPass> > delegatedRenderPasses; + CCTestRenderPass* pass1 = addRenderPass(delegatedRenderPasses, CCRenderPass::Id(9, 6), IntRect(6, 6, 6, 6), WebTransformationMatrix()); + addQuad(pass1, IntRect(0, 0, 6, 6), 33u); + CCTestRenderPass* pass2 = addRenderPass(delegatedRenderPasses, CCRenderPass::Id(9, 7), IntRect(7, 7, 7, 7), WebTransformationMatrix()); + addQuad(pass2, IntRect(0, 0, 7, 7), 22u); + addRenderPassQuad(pass2, pass1); + CCTestRenderPass* pass3 = addRenderPass(delegatedRenderPasses, CCRenderPass::Id(9, 8), IntRect(8, 8, 8, 8), WebTransformationMatrix()); + addRenderPassQuad(pass3, pass2); + delegatedRendererLayer->setRenderPasses(delegatedRenderPasses); + + // The RenderPasses should be taken by the layer. + EXPECT_EQ(0u, delegatedRenderPasses.size()); + + m_rootLayerPtr = rootLayer.get(); + m_layerBeforePtr = layerBefore.get(); + m_layerAfterPtr = layerAfter.get(); + m_delegatedRendererLayerPtr = delegatedRendererLayer.get(); + + // Force the delegated RenderPasses to come before the RenderPass from layerAfter. + layerAfter->addChild(delegatedRendererLayer.release()); + rootLayer->addChild(layerAfter.release()); + + // Get the RenderPass generated by layerBefore to come before the delegated RenderPasses. + rootLayer->addChild(layerBefore.release()); + + m_hostImpl->setRootLayer(rootLayer.release()); + } + +protected: + CCSolidColorLayerImpl* m_rootLayerPtr; + CCSolidColorLayerImpl* m_layerBeforePtr; + CCSolidColorLayerImpl* m_layerAfterPtr; + CCDelegatedRendererLayerImpl* m_delegatedRendererLayerPtr; +}; + +TEST_F(CCDelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes. + ASSERT_EQ(5u, frame.renderPasses.size()); + + // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame. + EXPECT_EQ(4, frame.renderPasses[1]->id().layerId); + EXPECT_EQ(1, frame.renderPasses[1]->id().index); + EXPECT_EQ(4, frame.renderPasses[2]->id().layerId); + EXPECT_EQ(2, frame.renderPasses[2]->id().index); + // And all other RenderPasses should be non-delegated. + EXPECT_NE(4, frame.renderPasses[0]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[0]->id().index); + EXPECT_NE(4, frame.renderPasses[3]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[3]->id().index); + EXPECT_NE(4, frame.renderPasses[4]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[4]->id().index); + + // The DelegatedRendererLayer should have added its RenderPasses to the frame in order. + EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[1]->outputRect()); + EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[2]->outputRect()); +} + +TEST_F(CCDelegatedRendererLayerImplTestSimple, AddsQuadsToContributingRenderPasses) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes. + ASSERT_EQ(5u, frame.renderPasses.size()); + + // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame. + EXPECT_EQ(4, frame.renderPasses[1]->id().layerId); + EXPECT_EQ(1, frame.renderPasses[1]->id().index); + EXPECT_EQ(4, frame.renderPasses[2]->id().layerId); + EXPECT_EQ(2, frame.renderPasses[2]->id().index); + + // The DelegatedRendererLayer should have added copies of its quads to contributing RenderPasses. + ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size()); + EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect()); + + // Verify it added the right quads. + ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size()); + EXPECT_RECT_EQ(IntRect(0, 0, 7, 7), frame.renderPasses[2]->quadList()[0]->quadRect()); + EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[2]->quadList()[1]->quadRect()); + ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size()); + EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect()); +} + +TEST_F(CCDelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes. + ASSERT_EQ(5u, frame.renderPasses.size()); + + // The layer's target is the RenderPass from m_layerAfter. + EXPECT_EQ(CCRenderPass::Id(3, 0), frame.renderPasses[3]->id()); + + // The DelegatedRendererLayer should have added copies of quads in its root RenderPass to its target RenderPass. + // The m_layerAfter also adds one quad. + ASSERT_EQ(2u, frame.renderPasses[3]->quadList().size()); + + // Verify it added the right quads. + EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[3]->quadList()[0]->quadRect()); + + // Its target layer should have a quad as well. + EXPECT_RECT_EQ(IntRect(0, 0, 15, 15), frame.renderPasses[3]->quadList()[1]->quadRect()); +} + +TEST_F(CCDelegatedRendererLayerImplTestSimple, QuadsFromRootRenderPassAreModifiedForTheTarget) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes. + ASSERT_EQ(5u, frame.renderPasses.size()); + + // The DelegatedRendererLayer is at position 3,3 compared to its target, and has a translation transform of 1,1. + // So its root RenderPass' quads should all be transformed by that combined amount. + WebTransformationMatrix transform; + transform.translate(4, 4); + EXPECT_TRANSFORMATION_MATRIX_EQ(transform, frame.renderPasses[3]->quadList()[0]->quadTransform()); + + // Quads from non-root RenderPasses should not be shifted though. + ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size()); + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[0]->quadTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[1]->quadTransform()); + ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size()); + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[1]->quadList()[0]->quadTransform()); +} + +class CCDelegatedRendererLayerImplTestOwnSurface : public CCDelegatedRendererLayerImplTestSimple { +public: + CCDelegatedRendererLayerImplTestOwnSurface() + : CCDelegatedRendererLayerImplTestSimple() + { + m_delegatedRendererLayerPtr->setForceRenderSurface(true); + } +}; + +TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass. + ASSERT_EQ(6u, frame.renderPasses.size()); + + // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame. + EXPECT_EQ(4, frame.renderPasses[1]->id().layerId); + EXPECT_EQ(1, frame.renderPasses[1]->id().index); + EXPECT_EQ(4, frame.renderPasses[2]->id().layerId); + EXPECT_EQ(2, frame.renderPasses[2]->id().index); + // The DelegatedRendererLayer should have added a RenderPass for its surface to the frame. + EXPECT_EQ(4, frame.renderPasses[1]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[3]->id().index); + // And all other RenderPasses should be non-delegated. + EXPECT_NE(4, frame.renderPasses[0]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[0]->id().index); + EXPECT_NE(4, frame.renderPasses[4]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[4]->id().index); + EXPECT_NE(4, frame.renderPasses[5]->id().layerId); + EXPECT_EQ(0, frame.renderPasses[5]->id().index); + + // The DelegatedRendererLayer should have added its RenderPasses to the frame in order. + EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[1]->outputRect()); + EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[2]->outputRect()); +} + +TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, AddsQuadsToContributingRenderPasses) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass. + ASSERT_EQ(6u, frame.renderPasses.size()); + + // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame. + EXPECT_EQ(4, frame.renderPasses[1]->id().layerId); + EXPECT_EQ(1, frame.renderPasses[1]->id().index); + EXPECT_EQ(4, frame.renderPasses[2]->id().layerId); + EXPECT_EQ(2, frame.renderPasses[2]->id().index); + + // The DelegatedRendererLayer should have added copies of its quads to contributing RenderPasses. + ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size()); + EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect()); + + // Verify it added the right quads. + ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size()); + EXPECT_RECT_EQ(IntRect(0, 0, 7, 7), frame.renderPasses[2]->quadList()[0]->quadRect()); + EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[2]->quadList()[1]->quadRect()); + ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size()); + EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect()); +} + +TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass. + ASSERT_EQ(6u, frame.renderPasses.size()); + + // The layer's target is the RenderPass owned by itself. + EXPECT_EQ(CCRenderPass::Id(4, 0), frame.renderPasses[3]->id()); + + // The DelegatedRendererLayer should have added copies of quads in its root RenderPass to its target RenderPass. + // The m_layerAfter also adds one quad. + ASSERT_EQ(1u, frame.renderPasses[3]->quadList().size()); + + // Verify it added the right quads. + EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[3]->quadList()[0]->quadRect()); +} + +TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, QuadsFromRootRenderPassAreNotModifiedForTheTarget) +{ + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass. + ASSERT_EQ(6u, frame.renderPasses.size()); + + // Because the DelegatedRendererLayer owns a RenderSurface, its root RenderPass' quads do not need to be + // modified at all. + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[3]->quadList()[0]->quadTransform()); + + // Quads from non-root RenderPasses should not be shifted though. + ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size()); + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[0]->quadTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[1]->quadTransform()); + ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size()); + EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[1]->quadList()[0]->quadTransform()); +} + +} // namespace diff --git a/cc/CCLayerImpl.h b/cc/CCLayerImpl.h index 459b76f..ea6582e 100644 --- a/cc/CCLayerImpl.h +++ b/cc/CCLayerImpl.h @@ -7,6 +7,7 @@ #include "CCInputHandler.h" #include "CCLayerAnimationController.h" +#include "CCRenderPass.h" #include "CCRenderSurface.h" #include "CCResourceProvider.h" #include "CCSharedQuadState.h" @@ -81,6 +82,10 @@ public: virtual CCResourceProvider::ResourceId contentsResourceId() const; + virtual bool hasContributingDelegatedRenderPasses() const { return false; } + virtual CCRenderPass::Id firstContributingRenderPassId() const { return CCRenderPass::Id(0, 0); } + virtual CCRenderPass::Id nextContributingRenderPassId(CCRenderPass::Id) const { return CCRenderPass::Id(0, 0); } + // Returns true if this layer has content to draw. void setDrawsContent(bool); bool drawsContent() const { return m_drawsContent; } @@ -89,7 +94,7 @@ public: void setForceRenderSurface(bool force) { m_forceRenderSurface = force; } // Returns true if any of the layer's descendants has content to draw. - bool descendantDrawsContent(); + virtual bool descendantDrawsContent(); void setAnchorPoint(const FloatPoint&); const FloatPoint& anchorPoint() const { return m_anchorPoint; } diff --git a/cc/CCLayerTreeHostCommon.cpp b/cc/CCLayerTreeHostCommon.cpp index b5257e0..141b3ff 100644 --- a/cc/CCLayerTreeHostCommon.cpp +++ b/cc/CCLayerTreeHostCommon.cpp @@ -341,7 +341,7 @@ void setupRootLayerAndSurfaceForRecursion(LayerType* rootLayer, LayerList& rende rootLayer->createRenderSurface(); rootLayer->renderSurface()->setContentRect(IntRect(IntPoint::zero(), deviceViewportSize)); - rootLayer->renderSurface()->clearLayerList(); + rootLayer->renderSurface()->clearLayerLists(); ASSERT(renderSurfaceLayerList.isEmpty()); renderSurfaceLayerList.append(rootLayer); @@ -528,7 +528,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay layer->createRenderSurface(); RenderSurfaceType* renderSurface = layer->renderSurface(); - renderSurface->clearLayerList(); + renderSurface->clearLayerLists(); // The origin of the new surface is the upper left corner of the layer. renderSurface->setDrawTransform(drawTransform); @@ -697,7 +697,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay clippedContentRect.setHeight(std::min(clippedContentRect.height(), maxTextureSize)); if (clippedContentRect.isEmpty()) - renderSurface->clearLayerList(); + renderSurface->clearLayerLists(); renderSurface->setContentRect(clippedContentRect); renderSurface->setScreenSpaceTransform(layer->screenSpaceTransform()); @@ -753,7 +753,8 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay else drawableContentRectOfSubtree = localDrawableContentRectOfSubtree; - return; + if (layer->hasContributingDelegatedRenderPasses()) + layer->renderTarget()->renderSurface()->addContributingDelegatedRenderPassLayer(layer); } // FIXME: Instead of using the following function to set visibility rects on a second diff --git a/cc/CCLayerTreeHostImpl.cpp b/cc/CCLayerTreeHostImpl.cpp index e91a7fc..7168fe4 100644 --- a/cc/CCLayerTreeHostImpl.cpp +++ b/cc/CCLayerTreeHostImpl.cpp @@ -291,7 +291,7 @@ bool CCLayerTreeHostImpl::calculateRenderPasses(FrameData& frame) occlusionTracker.enterLayer(it); - CCAppendQuadsData appendQuadsData; + CCAppendQuadsData appendQuadsData(targetRenderPass->id()); if (it.representsContributingRenderSurface()) { CCRenderPass::Id contributingRenderPassId = it->renderSurface()->renderPassId(); @@ -304,6 +304,19 @@ bool CCLayerTreeHostImpl::calculateRenderPasses(FrameData& frame) else { it->willDraw(m_resourceProvider.get()); frame.willDrawLayers.append(*it); + + if (it->hasContributingDelegatedRenderPasses()) { + CCRenderPass::Id contributingRenderPassId = it->firstContributingRenderPassId(); + while (frame.renderPassesById.contains(contributingRenderPassId)) { + CCRenderPass* renderPass = frame.renderPassesById.get(contributingRenderPassId); + + CCAppendQuadsData appendQuadsData(renderPass->id()); + renderPass->appendQuadsForLayer(*it, &occlusionTracker, appendQuadsData); + + contributingRenderPassId = it->nextContributingRenderPassId(contributingRenderPassId); + } + } + targetRenderPass->appendQuadsForLayer(*it, &occlusionTracker, appendQuadsData); } } diff --git a/cc/CCLayerTreeHostImplTest.cpp b/cc/CCLayerTreeHostImplTest.cpp index f897409..baaba5c 100644 --- a/cc/CCLayerTreeHostImplTest.cpp +++ b/cc/CCLayerTreeHostImplTest.cpp @@ -7,6 +7,7 @@ #include "CCLayerTreeHostImpl.h" #include "CCAnimationTestCommon.h" +#include "CCDelegatedRendererLayerImpl.h" #include "CCGeometryTestUtils.h" #include "CCHeadsUpDisplayLayerImpl.h" #include "CCIOSurfaceLayerImpl.h" @@ -15,6 +16,7 @@ #include "CCLayerTilingData.h" #include "CCQuadSink.h" #include "CCRenderPassDrawQuad.h" +#include "CCRenderPassTestCommon.h" #include "CCRendererGL.h" #include "CCScrollbarGeometryFixedThumb.h" #include "CCScrollbarLayerImpl.h" @@ -22,6 +24,7 @@ #include "CCSingleThreadProxy.h" #include "CCSolidColorDrawQuad.h" #include "CCTestCommon.h" +#include "CCTextureDrawQuad.h" #include "CCTextureLayerImpl.h" #include "CCTileDrawQuad.h" #include "CCTiledLayerImpl.h" @@ -2480,6 +2483,20 @@ protected: } }; +static inline PassOwnPtr<CCRenderPass> createRenderPassWithResource(CCResourceProvider* provider) +{ + CCResourceProvider::ResourceId resourceId = provider->createResource(0, IntSize(1, 1), GraphicsContext3D::RGBA, CCResourceProvider::TextureUsageAny); + + OwnPtr<CCRenderPass> pass = CCRenderPass::create(CCRenderPass::Id(1, 1), IntRect(0, 0, 1, 1), WebTransformationMatrix()); + OwnPtr<CCSharedQuadState> sharedState = CCSharedQuadState::create(WebTransformationMatrix(), IntRect(0, 0, 1, 1), IntRect(0, 0, 1, 1), 1, false); + OwnPtr<CCTextureDrawQuad> quad = CCTextureDrawQuad::create(sharedState.get(), IntRect(0, 0, 1, 1), resourceId, false, FloatRect(0, 0, 1, 1), false); + + static_cast<CCTestRenderPass*>(pass.get())->appendSharedQuadState(sharedState.release()); + static_cast<CCTestRenderPass*>(pass.get())->appendQuad(quad.release()); + + return pass.release(); +} + TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) { OwnPtr<CCLayerImpl> rootLayer(CCLayerImpl::create(1)); @@ -2546,7 +2563,6 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) rootLayer->addChild(hudLayer.release()); OwnPtr<FakeScrollbarLayerImpl> scrollbarLayer(FakeScrollbarLayerImpl::create(8)); - scrollbarLayer->setLayerTreeHostImpl(m_hostImpl.get()); scrollbarLayer->setBounds(IntSize(10, 10)); scrollbarLayer->setContentBounds(IntSize(10, 10)); scrollbarLayer->setDrawsContent(true); @@ -2554,6 +2570,17 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) scrollbarLayer->createResources(m_hostImpl->resourceProvider()); rootLayer->addChild(scrollbarLayer.release()); + OwnPtr<CCDelegatedRendererLayerImpl> delegatedRendererLayer(CCDelegatedRendererLayerImpl::create(9)); + delegatedRendererLayer->setBounds(IntSize(10, 10)); + delegatedRendererLayer->setContentBounds(IntSize(10, 10)); + delegatedRendererLayer->setDrawsContent(true); + delegatedRendererLayer->setLayerTreeHostImpl(m_hostImpl.get()); + Vector<OwnPtr<CCRenderPass> > passList; + passList.append(createRenderPassWithResource(m_hostImpl->resourceProvider())); + delegatedRendererLayer->setRenderPasses(passList); + EXPECT_TRUE(passList.isEmpty()); + rootLayer->addChild(delegatedRendererLayer.release()); + // Use a context that supports IOSurfaces m_hostImpl->initializeRenderer(FakeWebCompositorOutputSurface::create(adoptPtr(new FakeWebGraphicsContext3DWithIOSurface)), UnthrottledUploader); @@ -3862,16 +3889,6 @@ struct RenderPassRemovalTestData : public CCLayerTreeHostImpl::FrameData { OwnPtr<CCSharedQuadState> sharedQuadState; }; -class CCTestRenderPass: public CCRenderPass { -public: - static PassOwnPtr<CCRenderPass> create(CCRenderPass::Id id, IntRect outputRect, const WebTransformationMatrix& rootTransform) { return adoptPtr(new CCTestRenderPass(id, outputRect, rootTransform)); } - - void appendQuad(PassOwnPtr<CCDrawQuad> quad) { m_quadList.append(quad); } - -protected: - CCTestRenderPass(CCRenderPass::Id id, IntRect outputRect, const WebTransformationMatrix& rootTransform) : CCRenderPass(id, outputRect, rootTransform) { } -}; - class CCTestRenderer : public CCRendererGL, public CCRendererClient { public: static PassOwnPtr<CCTestRenderer> create(CCResourceProvider* resourceProvider) @@ -3917,7 +3934,7 @@ static void configureRenderPassTestData(const char* testScript, RenderPassRemova // Pre-create root pass CCRenderPass::Id rootRenderPassId = CCRenderPass::Id(testScript[0], testScript[1]); - OwnPtr<CCRenderPass> rootRenderPass = CCTestRenderPass::create(rootRenderPassId, IntRect(), WebTransformationMatrix()); + OwnPtr<CCRenderPass> rootRenderPass = CCRenderPass::create(rootRenderPassId, IntRect(), WebTransformationMatrix()); testData.renderPassCache.insert(std::pair<CCRenderPass::Id, RenderPassCacheEntry>(rootRenderPassId, RenderPassCacheEntry(rootRenderPass.release()))); while (*currentChar) { int layerId = *currentChar; diff --git a/cc/CCRenderSurface.cpp b/cc/CCRenderSurface.cpp index dfbeeab..f4e1d8d 100644 --- a/cc/CCRenderSurface.cpp +++ b/cc/CCRenderSurface.cpp @@ -11,6 +11,7 @@ #include "base/stringprintf.h" #include "CCDamageTracker.h" #include "CCDebugBorderDrawQuad.h" +#include "CCDelegatedRendererLayerImpl.h" #include "CCLayerImpl.h" #include "CCMathUtil.h" #include "CCQuadSink.h" @@ -144,6 +145,19 @@ bool CCRenderSurface::surfacePropertyChangedOnlyFromDescendant() const return m_surfacePropertyChanged && !m_owningLayer->layerPropertyChanged(); } +void CCRenderSurface::addContributingDelegatedRenderPassLayer(CCLayerImpl* layer) +{ + ASSERT(m_layerList.contains(layer)); + CCDelegatedRendererLayerImpl* delegatedRendererLayer = static_cast<CCDelegatedRendererLayerImpl*>(layer); + m_contributingDelegatedRenderPassLayerList.append(delegatedRendererLayer); +} + +void CCRenderSurface::clearLayerLists() +{ + m_layerList.clear(); + m_contributingDelegatedRenderPassLayerList.clear(); +} + static inline IntRect computeClippedRectInTarget(const CCLayerImpl* owningLayer) { ASSERT(owningLayer->parent()); @@ -174,6 +188,9 @@ CCRenderPass::Id CCRenderSurface::renderPassId() void CCRenderSurface::appendRenderPasses(CCRenderPassSink& passSink) { + for (size_t i = 0; i < m_contributingDelegatedRenderPassLayerList.size(); ++i) + m_contributingDelegatedRenderPassLayerList[i]->appendContributingRenderPasses(passSink); + OwnPtr<CCRenderPass> pass = CCRenderPass::create(renderPassId(), m_contentRect, m_screenSpaceTransform); pass->setDamageRect(m_damageTracker->currentDamageRect()); pass->setFilters(m_owningLayer->filters()); diff --git a/cc/CCRenderSurface.h b/cc/CCRenderSurface.h index 55dc483..107cf67 100644 --- a/cc/CCRenderSurface.h +++ b/cc/CCRenderSurface.h @@ -18,6 +18,7 @@ namespace cc { class CCDamageTracker; +class CCDelegatedRendererLayerImpl; class CCQuadSink; class CCRenderPassSink; class CCLayerImpl; @@ -72,8 +73,9 @@ public: void setContentRect(const IntRect&); const IntRect& contentRect() const { return m_contentRect; } - void clearLayerList() { m_layerList.clear(); } Vector<CCLayerImpl*>& layerList() { return m_layerList; } + void addContributingDelegatedRenderPassLayer(CCLayerImpl*); + void clearLayerLists(); int owningLayerId() const; @@ -108,6 +110,7 @@ private: IntRect m_clipRect; Vector<CCLayerImpl*> m_layerList; + Vector<CCDelegatedRendererLayerImpl*> m_contributingDelegatedRenderPassLayerList; // The nearest ancestor target surface that will contain the contents of this surface, and that is going // to move pixels within the surface (such as with a blur). This can point to itself. diff --git a/cc/CCRenderSurfaceTest.cpp b/cc/CCRenderSurfaceTest.cpp index 9322275..65c8785 100644 --- a/cc/CCRenderSurfaceTest.cpp +++ b/cc/CCRenderSurfaceTest.cpp @@ -70,7 +70,7 @@ TEST(CCRenderSurfaceTest, verifySurfaceChangesAreTrackedProperly) EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE(renderSurface->setDrawOpacity(0.5)); EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE(renderSurface->setDrawTransform(dummyMatrix)); EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE(renderSurface->setReplicaDrawTransform(dummyMatrix)); - EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE(renderSurface->clearLayerList()); + EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE(renderSurface->clearLayerLists()); } TEST(CCRenderSurfaceTest, sanityCheckSurfaceCreatesCorrectSharedQuadState) diff --git a/cc/DelegatedRendererLayerChromium.cpp b/cc/DelegatedRendererLayerChromium.cpp new file mode 100644 index 0000000..8b7a710 --- /dev/null +++ b/cc/DelegatedRendererLayerChromium.cpp @@ -0,0 +1,33 @@ +// 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 "DelegatedRendererLayerChromium.h" + +#include "CCDelegatedRendererLayerImpl.h" + +namespace cc { + +PassRefPtr<DelegatedRendererLayerChromium> DelegatedRendererLayerChromium::create() +{ + return adoptRef(new DelegatedRendererLayerChromium()); +} + +DelegatedRendererLayerChromium::DelegatedRendererLayerChromium() + : LayerChromium() +{ + setIsDrawable(true); + setMasksToBounds(true); +} + +DelegatedRendererLayerChromium::~DelegatedRendererLayerChromium() +{ +} + +PassOwnPtr<CCLayerImpl> DelegatedRendererLayerChromium::createCCLayerImpl() +{ + return CCDelegatedRendererLayerImpl::create(m_layerId); +} + +} diff --git a/cc/DelegatedRendererLayerChromium.h b/cc/DelegatedRendererLayerChromium.h new file mode 100644 index 0000000..1e464ae --- /dev/null +++ b/cc/DelegatedRendererLayerChromium.h @@ -0,0 +1,24 @@ +// 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. + +#ifndef DelegatedRendererLayerChromium_h +#define DelegatedRendererLayerChromium_h + +#include "LayerChromium.h" + +namespace cc { + +class DelegatedRendererLayerChromium : public LayerChromium { +public: + static PassRefPtr<DelegatedRendererLayerChromium> create(); + virtual ~DelegatedRendererLayerChromium(); + + virtual PassOwnPtr<CCLayerImpl> createCCLayerImpl() OVERRIDE; + +protected: + DelegatedRendererLayerChromium(); +}; + +} +#endif diff --git a/cc/LayerChromium.h b/cc/LayerChromium.h index 0b4fe63..71ec0cc 100644 --- a/cc/LayerChromium.h +++ b/cc/LayerChromium.h @@ -172,6 +172,8 @@ public: virtual void setLayerTreeHost(CCLayerTreeHost*); + bool hasContributingDelegatedRenderPasses() const { return false; } + void setIsDrawable(bool); void setReplicaLayer(LayerChromium*); diff --git a/cc/RenderSurfaceChromium.h b/cc/RenderSurfaceChromium.h index 22d8880..e9fa522 100644 --- a/cc/RenderSurfaceChromium.h +++ b/cc/RenderSurfaceChromium.h @@ -57,8 +57,11 @@ public: const IntRect& clipRect() const { return m_clipRect; } void setClipRect(const IntRect& clipRect) { m_clipRect = clipRect; } - void clearLayerList() { m_layerList.clear(); } Vector<RefPtr<LayerChromium> >& layerList() { return m_layerList; } + // A no-op since DelegatedRendererLayers on the main thread don't have any + // RenderPasses so they can't contribute to a surface. + void addContributingDelegatedRenderPassLayer(LayerChromium*) { } + void clearLayerLists() { m_layerList.clear(); } void setNearestAncestorThatMovesPixels(RenderSurfaceChromium* surface) { m_nearestAncestorThatMovesPixels = surface; } const RenderSurfaceChromium* nearestAncestorThatMovesPixels() const { return m_nearestAncestorThatMovesPixels; } @@ -28,6 +28,8 @@ 'CCDebugRectHistory.h', 'CCDelayBasedTimeSource.cpp', 'CCDelayBasedTimeSource.h', + 'CCDelegatedRendererLayerImpl.cpp', + 'CCDelegatedRendererLayerImpl.h', 'CCDirectRenderer.cpp', 'CCDirectRenderer.h', 'CCDrawQuad.cpp', @@ -163,6 +165,8 @@ 'ContentLayerChromium.cpp', 'ContentLayerChromium.h', 'ContentLayerChromiumClient.h', + 'DelegatedRendererLayerChromium.cpp', + 'DelegatedRendererLayerChromium.h', 'FrameBufferSkPictureCanvasLayerTextureUpdater.cpp', 'FrameBufferSkPictureCanvasLayerTextureUpdater.h', 'GeometryBinding.cpp', diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 1f26448..8201254 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -11,6 +11,7 @@ 'CCDamageTrackerTest.cpp', 'CCDelayBasedTimeSourceTest.cpp', 'CCDrawQuadTest.cpp', + 'CCDelegatedRendererLayerImplTest.cpp', 'CCFrameRateControllerTest.cpp', 'CCHeadsUpDisplayTest.cpp', 'CCKeyframedAnimationCurveTest.cpp', @@ -61,6 +62,7 @@ 'test/CCLayerTestCommon.h', 'test/CCOcclusionTrackerTestCommon.h', 'test/CCSchedulerTestCommon.h', + 'test/CCRenderPassTestCommon.h', 'test/CCTestCommon.h', 'test/CCTiledLayerTestCommon.cpp', 'test/CCTiledLayerTestCommon.h', diff --git a/cc/test/CCRenderPassTestCommon.h b/cc/test/CCRenderPassTestCommon.h new file mode 100644 index 0000000..8bb9839 --- /dev/null +++ b/cc/test/CCRenderPassTestCommon.h @@ -0,0 +1,24 @@ +// 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. + +#ifndef CCRenderPassTestCommon_h +#define CCRenderPassTestCommon_h + +#include "CCRenderPass.h" +#include <wtf/PassOwnPtr.h> + +namespace WebKitTests { + +class CCTestRenderPass : public cc::CCRenderPass { +public: + cc::CCQuadList& quadList() { return m_quadList; } + cc::CCSharedQuadStateList& sharedQuadStateList() { return m_sharedQuadStateList; } + + void appendQuad(PassOwnPtr<cc::CCDrawQuad> quad) { m_quadList.append(quad); } + void appendSharedQuadState(PassOwnPtr<cc::CCSharedQuadState> state) { m_sharedQuadStateList.append(state); } +}; + +} //namespace WebKitTests + +#endif // CCRenderPassTestCommon_h diff --git a/webkit/compositor_bindings/WebDelegatedRendererLayerImpl.cpp b/webkit/compositor_bindings/WebDelegatedRendererLayerImpl.cpp new file mode 100644 index 0000000..d8c9d1b --- /dev/null +++ b/webkit/compositor_bindings/WebDelegatedRendererLayerImpl.cpp @@ -0,0 +1,28 @@ +// 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 "WebDelegatedRendererLayerImpl.h" + +#include "DelegatedRendererLayerChromium.h" + +using namespace cc; + +namespace WebKit { + +WebDelegatedRendererLayerImpl::WebDelegatedRendererLayerImpl() + : m_layer(adoptPtr(new WebLayerImpl(DelegatedRendererLayerChromium::create()))) +{ +} + +WebDelegatedRendererLayerImpl::~WebDelegatedRendererLayerImpl() +{ +} + +WebLayer* WebDelegatedRendererLayerImpl::layer() +{ + return m_layer.get(); +} + +} // namespace WebKit diff --git a/webkit/compositor_bindings/WebDelegatedRendererLayerImpl.h b/webkit/compositor_bindings/WebDelegatedRendererLayerImpl.h new file mode 100644 index 0000000..321e9c3 --- /dev/null +++ b/webkit/compositor_bindings/WebDelegatedRendererLayerImpl.h @@ -0,0 +1,30 @@ +// 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. + +#ifndef WebDelegatedRendererLayerImpl_h +#define WebDelegatedRendererLayerImpl_h + +#include "WebLayerImpl.h" +#include <public/WebDelegatedRendererLayer.h> +#include <wtf/OwnPtr.h> + +namespace WebKit { + +class WebDelegatedRendererLayerImpl : public WebDelegatedRendererLayer { +public: + WebDelegatedRendererLayerImpl(); + + // WebDelegatedRendererLayer implementation. + virtual WebLayer* layer() OVERRIDE; + +protected: + virtual ~WebDelegatedRendererLayerImpl(); + +private: + OwnPtr<WebLayerImpl> m_layer; +}; + +} // namespace WebKit + +#endif // WebDelegatedLayerImpl_h diff --git a/webkit/compositor_bindings/compositor_bindings.gyp b/webkit/compositor_bindings/compositor_bindings.gyp index 0316b4a..f26950d 100644 --- a/webkit/compositor_bindings/compositor_bindings.gyp +++ b/webkit/compositor_bindings/compositor_bindings.gyp @@ -17,6 +17,8 @@ 'WebCompositorImpl.h', 'WebContentLayerImpl.cpp', 'WebContentLayerImpl.h', + 'WebDelegatedRendererLayerImpl.cpp', + 'WebDelegatedRendererLayerImpl.h', 'WebExternalTextureLayerImpl.cpp', 'WebExternalTextureLayerImpl.h', 'WebFloatAnimationCurveImpl.cpp', diff --git a/webkit/compositor_bindings/web_compositor_support_impl.cc b/webkit/compositor_bindings/web_compositor_support_impl.cc index c66c3de..9c7a1fa 100644 --- a/webkit/compositor_bindings/web_compositor_support_impl.cc +++ b/webkit/compositor_bindings/web_compositor_support_impl.cc @@ -11,6 +11,7 @@ #include "webkit/compositor_bindings/WebLayerTreeViewImpl.h" #include "webkit/compositor_bindings/WebCompositorImpl.h" #include "webkit/compositor_bindings/WebContentLayerImpl.h" +#include "webkit/compositor_bindings/WebDelegatedRendererLayerImpl.h" #include "webkit/compositor_bindings/WebExternalTextureLayerImpl.h" #include "webkit/compositor_bindings/WebIOSurfaceLayerImpl.h" #include "webkit/compositor_bindings/WebSolidColorLayerImpl.h" @@ -39,6 +40,7 @@ using WebKit::WebAnimation; using WebKit::WebAnimationCurve; using WebKit::WebContentLayer; using WebKit::WebContentLayerClient; +using WebKit::WebDelegatedRendererLayer; using WebKit::WebExternalTextureLayer; using WebKit::WebExternalTextureLayerClient; using WebKit::WebFloatAnimationCurve; @@ -152,6 +154,11 @@ WebContentLayer* WebCompositorSupportImpl::createContentLayer( #endif } +WebDelegatedRendererLayer* + WebCompositorSupportImpl::createDelegatedRendererLayer() { + return new WebKit::WebDelegatedRendererLayerImpl(); +} + WebExternalTextureLayer* WebCompositorSupportImpl::createExternalTextureLayer( WebExternalTextureLayerClient* client) { #if defined(USE_LIBCC_FOR_COMPOSITOR) diff --git a/webkit/compositor_bindings/web_compositor_support_impl.h b/webkit/compositor_bindings/web_compositor_support_impl.h index a2530cc..f532326 100644 --- a/webkit/compositor_bindings/web_compositor_support_impl.h +++ b/webkit/compositor_bindings/web_compositor_support_impl.h @@ -27,6 +27,7 @@ class WebCompositorSupportImpl : public WebKit::WebCompositorSupport { virtual WebKit::WebLayer* createLayer(); virtual WebKit::WebContentLayer* createContentLayer( WebKit::WebContentLayerClient* client); + virtual WebKit::WebDelegatedRendererLayer* createDelegatedRendererLayer(); virtual WebKit::WebExternalTextureLayer* createExternalTextureLayer(WebKit::WebExternalTextureLayerClient* client); virtual WebKit::WebIOSurfaceLayer* |