Mailbox support for texture layers.
[chromium-blink-merge.git] / cc / delegated_renderer_layer_impl.cc
bloba8c930f318b6f56d2c82c4e9a3c50ffe3bdd75c0
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"
13 namespace cc {
15 DelegatedRendererLayerImpl::DelegatedRendererLayerImpl(LayerTreeImpl* treeImpl, int id)
16 : LayerImpl(treeImpl, id)
20 DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl()
22 clearRenderPasses();
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;
44 clearRenderPasses();
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()
65 clearRenderPasses();
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())
106 return;
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
113 // renderer.
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);
121 } else {
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);
158 else {
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";
176 } // namespace cc