Commit 534a77d7 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

More cases of explicit output clip of effect nodes

Now exclude cases of using null output clip for an effect node
if the out-of-flow descenant's containing block has the same clip
as the current clip. This lets PaintChunksToCcLayers and
PropertyTreeManager go through the more optimized path for
more cases.

Bug: 879173
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I5c9e0006dc678c36b752823293f08355a194578b
Reviewed-on: https://chromium-review.googlesource.com/1246686Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594512}
parent 32e5d362
<!DOCTYPE html>
Passes if no red.
<div style="width: 300px; height: 300px; background: green; outline: 1px solid green"></div>
<!DOCTYPE html>
Passes if no red.
<div style="width: 300px; height: 300px; background: green; outline: 1px solid green; position: absolute; z-index: 1"></div>
<div style="width: 300px; height: 300px; overflow: hidden">
<div style="transform: rotate(45deg); width: 300px; height: 300px">
<div style="opacity: 0.9">
<div style="position: fixed; will-change: transform; width: 300px; height: 300px; background: red"></div>
</div>
</div>
</div>
...@@ -137,6 +137,7 @@ class FragmentPaintPropertyTreeBuilder { ...@@ -137,6 +137,7 @@ class FragmentPaintPropertyTreeBuilder {
ALWAYS_INLINE void UpdateStickyTranslation(); ALWAYS_INLINE void UpdateStickyTranslation();
ALWAYS_INLINE void UpdateTransform(); ALWAYS_INLINE void UpdateTransform();
ALWAYS_INLINE void UpdateTransformForNonRootSVG(); ALWAYS_INLINE void UpdateTransformForNonRootSVG();
ALWAYS_INLINE bool EffectCanUseCurrentClipAsOutputClip() const;
ALWAYS_INLINE void UpdateEffect(); ALWAYS_INLINE void UpdateEffect();
ALWAYS_INLINE void UpdateLinkHighlightEffect(); ALWAYS_INLINE void UpdateLinkHighlightEffect();
ALWAYS_INLINE void UpdateFilter(); ALWAYS_INLINE void UpdateFilter();
...@@ -734,26 +735,35 @@ static bool NeedsEffect(const LayoutObject& object) { ...@@ -734,26 +735,35 @@ static bool NeedsEffect(const LayoutObject& object) {
// An effect node can use the current clip as its output clip if the clip won't // An effect node can use the current clip as its output clip if the clip won't
// end before the effect ends. Having explicit output clip can let the later // end before the effect ends. Having explicit output clip can let the later
// stages use more optimized code path. // stages use more optimized code path.
static bool EffectCanUseCurrentClipAsOutputClip(const LayoutObject& object) { bool FragmentPaintPropertyTreeBuilder::EffectCanUseCurrentClipAsOutputClip()
DCHECK(NeedsEffect(object)); const {
DCHECK(NeedsEffect(object_));
if (!object.HasLayer()) { if (!object_.HasLayer()) {
// An SVG object's effect never interleaves with clips. // An SVG object's effect never interleaves with clips.
DCHECK(object.IsSVG()); DCHECK(object_.IsSVG());
return true; return true;
} }
const auto* layer = ToLayoutBoxModelObject(object).Layer(); const auto* layer = ToLayoutBoxModelObject(object_).Layer();
// Out-of-flow descendants not contained by this object may escape clips. // Out-of-flow descendants not contained by this object may escape clips.
if (layer->HasNonContainedAbsolutePositionDescendant()) if (layer->HasNonContainedAbsolutePositionDescendant() &&
object_.ContainingBlockForAbsolutePosition()
->FirstFragment()
.PostOverflowClip() != context_.current.clip)
return false; return false;
if (layer->HasFixedPositionDescendant() && if (layer->HasFixedPositionDescendant() &&
!object.CanContainFixedPositionObjects()) !object_.CanContainFixedPositionObjects() &&
object_.ContainingBlockForFixedPosition()
->FirstFragment()
.PostOverflowClip() != context_.current.clip)
return false; return false;
// Some descendants under a pagination container (e.g. composited objects // Some descendants under a pagination container (e.g. composited objects
// in SPv1 and column spanners) may escape fragment clips. // in SPv1 and column spanners) may escape fragment clips.
if (layer->EnclosingPaginationLayer()) if (layer->EnclosingPaginationLayer())
return false; return false;
return true; return true;
} }
...@@ -790,7 +800,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() { ...@@ -790,7 +800,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
clip_path_clip = IntRect(); clip_path_clip = IntRect();
} }
const auto* output_clip = EffectCanUseCurrentClipAsOutputClip(object_) const auto* output_clip = EffectCanUseCurrentClipAsOutputClip()
? context_.current.clip ? context_.current.clip
: nullptr; : nullptr;
......
...@@ -950,7 +950,8 @@ TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossStackingContext) { ...@@ -950,7 +950,8 @@ TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossStackingContext) {
const ObjectPaintProperties* node_with_opacity_properties = const ObjectPaintProperties* node_with_opacity_properties =
node_with_opacity->FirstFragment().PaintProperties(); node_with_opacity->FirstFragment().PaintProperties();
EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity()); EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity());
EXPECT_EQ(nullptr, node_with_opacity_properties->Effect()->OutputClip()); EXPECT_EQ(DocContentClip(),
node_with_opacity_properties->Effect()->OutputClip());
EXPECT_NE(nullptr, node_with_opacity_properties->Effect()->Parent()); EXPECT_NE(nullptr, node_with_opacity_properties->Effect()->Parent());
EXPECT_EQ(nullptr, node_with_opacity_properties->Transform()); EXPECT_EQ(nullptr, node_with_opacity_properties->Transform());
CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 100, 200), node_with_opacity, CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 100, 200), node_with_opacity,
......
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