Remove LayoutBlockFlow overflow invalidation

"Overflow" invalidation was to invalidate changed lines in a
LayoutBlockFlow with inline children. Upper and lower bounds of
changed lines are recorded during layout. The concept was not
properly named, and the implementation is complex.

Now switch to LayoutInline/LayoutText invalidation. Set the owning
inline LayoutObject shouldDoFullPaintInvalidation when a InlineBox
is deleted or changed.

This also improves performance during inline layout for paint
invalidation when many InlineBoxes are deleted.

Under-invalidation checking didn't find any error in layout tests (which
would be pixel mismatches or crashes).

With this patch, we may invalidate bigger rect in case that not all
InlineBoxes changed in a big LayutInline or LayoutText. Previously the
paint invalidation rects cover the changed InlineBoxes only; now
the rects cover the whole LayoutInline and LayoutText containing the
changed InlineBoxes. The case normally happens when some intruding
floating objects change geometry which is not very common.

In other cases we may invalidate smaller rects because we no longer
invalidate the whole width of the LayoutBlockFlow.

We may invalidate more rects than before.

BUG=619630

Review-Url: https://codereview.chromium.org/2087513003
Cr-Commit-Position: refs/heads/master@{#402292}
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index fde4e91c..3adaa21 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -383,7 +383,8 @@
 crbug.com/548904 [ Linux Win ] fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure Pass ]
 
 crbug.com/552433 [ Win7 Debug ] svg/W3C-SVG-1.1/coords-units-02-b.svg [ Failure ]
-crbug.com/605024 [ Mac ] svg/transforms/animated-path-inside-transformed-html.xhtml [ Failure ]
+# TODO(wangxianzhu): Examine this after rebaseline.
+# crbug.com/605024 [ Mac ] svg/transforms/animated-path-inside-transformed-html.xhtml [ Failure ]
 
 # This directly has manual tests that don't have to run with run-webkit-tests
 crbug.com/359838 http/tests/ManualTests/ [ Skip ]
@@ -890,6 +891,138 @@
 crbug.com/400829 media/video-object-fit.html [ Failure ]
 crbug.com/400829 virtual/stable/media/stable/video-object-fit-stable.html [ Failure ]
 
