Commit e57e1440 authored by Philip Rogers's avatar Philip Rogers Committed by Commit Bot

Use filter paint properties for SVG

Compositing SVG exposed a bug where the filter paint property was not
used when painting. Before CompositeSVG, this was not needed because
filter paint properties were not created for SVG. This will be useful
when SVG supports CSS filters (https://crbug.com/109224).

Bug: 1106780
Change-Id: I664995c8b81f201e9e30e0a670e9c252829013ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2311114Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791795}
parent 0ea35140
...@@ -1362,6 +1362,7 @@ jumbo_source_set("unit_tests") { ...@@ -1362,6 +1362,7 @@ jumbo_source_set("unit_tests") {
"paint/paint_property_tree_update_tests.cc", "paint/paint_property_tree_update_tests.cc",
"paint/paint_timing_test_helper.h", "paint/paint_timing_test_helper.h",
"paint/pre_paint_tree_walk_test.cc", "paint/pre_paint_tree_walk_test.cc",
"paint/svg_container_painter_test.cc",
"paint/table_painter_test.cc", "paint/table_painter_test.cc",
"paint/text_paint_timing_detector_test.cc", "paint/text_paint_timing_detector_test.cc",
"paint/text_painter_test.cc", "paint/text_painter_test.cc",
......
...@@ -285,8 +285,12 @@ TEST_P(CompositingTest, PaintPropertiesWhenCompositingSVG) { ...@@ -285,8 +285,12 @@ TEST_P(CompositingTest, PaintPropertiesWhenCompositingSVG) {
EXPECT_EQ(svg_root_effect_node->parent_id, ancestor_effect_node->id); EXPECT_EQ(svg_root_effect_node->parent_id, ancestor_effect_node->id);
auto* rect = CcLayerByDOMElementId("rect"); auto* rect = CcLayerByDOMElementId("rect");
auto* rect_effect_node = auto* rect_filter_node =
GetPropertyTrees()->effect_tree.Node(rect->effect_tree_index()); GetPropertyTrees()->effect_tree.Node(rect->effect_tree_index());
EXPECT_EQ(rect_filter_node->opacity, 1);
auto* rect_effect_node =
GetPropertyTrees()->effect_tree.Node(rect_filter_node->parent_id);
EXPECT_EQ(rect_effect_node->opacity, 0.7f); EXPECT_EQ(rect_effect_node->opacity, 0.7f);
EXPECT_EQ(rect_effect_node->parent_id, svg_root_effect_node->id); EXPECT_EQ(rect_effect_node->parent_id, svg_root_effect_node->id);
} }
......
...@@ -165,14 +165,13 @@ void ScopedSVGPaintState::ApplyPaintPropertyState( ...@@ -165,14 +165,13 @@ void ScopedSVGPaintState::ApplyPaintPropertyState(
if (object_.IsSVGRoot()) if (object_.IsSVGRoot())
return; return;
// MaskClip() implies Effect(), thus we don't need to check MaskClip().
if (!properties.Effect() && !properties.ClipPathClip())
return;
auto& paint_controller = GetPaintInfo().context.GetPaintController(); auto& paint_controller = GetPaintInfo().context.GetPaintController();
auto state = paint_controller.CurrentPaintChunkProperties(); auto state = paint_controller.CurrentPaintChunkProperties();
if (const auto* effect = properties.Effect()) if (const auto* filter = properties.Filter())
state.SetEffect(*filter);
else if (const auto* effect = properties.Effect())
state.SetEffect(*effect); state.SetEffect(*effect);
if (const auto* mask_clip = properties.MaskClip()) if (const auto* mask_clip = properties.MaskClip())
state.SetClip(*mask_clip); state.SetClip(*mask_clip);
else if (const auto* clip_path_clip = properties.ClipPathClip()) else if (const auto* clip_path_clip = properties.ClipPathClip())
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/paint/svg_container_painter.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
using testing::ElementsAre;
namespace blink {
using SVGContainerPainterTest = PaintControllerPaintTest;
INSTANTIATE_PAINT_TEST_SUITE_P(SVGContainerPainterTest);
TEST_P(SVGContainerPainterTest, FilterPaintProperties) {
ScopedCompositeSVGForTest enable_feature(true);
SetBodyInnerHTML(R"HTML(
<style>
#container, #before, #after { will-change: transform; }
</style>
<svg id="svg" width="40" height="40">
<g id="container">
<rect id="before" width="10" height="10" fill="lightgray" />
<rect id="rect" width="11" height="11" fill="lightblue" />
<rect id="after" width="12" height="12" fill="blue" />
</g>
</svg>
)HTML");
const auto* root = GetLayoutObjectByElementId("svg");
const DisplayItem::Type kSVGEffectPaintPhaseForeground =
static_cast<DisplayItem::Type>(DisplayItem::kSVGEffectPaintPhaseFirst +
5);
const auto* before = GetLayoutObjectByElementId("before");
PaintChunk::Id before_id(*before, kSVGEffectPaintPhaseForeground);
const auto& before_properties = before->FirstFragment().ContentsProperties();
const auto* rect = GetLayoutObjectByElementId("rect");
PaintChunk::Id rect_id(*rect, DisplayItem::kHitTest);
const auto* container = GetLayoutObjectByElementId("container");
// Because the rect doesn't create paint properties, it uses the container's.
const auto& container_properties =
container->FirstFragment().ContentsProperties();
const auto* after = GetLayoutObjectByElementId("after");
PaintChunk::Id after_id(*after, kSVGEffectPaintPhaseForeground);
const auto& after_properties = after->FirstFragment().ContentsProperties();
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
PaintChunk::Id view_id(GetLayoutView(), DisplayItem::kScrollHitTest);
const auto& view_properties =
GetLayoutView().FirstFragment().LocalBorderBoxProperties();
auto scrolling_view_state =
GetLayoutView().FirstFragment().ContentsProperties();
HitTestData scroll_hit_test;
scroll_hit_test.scroll_translation =
&ToUnaliased(scrolling_view_state.Transform());
scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(
IsPaintChunk(0, 0, view_id, view_properties, &scroll_hit_test),
IsPaintChunk(0, 1,
PaintChunk::Id(ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
scrolling_view_state),
IsPaintChunk(1, 2, before_id, before_properties),
IsPaintChunk(2, 3, rect_id, container_properties),
IsPaintChunk(3, 4, after_id, after_properties)));
} else {
const auto* svg_paint_layer = ToLayoutSVGRoot(root)->Layer();
const auto* svg_graphics_layer =
svg_paint_layer->GetCompositedLayerMapping()->MainGraphicsLayer();
EXPECT_THAT(svg_graphics_layer->GetPaintController().PaintChunks(),
ElementsAre(IsPaintChunk(0, 1, before_id, before_properties),
IsPaintChunk(1, 2, rect_id, container_properties),
IsPaintChunk(2, 3, after_id, after_properties)));
}
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment