Commit a632d48d authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

[SPv175] Reduce over-invalidation of repaint during style update on paint property change.

In SPv1 mode, LayoutObject::AdjustStyleDifference will cause subtree paint invalidation
(including PaintLayer repaint) on change of paint properties or z-index, but only
if there is no direct compositing reason for the object. The reason for the LayoutObject
paint invalidations was to cause raster invalidation as a side-effect. Painted
display list output of individual LayoutObjects does not change as a result of these
updates.

In SPv175 mode, we don't need to invalidate paint of individual LayoutObjects just
becaue of these changes, since raster invalidation happens via a new PaintChunk
mechanism. However, we still need to cause PaintLayer repaint if any paint property
tree nodes are added or removed, or z-index changes, to cause re-drawing of PaintChunks
with the correct paint properties and order.

There is already invalidation of PaintLayer repaint for paint property node change,
in PaintPropertyTreeBuilder::UpdateForSelf and ::UpdateForChildren (it was added
recently, after the code being removed in this CL was committed). Therefore we
only need to invalidate repaint for z-index change. Further, this is only needed
if the LayoutObject already had a PaintLayer, because z-index has no effect on
objects without a PaintLayer, and there is already invalidation happening on
PaintLayer addition or removal.

Tested by:

LayoutTests/paint/invalidation/compositing/chunk-reorder.html
svg/transforms/change-transform-to-none-shape.html

