Chromium Code Reviews| Index: Source/core/rendering/RenderBox.cpp |
| diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp |
| index 9fbbb8b7a364b3f66cce6f67fb94f2afd0f1b294..03af0e2183abe6edd1207e1e05d2288b30078ec3 100644 |
| --- a/Source/core/rendering/RenderBox.cpp |
| +++ b/Source/core/rendering/RenderBox.cpp |
| @@ -4070,32 +4070,82 @@ InvalidationReason RenderBox::getPaintInvalidationReason(const RenderLayerModelO |
| if (!style()->hasBackground() && !style()->hasBoxDecorations()) |
| return invalidationReason; |
| - LayoutSize oldBorderBoxSize; |
| - if (m_rareData && m_rareData->m_previousBorderBoxSize.width() != -1) { |
| - oldBorderBoxSize = m_rareData->m_previousBorderBoxSize; |
| - } else { |
| - // We didn't save the old border box size because it was the same as the size of oldBounds. |
| - oldBorderBoxSize = oldBounds.size(); |
| - } |
| - |
| + LayoutSize oldBorderBoxSize = getPreviousBorderBoxSize(oldBounds.size()); |
| LayoutSize newBorderBoxSize = size(); |
| if (oldBorderBoxSize == newBorderBoxSize) |
| return invalidationReason; |
| + // FIXME: Implement correct incremental invalidation for visual overflowing effects. |
| + if (style()->hasVisualOverflowingEffect() || style()->hasAppearance()) |
| + return InvalidationBorderBoxChange; |
| + |
| + if (style()->hasBorderRadius()) { |
| + // If a border-radius exists and width/height is smaller than |
| + // radius width/height, we cannot use incremental invalidation. |
|
esprehn
2014/08/19 01:59:12
Why is this?
Xianzhu
2014/08/19 16:06:19
Modified comments to state the reason.
|
| + RoundedRect oldRoundedRect = style()->getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), oldBorderBoxSize)); |
| + RoundedRect newRoundedRect = style()->getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), newBorderBoxSize)); |
| + if (oldRoundedRect.radii() != newRoundedRect.radii()) |
| + return InvalidationBorderBoxChange; |
| + } |
| + |
| if (oldBorderBoxSize.width() != newBorderBoxSize.width() && mustInvalidateBackgroundOrBorderPaintOnWidthChange()) |
| return InvalidationBorderBoxChange; |
| if (oldBorderBoxSize.height() != newBorderBoxSize.height() && mustInvalidateBackgroundOrBorderPaintOnHeightChange()) |
| return InvalidationBorderBoxChange; |
| - // If size of repaint rect equals to size of border box, RenderObject::incrementallyInvalidatePaint() |
| + return InvalidationIncremental; |
| +} |
| + |
| +void RenderBox::incrementallyInvalidatePaint(const RenderLayerModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationContainer) |
| +{ |
| + RenderObject::incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newBounds, positionFromPaintInvalidationContainer); |
| + |
| + LayoutSize oldBorderBoxSize = getPreviousBorderBoxSize(oldBounds.size()); |
| + LayoutSize newBorderBoxSize = size(); |
| + |
| + bool hasBoxDecorations = style()->hasBoxDecorations(); |
| + if (!style()->hasBackground() && !hasBoxDecorations) |
| + return; |
| + |
| + // If border box size didn't change, RenderBox's incrementallyInvalidatePaint() is good. |
| + if (oldBorderBoxSize == newBorderBoxSize) |
| + return; |
| + |
| + // If repaint rect equals border box, RenderObject::incrementallyInvalidatePaint() |
| // is good for boxes having background without box decorations. |
| - if (oldBorderBoxSize == oldBounds.size() && newBorderBoxSize == newBounds.size() && !style()->hasBoxDecorations()) |
| - return invalidationReason; |
| + ASSERT(oldBounds.location() == newBounds.location()); // Otherwise we won't do incremental invalidation. |
| + if (!hasBoxDecorations && positionFromPaintInvalidationContainer == newBounds.location() |
| + && oldBorderBoxSize == oldBounds.size() && newBorderBoxSize == newBounds.size()) |
|
esprehn
2014/08/19 01:59:12
one statement per line might make this easier to r
Xianzhu
2014/08/19 16:06:19
Done.
|
| + return; |
| + |
| + // Invalidate the right delta part and the right border of the old or new box which has smaller width. |
| + LayoutUnit deltaWidth = absoluteValue(oldBorderBoxSize.width() - newBorderBoxSize.width()); |
|
esprehn
2014/08/19 01:59:12
= not () for initialization, it's nice to be consi
Xianzhu
2014/08/19 16:06:19
'=' is used in most cases except that the construc
|
| + if (deltaWidth) { |
| + LayoutUnit smallerWidth = std::min(oldBorderBoxSize.width(), newBorderBoxSize.width()); |
| + LayoutUnit borderTopRightRadiusWidth = valueForLength(style()->borderTopRightRadius().width(), smallerWidth); |
| + LayoutUnit borderBottomRightRadiusWidth = valueForLength(style()->borderBottomRightRadius().width(), smallerWidth); |
| + LayoutUnit borderWidth = std::max<LayoutUnit>(borderRight(), std::max(borderTopRightRadiusWidth, borderBottomRightRadiusWidth)); |
| + LayoutRect rightDeltaRect(positionFromPaintInvalidationContainer.x() + smallerWidth - borderWidth, |
| + positionFromPaintInvalidationContainer.y(), |
| + deltaWidth + borderWidth, |
| + std::max(oldBorderBoxSize.height(), newBorderBoxSize.height())); |
| + invalidatePaintUsingContainer(&paintInvalidationContainer, rightDeltaRect, InvalidationIncremental); |
| + } |
| - // FIXME: Since we have accurate old border box size, we could do more accurate |
| - // incremental invalidation instead of full invalidation. |
| - return InvalidationBorderBoxChange; |
| + // Invalidate the bottom delta part and the bottom border of the old or new box which has smaller height. |
| + LayoutUnit deltaHeight = absoluteValue(oldBorderBoxSize.height() - newBorderBoxSize.height()); |
| + if (deltaHeight) { |
| + LayoutUnit smallerHeight = std::min(oldBorderBoxSize.height(), newBorderBoxSize.height()); |
| + LayoutUnit borderBottomLeftRadiusHeight = valueForLength(style()->borderBottomLeftRadius().height(), smallerHeight); |
| + LayoutUnit borderBottomRightRadiusHeight = valueForLength(style()->borderBottomRightRadius().height(), smallerHeight); |
| + LayoutUnit borderHeight = std::max<LayoutUnit>(borderBottom(), std::max(borderBottomLeftRadiusHeight, borderBottomRightRadiusHeight)); |
| + LayoutRect bottomDeltaRect(positionFromPaintInvalidationContainer.x(), |
| + positionFromPaintInvalidationContainer.y() + smallerHeight - borderHeight, |
| + std::max(oldBorderBoxSize.width(), newBorderBoxSize.width()), |
| + deltaHeight + borderHeight); |
| + invalidatePaintUsingContainer(&paintInvalidationContainer, bottomDeltaRect, InvalidationIncremental); |
| + } |
| } |
| void RenderBox::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope) |
| @@ -4676,6 +4726,18 @@ void RenderBox::savePreviousBorderBoxSizeIfNeeded() |
| ensureRareData().m_previousBorderBoxSize = size(); |
| } |
| +LayoutSize RenderBox::getPreviousBorderBoxSize(const LayoutSize& oldBoundsSize) const |
| +{ |
| + // PreviousBorderBoxSize is only valid when there is background or box decorations. |
| + ASSERT(style()->hasBackground() || style()->hasBoxDecorations()); |
| + |
| + if (m_rareData && m_rareData->m_previousBorderBoxSize.width() != -1) |
| + return m_rareData->m_previousBorderBoxSize; |
| + |
| + // We didn't save the old border box size because it was the same as the size of oldBounds. |
| + return oldBoundsSize; |
| +} |
| + |
| RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style) |
| { |
| backgroundColor = style.visitedDependentColor(CSSPropertyBackgroundColor); |