summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-20 17:26:57 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-20 17:26:57 +0000
commit7d929c0747bb29fa2bbe74085eab16c45405c3c5 (patch)
tree95f066b29a1eb764b21450e7a29c0fae49ec87c3 /cc
parentb55715ef252cc4fa13f03e188b095202b542527b (diff)
downloadchromium_src-7d929c0747bb29fa2bbe74085eab16c45405c3c5.zip
chromium_src-7d929c0747bb29fa2bbe74085eab16c45405c3c5.tar.gz
chromium_src-7d929c0747bb29fa2bbe74085eab16c45405c3c5.tar.bz2
Add the ubercomp DelegatedRendererLayer.
This adds a layer that owns a set of RenderPasses with DrawQuads, and is able to insert those RenderPasses and DrawQuads into the current frame during CCLayerTreeHostImpl::calculateRenderPasses(). The layer owns whatever quads/passes you give to it, and copies them with modifications as needed into the current frame via the QuadSink. Quads from the layer's root RenderPass are merged into its target RenderPass, with the transform and opacity being modified if needed. Other RenderPasses are inserted into the frame as-is, with RenderPass ids being adjusted to not collide with any other RenderPasses in the frame, and using a scheme that allows the layer to reverse-lookup its own copy of a RenderPass from the id it generated. Moved from: https://bugs.webkit.org/show_bug.cgi?id=94145 Tests: CCDelegatedRendererLayerImplTestSimple.AddsContributingRenderPasses CCDelegatedRendererLayerImplTestSimple.AddsQuadsToContributingRenderPasses CCDelegatedRendererLayerImplTestSimple.AddsQuadsToTargetRenderPass CCDelegatedRendererLayerImplTestSimple.QuadsFromRootRenderPassAreModifiedForTheTarget CCDelegatedRendererLayerImplTestOwnSurface.AddsRenderPasses CCDelegatedRendererLayerImplTestOwnSurface.AddsQuadsToContributingRenderPasses CCDelegatedRendererLayerImplTestOwnSurface.AddsQuadsToTargetRenderPass CCDelegatedRendererLayerImplTestOwnSurface.QuadsFromRootRenderPassAreNotModifiedForTheTarget BUG=123445 Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=157700 Review URL: https://chromiumcodereview.appspot.com/10916307 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157794 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/CCAppendQuadsData.h12
-rw-r--r--cc/CCDamageTrackerTest.cpp2
-rw-r--r--cc/CCDelegatedRendererLayerImpl.cpp177
-rw-r--r--cc/CCDelegatedRendererLayerImpl.h49
-rw-r--r--cc/CCDelegatedRendererLayerImplTest.cpp379
-rw-r--r--cc/CCLayerImpl.h7
-rw-r--r--cc/CCLayerTreeHostCommon.cpp9
-rw-r--r--cc/CCLayerTreeHostImpl.cpp15
-rw-r--r--cc/CCLayerTreeHostImplTest.cpp41
-rw-r--r--cc/CCRenderSurface.cpp17
-rw-r--r--cc/CCRenderSurface.h5
-rw-r--r--cc/CCRenderSurfaceTest.cpp2
-rw-r--r--cc/DelegatedRendererLayerChromium.cpp33
-rw-r--r--cc/DelegatedRendererLayerChromium.h24
-rw-r--r--cc/LayerChromium.h2
-rw-r--r--cc/RenderSurfaceChromium.h5
-rw-r--r--cc/cc.gyp4
-rw-r--r--cc/cc_tests.gyp2
-rw-r--r--cc/test/CCRenderPassTestCommon.h24
19 files changed, 787 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..fafd3a8
--- /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(OwnPtrVector<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.take(i));
+ }
+ 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();
+ 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];
+ 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];
+
+ 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..0e83342
--- /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(OwnPtrVector<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"; }
+
+ OwnPtrVector<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..e5fcdc8
--- /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(OwnPtrVector<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);
+
+ OwnPtrVector<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 3c48367..35ade76 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..c1edc70 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());
+ OwnPtrVector<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; }
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 70bbe5b..b166d13 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -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