+crbug.com/619630 fast/repaint/vertical-align-length1.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/quotes.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-8.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/invisible-objects.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/overflow-delete-line.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/use-setAttribute-crash.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/control-clip.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/crbug-371640.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/crbug-371640-4.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/text-repaint-including-stroke.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/stacked-diacritics.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/selection-after-remove.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/subtree-root-skipped.html [ NeedsRebaseline ]
+crbug.com/619630 compositing/squashing/remove-squashed-layer-plus-move.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/gradients-em-stops-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/text-mask-update.svg [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/text-xy-updates-SVGList.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/remove-inline-layer-after-layout.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-image.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/list-marker-2.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-use-on-symbol.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/table/border-collapsing/cached-change-cell-sl-border-color.html [ NeedsRebaseline ]
+crbug.com/619630 svg/text/tspan-dynamic-positioning.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-4.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-in-scrolled-clipped-block.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/transform-layout-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/js-late-gradient-creation.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/layout-state-scrolloffset.html [ NeedsRebaseline ]
+crbug.com/619630 fast/table/resize-table-repaint-vertical-align-cell.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-6.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/inline-relative-positioned.html [ NeedsRebaseline ]
+crbug.com/619630 svg/as-object/deep-nested-embedded-svg-size-changes-no-layout-triggers-1.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-10.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/positioned-document-element.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/inline-block-resize.html [ NeedsRebaseline ]
+crbug.com/619630 svg/text/modify-text-node-in-tspan.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/shift-relative-positioned-container-with-image-removal.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/window-resize-centered-inline-under-fixed-pos.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-7.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/overflow-scroll-delete.html [ NeedsRebaseline ]
+crbug.com/619630 fast/table/resize-table-repaint-percent-size-cell.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/text-append-dirty-lines.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/change-text-content-and-background-color.html [ NeedsRebaseline ]
+crbug.com/619630 svg/as-image/svg-image-change-content-size.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/vertical-align-length2.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/layout-state-relative.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-shadow-tree-content-with-symbol.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/vertical-align1.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/inline-reflow.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/js-late-clipPath-creation.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/window-resize-vertical-writing-mode.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-content.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/text-match-document-change.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/layoutstate-invalid-invalidation-inline-relative-positioned.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/outline-offset-text.html [ NeedsRebaseline ]
+crbug.com/619630 svg/as-object/deep-nested-embedded-svg-size-changes-no-layout-triggers-2.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/relative-inline-positioned-movement-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/reflection-repaint-test.html [ NeedsRebaseline ]
+crbug.com/619630 svg/text/append-text-node-to-tspan.html [ NeedsRebaseline ]
+crbug.com/619630 svg/carto.net/tabgroup.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/remove-block-after-layout.html [ NeedsRebaseline ]
+crbug.com/619630 fast/table/resize-table-row-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/layout-state-scrolloffset3.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-1.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/table-collapsed-border.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-overflow.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-deep-shadow-tree-content.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/multicol-with-text.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/box-inline-resize.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-use-without-attributes-on-symbol.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/resize-scrollable-iframe.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/remove-inline-block-descendant-of-flex.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/add-outline-property-on-root.html [ NeedsRebaseline ]
+crbug.com/619630 css3/flexbox/repaint.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-shadow-tree-content.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/outline-continuations.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/transform-text-element.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/repaint-non-scaling-stroke-text-decoration.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/selection-after-delete.html [ NeedsRebaseline ]
+crbug.com/619630 css3/flexbox/repaint-on-layout.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/text-dom-removal.svg [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/absolute-sized-content-with-resources.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/clipped-relative.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/scrolling-embedded-svg-file-image-repaint-problem.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/outline-change-invalidation.html [ NeedsRebaseline ]
+crbug.com/619630 svg/transforms/animated-path-inside-transformed-html.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/bugzilla-5699.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/bugzilla-6278.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/bugzilla-7235.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/remove-inline-after-layout.html [ NeedsRebaseline ]
+crbug.com/619630 css3/flexbox/scrollbars-changed.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/delete-into-nested-block.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/inner-svg-change-viewPort-relative.svg [ NeedsRebaseline ]
+crbug.com/619630 svg/text/remove-tspan-from-text.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-3.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/js-late-clipPath-and-object-creation.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/multi-layout-one-frame.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/selection-clear.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/layout-state-scrolloffset2.html [ NeedsRebaseline ]
+crbug.com/619630 svg/as-object/embedded-svg-size-changes-no-layout-triggers.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-inner-svg.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/offset-change-wrong-invalidation-with-float.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-5.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/positioned-list-offset-change-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/overflow-scroll-body-appear.html [ NeedsRebaseline ]
+crbug.com/619630 svg/as-object/nested-embedded-svg-size-changes-no-layout-triggers-1.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/bugzilla-3509.html [ NeedsRebaseline ]
+crbug.com/619630 svg/text/remove-text-node-from-tspan.html [ NeedsRebaseline ]
+crbug.com/619630 svg/as-object/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/use-clipped-hit.svg [ NeedsRebaseline ]
+crbug.com/619630 svg/text/text-rescale.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/vertical-align2.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/repaint-non-scaling-stroke-text.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/lines-with-layout-delta.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/multicol-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 compositing/squashing/iframe-inside-squashed-layer.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/relative-sized-content-with-resources.xhtml [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/inline-focus.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-2.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/block-no-inflow-children.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/make-children-non-inline.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/clip-with-layout-delta.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/text-in-relative-positioned-inline.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/modify-transferred-listitem-different-attr.html [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/inline-outline-repaint.html [ NeedsRebaseline ]
+crbug.com/619630 svg/repaint/remove-outline-property-on-root.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/use-detach.svg [ NeedsRebaseline ]
+crbug.com/619630 fast/repaint/line-flow-with-floats-9.html [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/object-sizing-no-width-height-change-content-box-size.xhtml [ NeedsRebaseline ]
+crbug.com/619630 svg/custom/js-late-pattern-creation.svg [ NeedsRebaseline ]
+crbug.com/619630 svg/text/text-viewbox-rescale.html [ NeedsManualRebaseline ]
+
 # We only want to run one of the web-animations-api tests in stable mode.
 crbug.com/441553 virtual/stable/web-animations-api [ Skip ]
 crbug.com/368946 virtual/stable/web-animations-api/eased-keyframes.html [ Pass ]
@@ -1266,7 +1399,8 @@
 crbug.com/619103 paint/invalidation/animated-gif.html [ Pass Failure ]
 crbug.com/619103 paint/invalidation/animated-gif-background.html [ Pass Failure ]
 crbug.com/619103 paint/invalidation/animated-gif-background-offscreen.html [ Pass Failure ]
-crbug.com/619103 [ Win ] svg/text/text-viewbox-rescale.html [ Pass Failure ]
+# TODO(wangxianzhu): Restore this after rebaseline
+# crbug.com/619103 [ Win ] svg/text/text-viewbox-rescale.html [ Pass Failure ]
 
 crbug.com/443596 media/sources-fallback-codecs.html [ Pass Failure ]
 
diff --git a/third_party/WebKit/Source/core/layout/InlineTextBoxTest.cpp b/third_party/WebKit/Source/core/layout/InlineTextBoxTest.cpp
index b2f4818f..d70cb9c 100644
--- a/third_party/WebKit/Source/core/layout/InlineTextBoxTest.cpp
+++ b/third_party/WebKit/Source/core/layout/InlineTextBoxTest.cpp
@@ -24,6 +24,7 @@
     {
         Text* node = document.createTextNode(string);
         LayoutText* text = new LayoutText(node, string.impl());
+        text->setStyle(ComputedStyle::create());
         return new TestInlineTextBox(LineLayoutItem(text));
     }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index a7c3fbaa..8872d901 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -58,7 +58,6 @@
 
 struct SameSizeAsLayoutBlockFlow : public LayoutBlock {
     LineBoxList lineBoxes;
-    LayoutUnit m_paintInvalidationLogicalTopAndBottom[2];
     void* pointers[2];
 };
 
@@ -397,17 +396,6 @@
 
     updateAfterLayout();
 
-    if (m_paintInvalidationLogicalTop != m_paintInvalidationLogicalBottom) {
-        bool hasVisibleContent = style()->visibility() == VISIBLE;
-        if (!hasVisibleContent) {
-            PaintLayer* layer = enclosingLayer();
-            layer->updateDescendantDependentFlags();
-            hasVisibleContent = layer->hasVisibleContent();
-        }
-        if (hasVisibleContent)
-            setShouldInvalidateOverflowForPaint();
-    }
-
     if (isHTMLDialogElement(node()) && isOutOfFlowPositioned())
         positionDialog();
 
@@ -467,8 +455,6 @@
     LayoutUnit previousHeight = logicalHeight();
     setLogicalHeight(beforeEdge);
 
-    m_paintInvalidationLogicalTop = LayoutUnit();
-    m_paintInvalidationLogicalBottom = LayoutUnit();
     if (!firstChild() && !isAnonymousBlock())
         setChildrenInline(true);
 
@@ -480,7 +466,7 @@
     // all inline children are removed from this block.
     setContainsInlineWithOutlineAndContinuation(false);
     if (childrenInline())
-        layoutInlineChildren(relayoutChildren, m_paintInvalidationLogicalTop, m_paintInvalidationLogicalBottom, afterEdge);
+        layoutInlineChildren(relayoutChildren, afterEdge);
     else
         layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge);
 
@@ -2789,48 +2775,6 @@
     }
 }
 
-void LayoutBlockFlow::invalidatePaintForOverflow()
-{
-    // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
-    // it had to lay out. We wouldn't need the hasOverflowClip() hack in that case either.
-    LayoutUnit paintInvalidationLogicalLeft = logicalLeftVisualOverflow();
-    LayoutUnit paintInvalidationLogicalRight = logicalRightVisualOverflow();
-    if (hasOverflowClip()) {
-        // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow.
-        // Note the old code did this as well but even for overflow:visible. The addition of hasOverflowClip() at least tightens up the hack a bit.
-        // layoutInlineChildren should be patched to compute the entire paint invalidation rect.
-        paintInvalidationLogicalLeft = std::min(paintInvalidationLogicalLeft, logicalLeftLayoutOverflow());
-        paintInvalidationLogicalRight = std::max(paintInvalidationLogicalRight, logicalRightLayoutOverflow());
-    }
-
-    LayoutRect paintInvalidationRect;
-    if (isHorizontalWritingMode())
-        paintInvalidationRect = LayoutRect(paintInvalidationLogicalLeft, m_paintInvalidationLogicalTop, paintInvalidationLogicalRight - paintInvalidationLogicalLeft, m_paintInvalidationLogicalBottom - m_paintInvalidationLogicalTop);
-    else
-        paintInvalidationRect = LayoutRect(m_paintInvalidationLogicalTop, paintInvalidationLogicalLeft, m_paintInvalidationLogicalBottom - m_paintInvalidationLogicalTop, paintInvalidationLogicalRight - paintInvalidationLogicalLeft);
-
-    if (hasOverflowClip()) {
-        // Adjust the paint invalidation rect for scroll offset
-        paintInvalidationRect.move(-scrolledContentOffset());
-
-        // Don't allow this rect to spill out of our overflow box.
-        paintInvalidationRect.intersect(LayoutRect(LayoutPoint(), size()));
-    }
-
-    // Make sure the rect is still non-empty after intersecting for overflow above
-    if (!paintInvalidationRect.isEmpty()) {
-        // Hits in media/event-attributes.html
-        DisableCompositingQueryAsserts disabler;
-
-        invalidatePaintRectangle(paintInvalidationRect); // We need to do a partial paint invalidation of our content.
-        if (hasReflection())
-            invalidatePaintRectangle(reflectedRect(paintInvalidationRect));
-    }
-
-    m_paintInvalidationLogicalTop = LayoutUnit();
-    m_paintInvalidationLogicalBottom = LayoutUnit();
-}
-
 void LayoutBlockFlow::invalidateDisplayItemClients(PaintInvalidationReason invalidationReason) const
 {
     LayoutBlock::invalidateDisplayItemClients(invalidationReason);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
index 4734a25..1ed48cc 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -288,7 +288,7 @@
         return containsFloats() ? m_floatingObjects->set().last().get() : nullptr;
     }
 
-    void invalidateDisplayItemClientsOfFirstLine();
+    void setShouldDoFullPaintInvalidationForFirstLine();
 
     void simplifiedNormalFlowInlineLayout();
     bool recalcInlineChildrenOverflowAfterStyleChange();
@@ -303,7 +303,7 @@
 
 protected:
     void rebuildFloatsFromIntruding();
-    void layoutInlineChildren(bool relayoutChildren, LayoutUnit& paintInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUnit afterEdge);
+    void layoutInlineChildren(bool relayoutChildren, LayoutUnit afterEdge);
     void addLowestFloatFromChildren(LayoutBlockFlow*);
 
     void createFloatingObjects();
@@ -379,7 +379,6 @@
     bool hitTestFloats(HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
 
     void invalidatePaintForOverhangingFloats(bool paintAllDescendants) final;
-    void invalidatePaintForOverflow() final;
     void invalidateDisplayItemClients(PaintInvalidationReason) const override;
 
     void clearFloats(EClear);
@@ -609,9 +608,6 @@
 
     LayoutBlockFlowRareData& ensureRareData();
 
-    LayoutUnit m_paintInvalidationLogicalTop;
-    LayoutUnit m_paintInvalidationLogicalBottom;
-
     bool isSelfCollapsingBlock() const override;
     bool checkIfIsSelfCollapsingBlock() const;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index 67ae6798..f8daa687 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -739,7 +739,6 @@
 {
     RootInlineBox* boxToDelete = startLine;
     while (boxToDelete && boxToDelete != stopLine) {
-        layoutState.updatePaintInvalidationRangeFromBox(boxToDelete);
         // Note: deleteLineRange(firstRootBox()) is not identical to deleteLineBoxTree().
         // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing.
         RootInlineBox* next = boxToDelete->nextRootBox();
@@ -764,11 +763,8 @@
     if (!layoutState.isFullLayout() && startLine)
         determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBidiStatus);
 
-    if (startLine) {
-        if (!layoutState.usesPaintInvalidationBounds())
-            layoutState.setPaintInvalidationRange(logicalHeight());
+    if (startLine)
         deleteLineRange(layoutState, startLine);
-    }
 
     layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineBidiStatus);
     linkToEndLineIfNeeded(layoutState);
@@ -908,9 +904,6 @@
 
             if (lineBox) {
                 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLine.offset(), resolver.status());
-                if (layoutState.usesPaintInvalidationBounds())
-                    layoutState.updatePaintInvalidationRangeFromBox(lineBox);
-
                 if (paginated) {
                     if (paginationStrutFromDeletedLine) {
                         // This is a line that got re-created because it got pushed to the next fragmentainer, and there
@@ -925,9 +918,6 @@
                         if (adjustment) {
                             LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIndentText);
                             lineBox->moveInBlockDirection(adjustment);
-                            if (layoutState.usesPaintInvalidationBounds())
-                                layoutState.updatePaintInvalidationRangeFromBox(lineBox);
-
                             if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText) != oldLineWidth) {
                                 // We have to delete this line, remove all floats that got added, and let line layout
                                 // re-run. We had just calculated the pagination strut for this line, and we need to
@@ -1047,10 +1037,8 @@
                     delta -= line->paginationStrut();
                     adjustLinePositionForPagination(*line, delta);
                 }
-                if (delta) {
-                    layoutState.updatePaintInvalidationRangeFromBox(line, delta);
+                if (delta)
                     line->moveInBlockDirection(delta);
-                }
                 if (Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr()) {
                     for (auto* box : *cleanLineFloats) {
                         FloatingObject* floatingObject = insertFloatingObject(*box);
@@ -1546,12 +1534,12 @@
     return objectToCheck->hasOverflowClip() && objectToCheck->style()->getTextOverflow();
 }
 
-void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& paintInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUnit afterEdge)
+void LayoutBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit afterEdge)
 {
     // Figure out if we should clear out our line boxes.
     // FIXME: Handle resize eventually!
     bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren;
-    LineLayoutState layoutState(isFullLayout, paintInvalidationLogicalTop, paintInvalidationLogicalBottom);
+    LineLayoutState layoutState(isFullLayout);
 
     if (isFullLayout) {
         // Ensure the old line boxes will be erased.
@@ -1661,8 +1649,6 @@
                         layoutState.markForFullLayout();
                         break;
                     }
-
-                    layoutState.updatePaintInvalidationRangeFromBox(curr, paginationDelta);
                     curr->moveInBlockDirection(paginationDelta);
                 }
             }
@@ -2068,11 +2054,11 @@
     return logicalLeft;
 }
 
