diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-11 20:09:03 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-11 20:09:03 +0000 |
commit | 6fae8a38608b2c3045ab9d177de1a61f3aa73917 (patch) | |
tree | b43bb918797048d8f4028015d966eb5c799932a4 /cc/surfaces/surface_aggregator.cc | |
parent | edef1c25eb44529879f759b46719bfed1fdfe4ff (diff) | |
download | chromium_src-6fae8a38608b2c3045ab9d177de1a61f3aa73917.zip chromium_src-6fae8a38608b2c3045ab9d177de1a61f3aa73917.tar.gz chromium_src-6fae8a38608b2c3045ab9d177de1a61f3aa73917.tar.bz2 |
Pixel tests and some shared quad state fixups
This adds some pixel tests for the output of SurfaceAggregator and fixes several
issues related to shared quad state management. This also concatenates the
transform for the surface draw quad with the quads aggregated into the root draw
pass of the referenced surface.
Shared quad state mapping is a little bit nontrivial when doing aggregation
since we copy the shared quad state entries from the aggregated frame's root
pass into the shared quad state list of the pass containing the surface quad.
When doing multiple levels of aggregation the relationship between the shared
quad list offset from the aggregated pass to the destination pass gets tricky.
Here's how this patch handles things:
Root surface root pass:
shared_quad_state_list: [A], [B]
quad_list: [Quad using (A)], [Quad using (A)], [Surface 1], [Quad using (B)]
Surface 1 root pass:
shared_quad_state_list: [C], [D]
quad_list: [Quad using (C)], [Surface 2], [Surface 3], [Quad using (D)]
Surface 2 root pass:
shared_quad_state_list: [E]
quad_list: [Quad using (E)]
Surface 3 root pass:
shared_quad_state_list: [F]
quad_list: [Quad using (F)]
We append the shared quad stats to the aggregated pass' list as we encounter
the quads that reference them, so the final aggregated frame looks like this:
Aggregated frame root pass:
shared_quad_state_list: [A], [C], [E], [F], [D], [B]
quad_list: [Quad using (A)], [Quad using (A)], [Quad using (C)],
[Quad using (E)], [Quad using (F)], [Quad using (D)],
[Quad using (B)]
Note that there's no shared quad state for the surface quads in the final shared
quad state list. We use the transform and other properties from the surface quad's
shared quad state when aggregating, but don't need them beyond aggregation.
BUG=334876
Review URL: https://codereview.chromium.org/142863015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250484 0039d316-1c4b-4281-b951-d872f2087c98
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 |