summaryrefslogtreecommitdiffstats
path: root/cc/surfaces
diff options
context:
space:
mode:
authorsky <sky@chromium.org>2014-11-20 20:37:50 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-21 04:39:01 +0000
commit891df4b54f7a7b2dfb5d2a26b8614aecee875608 (patch)
tree0527091ab472cf62d768f143b0523f4ae8969f46 /cc/surfaces
parent4866abd7d1c6bfeb520ccd74ffb730ed45dd3cf3 (diff)
downloadchromium_src-891df4b54f7a7b2dfb5d2a26b8614aecee875608.zip
chromium_src-891df4b54f7a7b2dfb5d2a26b8614aecee875608.tar.gz
chromium_src-891df4b54f7a7b2dfb5d2a26b8614aecee875608.tar.bz2
Makes SurfaceAggregator properly pass through opacity
BUG=434110 TEST=SurfaceAggregatorValidSurfaceTest.OpacityCopied R=jamesr@chromium.org Review URL: https://codereview.chromium.org/734813002 Cr-Commit-Position: refs/heads/master@{#305164}
Diffstat (limited to 'cc/surfaces')
-rw-r--r--cc/surfaces/surface_aggregator.cc25
-rw-r--r--cc/surfaces/surface_aggregator.h2
-rw-r--r--cc/surfaces/surface_aggregator_test_helpers.cc4
-rw-r--r--cc/surfaces/surface_aggregator_test_helpers.h5
-rw-r--r--cc/surfaces/surface_aggregator_unittest.cc106
5 files changed, 113 insertions, 29 deletions
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
index 588d624..f5689c5b 100644
--- a/cc/surfaces/surface_aggregator.cc
+++ b/cc/surfaces/surface_aggregator.cc
@@ -163,6 +163,7 @@ gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface,
}
void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
+ float opacity,
RenderPass* dest_pass) {
SurfaceId surface_id = surface_quad->surface_id;
// If this surface's id is already in our referenced set then it creates
@@ -227,11 +228,8 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
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);
+ CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
+ gfx::Transform(), 1.f, copy_pass.get(), surface_id);
dest_pass_list_->push_back(copy_pass.Pass());
}
@@ -242,17 +240,16 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
const QuadList& quads = last_pass.quad_list;
// TODO(jamesr): Make sure clipping is enforced.
- CopyQuadsToPass(quads,
- last_pass.shared_quad_state_list,
+ CopyQuadsToPass(quads, last_pass.shared_quad_state_list,
surface_quad->quadTransform(),
- dest_pass,
- surface_id);
+ surface_quad->opacity() * opacity, dest_pass, surface_id);
} else {
RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
SharedQuadState* shared_quad_state =
dest_pass->CreateAndAppendSharedQuadState();
shared_quad_state->CopyFrom(surface_quad->shared_quad_state);
+ shared_quad_state->opacity *= opacity;
RenderPassDrawQuad* quad =
dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
quad->SetNew(shared_quad_state,
@@ -300,6 +297,7 @@ void SurfaceAggregator::CopyQuadsToPass(
const QuadList& source_quad_list,
const SharedQuadStateList& source_shared_quad_state_list,
const gfx::Transform& content_to_target_transform,
+ float opacity,
RenderPass* dest_pass,
SurfaceId surface_id) {
const SharedQuadState* last_copied_source_shared_quad_state = NULL;
@@ -315,11 +313,12 @@ void SurfaceAggregator::CopyQuadsToPass(
if (quad->material == DrawQuad::SURFACE_CONTENT) {
const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
- HandleSurfaceQuad(surface_quad, dest_pass);
+ HandleSurfaceQuad(surface_quad, opacity, dest_pass);
} else {
if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
CopySharedQuadState(
quad->shared_quad_state, content_to_target_transform, dest_pass);
+ dest_pass->shared_quad_state_list.back()->opacity *= opacity;
last_copied_source_shared_quad_state = quad->shared_quad_state;
}
if (quad->material == DrawQuad::RENDER_PASS) {
@@ -371,10 +370,8 @@ void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data,
source.transform_to_root_target,
source.has_transparent_background);
- CopyQuadsToPass(source.quad_list,
- source.shared_quad_state_list,
- gfx::Transform(),
- copy_pass.get(),
+ CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
+ gfx::Transform(), 1.f, copy_pass.get(),
surface->surface_id());
dest_pass_list_->push_back(copy_pass.Pass());
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
index aeeb590..6965041 100644
--- a/cc/surfaces/surface_aggregator.h
+++ b/cc/surfaces/surface_aggregator.h
@@ -41,6 +41,7 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
SurfaceId surface_id);
void HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
+ float opacity,
RenderPass* dest_pass);
void CopySharedQuadState(const SharedQuadState* source_sqs,
const gfx::Transform& content_to_target_transform,
@@ -48,6 +49,7 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
void CopyQuadsToPass(const QuadList& source_quad_list,
const SharedQuadStateList& source_shared_quad_state_list,
const gfx::Transform& content_to_target_transform,
+ float opacity,
RenderPass* dest_pass,
SurfaceId surface_id);
void CopyPasses(const DelegatedFrameData* frame_data, Surface* surface);
diff --git a/cc/surfaces/surface_aggregator_test_helpers.cc b/cc/surfaces/surface_aggregator_test_helpers.cc
index 6b527c0..b21b37e 100644
--- a/cc/surfaces/surface_aggregator_test_helpers.cc
+++ b/cc/surfaces/surface_aggregator_test_helpers.cc
@@ -24,13 +24,13 @@ namespace test {
void AddTestSurfaceQuad(TestRenderPass* pass,
const gfx::Size& surface_size,
+ float opacity,
SurfaceId surface_id) {
gfx::Transform content_to_target_transform;
gfx::Size content_bounds = surface_size;
gfx::Rect visible_content_rect = gfx::Rect(surface_size);
gfx::Rect clip_rect = gfx::Rect(surface_size);
bool is_clipped = false;
- float opacity = 1.0;
SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
@@ -82,7 +82,7 @@ void AddQuadInPass(TestRenderPass* pass, Quad desc) {
AddQuad(pass, gfx::Rect(0, 0, 5, 5), desc.color);
break;
case DrawQuad::SURFACE_CONTENT:
- AddTestSurfaceQuad(pass, gfx::Size(5, 5), desc.surface_id);
+ AddTestSurfaceQuad(pass, gfx::Size(5, 5), desc.opacity, desc.surface_id);
break;
case DrawQuad::RENDER_PASS:
AddTestRenderPassQuad(pass, desc.render_pass_id);
diff --git a/cc/surfaces/surface_aggregator_test_helpers.h b/cc/surfaces/surface_aggregator_test_helpers.h
index 6f3a342..05c8344 100644
--- a/cc/surfaces/surface_aggregator_test_helpers.h
+++ b/cc/surfaces/surface_aggregator_test_helpers.h
@@ -30,9 +30,10 @@ struct Quad {
return quad;
}
- static Quad SurfaceQuad(SurfaceId surface_id) {
+ static Quad SurfaceQuad(SurfaceId surface_id, float opacity) {
Quad quad;
quad.material = DrawQuad::SURFACE_CONTENT;
+ quad.opacity = opacity;
quad.surface_id = surface_id;
return quad;
}
@@ -47,6 +48,7 @@ struct Quad {
DrawQuad::Material material;
// Set when material==DrawQuad::SURFACE_CONTENT.
SurfaceId surface_id;
+ float opacity;
// Set when material==DrawQuad::SOLID_COLOR.
SkColor color;
// Set when material==DrawQuad::RENDER_PASS.
@@ -55,6 +57,7 @@ struct Quad {
private:
Quad()
: material(DrawQuad::INVALID),
+ opacity(1.f),
color(SK_ColorWHITE),
render_pass_id(-1, -1) {}
};
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
index 5213327..2e47708 100644
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -155,6 +155,88 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
}
+TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
+ SurfaceId embedded_surface_id = allocator_.GenerateId();
+ factory_.Create(embedded_surface_id, SurfaceSize());
+
+ test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
+ test::Pass embedded_passes[] = {
+ test::Pass(embedded_quads, arraysize(embedded_quads))};
+
+ SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
+
+ test::Quad quads[] = {test::Quad::SurfaceQuad(embedded_surface_id, .5f)};
+ test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
+
+ SubmitFrame(passes, arraysize(passes), root_surface_id_);
+
+ scoped_ptr<CompositorFrame> aggregated_frame =
+ aggregator_.Aggregate(root_surface_id_);
+
+ ASSERT_TRUE(aggregated_frame);
+ ASSERT_TRUE(aggregated_frame->delegated_frame_data);
+
+ DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
+
+ RenderPassList& render_pass_list(frame_data->render_pass_list);
+ ASSERT_EQ(1u, render_pass_list.size());
+ SharedQuadStateList& shared_quad_state_list(
+ render_pass_list[0]->shared_quad_state_list);
+ ASSERT_EQ(1u, shared_quad_state_list.size());
+ EXPECT_EQ(.5f, shared_quad_state_list.ElementAt(0)->opacity);
+
+ factory_.Destroy(embedded_surface_id);
+}
+
+TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCombinedWithNesting) {
+ SurfaceId surface_id1 = allocator_.GenerateId();
+ factory_.Create(surface_id1, SurfaceSize());
+ SurfaceId surface_id2 = allocator_.GenerateId();
+ factory_.Create(surface_id2, SurfaceSize());
+
+ // |surface_id1| is color quad.
+ {
+ test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
+ test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
+ SubmitFrame(passes, arraysize(passes), surface_id1);
+ }
+
+ // |surface_id2| has a color quad and a surface quad using |surface_id1| at .5
+ // opacity.
+ {
+ test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE),
+ test::Quad::SurfaceQuad(surface_id1, .5f)};
+ test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
+ SubmitFrame(passes, arraysize(passes), surface_id2);
+ }
+
+ // Another frame with a surface referencing |surface_id2| @ .6 opacity.
+ {
+ test::Quad quads[] = {test::Quad::SurfaceQuad(surface_id2, .6f)};
+ test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
+ SubmitFrame(passes, arraysize(passes), root_surface_id_);
+ }
+
+ scoped_ptr<CompositorFrame> aggregated_frame =
+ aggregator_.Aggregate(root_surface_id_);
+
+ ASSERT_TRUE(aggregated_frame);
+ ASSERT_TRUE(aggregated_frame->delegated_frame_data);
+
+ DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
+
+ RenderPassList& render_pass_list(frame_data->render_pass_list);
+ ASSERT_EQ(1u, render_pass_list.size());
+ SharedQuadStateList& shared_quad_state_list(
+ render_pass_list[0]->shared_quad_state_list);
+ ASSERT_EQ(2u, shared_quad_state_list.size());
+ EXPECT_EQ(.6f, shared_quad_state_list.ElementAt(0)->opacity);
+ EXPECT_EQ(.3f, shared_quad_state_list.ElementAt(1)->opacity);
+
+ factory_.Destroy(surface_id1);
+ factory_.Destroy(surface_id2);
+}
+
TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
test::Quad quads[][2] = {{test::Quad::SolidColorQuad(SK_ColorWHITE),
test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
@@ -185,7 +267,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
- test::Quad::SurfaceQuad(embedded_surface_id),
+ test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
test::Quad::SolidColorQuad(SK_ColorBLACK)};
test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
@@ -218,7 +300,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
factory_.RequestCopyOfSurface(embedded_surface_id, copy_request.Pass());
test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
- test::Quad::SurfaceQuad(embedded_surface_id),
+ test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
test::Quad::SolidColorQuad(SK_ColorBLACK)};
test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
@@ -277,7 +359,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) {
CopyOutputRequest* copy_request2_ptr = copy_request2.get();
test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
- test::Quad::SurfaceQuad(embedded_surface_id),
+ test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
test::Quad::SolidColorQuad(SK_ColorBLACK)};
test::Quad root_quads2[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
test::Pass root_passes[] = {
@@ -368,7 +450,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
test::Quad root_quads[][2] = {
{test::Quad::SolidColorQuad(5), test::Quad::SolidColorQuad(6)},
- {test::Quad::SurfaceQuad(embedded_surface_id),
+ {test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
test::Quad::RenderPassQuad(pass_ids[0])},
{test::Quad::SolidColorQuad(7), test::Quad::RenderPassQuad(pass_ids[1])}};
test::Pass root_passes[] = {
@@ -489,7 +571,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
// be dropped.
TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
- test::Quad::SurfaceQuad(InvalidSurfaceId()),
+ test::Quad::SurfaceQuad(InvalidSurfaceId(), 1.f),
test::Quad::SolidColorQuad(SK_ColorBLUE)};
test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
@@ -510,7 +592,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
SurfaceId surface_with_no_frame_id = allocator_.GenerateId();
factory_.Create(surface_with_no_frame_id, gfx::Size(5, 5));
test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
- test::Quad::SurfaceQuad(surface_with_no_frame_id),
+ test::Quad::SurfaceQuad(surface_with_no_frame_id, 1.f),
test::Quad::SolidColorQuad(SK_ColorBLUE)};
test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
@@ -529,7 +611,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
// Tests a surface quad referencing itself, generating a trivial cycle.
// The quad creating the cycle should be dropped from the final frame.
TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
- test::Quad quads[] = {test::Quad::SurfaceQuad(root_surface_id_),
+ test::Quad quads[] = {test::Quad::SurfaceQuad(root_surface_id_, 1.f),
test::Quad::SolidColorQuad(SK_ColorYELLOW)};
test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
@@ -549,7 +631,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
factory_.Create(child_surface_id, SurfaceSize());
test::Quad parent_quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE),
- test::Quad::SurfaceQuad(child_surface_id),
+ test::Quad::SurfaceQuad(child_surface_id, 1.f),
test::Quad::SolidColorQuad(SK_ColorCYAN)};
test::Pass parent_passes[] = {
test::Pass(parent_quads, arraysize(parent_quads))};
@@ -557,7 +639,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
SubmitFrame(parent_passes, arraysize(parent_passes), root_surface_id_);
test::Quad child_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
- test::Quad::SurfaceQuad(root_surface_id_),
+ test::Quad::SurfaceQuad(root_surface_id_, 1.f),
test::Quad::SolidColorQuad(SK_ColorMAGENTA)};
test::Pass child_passes[] = {test::Pass(child_quads, arraysize(child_quads))};
@@ -599,7 +681,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
// Pass IDs from the parent surface may collide with ones from the child.
RenderPassId parent_pass_id[] = {RenderPassId(2, 1), RenderPassId(1, 2)};
test::Quad parent_quad[][1] = {
- {test::Quad::SurfaceQuad(child_surface_id)},
+ {test::Quad::SurfaceQuad(child_surface_id, 1.f)},
{test::Quad::RenderPassQuad(parent_pass_id[0])}};
test::Pass parent_passes[] = {
test::Pass(parent_quad[0], arraysize(parent_quad[0]), parent_pass_id[0]),
@@ -858,7 +940,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
test::Quad root_quads[] = {test::Quad::SolidColorQuad(1),
- test::Quad::SurfaceQuad(child_surface_id)};
+ test::Quad::SurfaceQuad(child_surface_id, 1.f)};
test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
RenderPassList root_pass_list;
@@ -981,7 +1063,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure());
- test::Quad root_quads[] = {test::Quad::SurfaceQuad(child_surface_id)};
+ test::Quad root_quads[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)};
test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
RenderPassList root_pass_list;