-void LayoutBlockFlow::invalidateDisplayItemClientsOfFirstLine()
+void LayoutBlockFlow::setShouldDoFullPaintInvalidationForFirstLine()
 {
     ASSERT(childrenInline());
     if (RootInlineBox* firstRootBox = this->firstRootBox())
-        firstRootBox->invalidateDisplayItemClientsRecursively();
+        firstRootBox->setShouldDoFullPaintInvalidationRecursively();
 }
 
 PaintInvalidationReason LayoutBlockFlow::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState)
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 7998e9f4..28bbdac 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -1556,9 +1556,6 @@
 
     PaintInvalidationReason reason = LayoutBoxModelObject::invalidatePaintIfNeeded(paintInvalidationState);
 
-    if (!isFullPaintInvalidationReason(reason))
-        invalidatePaintForOverflowIfNeeded();
-
     if (PaintLayerScrollableArea* area = getScrollableArea())
         area->invalidatePaintOfScrollControlsIfNeeded(paintInvalidationState);
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 915e7e4..22334c6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -1552,16 +1552,6 @@
     invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, invalidationReason);
 }
 
-void LayoutObject::invalidatePaintForOverflow()
-{
-}
-
-void LayoutObject::invalidatePaintForOverflowIfNeeded()
-{
-    if (shouldInvalidateOverflowForPaint())
-        invalidatePaintForOverflow();
-}
-
 LayoutRect LayoutObject::absoluteClippedOverflowRect() const
 {
     LayoutRect rect = localOverflowRectForPaintInvalidation();
@@ -1838,13 +1828,8 @@
                     firstLineContainer = toLayoutBlockFlow(containingBlock());
             }
         }
