OLD | NEW |
(Empty) | |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 |
| 7 #include "CCDelegatedRendererLayerImpl.h" |
| 8 |
| 9 #include "CCAppendQuadsData.h" |
| 10 #include "CCQuadSink.h" |
| 11 #include "CCRenderPassDrawQuad.h" |
| 12 #include "CCRenderPassSink.h" |
| 13 |
| 14 namespace cc { |
| 15 |
| 16 CCDelegatedRendererLayerImpl::CCDelegatedRendererLayerImpl(int id) |
| 17 : CCLayerImpl(id) |
| 18 { |
| 19 } |
| 20 |
| 21 CCDelegatedRendererLayerImpl::~CCDelegatedRendererLayerImpl() |
| 22 { |
| 23 clearRenderPasses(); |
| 24 } |
| 25 |
| 26 bool CCDelegatedRendererLayerImpl::descendantDrawsContent() |
| 27 { |
| 28 // FIXME: This could possibly return false even though there are some |
| 29 // quads present as they could all be from a single layer (or set of |
| 30 // layers without children). If this happens, then make a test that |
| 31 // ensures the opacity is being changed on quads in the root RenderPass |
| 32 // when this layer doesn't own a RenderSurface. |
| 33 return !m_renderPassesInDrawOrder.isEmpty(); |
| 34 } |
| 35 |
| 36 bool CCDelegatedRendererLayerImpl::hasContributingDelegatedRenderPasses() const |
| 37 { |
| 38 // The root RenderPass for the layer is merged with its target |
| 39 // RenderPass in each frame. So we only have extra RenderPasses |
| 40 // to merge when we have a non-root RenderPass present. |
| 41 return m_renderPassesInDrawOrder.size() > 1; |
| 42 } |
| 43 |
| 44 void CCDelegatedRendererLayerImpl::setRenderPasses(OwnPtrVector<CCRenderPass>& r
enderPassesInDrawOrder) |
| 45 { |
| 46 FloatRect oldRootDamage; |
| 47 if (!m_renderPassesInDrawOrder.isEmpty()) |
| 48 oldRootDamage = m_renderPassesInDrawOrder.last()->damageRect(); |
| 49 |
| 50 clearRenderPasses(); |
| 51 |
| 52 for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) { |
| 53 m_renderPassesIndexById.set(renderPassesInDrawOrder[i]->id(), i); |
| 54 m_renderPassesInDrawOrder.append(renderPassesInDrawOrder.take(i)); |
| 55 } |
| 56 renderPassesInDrawOrder.clear(); |
| 57 |
| 58 if (!m_renderPassesInDrawOrder.isEmpty()) { |
| 59 FloatRect newRootDamage = m_renderPassesInDrawOrder.last()->damageRect()
; |
| 60 m_renderPassesInDrawOrder.last()->setDamageRect(unionRect(oldRootDamage,
newRootDamage)); |
| 61 } |
| 62 } |
| 63 |
| 64 void CCDelegatedRendererLayerImpl::clearRenderPasses() |
| 65 { |
| 66 // FIXME: Release the resources back to the nested compositor. |
| 67 m_renderPassesIndexById.clear(); |
| 68 m_renderPassesInDrawOrder.clear(); |
| 69 } |
| 70 |
| 71 void CCDelegatedRendererLayerImpl::didLoseContext() |
| 72 { |
| 73 clearRenderPasses(); |
| 74 } |
| 75 |
| 76 static inline int indexToId(int index) { return index + 1; } |
| 77 static inline int idToIndex(int id) { return id - 1; } |
| 78 |
| 79 CCRenderPass::Id CCDelegatedRendererLayerImpl::firstContributingRenderPassId() c
onst |
| 80 { |
| 81 return CCRenderPass::Id(id(), indexToId(0)); |
| 82 } |
| 83 |
| 84 CCRenderPass::Id CCDelegatedRendererLayerImpl::nextContributingRenderPassId(CCRe
nderPass::Id previous) const |
| 85 { |
| 86 return CCRenderPass::Id(previous.layerId, previous.index + 1); |
| 87 } |
| 88 |
| 89 CCRenderPass::Id CCDelegatedRendererLayerImpl::convertDelegatedRenderPassId(CCRe
nderPass::Id delegatedRenderPassId) const |
| 90 { |
| 91 unsigned delegatedRenderPassIndex = m_renderPassesIndexById.get(delegatedRen
derPassId); |
| 92 return CCRenderPass::Id(id(), indexToId(delegatedRenderPassIndex)); |
| 93 } |
| 94 |
| 95 void CCDelegatedRendererLayerImpl::appendContributingRenderPasses(CCRenderPassSi
nk& renderPassSink) |
| 96 { |
| 97 ASSERT(hasContributingDelegatedRenderPasses()); |
| 98 |
| 99 for (size_t i = 0; i < m_renderPassesInDrawOrder.size() - 1; ++i) { |
| 100 CCRenderPass::Id outputRenderPassId = convertDelegatedRenderPassId(m_ren
derPassesInDrawOrder[i]->id()); |
| 101 |
| 102 // Don't clash with the RenderPass we generate if we own a RenderSurface
. |
| 103 ASSERT(outputRenderPassId.index > 0); |
| 104 |
| 105 renderPassSink.appendRenderPass(m_renderPassesInDrawOrder[i]->copy(outpu
tRenderPassId)); |
| 106 } |
| 107 } |
| 108 |
| 109 void CCDelegatedRendererLayerImpl::appendQuads(CCQuadSink& quadSink, CCAppendQua
dsData& appendQuadsData) |
| 110 { |
| 111 if (m_renderPassesInDrawOrder.isEmpty()) |
| 112 return; |
| 113 |
| 114 CCRenderPass::Id targetRenderPassId = appendQuadsData.renderPassId; |
| 115 |
| 116 // If the index of the renderPassId is 0, then it is a renderPass generated
for a layer |
| 117 // in this compositor, not the delegated renderer. Then we want to merge our
root renderPass with |
| 118 // the target renderPass. Otherwise, it is some renderPass which we added fr
om the delegated |
| 119 // renderer. |
| 120 bool shouldMergeRootRenderPassWithTarget = !targetRenderPassId.index; |
| 121 if (shouldMergeRootRenderPassWithTarget) { |
| 122 // Verify that the renderPass we are appending to is created our renderT
arget. |
| 123 ASSERT(targetRenderPassId.layerId == renderTarget()->id()); |
| 124 |
| 125 CCRenderPass* rootDelegatedRenderPass = m_renderPassesInDrawOrder.last()
; |
| 126 appendRenderPassQuads(quadSink, appendQuadsData, rootDelegatedRenderPass
); |
| 127 } else { |
| 128 // Verify that the renderPass we are appending to was created by us. |
| 129 ASSERT(targetRenderPassId.layerId == id()); |
| 130 |
| 131 int renderPassIndex = idToIndex(targetRenderPassId.index); |
| 132 CCRenderPass* delegatedRenderPass = m_renderPassesInDrawOrder[renderPass
Index]; |
| 133 appendRenderPassQuads(quadSink, appendQuadsData, delegatedRenderPass); |
| 134 } |
| 135 } |
| 136 |
| 137 void CCDelegatedRendererLayerImpl::appendRenderPassQuads(CCQuadSink& quadSink, C
CAppendQuadsData& appendQuadsData, CCRenderPass* delegatedRenderPass) const |
| 138 { |
| 139 const CCSharedQuadState* currentSharedQuadState = 0; |
| 140 CCSharedQuadState* copiedSharedQuadState = 0; |
| 141 for (size_t i = 0; i < delegatedRenderPass->quadList().size(); ++i) { |
| 142 CCDrawQuad* quad = delegatedRenderPass->quadList()[i]; |
| 143 |
| 144 if (quad->sharedQuadState() != currentSharedQuadState) { |
| 145 currentSharedQuadState = quad->sharedQuadState(); |
| 146 copiedSharedQuadState = quadSink.useSharedQuadState(currentSharedQua
dState->copy()); |
| 147 } |
| 148 ASSERT(copiedSharedQuadState); |
| 149 |
| 150 bool targetIsFromDelegatedRendererLayer = appendQuadsData.renderPassId.l
ayerId == id(); |
| 151 if (!targetIsFromDelegatedRendererLayer) { |
| 152 // Should be the root render pass. |
| 153 ASSERT(delegatedRenderPass == m_renderPassesInDrawOrder.last()); |
| 154 // This layer must be drawing to a renderTarget other than itself. |
| 155 ASSERT(renderTarget() != this); |
| 156 |
| 157 copiedSharedQuadState->quadTransform = copiedSharedQuadState->quadTr
ansform * drawTransform(); |
| 158 copiedSharedQuadState->opacity *= drawOpacity(); |
| 159 } |
| 160 |
| 161 OwnPtr<CCDrawQuad> copyQuad; |
| 162 if (quad->material() != CCDrawQuad::RenderPass) |
| 163 copyQuad = quad->copy(copiedSharedQuadState); |
| 164 else { |
| 165 CCRenderPass::Id contributingDelegatedRenderPassId = CCRenderPassDra
wQuad::materialCast(quad)->renderPassId(); |
| 166 CCRenderPass::Id contributingRenderPassId = convertDelegatedRenderPa
ssId(contributingDelegatedRenderPassId); |
| 167 ASSERT(contributingRenderPassId != appendQuadsData.renderPassId); |
| 168 |
| 169 copyQuad = CCRenderPassDrawQuad::materialCast(quad)->copy(copiedShar
edQuadState, contributingRenderPassId); |
| 170 } |
| 171 ASSERT(copyQuad); |
| 172 |
| 173 quadSink.append(copyQuad.release(), appendQuadsData); |
| 174 } |
| 175 } |
| 176 |
| 177 } |
OLD | NEW |