Commit e6a9a5cd authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[SPv175+] Fix filter painting with empty content

Some filters have drawing effects even if they have no content.

- Output a no-op display item to ensure a chunk for the filter will
  be created;
- Let CC side know the filter (with or without content) with correct
  visual rect.

Bug: 771643
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: Ic841823706d5547c5c67ffa8c63620251733bd49
Reviewed-on: https://chromium-review.googlesource.com/871834
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarTien-Ren Chen <trchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#530744}
parent 8b5ac80d
...@@ -83,16 +83,10 @@ crbug.com/769942 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Failure ] ...@@ -83,16 +83,10 @@ crbug.com/769942 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Failure ]
crbug.com/769942 virtual/gpu-rasterization/images/color-profile-svg-foreign-object.html [ Failure ] crbug.com/769942 virtual/gpu-rasterization/images/color-profile-svg-foreign-object.html [ Failure ]
crbug.com/769942 virtual/exotic-color-space/images/color-profile-svg-foreign-object.html [ Failure ] crbug.com/769942 virtual/exotic-color-space/images/color-profile-svg-foreign-object.html [ Failure ]
crbug.com/771643 css3/filters/effect-reference-image-lazy-attach.html [ Failure ]
crbug.com/771643 css3/filters/effect-reference-image.html [ Failure ]
crbug.com/771643 css3/filters/effect-reference-on-transparent-element.html [ Failure ]
crbug.com/771643 css3/filters/effect-reference-tile.html [ Pass Failure Crash ] crbug.com/771643 css3/filters/effect-reference-tile.html [ Pass Failure Crash ]
crbug.com/771643 css3/filters/empty-element-with-filter.html [ Failure ]
crbug.com/771643 css3/filters/filterRegions.html [ Failure ]
crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ] crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ] crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
crbug.com/771643 fast/reflections/reflection-masks-outset.html [ Pass Failure ] crbug.com/771643 fast/reflections/reflection-masks-outset.html [ Pass Failure ]
crbug.com/771643 http/tests/misc/slow-loading-mask.html [ Failure ]
crbug.com/771643 images/cross-fade-invalidation.html [ Failure ] crbug.com/771643 images/cross-fade-invalidation.html [ Failure ]
crbug.com/771643 images/drag-image-transformed-parent.html [ Failure ] crbug.com/771643 images/drag-image-transformed-parent.html [ Failure ]
crbug.com/771643 plugins/webview-plugin-lifecycle.html [ Failure ] crbug.com/771643 plugins/webview-plugin-lifecycle.html [ Failure ]
...@@ -104,9 +98,6 @@ crbug.com/771643 svg/as-background-image/svg-as-background-6.html [ Failure ] ...@@ -104,9 +98,6 @@ crbug.com/771643 svg/as-background-image/svg-as-background-6.html [ Failure ]
crbug.com/771643 svg/as-image/svg-image-with-css-animation.html [ Failure ] crbug.com/771643 svg/as-image/svg-image-with-css-animation.html [ Failure ]
crbug.com/771643 svg/batik/masking/maskRegions.svg [ Failure ] crbug.com/771643 svg/batik/masking/maskRegions.svg [ Failure ]
crbug.com/771643 svg/custom/local-url-references.html [ Failure ] crbug.com/771643 svg/custom/local-url-references.html [ Failure ]
crbug.com/771643 svg/hixie/mixed/006.xml [ Failure ]
crbug.com/771643 svg/hixie/mixed/011.xml [ Failure ]
crbug.com/771643 svg/overflow/overflow-on-foreignObject.svg [ Failure ]
crbug.com/771643 svg/zoom/page/zoom-mask-with-percentages.svg [ Failure ] crbug.com/771643 svg/zoom/page/zoom-mask-with-percentages.svg [ Failure ]
crbug.com/771643 tables/table-transform-absolute-position-child.html [ Failure ] crbug.com/771643 tables/table-transform-absolute-position-child.html [ Failure ]
crbug.com/771643 virtual/exotic-color-space/images/cross-fade-invalidation.html [ Failure ] crbug.com/771643 virtual/exotic-color-space/images/cross-fade-invalidation.html [ Failure ]
......
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x421
LayoutBlockFlow {html} at (0,0) size 800x421
LayoutBlockFlow {body} at (8,8) size 784x405
LayoutSVGRoot {svg} at (0,200) size 200x200
LayoutSVGEllipse {circle} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [cx=100.00] [cy=100.00] [r=50.00]
LayoutSVGForeignObject {foreignObject} at (0,0) size 200x200
LayoutText {#text} at (0,0) size 0x0
layer at (8,8) size 200x200
LayoutBlockFlow (positioned) {div} at (8,8) size 200x200 [bgcolor=#FFFFFF]
LayoutText {#text} at (0,0) size 199x39
text run at (0,0) width 190: "There should be a green circle"
text run at (0,20) width 199: "below with no red on this page."
layer at (8,8) size 200x200 backgroundClip at (8,208) size 200x200 clip at (8,208) size 200x200
LayoutBlockFlow (positioned) {div} at (0,-200) size 200x200 [color=#FFFF00] [bgcolor=#FF0000]
LayoutText {#text} at (0,0) size 35x19
text run at (0,0) width 35: "FAIL"
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x221
LayoutBlockFlow {html} at (0,0) size 800x221
LayoutBlockFlow {body} at (8,8) size 784x205
LayoutSVGRoot {svg} at (0,0) size 200x200
LayoutSVGEllipse {circle} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [cx=100.00] [cy=100.00] [r=50.00]
LayoutSVGForeignObject {foreignObject} at (0,0) size 200x200
LayoutText {#text} at (0,0) size 0x0
layer at (50,0) size 150x200 backgroundClip at (0,8) size 149x283 clip at (0,8) size 149x283
LayoutBlockFlow (positioned) {div} at (50,0) size 150x200
LayoutText {#text} at (0,0) size 135x79
text run at (0,0) width 113: "There should be a"
text run at (0,20) width 126: "green circle and this"
text run at (0,40) width 135: "text should be rotated"
text run at (0,60) width 92: "by 45 degrees."
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutBlockFlow DIV class='before box'",
"rect": [78, 70, 100, 100],
"reason": "disappeared"
},
{ {
"object": "LayoutBlockFlow DIV class='box'", "object": "LayoutBlockFlow DIV class='box'",
"rect": [78, 70, 100, 100], "rect": [78, 70, 100, 100],
......
...@@ -563,9 +563,14 @@ PaintResult PaintLayerPainter::PaintLayerContents( ...@@ -563,9 +563,14 @@ PaintResult PaintLayerPainter::PaintLayerContents(
bool selection_only = bool selection_only =
local_painting_info.GetGlobalPaintFlags() & kGlobalPaintSelectionOnly; local_painting_info.GetGlobalPaintFlags() & kGlobalPaintSelectionOnly;
{ // Begin block for the lifetime of any filter. { // Begin block for the lifetime of any filter.
size_t display_item_list_size_before_painting =
context.GetPaintController().NewDisplayItemList().size();
Optional<FilterPainter> filter_painter; Optional<FilterPainter> filter_painter;
if (image_filter) { if (image_filter) {
DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV175Enabled());
// Compute clips outside the filter (#3, see above for discussion). // Compute clips outside the filter (#3, see above for discussion).
PaintLayerFragments filter_fragments; PaintLayerFragments filter_fragments;
paint_layer_.AppendSingleFragmentIgnoringPagination( paint_layer_.AppendSingleFragmentIgnoringPagination(
...@@ -579,6 +584,8 @@ PaintResult PaintLayerPainter::PaintLayerContents( ...@@ -579,6 +584,8 @@ PaintResult PaintLayerPainter::PaintLayerContents(
? ClipRect() ? ClipRect()
: filter_fragments[0].background_rect, : filter_fragments[0].background_rect,
local_painting_info, paint_flags); local_painting_info, paint_flags);
} else if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
paint_layer_.PaintsWithFilters()) {
} }
bool is_painting_root_layer = (&paint_layer_) == painting_info.root_layer; bool is_painting_root_layer = (&paint_layer_) == painting_info.root_layer;
...@@ -628,6 +635,15 @@ PaintResult PaintLayerPainter::PaintLayerContents( ...@@ -628,6 +635,15 @@ PaintResult PaintLayerPainter::PaintLayerContents(
PaintOverflowControlsForFragments(layer_fragments, context, PaintOverflowControlsForFragments(layer_fragments, context,
local_painting_info, paint_flags); local_painting_info, paint_flags);
} }
if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
!is_painting_overlay_scrollbars && paint_layer_.PaintsWithFilters() &&
display_item_list_size_before_painting ==
context.GetPaintController().NewDisplayItemList().size()) {
// If a layer with filters painted nothing, we need to issue a no-op
// display item to ensure the filters won't be ignored.
PaintEmptyContentForFilters(context);
}
} // FilterPainter block } // FilterPainter block
bool should_paint_mask = bool should_paint_mask =
...@@ -1364,4 +1380,23 @@ void PaintLayerPainter::FillMaskingFragment(GraphicsContext& context, ...@@ -1364,4 +1380,23 @@ void PaintLayerPainter::FillMaskingFragment(GraphicsContext& context,
context.FillRect(snapped_clip_rect, Color::kBlack); context.FillRect(snapped_clip_rect, Color::kBlack);
} }
// Generate a no-op DrawingDisplayItem to ensure a non-empty chunk for the
// filter without content.
void PaintLayerPainter::PaintEmptyContentForFilters(GraphicsContext& context) {
DCHECK(RuntimeEnabledFeatures::SlimmingPaintV175Enabled());
DCHECK(paint_layer_.PaintsWithFilters());
ScopedPaintChunkProperties paint_chunk_properties(
context.GetPaintController(),
*paint_layer_.GetLayoutObject()
.FirstFragment()
.LocalBorderBoxProperties(),
paint_layer_, DisplayItem::kEmptyContentForFilters);
if (DrawingRecorder::UseCachedDrawingIfPossible(
context, paint_layer_, DisplayItem::kEmptyContentForFilters))
return;
DrawingRecorder recorder(context, paint_layer_,
DisplayItem::kEmptyContentForFilters);
}
} // namespace blink } // namespace blink
...@@ -140,6 +140,8 @@ class CORE_EXPORT PaintLayerPainter { ...@@ -140,6 +140,8 @@ class CORE_EXPORT PaintLayerPainter {
const ClipRect&, const ClipRect&,
const DisplayItemClient&); const DisplayItemClient&);
void PaintEmptyContentForFilters(GraphicsContext&);
static bool NeedsToClip(const PaintLayerPaintingInfo& local_painting_info, static bool NeedsToClip(const PaintLayerPaintingInfo& local_painting_info,
const ClipRect&, const ClipRect&,
const PaintLayerFlags&, const PaintLayerFlags&,
......
...@@ -483,6 +483,11 @@ std::unique_ptr<JSONObject> ObjectForSkPaint(const SkPaint& paint) { ...@@ -483,6 +483,11 @@ std::unique_ptr<JSONObject> ObjectForSkPaint(const SkPaint& paint) {
paint_item->SetString("hinting", HintingName(paint.getHinting())); paint_item->SetString("hinting", HintingName(paint.getHinting()));
if (paint.getBlendMode() != SkBlendMode::kSrcOver) if (paint.getBlendMode() != SkBlendMode::kSrcOver)
paint_item->SetString("blendMode", SkBlendMode_Name(paint.getBlendMode())); paint_item->SetString("blendMode", SkBlendMode_Name(paint.getBlendMode()));
if (const auto* filter = paint.getImageFilter()) {
SkString str;
filter->toString(&str);
paint_item->SetString("imageFilter", str.c_str());
}
return paint_item; return paint_item;
} }
......
...@@ -24,12 +24,14 @@ void AppendDisplayItemToCcDisplayItemList(const DisplayItem& display_item, ...@@ -24,12 +24,14 @@ void AppendDisplayItemToCcDisplayItemList(const DisplayItem& display_item,
const IntRect& visual_rect_in_layer) { const IntRect& visual_rect_in_layer) {
DCHECK(display_item.IsDrawing()); DCHECK(display_item.IsDrawing());
sk_sp<const PaintRecord> record =
static_cast<const DrawingDisplayItem&>(display_item).GetPaintRecord();
if (!record)
return;
list.StartPaint(); list.StartPaint();
list.push<cc::DrawRecordOp>(std::move(record)); if (auto record =
static_cast<const DrawingDisplayItem&>(display_item).GetPaintRecord())
list.push<cc::DrawRecordOp>(std::move(record));
// StartPaint() and EndPaintOfUnpaired() are called regardless of whether the
// record is null to ensure we'll set correct visual rects for the enclosing
// paired display items. This is especially important for filters that draw
// content by themselves but don't enclose any non-empty DrawingDisplayItem.
list.EndPaintOfUnpaired(visual_rect_in_layer); list.EndPaintOfUnpaired(visual_rect_in_layer);
} }
......
...@@ -75,6 +75,7 @@ static WTF::String SpecialDrawingTypeAsDebugString(DisplayItem::Type type) { ...@@ -75,6 +75,7 @@ static WTF::String SpecialDrawingTypeAsDebugString(DisplayItem::Type type) {
DEBUG_STRING_CASE(DocumentBackground); DEBUG_STRING_CASE(DocumentBackground);
DEBUG_STRING_CASE(DragImage); DEBUG_STRING_CASE(DragImage);
DEBUG_STRING_CASE(DragCaret); DEBUG_STRING_CASE(DragCaret);
DEBUG_STRING_CASE(EmptyContentForFilters);
DEBUG_STRING_CASE(SVGImage); DEBUG_STRING_CASE(SVGImage);
DEBUG_STRING_CASE(LinkHighlight); DEBUG_STRING_CASE(LinkHighlight);
DEBUG_STRING_CASE(ImageAreaFocusRing); DEBUG_STRING_CASE(ImageAreaFocusRing);
......
...@@ -77,6 +77,7 @@ class PLATFORM_EXPORT DisplayItem { ...@@ -77,6 +77,7 @@ class PLATFORM_EXPORT DisplayItem {
kDocumentBackground, kDocumentBackground,
kDragImage, kDragImage,
kDragCaret, kDragCaret,
kEmptyContentForFilters,
kSVGImage, kSVGImage,
kLinkHighlight, kLinkHighlight,
kImageAreaFocusRing, kImageAreaFocusRing,
......
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