-        if (firstLineContainer) {
-            firstLineContainer->invalidateDisplayItemClientsOfFirstLine();
-            // The following is for rect invalidation. For slimming paint v2, we can invalidate the rects
-            // of the first line display item clients instead of the whole rect of the container.
-            if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled())
-                firstLineContainer->setShouldDoFullPaintInvalidation();
-        }
+        if (firstLineContainer)
+            firstLineContainer->setShouldDoFullPaintInvalidationForFirstLine();
     }
     if (diff.needsLayout())
         setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange);
@@ -3431,7 +3416,6 @@
     clearShouldDoFullPaintInvalidation();
     m_bitfields.setChildShouldCheckForPaintInvalidation(false);
     m_bitfields.setNeededLayoutBecauseOfChildren(false);
-    m_bitfields.setShouldInvalidateOverflowForPaint(false);
     m_bitfields.setMayNeedPaintInvalidation(false);
     m_bitfields.setMayNeedPaintInvalidationSubtree(false);
     m_bitfields.setShouldInvalidateSelection(false);
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index 92b66c90f..f0135a7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -1124,13 +1124,6 @@
     // Walk the tree after layout issuing paint invalidations for layoutObjects that have changed or moved, updating bounds that have changed, and clearing paint invalidation state.
     virtual void invalidateTreeIfNeeded(const PaintInvalidationState&);
 
