Chromium Code Reviews| 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 |