| 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 24d98a156c6b544941baf096995a507a95086c43..e8195e90beb6ba30acf91563244f9fd807b29af2 100644 | 
| --- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp | 
| +++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp | 
| @@ -67,6 +67,34 @@ | 
| 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() { | 
| LayoutBlockFlow::willBeRemovedFromTree(); | 
|  | 
| @@ -472,7 +500,7 @@ | 
| return; | 
| if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && | 
| oldStyle && oldStyle->border() != style()->border()) | 
| -    table->invalidateCollapsedBorders(PaintInvalidationStyleChange); | 
| +    table->invalidateCollapsedBorders(); | 
|  | 
| if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, | 
| *oldStyle)) { | 
| @@ -1275,7 +1303,7 @@ | 
| TableCellPainter(*this).paint(paintInfo, paintOffset); | 
| } | 
|  | 
| -static void addBorderStyle(Vector<CollapsedBorderValue>& borderValues, | 
| +static void addBorderStyle(LayoutTable::CollapsedBorderValues& borderValues, | 
| CollapsedBorderValue borderValue) { | 
| if (!borderValue.isVisible()) | 
| return; | 
| @@ -1287,34 +1315,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.allBordersAreInvisible()) { | 
| +  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 { | 
| -    changed = !m_collapsedBorderValues->bordersVisuallyEqual(newValues); | 
| +    // 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()); | 
| 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); | 
| } | 
|  | 
| @@ -1409,6 +1459,8 @@ | 
| return; | 
|  | 
| ObjectPaintInvalidator invalidator(*this); | 
| +  if (m_collapsedBorderValues) | 
| +    invalidator.invalidateDisplayItemClient(*m_collapsedBorderValues, reason); | 
| if (m_rowBackgroundDisplayItemClient) { | 
| invalidator.invalidateDisplayItemClient(*m_rowBackgroundDisplayItemClient, | 
| reason); | 
|  |