-    // This function only invalidates the visual overflow.
-    //
-    // Note that overflow is a box concept but this function
-    // is only supported for block-flow.
-    virtual void invalidatePaintForOverflow();
-    void invalidatePaintForOverflowIfNeeded();
-
     void invalidatePaintIncludingNonCompositingDescendants();
     void invalidatePaintIncludingNonSelfPaintingLayerDescendants(const LayoutBoxModelObject& paintInvalidationContainer);
     void setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
@@ -1341,8 +1334,6 @@
     void setShouldDoFullPaintInvalidation(PaintInvalidationReason = PaintInvalidationFull);
     void clearShouldDoFullPaintInvalidation() { m_bitfields.setFullPaintInvalidationReason(PaintInvalidationNone); }
 
-    bool shouldInvalidateOverflowForPaint() const { return m_bitfields.shouldInvalidateOverflowForPaint(); }
-
     virtual void clearPaintInvalidationFlags(const PaintInvalidationState&);
 
     bool mayNeedPaintInvalidation() const { return m_bitfields.mayNeedPaintInvalidation(); }
@@ -1592,7 +1583,6 @@
     void setIsBackgroundAttachmentFixedObject(bool);
 
     void clearSelfNeedsOverflowRecalcAfterStyleChange() { m_bitfields.setSelfNeedsOverflowRecalcAfterStyleChange(false); }