Bug:814711

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I208b03b9e6b1a6635dab9585b8884ed0e2f8688d
Reviewed-on: https://chromium-review.googlesource.com/954352
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541981}
parent 18fe8f8a
...@@ -2006,19 +2006,13 @@ void LayoutObject::SetStyle(scoped_refptr<ComputedStyle> style) { ...@@ -2006,19 +2006,13 @@ void LayoutObject::SetStyle(scoped_refptr<ComputedStyle> style) {
// Text nodes share style with their parents but the paint properties don't // Text nodes share style with their parents but the paint properties don't
// apply to them, hence the !isText() check. // apply to them, hence the !isText() check.
// In SPv175 mode, if property nodes are added or removed as a result of these
// style changes, PaintPropertyTreeBuilder will call SetNeedsRepaint
// to cause re-generation of PaintChunks.
if (!IsText() && (diff.TransformChanged() || diff.OpacityChanged() || if (!IsText() && (diff.TransformChanged() || diff.OpacityChanged() ||
diff.ZIndexChanged() || diff.FilterChanged() || diff.ZIndexChanged() || diff.FilterChanged() ||
diff.BackdropFilterChanged() || diff.CssClipChanged())) { diff.BackdropFilterChanged() || diff.CssClipChanged()))
SetNeedsPaintPropertyUpdate(); SetNeedsPaintPropertyUpdate();
// We don't need to invalidate paint of objects on SPv175 when only paint
// property or paint order change. Mark the painting layer needing repaint
// for changed paint property or paint order. Raster invalidation will be
// issued if needed during paint.
if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
!ShouldDoFullPaintInvalidation())
ObjectPaintInvalidator(*this).SlowSetPaintingLayerNeedsRepaint();
}
} }
void LayoutObject::StyleWillChange(StyleDifference diff, void LayoutObject::StyleWillChange(StyleDifference diff,
......
...@@ -3027,6 +3027,14 @@ void PaintLayer::StyleDidChange(StyleDifference diff, ...@@ -3027,6 +3027,14 @@ void PaintLayer::StyleDidChange(StyleDifference diff,
SetNeedsCompositingInputsUpdate(); SetNeedsCompositingInputsUpdate();
GetLayoutObject().SetNeedsPaintPropertyUpdate(); GetLayoutObject().SetNeedsPaintPropertyUpdate();
// We don't need to invalidate paint of objects on SPv175 when paint order
// changes. However, we do need to repaint the containing stacking context,
// in order to generate new paint chunks in the correct order. Raster
// invalidation will be issued if needed during paint.
if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
diff.ZIndexChanged())
SetNeedsRepaint();
} }
LayoutPoint PaintLayer::LocationInternal() const { LayoutPoint PaintLayer::LocationInternal() const {
......
...@@ -2264,7 +2264,8 @@ void ObjectPaintPropertyTreeBuilder::CreateFragmentContexts( ...@@ -2264,7 +2264,8 @@ void ObjectPaintPropertyTreeBuilder::CreateFragmentContexts(
} }
} }
void ObjectPaintPropertyTreeBuilder::UpdateFragments() { bool ObjectPaintPropertyTreeBuilder::UpdateFragments() {
bool had_paint_properties = object_.FirstFragment().PaintProperties();
// Note: It is important to short-circuit on object_.StyleRef().ClipPath() // Note: It is important to short-circuit on object_.StyleRef().ClipPath()
// because NeedsClipPathClip() and NeedsEffect() requires the clip path // because NeedsClipPathClip() and NeedsEffect() requires the clip path
// cache to be resolved, but the clip path cache invalidation must delayed // cache to be resolved, but the clip path cache invalidation must delayed
...@@ -2305,6 +2306,8 @@ void ObjectPaintPropertyTreeBuilder::UpdateFragments() { ...@@ -2305,6 +2306,8 @@ void ObjectPaintPropertyTreeBuilder::UpdateFragments() {
} }
UpdateRepeatingPaintOffsetAdjustment(); UpdateRepeatingPaintOffsetAdjustment();
return needs_paint_properties != had_paint_properties;
} }
bool ObjectPaintPropertyTreeBuilder::ObjectTypeMightNeedPaintProperties() bool ObjectPaintPropertyTreeBuilder::ObjectTypeMightNeedPaintProperties()
...@@ -2332,13 +2335,13 @@ void ObjectPaintPropertyTreeBuilder::UpdatePaintingLayer() { ...@@ -2332,13 +2335,13 @@ void ObjectPaintPropertyTreeBuilder::UpdatePaintingLayer() {
bool ObjectPaintPropertyTreeBuilder::UpdateForSelf() { bool ObjectPaintPropertyTreeBuilder::UpdateForSelf() {
UpdatePaintingLayer(); UpdatePaintingLayer();
bool property_added_or_removed = false;
if (ObjectTypeMightNeedPaintProperties()) if (ObjectTypeMightNeedPaintProperties())
UpdateFragments(); property_added_or_removed = UpdateFragments();
else else
object_.GetMutableForPainting().FirstFragment().ClearNextFragment(); object_.GetMutableForPainting().FirstFragment().ClearNextFragment();
bool property_changed = false; bool property_changed = false;
bool property_added_or_removed = false;
auto* fragment_data = &object_.GetMutableForPainting().FirstFragment(); auto* fragment_data = &object_.GetMutableForPainting().FirstFragment();
for (auto& fragment_context : context_.fragments) { for (auto& fragment_context : context_.fragments) {
FragmentPaintPropertyTreeBuilder builder(object_, context_, FragmentPaintPropertyTreeBuilder builder(object_, context_,
......
...@@ -198,7 +198,8 @@ class ObjectPaintPropertyTreeBuilder { ...@@ -198,7 +198,8 @@ class ObjectPaintPropertyTreeBuilder {
ContextForFragment(const Optional<LayoutRect>& fragment_clip, ContextForFragment(const Optional<LayoutRect>& fragment_clip,
LayoutUnit logical_top_in_flow_thread) const; LayoutUnit logical_top_in_flow_thread) const;
ALWAYS_INLINE void CreateFragmentContexts(bool needs_paint_properties); ALWAYS_INLINE void CreateFragmentContexts(bool needs_paint_properties);
ALWAYS_INLINE void UpdateFragments(); // Returns whether ObjectPaintProperties were allocated or deleted.
ALWAYS_INLINE bool UpdateFragments();
ALWAYS_INLINE void UpdatePaintingLayer(); ALWAYS_INLINE void UpdatePaintingLayer();
ALWAYS_INLINE void UpdateRepeatingPaintOffsetAdjustment(); ALWAYS_INLINE void UpdateRepeatingPaintOffsetAdjustment();
ALWAYS_INLINE void UpdateRepeatingTableHeaderPaintOffsetAdjustment(); ALWAYS_INLINE void UpdateRepeatingTableHeaderPaintOffsetAdjustment();
......
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