Index: third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp |
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp |
index 9b3e8de3fda26c2bb1947877dc405341a5772b82..41268c4f9dbaeff129b44be65d375e48a28d7471 100644 |
--- a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp |
+++ b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp |
@@ -30,7 +30,7 @@ void ObjectPaintInvalidator::objectWillBeDestroyed(const LayoutObject& object) |
selectionPaintInvalidationMap().remove(&object); |
} |
-void ObjectPaintInvalidator::incrementallyInvalidatePaint() |
+bool ObjectPaintInvalidator::incrementallyInvalidatePaint() |
{ |
const LayoutRect& oldBounds = m_context.oldBounds; |
const LayoutRect& newBounds = m_context.newBounds; |
@@ -38,6 +38,10 @@ void ObjectPaintInvalidator::incrementallyInvalidatePaint() |
DCHECK(oldBounds.location() == newBounds.location()); |
LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); |
+ LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); |
+ if (!deltaRight && !deltaBottom) |
+ return false; |
+ |
if (deltaRight > 0) { |
LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()); |
m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
@@ -46,7 +50,6 @@ void ObjectPaintInvalidator::incrementallyInvalidatePaint() |
m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
} |
- LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); |
if (deltaBottom > 0) { |
LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom); |
m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
@@ -54,6 +57,8 @@ void ObjectPaintInvalidator::incrementallyInvalidatePaint() |
LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom); |
m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
} |
+ |
+ return true; |
} |
void ObjectPaintInvalidator::fullyInvalidatePaint(PaintInvalidationReason reason, const LayoutRect& oldBounds, const LayoutRect& newBounds) |
@@ -86,10 +91,13 @@ PaintInvalidationReason ObjectPaintInvalidator::computePaintInvalidationReason() |
if (m_object.shouldDoFullPaintInvalidation()) |
return m_object.fullPaintInvalidationReason(); |
+ if (m_context.oldBounds.isEmpty() && m_context.newBounds.isEmpty()) |
+ return PaintInvalidationNone; |
+ |
if (backgroundObscurationChanged) |
return PaintInvalidationBackgroundObscurationChange; |
- if (m_object.paintedOutputOfObjectHasNoEffect()) |
+ if (m_object.paintedOutputOfObjectHasNoEffectRegardlessOfSize()) |
return PaintInvalidationNone; |
const ComputedStyle& style = m_object.styleRef(); |
@@ -104,14 +112,12 @@ PaintInvalidationReason ObjectPaintInvalidator::computePaintInvalidationReason() |
bool locationChanged = m_context.newLocation != m_context.oldLocation; |
// If the bounds are the same then we know that none of the statements below |
- // can match, so we can early out. |
+ // can match, so we can early out. However, we can't return PaintInvalidationNone even if |
+ // !locationChagned, but conservatively return PaintInvalidationIncremental because we are |
+ // not sure whether paint invalidation is actually needed just based on information known |
+ // to LayoutObject. For example, a LayoutBox may need paint invalidation if border box changes. |
if (m_context.oldBounds == m_context.newBounds) |
- return locationChanged && !m_context.oldBounds.isEmpty() ? PaintInvalidationLocationChange : PaintInvalidationNone; |
- |
- // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could |
- // be caused by some layout property (left / top) or some in-flow layoutObject inserted / removed before us in the tree. |
- if (m_context.newBounds.location() != m_context.oldBounds.location()) |
- return PaintInvalidationBoundsChange; |
+ return locationChanged ? PaintInvalidationLocationChange : PaintInvalidationIncremental; |
// If the size is zero on one of our bounds then we know we're going to have |
// to do a full invalidation of either old bounds or new bounds. |
@@ -120,6 +126,11 @@ PaintInvalidationReason ObjectPaintInvalidator::computePaintInvalidationReason() |
if (m_context.newBounds.isEmpty()) |
return PaintInvalidationBecameInvisible; |
+ // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could |
+ // be caused by some layout property (left / top) or some in-flow layoutObject inserted / removed before us in the tree. |
+ if (m_context.newBounds.location() != m_context.oldBounds.location()) |
+ return PaintInvalidationBoundsChange; |
+ |
if (locationChanged) |
return PaintInvalidationLocationChange; |
@@ -131,7 +142,7 @@ void ObjectPaintInvalidator::invalidateSelectionIfNeeded(PaintInvalidationReason |
// Update selection rect when we are doing full invalidation (in case that the object is moved, |
// composite status changed, etc.) or shouldInvalidationSelection is set (in case that the |
// selection itself changed). |
- bool fullInvalidation = isFullPaintInvalidationReason(reason); |
+ bool fullInvalidation = isImmediateFullPaintInvalidationReason(reason); |
if (!fullInvalidation && !m_object.shouldInvalidateSelection()) |
return; |
@@ -157,6 +168,9 @@ PaintInvalidationReason ObjectPaintInvalidator::invalidatePaintIfNeededWithCompu |
// This is because we need to update the previous selection rect regardless. |
invalidateSelectionIfNeeded(reason); |
+ if (reason == PaintInvalidationIncremental && !incrementallyInvalidatePaint()) |
+ reason = PaintInvalidationNone; |
+ |
switch (reason) { |
case PaintInvalidationNone: |
// TODO(trchen): Currently we don't keep track of paint offset of layout objects. |
@@ -170,12 +184,11 @@ PaintInvalidationReason ObjectPaintInvalidator::invalidatePaintIfNeededWithCompu |
} |
return PaintInvalidationNone; |
case PaintInvalidationIncremental: |
- incrementallyInvalidatePaint(); |
break; |
case PaintInvalidationDelayedFull: |
return PaintInvalidationDelayedFull; |
default: |
- DCHECK(isFullPaintInvalidationReason(reason)); |
+ DCHECK(isImmediateFullPaintInvalidationReason(reason)); |
fullyInvalidatePaint(reason, m_context.oldBounds, m_context.newBounds); |
} |