-    void setShouldInvalidateOverflowForPaint() { m_bitfields.setShouldInvalidateOverflowForPaint(true); }
     void setEverHadLayout() { m_bitfields.setEverHadLayout(true); }
 
     // Remove this object and all descendants from the containing LayoutFlowThread.
@@ -1735,7 +1725,6 @@
             , m_selfNeedsOverflowRecalcAfterStyleChange(false)
             , m_childNeedsOverflowRecalcAfterStyleChange(false)
             , m_preferredLogicalWidthsDirty(false)
-            , m_shouldInvalidateOverflowForPaint(false)
             , m_childShouldCheckForPaintInvalidation(false)
             , m_mayNeedPaintInvalidation(false)
             , m_mayNeedPaintInvalidationSubtree(false)
@@ -1774,7 +1763,7 @@
         {
         }
 
-        // 32 bits have been used in the first word, and 18 in the second.
+        // 32 bits have been used in the first word, and 17 in the second.
 
         // Self needs layout means that this layout object is marked for a full layout.
         // This is the default layout but it is expensive as it recomputes everything.
@@ -1822,7 +1811,6 @@
         // widths.
         ADD_BOOLEAN_BITFIELD(preferredLogicalWidthsDirty, PreferredLogicalWidthsDirty);
 
-        ADD_BOOLEAN_BITFIELD(shouldInvalidateOverflowForPaint, ShouldInvalidateOverflowForPaint); // TODO(wangxianzhu): Remove for slimming paint v2.
         ADD_BOOLEAN_BITFIELD(childShouldCheckForPaintInvalidation, ChildShouldCheckForPaintInvalidation);
         ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidation, MayNeedPaintInvalidation);
         ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidationSubtree, MayNeedPaintInvalidationSubtree);
@@ -1949,7 +1937,6 @@
     void setPosChildNeedsLayout(bool b) { m_bitfields.setPosChildNeedsLayout(b); }
     void setNeedsSimplifiedNormalFlowLayout(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); }
     void setIsDragging(bool b) { m_bitfields.setIsDragging(b); }
-    void clearShouldInvalidateOverflowForPaint() { m_bitfields.setShouldInvalidateOverflowForPaint(false); }
     void setSelfNeedsOverflowRecalcAfterStyleChange() { m_bitfields.setSelfNeedsOverflowRecalcAfterStyleChange(true); }
     void setChildNeedsOverflowRecalcAfterStyleChange() { m_bitfields.setChildNeedsOverflowRecalcAfterStyleChange(true); }
 
diff --git a/third_party/WebKit/Source/core/layout/api/LineLayoutItem.h b/third_party/WebKit/Source/core/layout/api/LineLayoutItem.h
index adf009b..46c7fe7 100644
--- a/third_party/WebKit/Source/core/layout/api/LineLayoutItem.h
+++ b/third_party/WebKit/Source/core/layout/api/LineLayoutItem.h
@@ -420,11 +420,6 @@
         return m_layoutObject->documentBeingDestroyed();
     }
 
