diff options
Diffstat (limited to 'cc/surfaces/surface_aggregator.cc')
-rw-r--r-- | cc/surfaces/surface_aggregator.cc | 85 |
1 files changed, 57 insertions, 28 deletions
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc index a85a2bc..5b108bb 100644 --- a/cc/surfaces/surface_aggregator.cc +++ b/cc/surfaces/surface_aggregator.cc @@ -99,8 +99,17 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, source.transform_to_root_target, source.has_transparent_background); + // Contributing passes aggregated in to the pass list need to take the + // transform of the surface quad into account to update their transform to + // the root surface. + // TODO(jamesr): Make sure this is sufficient for surfaces nested several + // levels deep and add tests. + copy_pass->transform_to_root_target.ConcatTransform( + surface_quad->quadTransform()); + CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, + gfx::Transform(), copy_pass.get(), surface_id); @@ -111,55 +120,72 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, const RenderPass& last_pass = *referenced_data->render_pass_list.back(); const QuadList& quads = last_pass.quad_list; - for (size_t j = 0; j < last_pass.shared_quad_state_list.size(); ++j) { - dest_pass->shared_quad_state_list.push_back( - last_pass.shared_quad_state_list[j]->Copy()); - } - // TODO(jamesr): Map transform correctly for quads in the referenced - // surface into this pass's space. // TODO(jamesr): Make sure clipping is enforced. - CopyQuadsToPass( - quads, last_pass.shared_quad_state_list, dest_pass, surface_id); + CopyQuadsToPass(quads, + last_pass.shared_quad_state_list, + surface_quad->quadTransform(), + dest_pass, + surface_id); referenced_surfaces_.erase(it); } +void SurfaceAggregator::CopySharedQuadState( + const SharedQuadState& source_sqs, + const gfx::Transform& content_to_target_transform, + SharedQuadStateList* dest_sqs_list) { + scoped_ptr<SharedQuadState> copy_shared_quad_state = source_sqs.Copy(); + // content_to_target_transform contains any transformation that may exist + // between the context that these quads are being copied from (i.e. the + // surface's draw transform when aggregated from within a surface) to the + // target space of the pass. This will be identity except when copying the + // root draw pass from a surface into a pass when the surface draw quad's + // transform is not identity. + copy_shared_quad_state->content_to_target_transform.ConcatTransform( + content_to_target_transform); + dest_sqs_list->push_back(copy_shared_quad_state.Pass()); +} + void SurfaceAggregator::CopyQuadsToPass( const QuadList& source_quad_list, const SharedQuadStateList& source_shared_quad_state_list, + const gfx::Transform& content_to_target_transform, RenderPass* dest_pass, int surface_id) { - for (size_t j = 0; j < source_shared_quad_state_list.size(); ++j) { - dest_pass->shared_quad_state_list.push_back( - source_shared_quad_state_list[j]->Copy()); - } + const SharedQuadState* last_copied_source_shared_quad_state = NULL; for (size_t i = 0, sqs_i = 0; i < source_quad_list.size(); ++i) { DrawQuad* quad = source_quad_list[i]; - while (quad->shared_quad_state != source_shared_quad_state_list[sqs_i]) { ++sqs_i; DCHECK_LT(sqs_i, source_shared_quad_state_list.size()); - DCHECK_LT(sqs_i, dest_pass->shared_quad_state_list.size()); } DCHECK_EQ(quad->shared_quad_state, source_shared_quad_state_list[sqs_i]); if (quad->material == DrawQuad::SURFACE_CONTENT) { const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad); HandleSurfaceQuad(surface_quad, dest_pass); - } else if (quad->material == DrawQuad::RENDER_PASS) { - const RenderPassDrawQuad* pass_quad = - RenderPassDrawQuad::MaterialCast(quad); - RenderPass::Id original_pass_id = pass_quad->render_pass_id; - RenderPass::Id remapped_pass_id = - RemapPassId(original_pass_id, surface_id); - - dest_pass->quad_list.push_back( - pass_quad->Copy(dest_pass->shared_quad_state_list[sqs_i], - remapped_pass_id).PassAs<DrawQuad>()); } else { - dest_pass->quad_list.push_back( - quad->Copy(dest_pass->shared_quad_state_list[sqs_i])); + if (quad->shared_quad_state != last_copied_source_shared_quad_state) { + CopySharedQuadState(*quad->shared_quad_state, + content_to_target_transform, + &dest_pass->shared_quad_state_list); + last_copied_source_shared_quad_state = quad->shared_quad_state; + } + if (quad->material == DrawQuad::RENDER_PASS) { + const RenderPassDrawQuad* pass_quad = + RenderPassDrawQuad::MaterialCast(quad); + RenderPass::Id original_pass_id = pass_quad->render_pass_id; + RenderPass::Id remapped_pass_id = + RemapPassId(original_pass_id, surface_id); + + dest_pass->quad_list.push_back( + pass_quad->Copy(dest_pass->shared_quad_state_list.back(), + remapped_pass_id).PassAs<DrawQuad>()); + } else { + dest_pass->quad_list.push_back( + quad->Copy(dest_pass->shared_quad_state_list.back())); + } } } } @@ -181,6 +207,7 @@ void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, + gfx::Transform(), copy_pass.get(), surface_id); @@ -204,12 +231,14 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(int surface_id) { const RenderPassList& source_pass_list = root_surface_frame->delegated_frame_data->render_pass_list; - referenced_surfaces_.insert(surface_id); + std::set<int>::iterator it = referenced_surfaces_.insert(surface_id).first; dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; CopyPasses(source_pass_list, surface_id); - referenced_surfaces_.clear(); + referenced_surfaces_.erase(it); + DCHECK(referenced_surfaces_.empty()); + dest_pass_list_ = NULL; // TODO(jamesr): Aggregate all resource references into the returned frame's |