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.
5 #include "cc/delegated_renderer_layer_impl.h"
7 #include "cc/append_quads_data.h"
8 #include "cc/math_util.h"
9 #include "cc/quad_sink.h"
10 #include "cc/render_pass_draw_quad.h"
11 #include "cc/render_pass_sink.h"
15 DelegatedRendererLayerImpl::DelegatedRendererLayerImpl(LayerTreeImpl
* treeImpl
, int id
)
16 : LayerImpl(treeImpl
, id
)
20 DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl()
25 bool DelegatedRendererLayerImpl::hasDelegatedContent() const
27 return !m_renderPassesInDrawOrder
.isEmpty();
30 bool DelegatedRendererLayerImpl::hasContributingDelegatedRenderPasses() const
32 // The root RenderPass for the layer is merged with its target
33 // RenderPass in each frame. So we only have extra RenderPasses
34 // to merge when we have a non-root RenderPass present.
35 return m_renderPassesInDrawOrder
.size() > 1;
38 void DelegatedRendererLayerImpl::setRenderPasses(ScopedPtrVector
<RenderPass
>& renderPassesInDrawOrder
)
40 gfx::RectF oldRootDamage
;
41 if (!m_renderPassesInDrawOrder
.isEmpty())
42 oldRootDamage
= m_renderPassesInDrawOrder
.last()->damage_rect
;
46 for (size_t i
= 0; i
< renderPassesInDrawOrder
.size(); ++i
) {
47 m_renderPassesIndexById
.insert(std::pair
<RenderPass::Id
, int>(renderPassesInDrawOrder
[i
]->id
, i
));
48 m_renderPassesInDrawOrder
.append(renderPassesInDrawOrder
.take(i
));
50 renderPassesInDrawOrder
.clear();
52 if (!m_renderPassesInDrawOrder
.isEmpty())
53 m_renderPassesInDrawOrder
.last()->damage_rect
.Union(oldRootDamage
);
56 void DelegatedRendererLayerImpl::clearRenderPasses()
58 // FIXME: Release the resources back to the nested compositor.
59 m_renderPassesIndexById
.clear();
60 m_renderPassesInDrawOrder
.clear();
63 void DelegatedRendererLayerImpl::didLoseOutputSurface()
68 static inline int indexToId(int index
) { return index
+ 1; }
69 static inline int idToIndex(int id
) { return id
- 1; }
71 RenderPass::Id
DelegatedRendererLayerImpl::firstContributingRenderPassId() const
73 return RenderPass::Id(id(), indexToId(0));
76 RenderPass::Id
DelegatedRendererLayerImpl::nextContributingRenderPassId(RenderPass::Id previous
) const
78 return RenderPass::Id(previous
.layer_id
, previous
.index
+ 1);
81 RenderPass::Id
DelegatedRendererLayerImpl::convertDelegatedRenderPassId(RenderPass::Id delegatedRenderPassId
) const
83 base::hash_map
<RenderPass::Id
, int>::const_iterator it
= m_renderPassesIndexById
.find(delegatedRenderPassId
);
84 DCHECK(it
!= m_renderPassesIndexById
.end());
85 unsigned delegatedRenderPassIndex
= it
->second
;
86 return RenderPass::Id(id(), indexToId(delegatedRenderPassIndex
));
89 void DelegatedRendererLayerImpl::appendContributingRenderPasses(RenderPassSink
& renderPassSink
)
91 DCHECK(hasContributingDelegatedRenderPasses());
93 for (size_t i
= 0; i
< m_renderPassesInDrawOrder
.size() - 1; ++i
) {
94 RenderPass::Id outputRenderPassId
= convertDelegatedRenderPassId(m_renderPassesInDrawOrder
[i
]->id
);
96 // Don't clash with the RenderPass we generate if we own a RenderSurfaceImpl.
97 DCHECK(outputRenderPassId
.index
> 0);
99 renderPassSink
.appendRenderPass(m_renderPassesInDrawOrder
[i
]->Copy(outputRenderPassId
));
103 void DelegatedRendererLayerImpl::appendQuads(QuadSink
& quadSink
, AppendQuadsData
& appendQuadsData
)
105 if (m_renderPassesInDrawOrder
.isEmpty())
108 RenderPass::Id targetRenderPassId
= appendQuadsData
.renderPassId
;
110 // If the index of the renderPassId is 0, then it is a renderPass generated for a layer
111 // in this compositor, not the delegated renderer. Then we want to merge our root renderPass with
112 // the target renderPass. Otherwise, it is some renderPass which we added from the delegated
114 bool shouldMergeRootRenderPassWithTarget
= !targetRenderPassId
.index
;
115 if (shouldMergeRootRenderPassWithTarget
) {
116 // Verify that the renderPass we are appending to is created our renderTarget.
117 DCHECK(targetRenderPassId
.layer_id
== renderTarget()->id());
119 const RenderPass
* rootDelegatedRenderPass
= m_renderPassesInDrawOrder
.last();
120 appendRenderPassQuads(quadSink
, appendQuadsData
, rootDelegatedRenderPass
);
122 // Verify that the renderPass we are appending to was created by us.
123 DCHECK(targetRenderPassId
.layer_id
== id());
125 int renderPassIndex
= idToIndex(targetRenderPassId
.index
);
126 const RenderPass
* delegatedRenderPass
= m_renderPassesInDrawOrder
[renderPassIndex
];
127 appendRenderPassQuads(quadSink
, appendQuadsData
, delegatedRenderPass
);
131 void DelegatedRendererLayerImpl::appendRenderPassQuads(QuadSink
& quadSink
, AppendQuadsData
& appendQuadsData
, const RenderPass
* delegatedRenderPass
) const
133 const SharedQuadState
* currentSharedQuadState
= 0;
134 SharedQuadState
* copiedSharedQuadState
= 0;
135 for (size_t i
= 0; i
< delegatedRenderPass
->quad_list
.size(); ++i
) {
136 const DrawQuad
* quad
= delegatedRenderPass
->quad_list
[i
];
138 if (quad
->shared_quad_state
!= currentSharedQuadState
) {
139 currentSharedQuadState
= quad
->shared_quad_state
;
140 copiedSharedQuadState
= quadSink
.useSharedQuadState(currentSharedQuadState
->Copy());
141 bool targetIsFromDelegatedRendererLayer
= appendQuadsData
.renderPassId
.layer_id
== id();
142 if (!targetIsFromDelegatedRendererLayer
) {
143 // Should be the root render pass.
144 DCHECK(delegatedRenderPass
== m_renderPassesInDrawOrder
.last());
145 // This layer must be drawing to a renderTarget other than itself.
146 DCHECK(renderTarget() != this);
148 copiedSharedQuadState
->content_to_target_transform
= copiedSharedQuadState
->content_to_target_transform
* drawTransform();
149 copiedSharedQuadState
->clipped_rect_in_target
= MathUtil::mapClippedRect(drawTransform(), copiedSharedQuadState
->clipped_rect_in_target
);
150 copiedSharedQuadState
->opacity
*= drawOpacity();
153 DCHECK(copiedSharedQuadState
);
155 scoped_ptr
<DrawQuad
> copyQuad
;
156 if (quad
->material
!= DrawQuad::RENDER_PASS
)
157 copyQuad
= quad
->Copy(copiedSharedQuadState
);
159 RenderPass::Id contributingDelegatedRenderPassId
= RenderPassDrawQuad::MaterialCast(quad
)->render_pass_id
;
160 RenderPass::Id contributingRenderPassId
= convertDelegatedRenderPassId(contributingDelegatedRenderPassId
);
161 DCHECK(contributingRenderPassId
!= appendQuadsData
.renderPassId
);
163 copyQuad
= RenderPassDrawQuad::MaterialCast(quad
)->Copy(copiedSharedQuadState
, contributingRenderPassId
).PassAs
<DrawQuad
>();
165 DCHECK(copyQuad
.get());
167 quadSink
.append(copyQuad
.Pass(), appendQuadsData
);
171 const char* DelegatedRendererLayerImpl::layerTypeAsString() const
173 return "DelegatedRendererLayer";