-    void slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(const DisplayItemClient& displayItemClient, PaintInvalidationReason reason)
-    {
-        return m_layoutObject->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(displayItemClient, reason);
-    }
-
     LayoutRect visualRect() const
     {
         return m_layoutObject->visualRect();
@@ -435,6 +430,11 @@
         return m_layoutObject == kHashTableDeletedValue;
     }
 
+    void setShouldDoFullPaintInvalidation()
+    {
+        m_layoutObject->setShouldDoFullPaintInvalidation();
+    }
+
     struct LineLayoutItemHash {
         STATIC_ONLY(LineLayoutItemHash);
         static unsigned hash(const LineLayoutItem& key) { return WTF::PtrHash<LayoutObject>::hash(key.m_layoutObject); }
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
index 93f1113..777d218 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
@@ -65,9 +65,17 @@
 {
     // We do not need to issue invalidations if the page is being destroyed
     // since these objects will never be repainted.
-    // TODO(crbug.com/619630): Make this fast.
-    if (!m_lineLayoutItem.documentBeingDestroyed())
-        m_lineLayoutItem.slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*this, PaintInvalidationFull);
+    if (!m_lineLayoutItem.documentBeingDestroyed()) {
+        setLineLayoutItemShouldDoFullPaintInvalidationIfNeeded();
+
+#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+        // This object may have display items in a cached subsequence, but we are
+        // sure that the subsequence will be invalidated because m_lineLayoutItem has
+        // been setShouldFullPaintInvalidation(), so deletion of this object is safe.
+        endShouldKeepAlive();
+#endif
+    }
+
     delete this;
 }
 
@@ -214,6 +222,8 @@
 
     if (getLineLayoutItem().isAtomicInlineLevel())
         LineLayoutBox(getLineLayoutItem()).move(delta.width(), delta.height());
+
+    setLineLayoutItemShouldDoFullPaintInvalidationIfNeeded();
 }
 
 void InlineBox::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /* lineTop */, LayoutUnit /* lineBottom */) const
@@ -383,14 +393,21 @@
     return root().block().flipForWritingMode(point);
 }
 
-void InlineBox::invalidateDisplayItemClientsRecursively()
+void InlineBox::setShouldDoFullPaintInvalidationRecursively()
 {
-    // TODO(crbug.com/619630): Make this fast.
-    getLineLayoutItem().slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*this, PaintInvalidationFull);
+    getLineLayoutItem().setShouldDoFullPaintInvalidation();
     if (!isInlineFlowBox())
         return;
     for (InlineBox* child = toInlineFlowBox(this)->firstChild(); child; child = child->nextOnLine())
