summaryrefslogtreecommitdiffstats
path: root/cc/surfaces/surface_aggregator.cc
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-11 20:09:03 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-11 20:09:03 +0000
commit6fae8a38608b2c3045ab9d177de1a61f3aa73917 (patch)
treeb43bb918797048d8f4028015d966eb5c799932a4 /cc/surfaces/surface_aggregator.cc
parentedef1c25eb44529879f759b46719bfed1fdfe4ff (diff)
downloadchromium_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.cc85
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