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

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: Created 6 years, 4 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
« no previous file with comments | « Source/core/rendering/RenderBox.h ('k') | Source/core/rendering/RenderObject.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/RenderBox.cpp
diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
index d722af5d84f9c9cd6a3c06dfa6c90b7b7d5cbc18..469d6b4bf5fb6c49f573c44cb5063e1072f74e1d 100644
--- a/Source/core/rendering/RenderBox.cpp
+++ b/Source/core/rendering/RenderBox.cpp
@@ -4074,32 +4074,84 @@ 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 = computePreviousBorderBoxSize(oldBounds.size());
LayoutSize newBorderBoxSize = size();
if (oldBorderBoxSize == newBorderBoxSize)
return invalidationReason;
+ // FIXME: Implement correct incremental invalidation for visual overflowing effects.
+ if (style()->hasVisualOverflowingEffect() || style()->hasAppearance() || style()->hasFilter())
+ return InvalidationBorderBoxChange;
+
+ if (style()->hasBorderRadius()) {
+ // If a border-radius exists and width/height is smaller than radius width/height,
+ // we need to fully invalidate to cover the changed radius.
+ 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;
+ return InvalidationIncremental;
+}
+
+void RenderBox::incrementallyInvalidatePaint(const RenderLayerModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationContainer)
+{
+ RenderObject::incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newBounds, positionFromPaintInvalidationContainer);
+
+ bool hasBoxDecorations = style()->hasBoxDecorations();
+ if (!style()->hasBackground() && !hasBoxDecorations)
+ return;
+
+ LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldBounds.size());
+ LayoutSize newBorderBoxSize = size();
+
+ // If border box size didn't change, RenderBox's incrementallyInvalidatePaint() is good.
+ if (oldBorderBoxSize == newBorderBoxSize)
+ return;
+
// If size of the paint invalidation rect equals to size of 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())
+ return;
- // FIXME: Since we have accurate old border box size, we could do more accurate
- // incremental invalidation instead of full invalidation.
- return InvalidationBorderBoxChange;
+ // 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());
+ 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);
+ }
+
+ // 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)
@@ -4693,6 +4745,18 @@ void RenderBox::savePreviousBorderBoxSizeIfNeeded()
ensureRareData().m_previousBorderBoxSize = size();
}
+LayoutSize RenderBox::computePreviousBorderBoxSize(const LayoutSize& previousBoundsSize) 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 previousBoundsSize;
+}
+
RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style)
{
backgroundColor = style.visitedDependentColor(CSSPropertyBackgroundColor);
« no previous file with comments | « Source/core/rendering/RenderBox.h ('k') | Source/core/rendering/RenderObject.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698