diff options
author | rosca <rosca@adobe.com> | 2014-11-09 02:25:13 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-09 10:25:38 +0000 |
commit | 948d29d0425d45276a41d5f994e443938e6a9256 (patch) | |
tree | 2160f8fd570275a84dd4a3999d29ba4d1306b24f | |
parent | 18550cbbb68bb9df91fe04a42bb019421c3fd077 (diff) | |
download | chromium_src-948d29d0425d45276a41d5f994e443938e6a9256.zip chromium_src-948d29d0425d45276a41d5f994e443938e6a9256.tar.gz chromium_src-948d29d0425d45276a41d5f994e443938e6a9256.tar.bz2 |
Render surface's owning layer should not generate quads with blend mode.
The root layer of a subtree that is render to a separate surface
doesn't need to use a blend mode for its draw quads.
GL renderer currently uses the blend mode only in DrawRPDQ, so it
shouldn't be affected by this change.
Software renderer uses blend mode for all kind of layers, but this patch
should not change the output pixels, since blending layers are always
promoted to render surfaces, and the first layer drawing to a clean
render surface will not be affected by the blend mode.
BUG=314865
Review URL: https://codereview.chromium.org/699893003
Cr-Commit-Position: refs/heads/master@{#303402}
-rw-r--r-- | cc/layers/draw_properties.h | 6 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 13 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 3 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 13 | ||||
-rw-r--r-- | cc/layers/render_surface_unittest.cc | 4 | ||||
-rw-r--r-- | cc/layers/solid_color_layer_impl_unittest.cc | 25 | ||||
-rw-r--r-- | cc/layers/video_layer_impl.cc | 11 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common.cc | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common_unittest.cc | 30 |
9 files changed, 83 insertions, 24 deletions
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h index 403393e..2e54083 100644 --- a/cc/layers/draw_properties.h +++ b/cc/layers/draw_properties.h @@ -6,6 +6,7 @@ #define CC_LAYERS_DRAW_PROPERTIES_H_ #include "base/memory/scoped_ptr.h" +#include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/transform.h" @@ -17,6 +18,7 @@ template <typename LayerType> struct CC_EXPORT DrawProperties { DrawProperties() : opacity(0.f), + blend_mode(SkXfermode::kSrcOver_Mode), opacity_is_animating(false), screen_space_opacity_is_animating(false), target_space_transform_is_animating(false), @@ -53,6 +55,10 @@ struct CC_EXPORT DrawProperties { // opacity, or when opacity is compounded by the hierarchy. float opacity; + // DrawProperties::blend_mode may be different than LayerType::blend_mode, + // when a RenderSurface re-parents the layer's blend_mode. + SkXfermode::Mode blend_mode; + // xxx_is_animating flags are used to indicate whether the DrawProperties // are actually meaningful on the main thread. When the properties are // animating, the main thread may not have the same values that are used diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index f09761b..a99ede8 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -255,14 +255,11 @@ void LayerImpl::ClearRenderSurfaceLayerList() { } void LayerImpl::PopulateSharedQuadState(SharedQuadState* state) const { - state->SetAll(draw_properties_.target_space_transform, - draw_properties_.content_bounds, - draw_properties_.visible_content_rect, - draw_properties_.clip_rect, - draw_properties_.is_clipped, - draw_properties_.opacity, - blend_mode_, - sorting_context_id_); + state->SetAll( + draw_properties_.target_space_transform, draw_properties_.content_bounds, + draw_properties_.visible_content_rect, draw_properties_.clip_rect, + draw_properties_.is_clipped, draw_properties_.opacity, + draw_properties_.blend_mode, sorting_context_id_); } bool LayerImpl::WillDraw(DrawMode draw_mode, diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 5fe679c..12f1dca 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -323,6 +323,9 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, return draw_properties_.screen_space_transform; } float draw_opacity() const { return draw_properties_.opacity; } + SkXfermode::Mode draw_blend_mode() const { + return draw_properties_.blend_mode; + } bool draw_opacity_is_animating() const { return draw_properties_.opacity_is_animating; } diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 822fcf3..e48f5f8 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -210,14 +210,11 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, occlusion_in_content_space.GetOcclusionWithGivenDrawTransform( scaled_draw_transform); - shared_quad_state->SetAll(scaled_draw_transform, - scaled_content_bounds, - scaled_visible_content_rect, - draw_properties().clip_rect, - draw_properties().is_clipped, - draw_properties().opacity, - blend_mode(), - sorting_context_id_); + shared_quad_state->SetAll( + scaled_draw_transform, scaled_content_bounds, scaled_visible_content_rect, + draw_properties().clip_rect, draw_properties().is_clipped, + draw_properties().opacity, draw_properties().blend_mode, + sorting_context_id_); if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) { AppendDebugBorderQuad( diff --git a/cc/layers/render_surface_unittest.cc b/cc/layers/render_surface_unittest.cc index 68398fe..8175efa 100644 --- a/cc/layers/render_surface_unittest.cc +++ b/cc/layers/render_surface_unittest.cc @@ -92,6 +92,9 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { owning_layer->CreateRenderSurface(); ASSERT_TRUE(owning_layer->render_surface()); owning_layer->draw_properties().render_target = owning_layer.get(); + + SkXfermode::Mode blend_mode = SkXfermode::kSoftLight_Mode; + owning_layer->SetBlendMode(blend_mode); RenderSurfaceImpl* render_surface = owning_layer->render_surface(); root_layer->AddChild(owning_layer.Pass()); @@ -131,6 +134,7 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { EXPECT_RECT_EQ(content_rect, gfx::Rect(shared_quad_state->visible_content_rect)); EXPECT_EQ(1.f, shared_quad_state->opacity); + EXPECT_EQ(blend_mode, shared_quad_state->blend_mode); } class TestRenderPassSink : public RenderPassSink { diff --git a/cc/layers/solid_color_layer_impl_unittest.cc b/cc/layers/solid_color_layer_impl_unittest.cc index 768fae4..320345f 100644 --- a/cc/layers/solid_color_layer_impl_unittest.cc +++ b/cc/layers/solid_color_layer_impl_unittest.cc @@ -102,6 +102,31 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { ->opacity()); } +TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) { + const SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode; + + scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + + gfx::Size layer_size = gfx::Size(100, 100); + gfx::Rect visible_content_rect = gfx::Rect(layer_size); + + FakeImplProxy proxy; + TestSharedBitmapManager shared_bitmap_manager; + FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager); + scoped_ptr<SolidColorLayerImpl> layer = + SolidColorLayerImpl::Create(host_impl.active_tree(), 1); + layer->SetBounds(layer_size); + layer->SetContentBounds(layer_size); + layer->draw_properties().blend_mode = blend_mode; + + AppendQuadsData data; + layer->AppendQuads(render_pass.get(), Occlusion(), &data); + + ASSERT_EQ(render_pass->quad_list.size(), 1U); + EXPECT_EQ(blend_mode, + render_pass->quad_list.front()->shared_quad_state->blend_mode); +} + TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { gfx::Size layer_size = gfx::Size(100, 100); gfx::Rect visible_content_rect = gfx::Rect(layer_size); diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index 8251a09..a7e1bde 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc @@ -159,14 +159,9 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass, SharedQuadState* shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); - shared_quad_state->SetAll(transform, - rotated_size, - visible_content_rect(), - clip_rect(), - is_clipped(), - draw_opacity(), - blend_mode(), - sorting_context_id()); + shared_quad_state->SetAll(transform, rotated_size, visible_content_rect(), + clip_rect(), is_clipped(), draw_opacity(), + draw_blend_mode(), sorting_context_id()); AppendDebugBorderQuad( render_pass, rotated_size, shared_quad_state, append_quads_data); diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index fd15b52..0ff6608 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc @@ -1883,6 +1883,7 @@ static void CalculateDrawPropertiesInternal( render_surface->SetDrawOpacityIsAnimating(animating_opacity_to_target); animating_opacity_to_target = false; layer_draw_properties.opacity = 1.f; + layer_draw_properties.blend_mode = SkXfermode::kSrcOver_Mode; layer_draw_properties.opacity_is_animating = animating_opacity_to_target; layer_draw_properties.screen_space_opacity_is_animating = animating_opacity_to_screen; @@ -2007,6 +2008,7 @@ static void CalculateDrawPropertiesInternal( layer_draw_properties.screen_space_transform_is_animating = animating_transform_to_screen; layer_draw_properties.opacity = accumulated_draw_opacity; + layer_draw_properties.blend_mode = layer->blend_mode(); layer_draw_properties.opacity_is_animating = animating_opacity_to_target; layer_draw_properties.screen_space_opacity_is_animating = animating_opacity_to_screen; diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index e0436ba..b40f66db 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -1392,6 +1392,36 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { EXPECT_EQ(gfx::Rect(), parent->drawable_content_rect()); } +TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { + scoped_refptr<Layer> parent = Layer::Create(); + scoped_refptr<LayerWithForcedDrawsContent> child = + make_scoped_refptr(new LayerWithForcedDrawsContent()); + + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); + host->SetRootLayer(parent); + + const gfx::Transform identity_matrix; + const SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode; + SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), + gfx::PointF(), gfx::Size(10, 10), true, false); + + parent->AddChild(child); + child->SetBlendMode(blend_mode); + + RenderSurfaceLayerList render_surface_layer_list; + LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( + parent.get(), parent->bounds(), &render_surface_layer_list); + LayerTreeHostCommon::CalculateDrawProperties(&inputs); + + // Since the child layer has a blend mode other than normal, it should get + // its own render surface. Also, layer's draw_properties should contain the + // default blend mode, since the render surface becomes responsible for + // applying the blend mode. + ASSERT_TRUE(child->render_surface()); + EXPECT_EQ(1U, child->render_surface()->layer_list().size()); + EXPECT_EQ(SkXfermode::kSrcOver_Mode, child->draw_properties().blend_mode); +} + TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { scoped_refptr<Layer> parent = Layer::Create(); scoped_refptr<Layer> render_surface1 = Layer::Create(); |