diff options
author | sky <sky@chromium.org> | 2014-11-20 20:37:50 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-21 04:39:01 +0000 |
commit | 891df4b54f7a7b2dfb5d2a26b8614aecee875608 (patch) | |
tree | 0527091ab472cf62d768f143b0523f4ae8969f46 /cc/surfaces | |
parent | 4866abd7d1c6bfeb520ccd74ffb730ed45dd3cf3 (diff) | |
download | chromium_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.cc | 25 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator.h | 2 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator_test_helpers.cc | 4 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator_test_helpers.h | 5 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator_unittest.cc | 106 |
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; |