OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/surfaces/surface_aggregator.h" | 5 #include "cc/surfaces/surface_aggregator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/containers/hash_tables.h" | 8 #include "base/containers/hash_tables.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 return; | 163 return; |
164 } | 164 } |
165 contained_surfaces_[surface_id] = surface->frame_index(); | 165 contained_surfaces_[surface_id] = surface->frame_index(); |
166 const CompositorFrame* frame = surface->GetEligibleFrame(); | 166 const CompositorFrame* frame = surface->GetEligibleFrame(); |
167 if (!frame) | 167 if (!frame) |
168 return; | 168 return; |
169 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); | 169 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
170 if (!frame_data) | 170 if (!frame_data) |
171 return; | 171 return; |
172 | 172 |
| 173 ScopedPtrVector<ScopedPtrVector<CopyOutputRequest>> copy_requests; |
| 174 surface->TakeCopyOutputRequests(©_requests); |
| 175 |
173 RenderPassList render_pass_list; | 176 RenderPassList render_pass_list; |
174 bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list); | 177 bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list); |
175 if (invalid_frame) | 178 if (invalid_frame) { |
| 179 for (auto* request_list : copy_requests) { |
| 180 for (auto* request : *request_list) |
| 181 request->SendEmptyResult(); |
| 182 } |
176 return; | 183 return; |
| 184 } |
177 | 185 |
178 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 186 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
179 | 187 |
180 ScopedPtrVector<CopyOutputRequest> copy_requests; | 188 bool merge_pass = copy_requests.back()->empty(); |
181 surface->TakeCopyOutputRequests(©_requests); | |
182 | |
183 bool merge_pass = copy_requests.empty(); | |
184 | 189 |
185 const RenderPassList& referenced_passes = render_pass_list; | 190 const RenderPassList& referenced_passes = render_pass_list; |
186 size_t passes_to_copy = | 191 size_t passes_to_copy = |
187 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); | 192 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); |
188 for (size_t j = 0; j < passes_to_copy; ++j) { | 193 for (size_t j = 0; j < passes_to_copy; ++j) { |
189 const RenderPass& source = *referenced_passes[j]; | 194 const RenderPass& source = *referenced_passes[j]; |
190 | 195 |
191 scoped_ptr<RenderPass> copy_pass(RenderPass::Create()); | 196 scoped_ptr<RenderPass> copy_pass(RenderPass::Create()); |
192 | 197 |
193 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); | 198 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); |
194 | 199 |
195 copy_pass->SetAll(remapped_pass_id, | 200 copy_pass->SetAll(remapped_pass_id, |
196 source.output_rect, | 201 source.output_rect, |
197 source.damage_rect, | 202 source.damage_rect, |
198 source.transform_to_root_target, | 203 source.transform_to_root_target, |
199 source.has_transparent_background); | 204 source.has_transparent_background); |
200 | 205 |
| 206 copy_pass->copy_requests.swap(*copy_requests[j]); |
| 207 |
201 // Contributing passes aggregated in to the pass list need to take the | 208 // Contributing passes aggregated in to the pass list need to take the |
202 // transform of the surface quad into account to update their transform to | 209 // transform of the surface quad into account to update their transform to |
203 // the root surface. | 210 // the root surface. |
204 // TODO(jamesr): Make sure this is sufficient for surfaces nested several | 211 // TODO(jamesr): Make sure this is sufficient for surfaces nested several |
205 // levels deep and add tests. | 212 // levels deep and add tests. |
206 copy_pass->transform_to_root_target.ConcatTransform( | 213 copy_pass->transform_to_root_target.ConcatTransform( |
207 surface_quad->quadTransform()); | 214 surface_quad->quadTransform()); |
208 | 215 |
209 CopyQuadsToPass(source.quad_list, | 216 CopyQuadsToPass(source.quad_list, |
210 source.shared_quad_state_list, | 217 source.shared_quad_state_list, |
(...skipping 11 matching lines...) Expand all Loading... |
222 | 229 |
223 // TODO(jamesr): Make sure clipping is enforced. | 230 // TODO(jamesr): Make sure clipping is enforced. |
224 CopyQuadsToPass(quads, | 231 CopyQuadsToPass(quads, |
225 last_pass.shared_quad_state_list, | 232 last_pass.shared_quad_state_list, |
226 surface_quad->quadTransform(), | 233 surface_quad->quadTransform(), |
227 dest_pass, | 234 dest_pass, |
228 surface_id); | 235 surface_id); |
229 } else { | 236 } else { |
230 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); | 237 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); |
231 | 238 |
232 dest_pass_list_->back()->copy_requests.swap(copy_requests); | |
233 | |
234 SharedQuadState* shared_quad_state = | 239 SharedQuadState* shared_quad_state = |
235 dest_pass->CreateAndAppendSharedQuadState(); | 240 dest_pass->CreateAndAppendSharedQuadState(); |
236 shared_quad_state->CopyFrom(surface_quad->shared_quad_state); | 241 shared_quad_state->CopyFrom(surface_quad->shared_quad_state); |
237 RenderPassDrawQuad* quad = | 242 RenderPassDrawQuad* quad = |
238 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 243 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
239 quad->SetNew(shared_quad_state, | 244 quad->SetNew(shared_quad_state, |
240 surface_quad->rect, | 245 surface_quad->rect, |
241 surface_quad->visible_rect, | 246 surface_quad->visible_rect, |
242 remapped_pass_id, | 247 remapped_pass_id, |
243 0, | 248 0, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 dest_pass->shared_quad_state_list.back(), | 321 dest_pass->shared_quad_state_list.back(), |
317 remapped_pass_id); | 322 remapped_pass_id); |
318 } else { | 323 } else { |
319 dest_pass->CopyFromAndAppendDrawQuad( | 324 dest_pass->CopyFromAndAppendDrawQuad( |
320 quad, dest_pass->shared_quad_state_list.back()); | 325 quad, dest_pass->shared_quad_state_list.back()); |
321 } | 326 } |
322 } | 327 } |
323 } | 328 } |
324 } | 329 } |
325 | 330 |
326 void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, | 331 void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, |
327 const Surface* surface) { | 332 Surface* surface) { |
| 333 RenderPassList source_pass_list; |
| 334 |
| 335 // The root surface is allowed to have copy output requests, so grab them |
| 336 // off its render passes. |
| 337 ScopedPtrVector<ScopedPtrVector<CopyOutputRequest>> output_requests; |
| 338 surface->TakeCopyOutputRequests(&output_requests); |
| 339 |
| 340 bool invalid_frame = TakeResources(surface, frame_data, &source_pass_list); |
| 341 DCHECK(!invalid_frame); |
| 342 |
328 for (size_t i = 0; i < source_pass_list.size(); ++i) { | 343 for (size_t i = 0; i < source_pass_list.size(); ++i) { |
329 const RenderPass& source = *source_pass_list[i]; | 344 const RenderPass& source = *source_pass_list[i]; |
330 | 345 |
331 scoped_ptr<RenderPass> copy_pass(RenderPass::Create()); | 346 scoped_ptr<RenderPass> copy_pass(RenderPass::Create()); |
332 | 347 |
| 348 copy_pass->copy_requests.swap(*output_requests[i]); |
| 349 |
333 RenderPassId remapped_pass_id = | 350 RenderPassId remapped_pass_id = |
334 RemapPassId(source.id, surface->surface_id()); | 351 RemapPassId(source.id, surface->surface_id()); |
335 | 352 |
336 copy_pass->SetAll(remapped_pass_id, | 353 copy_pass->SetAll(remapped_pass_id, |
337 source.output_rect, | 354 source.output_rect, |
338 DamageRectForSurface(surface, source), | 355 DamageRectForSurface(surface, source), |
339 source.transform_to_root_target, | 356 source.transform_to_root_target, |
340 source.has_transparent_background); | 357 source.has_transparent_background); |
341 | 358 |
342 CopyQuadsToPass(source.quad_list, | 359 CopyQuadsToPass(source.quad_list, |
(...skipping 13 matching lines...) Expand all Loading... |
356 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); | 373 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); |
357 if (!root_surface_frame) | 374 if (!root_surface_frame) |
358 return nullptr; | 375 return nullptr; |
359 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 376 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
360 | 377 |
361 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | 378 scoped_ptr<CompositorFrame> frame(new CompositorFrame); |
362 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); | 379 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); |
363 | 380 |
364 DCHECK(root_surface_frame->delegated_frame_data); | 381 DCHECK(root_surface_frame->delegated_frame_data); |
365 | 382 |
366 RenderPassList source_pass_list; | |
367 | |
368 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 383 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
369 | 384 |
370 dest_resource_list_ = &frame->delegated_frame_data->resource_list; | 385 dest_resource_list_ = &frame->delegated_frame_data->resource_list; |
371 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; | 386 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
372 | 387 |
373 bool invalid_frame = | 388 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
374 TakeResources(surface, | |
375 root_surface_frame->delegated_frame_data.get(), | |
376 &source_pass_list); | |
377 DCHECK(!invalid_frame); | |
378 | |
379 CopyPasses(source_pass_list, surface); | |
380 | 389 |
381 referenced_surfaces_.erase(it); | 390 referenced_surfaces_.erase(it); |
382 DCHECK(referenced_surfaces_.empty()); | 391 DCHECK(referenced_surfaces_.empty()); |
383 | 392 |
384 dest_pass_list_ = NULL; | 393 dest_pass_list_ = NULL; |
385 contained_surfaces_.swap(previous_contained_surfaces_); | 394 contained_surfaces_.swap(previous_contained_surfaces_); |
386 contained_surfaces_.clear(); | 395 contained_surfaces_.clear(); |
387 | 396 |
388 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); | 397 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); |
389 it != previous_contained_surfaces_.end(); | 398 it != previous_contained_surfaces_.end(); |
390 ++it) { | 399 ++it) { |
391 Surface* surface = manager_->GetSurfaceForId(it->first); | 400 Surface* surface = manager_->GetSurfaceForId(it->first); |
392 if (surface) | 401 if (surface) |
393 surface->TakeLatencyInfo(&frame->metadata.latency_info); | 402 surface->TakeLatencyInfo(&frame->metadata.latency_info); |
394 } | 403 } |
395 | 404 |
396 // TODO(jamesr): Aggregate all resource references into the returned frame's | 405 // TODO(jamesr): Aggregate all resource references into the returned frame's |
397 // resource list. | 406 // resource list. |
398 | 407 |
399 return frame.Pass(); | 408 return frame.Pass(); |
400 } | 409 } |
401 | 410 |
402 } // namespace cc | 411 } // namespace cc |
OLD | NEW |