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