Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Unified Diff: Source/core/rendering/RenderBox.cpp

Issue 399173005: Incrementally invalidate boxes with borders if possible (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698