Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(781)

Side by Side Diff: cc/delegated_renderer_layer_impl.cc

Issue 12603013: Part 10 of cc/ directory shuffles: layers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/delegated_renderer_layer_impl.h ('k') | cc/delegated_renderer_layer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "cc/delegated_renderer_layer_impl.h"
6
7 #include "base/bind.h"
8 #include "cc/append_quads_data.h"
9 #include "cc/base/math_util.h"
10 #include "cc/output/delegated_frame_data.h"
11 #include "cc/quad_sink.h"
12 #include "cc/quads/render_pass_draw_quad.h"
13 #include "cc/render_pass_sink.h"
14 #include "cc/trees/layer_tree_impl.h"
15
16 namespace cc {
17
18 DelegatedRendererLayerImpl::DelegatedRendererLayerImpl(
19 LayerTreeImpl* tree_impl, int id)
20 : LayerImpl(tree_impl, id),
21 child_id_(0) {
22 }
23
24 DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl() {
25 ClearRenderPasses();
26 ClearChildId();
27 }
28
29 bool DelegatedRendererLayerImpl::HasDelegatedContent() const {
30 return !render_passes_in_draw_order_.empty();
31 }
32
33 bool DelegatedRendererLayerImpl::HasContributingDelegatedRenderPasses() const {
34 // The root RenderPass for the layer is merged with its target
35 // RenderPass in each frame. So we only have extra RenderPasses
36 // to merge when we have a non-root RenderPass present.
37 return render_passes_in_draw_order_.size() > 1;
38 }
39
40 static ResourceProvider::ResourceId ResourceRemapHelper(
41 bool* invalid_frame,
42 const ResourceProvider::ResourceIdMap& child_to_parent_map,
43 ResourceProvider::ResourceIdSet *remapped_resources,
44 ResourceProvider::ResourceId id) {
45
46 ResourceProvider::ResourceIdMap::const_iterator it =
47 child_to_parent_map.find(id);
48 if (it == child_to_parent_map.end()) {
49 *invalid_frame = true;
50 return 0;
51 }
52
53 DCHECK(it->first == id);
54 ResourceProvider::ResourceId remapped_id = it->second;
55 remapped_resources->insert(remapped_id);
56 return remapped_id;
57 }
58
59 void DelegatedRendererLayerImpl::SetFrameData(
60 scoped_ptr<DelegatedFrameData> frame_data,
61 gfx::RectF damage_in_frame,
62 TransferableResourceArray* resources_for_ack) {
63 CreateChildIdIfNeeded();
64 DCHECK(child_id_);
65
66 ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
67 const ResourceProvider::ResourceIdMap& resource_map =
68 resource_provider->GetChildToParentMap(child_id_);
69
70 if (frame_data) {
71 // A frame with an empty root render pass is invalid.
72 DCHECK(frame_data->render_pass_list.empty() ||
73 !frame_data->render_pass_list.back()->output_rect.IsEmpty());
74
75 // Display size is already set so we can compute what the damage rect
76 // will be in layer space.
77 if (!frame_data->render_pass_list.empty()) {
78 RenderPass* new_root_pass = frame_data->render_pass_list.back();
79 gfx::RectF damage_in_layer = MathUtil::MapClippedRect(
80 DelegatedFrameToLayerSpaceTransform(
81 new_root_pass->output_rect.size()),
82 damage_in_frame);
83 set_update_rect(gfx::UnionRects(update_rect(), damage_in_layer));
84 }
85
86 resource_provider->ReceiveFromChild(child_id_, frame_data->resource_list);
87
88 bool invalid_frame = false;
89 ResourceProvider::ResourceIdSet used_resources;
90 DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback =
91 base::Bind(&ResourceRemapHelper,
92 &invalid_frame,
93 resource_map,
94 &used_resources);
95 for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) {
96 RenderPass* pass = frame_data->render_pass_list[i];
97 for (size_t j = 0; j < pass->quad_list.size(); ++j) {
98 DrawQuad* quad = pass->quad_list[j];
99 quad->IterateResources(remap_resources_to_parent_callback);
100 }
101 }
102
103 if (!invalid_frame) {
104 // Save the remapped quads on the layer. This steals the quads and render
105 // passes from the frame_data.
106 SetRenderPasses(&frame_data->render_pass_list);
107 resources_.swap(used_resources);
108 }
109 }
110
111 ResourceProvider::ResourceIdArray unused_resources;
112 for (ResourceProvider::ResourceIdMap::const_iterator it =
113 resource_map.begin();
114 it != resource_map.end();
115 ++it) {
116 bool resource_is_in_current_frame = resources_.count(it->second);
117 bool resource_is_in_use = resource_provider->InUseByConsumer(it->second);
118 if (!resource_is_in_current_frame && !resource_is_in_use)
119 unused_resources.push_back(it->second);
120 }
121 resource_provider->PrepareSendToChild(
122 child_id_, unused_resources, resources_for_ack);
123 }
124
125 void DelegatedRendererLayerImpl::SetDisplaySize(gfx::Size size) {
126 if (display_size_ == size)
127 return;
128 display_size_ = size;
129 NoteLayerPropertyChanged();
130 }
131
132 void DelegatedRendererLayerImpl::SetRenderPasses(
133 ScopedPtrVector<RenderPass>* render_passes_in_draw_order) {
134 gfx::RectF old_root_damage;
135 if (!render_passes_in_draw_order_.empty())
136 old_root_damage = render_passes_in_draw_order_.back()->damage_rect;
137
138 ClearRenderPasses();
139
140 for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) {
141 ScopedPtrVector<RenderPass>::iterator to_take =
142 render_passes_in_draw_order->begin() + i;
143 render_passes_index_by_id_.insert(
144 std::pair<RenderPass::Id, int>((*to_take)->id, i));
145 scoped_ptr<RenderPass> taken_render_pass =
146 render_passes_in_draw_order->take(to_take);
147 render_passes_in_draw_order_.push_back(taken_render_pass.Pass());
148 }
149
150 if (!render_passes_in_draw_order_.empty())
151 render_passes_in_draw_order_.back()->damage_rect.Union(old_root_damage);
152 }
153
154 void DelegatedRendererLayerImpl::ClearRenderPasses() {
155 // FIXME: Release the resources back to the nested compositor.
156 render_passes_index_by_id_.clear();
157 render_passes_in_draw_order_.clear();
158 }
159
160 scoped_ptr<LayerImpl> DelegatedRendererLayerImpl::CreateLayerImpl(
161 LayerTreeImpl* treeImpl) {
162 return DelegatedRendererLayerImpl::Create(treeImpl, id()).PassAs<LayerImpl>();
163 }
164
165 void DelegatedRendererLayerImpl::DidLoseOutputSurface() {
166 ClearRenderPasses();
167 ClearChildId();
168 }
169
170 gfx::Transform DelegatedRendererLayerImpl::DelegatedFrameToLayerSpaceTransform(
171 gfx::Size frame_size) const {
172 gfx::Size display_size = display_size_.IsEmpty() ? bounds() : display_size_;
173
174 gfx::Transform delegated_frame_to_layer_space_transform;
175 delegated_frame_to_layer_space_transform.Scale(
176 static_cast<double>(display_size.width()) / frame_size.width(),
177 static_cast<double>(display_size.height()) / frame_size.height());
178 return delegated_frame_to_layer_space_transform;
179 }
180
181 static inline int IndexToId(int index) { return index + 1; }
182 static inline int IdToIndex(int id) { return id - 1; }
183
184 RenderPass::Id DelegatedRendererLayerImpl::FirstContributingRenderPassId()
185 const {
186 return RenderPass::Id(id(), IndexToId(0));
187 }
188
189 RenderPass::Id DelegatedRendererLayerImpl::NextContributingRenderPassId(
190 RenderPass::Id previous) const {
191 return RenderPass::Id(previous.layer_id, previous.index + 1);
192 }
193
194 RenderPass::Id DelegatedRendererLayerImpl::ConvertDelegatedRenderPassId(
195 RenderPass::Id delegated_render_pass_id) const {
196 base::hash_map<RenderPass::Id, int>::const_iterator found =
197 render_passes_index_by_id_.find(delegated_render_pass_id);
198 DCHECK(found != render_passes_index_by_id_.end());
199 unsigned delegatedRenderPassIndex = found->second;
200 return RenderPass::Id(id(), IndexToId(delegatedRenderPassIndex));
201 }
202
203 void DelegatedRendererLayerImpl::AppendContributingRenderPasses(
204 RenderPassSink* render_pass_sink) {
205 DCHECK(HasContributingDelegatedRenderPasses());
206
207 for (size_t i = 0; i < render_passes_in_draw_order_.size() - 1; ++i) {
208 RenderPass::Id output_render_pass_id =
209 ConvertDelegatedRenderPassId(render_passes_in_draw_order_[i]->id);
210
211 // Don't clash with the RenderPass we generate if we own a RenderSurface.
212 DCHECK(output_render_pass_id.index > 0);
213
214 render_pass_sink->AppendRenderPass(
215 render_passes_in_draw_order_[i]->Copy(output_render_pass_id));
216 }
217 }
218
219 void DelegatedRendererLayerImpl::AppendQuads(
220 QuadSink* quad_sink,
221 AppendQuadsData* append_quads_data) {
222 if (render_passes_in_draw_order_.empty())
223 return;
224
225 RenderPass::Id target_render_pass_id = append_quads_data->renderPassId;
226
227 const RenderPass* root_delegated_render_pass =
228 render_passes_in_draw_order_.back();
229
230 DCHECK(root_delegated_render_pass->output_rect.origin().IsOrigin());
231 gfx::Size frame_size = root_delegated_render_pass->output_rect.size();
232
233 // If the index of the renderPassId is 0, then it is a renderPass generated
234 // for a layer in this compositor, not the delegated renderer. Then we want to
235 // merge our root renderPass with the target renderPass. Otherwise, it is some
236 // renderPass which we added from the delegated renderer.
237 bool should_merge_root_render_pass_with_target = !target_render_pass_id.index;
238 if (should_merge_root_render_pass_with_target) {
239 // Verify that the renderPass we are appending to is created our
240 // renderTarget.
241 DCHECK(target_render_pass_id.layer_id == render_target()->id());
242
243 AppendRenderPassQuads(
244 quad_sink, append_quads_data, root_delegated_render_pass, frame_size);
245 } else {
246 // Verify that the renderPass we are appending to was created by us.
247 DCHECK(target_render_pass_id.layer_id == id());
248
249 int render_pass_index = IdToIndex(target_render_pass_id.index);
250 const RenderPass* delegated_render_pass =
251 render_passes_in_draw_order_[render_pass_index];
252 AppendRenderPassQuads(
253 quad_sink, append_quads_data, delegated_render_pass, frame_size);
254 }
255 }
256
257 void DelegatedRendererLayerImpl::AppendRenderPassQuads(
258 QuadSink* quad_sink,
259 AppendQuadsData* append_quads_data,
260 const RenderPass* delegated_render_pass,
261 gfx::Size frame_size) const {
262
263 const SharedQuadState* delegated_shared_quad_state = NULL;
264 SharedQuadState* output_shared_quad_state = NULL;
265
266 for (size_t i = 0; i < delegated_render_pass->quad_list.size(); ++i) {
267 const DrawQuad* delegated_quad = delegated_render_pass->quad_list[i];
268
269 if (delegated_quad->shared_quad_state != delegated_shared_quad_state) {
270 delegated_shared_quad_state = delegated_quad->shared_quad_state;
271 output_shared_quad_state = quad_sink->UseSharedQuadState(
272 delegated_shared_quad_state->Copy());
273
274 bool is_root_delegated_render_pass =
275 delegated_render_pass == render_passes_in_draw_order_.back();
276 if (is_root_delegated_render_pass) {
277 // Don't allow areas inside the bounds that are empty.
278 DCHECK(display_size_.IsEmpty() ||
279 gfx::Rect(display_size_).Contains(gfx::Rect(bounds())));
280 gfx::Transform delegated_frame_to_target_transform =
281 draw_transform() * DelegatedFrameToLayerSpaceTransform(frame_size);
282
283 output_shared_quad_state->content_to_target_transform.ConcatTransform(
284 delegated_frame_to_target_transform);
285
286 if (render_target() == this) {
287 DCHECK(!is_clipped());
288 DCHECK(render_surface());
289 output_shared_quad_state->clip_rect = MathUtil::MapClippedRect(
290 delegated_frame_to_target_transform,
291 output_shared_quad_state->clip_rect);
292 } else {
293 gfx::Rect clip_rect = drawable_content_rect();
294 if (output_shared_quad_state->is_clipped) {
295 clip_rect.Intersect(MathUtil::MapClippedRect(
296 delegated_frame_to_target_transform,
297 output_shared_quad_state->clip_rect));
298 }
299 output_shared_quad_state->clip_rect = clip_rect;
300 output_shared_quad_state->is_clipped = true;
301 }
302
303 output_shared_quad_state->opacity *= draw_opacity();
304 }
305 }
306 DCHECK(output_shared_quad_state);
307
308 scoped_ptr<DrawQuad> output_quad;
309 if (delegated_quad->material != DrawQuad::RENDER_PASS) {
310 output_quad = delegated_quad->Copy(output_shared_quad_state);
311 } else {
312 RenderPass::Id delegated_contributing_render_pass_id =
313 RenderPassDrawQuad::MaterialCast(delegated_quad)->render_pass_id;
314 RenderPass::Id output_contributing_render_pass_id =
315 ConvertDelegatedRenderPassId(delegated_contributing_render_pass_id);
316 DCHECK(output_contributing_render_pass_id !=
317 append_quads_data->renderPassId);
318
319 output_quad = RenderPassDrawQuad::MaterialCast(delegated_quad)->Copy(
320 output_shared_quad_state,
321 output_contributing_render_pass_id).PassAs<DrawQuad>();
322 }
323 DCHECK(output_quad.get());
324
325 quad_sink->Append(output_quad.Pass(), append_quads_data);
326 }
327 }
328
329 const char* DelegatedRendererLayerImpl::LayerTypeAsString() const {
330 return "DelegatedRendererLayer";
331 }
332
333 void DelegatedRendererLayerImpl::CreateChildIdIfNeeded() {
334 if (child_id_)
335 return;
336
337 ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
338 child_id_ = resource_provider->CreateChild();
339 }
340
341 void DelegatedRendererLayerImpl::ClearChildId() {
342 if (!child_id_)
343 return;
344
345 ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
346 resource_provider->DestroyChild(child_id_);
347 child_id_ = 0;
348 }
349
350 } // namespace cc
OLDNEW
« no previous file with comments | « cc/delegated_renderer_layer_impl.h ('k') | cc/delegated_renderer_layer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698