| Index: third_party/WebKit/Source/core/layout/LayoutTableCell.cpp | 
| diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp | 
| index e848406e9c08bd638c657f048cb429d0ce0d878c..b842de0d1adf12959601e2381e614de54c9f9d27 100644 | 
| --- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp | 
| +++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp | 
| @@ -64,6 +64,34 @@ | 
| // colSpanOrRowSpanChanged() so we need to set their initial values here in | 
| // case something asks for colSpan()/rowSpan() before then. | 
| updateColAndRowSpanFlags(); | 
| +} | 
| + | 
| +LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( | 
| +    const LayoutTable& layoutTable, | 
| +    const CollapsedBorderValue& startBorder, | 
| +    const CollapsedBorderValue& endBorder, | 
| +    const CollapsedBorderValue& beforeBorder, | 
| +    const CollapsedBorderValue& afterBorder) | 
| +    : m_layoutTable(layoutTable), | 
| +      m_startBorder(startBorder), | 
| +      m_endBorder(endBorder), | 
| +      m_beforeBorder(beforeBorder), | 
| +      m_afterBorder(afterBorder) {} | 
| + | 
| +void LayoutTableCell::CollapsedBorderValues::setCollapsedBorderValues( | 
| +    const CollapsedBorderValues& other) { | 
| +  m_startBorder = other.startBorder(); | 
| +  m_endBorder = other.endBorder(); | 
| +  m_beforeBorder = other.beforeBorder(); | 
| +  m_afterBorder = other.afterBorder(); | 
| +} | 
| + | 
| +String LayoutTableCell::CollapsedBorderValues::debugName() const { | 
| +  return "CollapsedBorderValues"; | 
| +} | 
| + | 
| +LayoutRect LayoutTableCell::CollapsedBorderValues::visualRect() const { | 
| +  return m_layoutTable.visualRect(); | 
| } | 
|  | 
| void LayoutTableCell::willBeRemovedFromTree() { | 
| @@ -1252,7 +1280,7 @@ | 
| TableCellPainter(*this).paint(paintInfo, paintOffset); | 
| } | 
|  | 
| -static void addBorderStyle(Vector<CollapsedBorderValue>& borderValues, | 
| +static void addBorderStyle(LayoutTable::CollapsedBorderValues& borderValues, | 
| CollapsedBorderValue borderValue) { | 
| if (!borderValue.isVisible()) | 
| return; | 
| @@ -1264,45 +1292,56 @@ | 
| borderValues.append(borderValue); | 
| } | 
|  | 
| -bool LayoutTableCell::collectBorderValues( | 
| -    Vector<CollapsedBorderValue>& borderValues) { | 
| -  CollapsedBorderValues newValues = { | 
| -      computeCollapsedStartBorder(), computeCollapsedEndBorder(), | 
| -      computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()}; | 
| +void LayoutTableCell::collectBorderValues( | 
| +    LayoutTable::CollapsedBorderValues& borderValues) { | 
| +  CollapsedBorderValues newValues( | 
| +      *table(), computeCollapsedStartBorder(), computeCollapsedEndBorder(), | 
| +      computeCollapsedBeforeBorder(), computeCollapsedAfterBorder()); | 
|  | 
| bool changed = false; | 
| -  if (!newValues.startBorder.isVisible() && !newValues.endBorder.isVisible() && | 
| -      !newValues.beforeBorder.isVisible() && | 
| -      !newValues.afterBorder.isVisible()) { | 
| +  if (!newValues.startBorder().isVisible() && | 
| +      !newValues.endBorder().isVisible() && | 
| +      !newValues.beforeBorder().isVisible() && | 
| +      !newValues.afterBorder().isVisible()) { | 
| changed = !!m_collapsedBorderValues; | 
| m_collapsedBorderValues = nullptr; | 
| } else if (!m_collapsedBorderValues) { | 
| changed = true; | 
| -    m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues(newValues)); | 
| +    m_collapsedBorderValues = wrapUnique(new CollapsedBorderValues( | 
| +        *table(), newValues.startBorder(), newValues.endBorder(), | 
| +        newValues.beforeBorder(), newValues.afterBorder())); | 
| } else { | 
| // We check visuallyEquals so that the table cell is invalidated only if a | 
| // changed collapsed border is visible in the first place. | 
| -    changed = !m_collapsedBorderValues->startBorder.visuallyEquals( | 
| -                  newValues.startBorder) || | 
| -              !m_collapsedBorderValues->endBorder.visuallyEquals( | 
| -                  newValues.endBorder) || | 
| -              !m_collapsedBorderValues->beforeBorder.visuallyEquals( | 
| -                  newValues.beforeBorder) || | 
| -              !m_collapsedBorderValues->afterBorder.visuallyEquals( | 
| -                  newValues.afterBorder); | 
| +    changed = !m_collapsedBorderValues->startBorder().visuallyEquals( | 
| +                  newValues.startBorder()) || | 
| +              !m_collapsedBorderValues->endBorder().visuallyEquals( | 
| +                  newValues.endBorder()) || | 
| +              !m_collapsedBorderValues->beforeBorder().visuallyEquals( | 
| +                  newValues.beforeBorder()) || | 
| +              !m_collapsedBorderValues->afterBorder().visuallyEquals( | 
| +                  newValues.afterBorder()); | 
| if (changed) | 
| -      *m_collapsedBorderValues = newValues; | 
| -  } | 
| - | 
| -  addBorderStyle(borderValues, newValues.startBorder); | 
| -  addBorderStyle(borderValues, newValues.endBorder); | 
| -  addBorderStyle(borderValues, newValues.beforeBorder); | 
| -  addBorderStyle(borderValues, newValues.afterBorder); | 
| -  return changed; | 
| +      m_collapsedBorderValues->setCollapsedBorderValues(newValues); | 
| +  } | 
| + | 
| +  // If collapsed borders changed, invalidate the cell's display item client on | 
| +  // the table's backing. | 
| +  // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders | 
| +  // only. | 
| +  if (changed) | 
| +    ObjectPaintInvalidator(*table()) | 
| +        .slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient( | 
| +            *this, PaintInvalidationStyleChange); | 
| + | 
| +  addBorderStyle(borderValues, newValues.startBorder()); | 
| +  addBorderStyle(borderValues, newValues.endBorder()); | 
| +  addBorderStyle(borderValues, newValues.beforeBorder()); | 
| +  addBorderStyle(borderValues, newValues.afterBorder()); | 
| } | 
|  | 
| void LayoutTableCell::sortBorderValues( | 
| -    Vector<CollapsedBorderValue>& borderValues) { | 
| +    LayoutTable::CollapsedBorderValues& borderValues) { | 
| std::sort(borderValues.begin(), borderValues.end(), compareBorders); | 
| } | 
|  | 
| @@ -1377,6 +1416,23 @@ | 
| return LayoutBlockFlow::backgroundIsKnownToBeOpaqueInRect(localRect); | 
| } | 
|  | 
| +bool LayoutTableCell::usesTableAsAdditionalDisplayItemClient() const { | 
| +  // In certain cases such as collapsed borders for composited table cells we | 
| +  // paint content for the cell into the table graphics layer backing and so | 
| +  // must use the table's visual rect. | 
| +  return (hasLayer() && layer()->compositingState() != NotComposited) || | 
| +         RuntimeEnabledFeatures::slimmingPaintV2Enabled(); | 
| +} | 
| + | 
| +void LayoutTableCell::invalidateDisplayItemClients( | 
| +    PaintInvalidationReason reason) const { | 
| +  if (m_collapsedBorderValues && usesTableAsAdditionalDisplayItemClient()) { | 
| +    ObjectPaintInvalidator(*this).invalidateDisplayItemClient( | 
| +        *m_collapsedBorderValues, reason); | 
| +  } | 
| +  LayoutBlockFlow::invalidateDisplayItemClients(reason); | 
| +} | 
| + | 
| // TODO(lunalu): Deliberately dump the "inner" box of table cells, since that | 
| // is what current results reflect.  We'd like to clean up the results to dump | 
| // both the outer box and the intrinsic padding so that both bits of information | 
|  |