-        child->invalidateDisplayItemClientsRecursively();
+        child->setShouldDoFullPaintInvalidationRecursively();
+}
+
+void InlineBox::setLineLayoutItemShouldDoFullPaintInvalidationIfNeeded()
+{
+    // For RootInlineBox, we only need to invalidate if it's using the first line style.
+    // otherwise it paints nothing so we don't need to invalidate it.
+    if (!isRootInlineBox() || isFirstLineStyle())
+        m_lineLayoutItem.setShouldDoFullPaintInvalidation();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.h b/third_party/WebKit/Source/core/layout/line/InlineBox.h
index 3ffc5cf..6d7f6f6d 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.h
@@ -301,8 +301,8 @@
     bool dirOverride() const { return m_bitfields.dirOverride(); }
     void setDirOverride(bool dirOverride) { m_bitfields.setDirOverride(dirOverride); }
 
-    // Invalidate display item clients in the whole sub inline box tree.
-    void invalidateDisplayItemClientsRecursively();
+    // Set all LineLayoutItems in the inline box subtree should do full paint invalidation.
+    void setShouldDoFullPaintInvalidationRecursively();
 
 #define ADD_BOOLEAN_BITFIELD(name, Name) \
     private:\
@@ -395,6 +395,8 @@
     // containing block. The size indicates the size of the box whose point is being flipped.
     LayoutPoint logicalPositionToPhysicalPoint(const LayoutPoint&, const LayoutSize&) const;
 
+    void setLineLayoutItemShouldDoFullPaintInvalidationIfNeeded();
+
     InlineBox* m_next; // The next element on the same line as us.
     InlineBox* m_prev; // The previous element on the same line as us.
 
diff --git a/third_party/WebKit/Source/core/layout/line/LineLayoutState.h b/third_party/WebKit/Source/core/layout/line/LineLayoutState.h
index 1c27fd3..e4ba33cf 100644
--- a/third_party/WebKit/Source/core/layout/line/LineLayoutState.h
+++ b/third_party/WebKit/Source/core/layout/line/LineLayoutState.h
@@ -35,36 +35,18 @@
 class LineLayoutState {
     STACK_ALLOCATED();
 public:
-    LineLayoutState(bool fullLayout, LayoutUnit& paintInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom)
+    LineLayoutState(bool fullLayout)
         : m_lastFloat(nullptr)
         , m_endLine(nullptr)
         , m_floatIndex(0)
         , m_endLineMatched(false)
         , m_hasInlineChild(false)
         , m_isFullLayout(fullLayout)
-        , m_paintInvalidationLogicalTop(paintInvalidationLogicalTop)
-        , m_paintInvalidationLogicalBottom(paintInvalidationLogicalBottom)
-        , m_usesPaintInvalidationBounds(false)
     { }
 
     void markForFullLayout() { m_isFullLayout = true; }
     bool isFullLayout() const { return m_isFullLayout; }
 
-    bool usesPaintInvalidationBounds() const { return m_usesPaintInvalidationBounds; }
-
-    void setPaintInvalidationRange(LayoutUnit logicalHeight)
-    {
-        m_usesPaintInvalidationBounds = true;
-        m_paintInvalidationLogicalTop = m_paintInvalidationLogicalBottom = logicalHeight;
-    }
-
-    void updatePaintInvalidationRangeFromBox(RootInlineBox* box, LayoutUnit paginationDelta = LayoutUnit())
-    {
-        m_usesPaintInvalidationBounds = true;
-        m_paintInvalidationLogicalTop = std::min(m_paintInvalidationLogicalTop, box->logicalTopVisualOverflow() + paginationDelta.clampPositiveToZero());
-        m_paintInvalidationLogicalBottom = std::max(m_paintInvalidationLogicalBottom, box->logicalBottomVisualOverflow() + paginationDelta.clampNegativeToZero());
-    }
-
     bool endLineMatched() const { return m_endLineMatched; }
     void setEndLineMatched(bool endLineMatched) { m_endLineMatched = endLineMatched; }
 
@@ -106,13 +88,7 @@
 
     bool m_isFullLayout;
 
-    // FIXME: Should this be a range object instead of two ints?
-    LayoutUnit& m_paintInvalidationLogicalTop;
-    LayoutUnit& m_paintInvalidationLogicalBottom;
-
     LayoutUnit m_adjustedLogicalLineTop;
-
-    bool m_usesPaintInvalidationBounds;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
index 838f43c..1a1502e8b 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
@@ -247,9 +247,7 @@
     setLogicalHeight(beforeEdge);
 
     LayoutState state(*this, locationOffset());
-    LayoutUnit paintInvalidationLogicalTop;
-    LayoutUnit paintInvalidationLogicalBottom;
-    layoutInlineChildren(true, paintInvalidationLogicalTop, paintInvalidationLogicalBottom, afterEdge);
+    layoutInlineChildren(true, afterEdge);
 
     m_needsReordering = false;
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp
index 1e196f2..a7da630 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp
@@ -58,6 +58,14 @@
         addResult.storedValue->value = debugName();
 }
 
+void DisplayItemClient::endShouldKeepAlive() const
+{
+    if (displayItemClientsShouldKeepAlive) {
+        for (auto item : *displayItemClientsShouldKeepAlive)
+            item.value.remove(this);
+    }
+}
+
 void DisplayItemClient::endShouldKeepAliveAllClients(const void* owner)
 {
     if (displayItemClientsShouldKeepAlive)
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h
index 383c57c..4d634751f 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h
@@ -63,9 +63,15 @@
 
     // Tests if this DisplayItemClient object has been created and has not been deleted yet.
     bool isAlive() const;
+
     // Called when any DisplayItem of this DisplayItemClient is added into PaintController
     // using PaintController::createAndAppend() or into a cached subsequence.
     void beginShouldKeepAlive(const void* owner) const;
+
+    // Called when the DisplayItemClient is sure that it can safely die before its owners
+    // have chance to remove it from the aliveness control.
+    void endShouldKeepAlive() const;
+
     // Clears all should-keep-alive DisplayItemClients of a PaintController. Called after
     // PaintController commits new display items or the subsequence owner is invalidated.
     static void endShouldKeepAliveAllClients(const void* owner);