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" |
11 #include "cc/base/math_util.h" | 11 #include "cc/base/math_util.h" |
12 #include "cc/output/compositor_frame.h" | 12 #include "cc/output/compositor_frame.h" |
13 #include "cc/output/delegated_frame_data.h" | 13 #include "cc/output/delegated_frame_data.h" |
14 #include "cc/quads/draw_quad.h" | 14 #include "cc/quads/draw_quad.h" |
15 #include "cc/quads/render_pass_draw_quad.h" | 15 #include "cc/quads/render_pass_draw_quad.h" |
16 #include "cc/quads/shared_quad_state.h" | 16 #include "cc/quads/shared_quad_state.h" |
17 #include "cc/quads/surface_draw_quad.h" | 17 #include "cc/quads/surface_draw_quad.h" |
18 #include "cc/surfaces/surface.h" | 18 #include "cc/surfaces/surface.h" |
19 #include "cc/surfaces/surface_factory.h" | 19 #include "cc/surfaces/surface_factory.h" |
20 #include "cc/surfaces/surface_manager.h" | 20 #include "cc/surfaces/surface_manager.h" |
21 #include "cc/trees/blocking_task_runner.h" | 21 #include "cc/trees/blocking_task_runner.h" |
22 | 22 |
23 namespace cc { | 23 namespace cc { |
24 namespace { | |
25 | |
26 void MoveMatchingRequests( | |
27 RenderPassId id, | |
28 std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests, | |
29 ScopedPtrVector<CopyOutputRequest>* output_requests) { | |
30 auto request_range = copy_requests->equal_range(id); | |
31 for (auto it = request_range.first; it != request_range.second; ++it) { | |
32 DCHECK(it->second); | |
33 output_requests->push_back(scoped_ptr<CopyOutputRequest>(it->second)); | |
34 it->second = nullptr; | |
35 } | |
36 copy_requests->erase(request_range.first, request_range.second); | |
37 } | |
38 | |
39 } // namespace | |
24 | 40 |
25 SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager, | 41 SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager, |
26 ResourceProvider* provider) | 42 ResourceProvider* provider) |
27 : manager_(manager), provider_(provider) { | 43 : manager_(manager), provider_(provider) { |
28 DCHECK(manager_); | 44 DCHECK(manager_); |
29 } | 45 } |
30 | 46 |
31 SurfaceAggregator::~SurfaceAggregator() {} | 47 SurfaceAggregator::~SurfaceAggregator() {} |
32 | 48 |
33 class SurfaceAggregator::RenderPassIdAllocator { | 49 class SurfaceAggregator::RenderPassIdAllocator { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 return; | 174 return; |
159 } | 175 } |
160 contained_surfaces_[surface_id] = surface->frame_index(); | 176 contained_surfaces_[surface_id] = surface->frame_index(); |
161 const CompositorFrame* frame = surface->GetEligibleFrame(); | 177 const CompositorFrame* frame = surface->GetEligibleFrame(); |
162 if (!frame) | 178 if (!frame) |
163 return; | 179 return; |
164 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); | 180 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
165 if (!frame_data) | 181 if (!frame_data) |
166 return; | 182 return; |
167 | 183 |
184 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; | |
185 surface->TakeCopyOutputRequests(©_requests); | |
186 | |
168 RenderPassList render_pass_list; | 187 RenderPassList render_pass_list; |
169 bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list); | 188 bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list); |
170 if (invalid_frame) | 189 if (invalid_frame) { |
190 for (auto& request : copy_requests) { | |
191 request.second->SendEmptyResult(); | |
192 delete request.second; | |
193 } | |
171 return; | 194 return; |
195 } | |
172 | 196 |
173 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 197 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
174 | 198 |
175 ScopedPtrVector<CopyOutputRequest> copy_requests; | |
176 surface->TakeCopyOutputRequests(©_requests); | |
177 | |
178 bool merge_pass = copy_requests.empty(); | 199 bool merge_pass = copy_requests.empty(); |
179 | 200 |
180 const RenderPassList& referenced_passes = render_pass_list; | 201 const RenderPassList& referenced_passes = render_pass_list; |
181 size_t passes_to_copy = | 202 size_t passes_to_copy = |
182 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); | 203 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); |
183 for (size_t j = 0; j < passes_to_copy; ++j) { | 204 for (size_t j = 0; j < passes_to_copy; ++j) { |
184 const RenderPass& source = *referenced_passes[j]; | 205 const RenderPass& source = *referenced_passes[j]; |
185 | 206 |
186 size_t sqs_size = source.shared_quad_state_list.size(); | 207 size_t sqs_size = source.shared_quad_state_list.size(); |
187 size_t dq_size = source.quad_list.size(); | 208 size_t dq_size = source.quad_list.size(); |
188 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); | 209 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); |
189 | 210 |
190 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); | 211 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); |
191 | 212 |
192 copy_pass->SetAll(remapped_pass_id, | 213 copy_pass->SetAll(remapped_pass_id, |
193 source.output_rect, | 214 source.output_rect, |
194 source.damage_rect, | 215 source.damage_rect, |
195 source.transform_to_root_target, | 216 source.transform_to_root_target, |
196 source.has_transparent_background); | 217 source.has_transparent_background); |
197 | 218 |
219 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | |
jamesr
2014/10/15 23:51:24
the RenderPassIds in copy_requests will be in the
| |
220 | |
198 // Contributing passes aggregated in to the pass list need to take the | 221 // Contributing passes aggregated in to the pass list need to take the |
199 // transform of the surface quad into account to update their transform to | 222 // transform of the surface quad into account to update their transform to |
200 // the root surface. | 223 // the root surface. |
201 // TODO(jamesr): Make sure this is sufficient for surfaces nested several | 224 // TODO(jamesr): Make sure this is sufficient for surfaces nested several |
202 // levels deep and add tests. | 225 // levels deep and add tests. |
203 copy_pass->transform_to_root_target.ConcatTransform( | 226 copy_pass->transform_to_root_target.ConcatTransform( |
204 surface_quad->quadTransform()); | 227 surface_quad->quadTransform()); |
205 | 228 |
206 CopyQuadsToPass(source.quad_list, | 229 CopyQuadsToPass(source.quad_list, |
207 source.shared_quad_state_list, | 230 source.shared_quad_state_list, |
(...skipping 11 matching lines...) Expand all Loading... | |
219 | 242 |
220 // TODO(jamesr): Make sure clipping is enforced. | 243 // TODO(jamesr): Make sure clipping is enforced. |
221 CopyQuadsToPass(quads, | 244 CopyQuadsToPass(quads, |
222 last_pass.shared_quad_state_list, | 245 last_pass.shared_quad_state_list, |
223 surface_quad->quadTransform(), | 246 surface_quad->quadTransform(), |
224 dest_pass, | 247 dest_pass, |
225 surface_id); | 248 surface_id); |
226 } else { | 249 } else { |
227 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); | 250 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); |
228 | 251 |
229 dest_pass_list_->back()->copy_requests.swap(copy_requests); | |
230 | |
231 SharedQuadState* shared_quad_state = | 252 SharedQuadState* shared_quad_state = |
232 dest_pass->CreateAndAppendSharedQuadState(); | 253 dest_pass->CreateAndAppendSharedQuadState(); |
233 shared_quad_state->CopyFrom(surface_quad->shared_quad_state); | 254 shared_quad_state->CopyFrom(surface_quad->shared_quad_state); |
234 RenderPassDrawQuad* quad = | 255 RenderPassDrawQuad* quad = |
235 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 256 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
236 quad->SetNew(shared_quad_state, | 257 quad->SetNew(shared_quad_state, |
237 surface_quad->rect, | 258 surface_quad->rect, |
238 surface_quad->visible_rect, | 259 surface_quad->visible_rect, |
239 remapped_pass_id, | 260 remapped_pass_id, |
240 0, | 261 0, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 dest_pass->shared_quad_state_list.back(), | 333 dest_pass->shared_quad_state_list.back(), |
313 remapped_pass_id); | 334 remapped_pass_id); |
314 } else { | 335 } else { |
315 dest_pass->CopyFromAndAppendDrawQuad( | 336 dest_pass->CopyFromAndAppendDrawQuad( |
316 &quad, dest_pass->shared_quad_state_list.back()); | 337 &quad, dest_pass->shared_quad_state_list.back()); |
317 } | 338 } |
318 } | 339 } |
319 } | 340 } |
320 } | 341 } |
321 | 342 |
322 void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, | 343 void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, |
323 const Surface* surface) { | 344 Surface* surface) { |
345 RenderPassList source_pass_list; | |
346 | |
347 // The root surface is allowed to have copy output requests, so grab them | |
348 // off its render passes. | |
349 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; | |
350 surface->TakeCopyOutputRequests(©_requests); | |
351 | |
352 bool invalid_frame = TakeResources(surface, frame_data, &source_pass_list); | |
353 DCHECK(!invalid_frame); | |
354 | |
324 for (size_t i = 0; i < source_pass_list.size(); ++i) { | 355 for (size_t i = 0; i < source_pass_list.size(); ++i) { |
325 const RenderPass& source = *source_pass_list[i]; | 356 const RenderPass& source = *source_pass_list[i]; |
326 | 357 |
327 size_t sqs_size = source.shared_quad_state_list.size(); | 358 size_t sqs_size = source.shared_quad_state_list.size(); |
328 size_t dq_size = source.quad_list.size(); | 359 size_t dq_size = source.quad_list.size(); |
329 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); | 360 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); |
330 | 361 |
362 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | |
363 | |
331 RenderPassId remapped_pass_id = | 364 RenderPassId remapped_pass_id = |
332 RemapPassId(source.id, surface->surface_id()); | 365 RemapPassId(source.id, surface->surface_id()); |
333 | 366 |
334 copy_pass->SetAll(remapped_pass_id, | 367 copy_pass->SetAll(remapped_pass_id, |
335 source.output_rect, | 368 source.output_rect, |
336 DamageRectForSurface(surface, source), | 369 DamageRectForSurface(surface, source), |
337 source.transform_to_root_target, | 370 source.transform_to_root_target, |
338 source.has_transparent_background); | 371 source.has_transparent_background); |
339 | 372 |
340 CopyQuadsToPass(source.quad_list, | 373 CopyQuadsToPass(source.quad_list, |
(...skipping 13 matching lines...) Expand all Loading... | |
354 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); | 387 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); |
355 if (!root_surface_frame) | 388 if (!root_surface_frame) |
356 return nullptr; | 389 return nullptr; |
357 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 390 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
358 | 391 |
359 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | 392 scoped_ptr<CompositorFrame> frame(new CompositorFrame); |
360 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); | 393 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); |
361 | 394 |
362 DCHECK(root_surface_frame->delegated_frame_data); | 395 DCHECK(root_surface_frame->delegated_frame_data); |
363 | 396 |
364 RenderPassList source_pass_list; | |
365 | |
366 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 397 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
367 | 398 |
368 dest_resource_list_ = &frame->delegated_frame_data->resource_list; | 399 dest_resource_list_ = &frame->delegated_frame_data->resource_list; |
369 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; | 400 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
370 | 401 |
371 bool invalid_frame = | 402 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
372 TakeResources(surface, | |
373 root_surface_frame->delegated_frame_data.get(), | |
374 &source_pass_list); | |
375 DCHECK(!invalid_frame); | |
376 | |
377 CopyPasses(source_pass_list, surface); | |
378 | 403 |
379 referenced_surfaces_.erase(it); | 404 referenced_surfaces_.erase(it); |
380 DCHECK(referenced_surfaces_.empty()); | 405 DCHECK(referenced_surfaces_.empty()); |
381 | 406 |
382 dest_pass_list_ = NULL; | 407 dest_pass_list_ = NULL; |
383 contained_surfaces_.swap(previous_contained_surfaces_); | 408 contained_surfaces_.swap(previous_contained_surfaces_); |
384 contained_surfaces_.clear(); | 409 contained_surfaces_.clear(); |
385 | 410 |
386 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); | 411 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); |
387 it != previous_contained_surfaces_.end(); | 412 it != previous_contained_surfaces_.end(); |
388 ++it) { | 413 ++it) { |
389 Surface* surface = manager_->GetSurfaceForId(it->first); | 414 Surface* surface = manager_->GetSurfaceForId(it->first); |
390 if (surface) | 415 if (surface) |
391 surface->TakeLatencyInfo(&frame->metadata.latency_info); | 416 surface->TakeLatencyInfo(&frame->metadata.latency_info); |
392 } | 417 } |
393 | 418 |
394 // TODO(jamesr): Aggregate all resource references into the returned frame's | 419 // TODO(jamesr): Aggregate all resource references into the returned frame's |
395 // resource list. | 420 // resource list. |
396 | 421 |
397 return frame.Pass(); | 422 return frame.Pass(); |
398 } | 423 } |
399 | 424 |
400 } // namespace cc | 425 } // namespace cc |
OLD | NEW |