| Index: Source/core/rendering/RenderObject.cpp
|
| diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
|
| index d55645e614dfe44aece0455d296605469d0c60a7..14551e3d83ab584bf0adf0eb7c9c6dcbfae47a50 100644
|
| --- a/Source/core/rendering/RenderObject.cpp
|
| +++ b/Source/core/rendering/RenderObject.cpp
|
| @@ -82,6 +82,7 @@
|
| #include "platform/graphics/GraphicsContext.h"
|
| #include "wtf/RefCountedLeakCounter.h"
|
| #include "wtf/text/StringBuilder.h"
|
| +#include "wtf/text/WTFString.h"
|
| #include <algorithm>
|
| #ifndef NDEBUG
|
| #include <stdio.h>
|
| @@ -1365,8 +1366,13 @@ RenderLayerModelObject* RenderObject::containerForRepaint() const
|
| return repaintContainer;
|
| }
|
|
|
| -void RenderObject::repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect& r) const
|
| +void RenderObject::repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect& r, InvalidationReason invalidationReason) const
|
| {
|
| + TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "RenderObject::repaintUsingContainer()",
|
| + "object", TRACE_STR_COPY(this->debugName().ascii().data()),
|
| + "info", TRACE_STR_COPY(String::format("rect: %d,%d %dx%d, invalidation_reason: %s",
|
| + r.x(), r.y(), r.width(), r.height(), invalidationReasonToString(invalidationReason)).ascii().data()));
|
| +
|
| if (!repaintContainer) {
|
| view()->repaintViewRectangle(r);
|
| return;
|
| @@ -1443,7 +1449,7 @@ void RenderObject::repaint() const
|
| // Until those states are fully fledged, I'll just disable the ASSERTS.
|
| DisableCompositingQueryAsserts disabler;
|
| RenderLayerModelObject* repaintContainer = containerForRepaint();
|
| - repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(clippedOverflowRectForRepaint(repaintContainer)));
|
| + repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(clippedOverflowRectForRepaint(repaintContainer)), InvalidationRepaint);
|
| }
|
|
|
| void RenderObject::repaintRectangle(const LayoutRect& r) const
|
| @@ -1466,7 +1472,7 @@ void RenderObject::repaintRectangle(const LayoutRect& r) const
|
|
|
| RenderLayerModelObject* repaintContainer = containerForRepaint();
|
| computeRectForRepaint(repaintContainer, dirtyRect);
|
| - repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(dirtyRect));
|
| + repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(dirtyRect), InvalidationRepaintRectangle);
|
| }
|
|
|
| IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
|
| @@ -1474,6 +1480,36 @@ IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
|
| return pixelSnappedIntRect(absoluteClippedOverflowRect());
|
| }
|
|
|
| +const char* RenderObject::invalidationReasonToString(InvalidationReason reason) const
|
| +{
|
| + switch (reason) {
|
| + case InvalidationIncremental:
|
| + return "incremental";
|
| + case InvalidationSelfLayout:
|
| + return "self layout";
|
| + case InvalidationBorderFitLines:
|
| + return "border fit lines";
|
| + case InvalidationBorderRadius:
|
| + return "border radius";
|
| + case InvalidationBoundsChangeWithBackground:
|
| + return "bounds change with background";
|
| + case InvalidationBoundsChange:
|
| + return "bounds change";
|
| + case InvalidationScroll:
|
| + return "scroll";
|
| + case InvalidationSelection:
|
| + return "selection";
|
| + case InvalidationLayer:
|
| + return "layer";
|
| + case InvalidationRepaint:
|
| + return "repaint";
|
| + case InvalidationRepaintRectangle:
|
| + return "repaint rectangle";
|
| + }
|
| + ASSERT_NOT_REACHED();
|
| + return "";
|
| +}
|
| +
|
| bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, bool wasSelfLayout,
|
| const LayoutRect& oldBounds, const LayoutRect* newBoundsPtr)
|
| {
|
| @@ -1485,33 +1521,36 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa
|
| // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
|
| LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
|
|
|
| - bool fullRepaint = wasSelfLayout;
|
| + InvalidationReason invalidationReason = wasSelfLayout ? InvalidationSelfLayout : InvalidationIncremental;
|
| +
|
| // Presumably a background or a border exists if border-fit:lines was specified.
|
| - if (!fullRepaint && style()->borderFit() == BorderFitLines)
|
| - fullRepaint = true;
|
| - if (!fullRepaint && style()->hasBorderRadius()) {
|
| + if (invalidationReason == InvalidationIncremental && style()->borderFit() == BorderFitLines)
|
| + invalidationReason = InvalidationBorderFitLines;
|
| +
|
| + if (invalidationReason == InvalidationIncremental && style()->hasBorderRadius()) {
|
| // If a border-radius exists and width/height is smaller than
|
| // radius width/height, we cannot use delta-repaint.
|
| RoundedRect oldRoundedRect = style()->getRoundedBorderFor(oldBounds);
|
| RoundedRect newRoundedRect = style()->getRoundedBorderFor(newBounds);
|
| - fullRepaint = oldRoundedRect.radii() != newRoundedRect.radii();
|
| + if (oldRoundedRect.radii() != newRoundedRect.radii())
|
| + invalidationReason = InvalidationBorderRadius;
|
| }
|
|
|
| - if (!fullRepaint && (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds)))
|
| - fullRepaint = true;
|
| + if (invalidationReason == InvalidationIncremental && (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds)))
|
| + invalidationReason = InvalidationBoundsChangeWithBackground;
|
|
|
| // 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 renderer inserted / removed before us in the tree.
|
| - if (!fullRepaint && newBounds.location() != oldBounds.location())
|
| - fullRepaint = true;
|
| + if (invalidationReason == InvalidationIncremental && newBounds.location() != oldBounds.location())
|
| + invalidationReason = InvalidationBoundsChange;
|
|
|
| if (!repaintContainer)
|
| repaintContainer = v;
|
|
|
| - if (fullRepaint) {
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds));
|
| + if (invalidationReason != InvalidationIncremental) {
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds), invalidationReason);
|
| if (newBounds != oldBounds)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds), invalidationReason);
|
| return true;
|
| }
|
|
|
| @@ -1520,27 +1559,27 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa
|
|
|
| LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
|
| if (deltaLeft > 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()), invalidationReason);
|
| else if (deltaLeft < 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()), invalidationReason);
|
|
|
| LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
|
| if (deltaRight > 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()), invalidationReason);
|
| else if (deltaRight < 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()), invalidationReason);
|
|
|
| LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
|
| if (deltaTop > 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop), invalidationReason);
|
| else if (deltaTop < 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop), invalidationReason);
|
|
|
| LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
|
| if (deltaBottom > 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom), invalidationReason);
|
| else if (deltaBottom < 0)
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom), invalidationReason);
|
|
|
| // FIXME: This is a limitation of our visual overflow being a single rectangle.
|
| if (!style()->boxShadow() && !style()->hasBorderImageOutsets() && !style()->hasOutline())
|
| @@ -1569,7 +1608,7 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa
|
| LayoutUnit right = min<LayoutUnit>(newBounds.maxX(), oldBounds.maxX());
|
| if (rightRect.x() < right) {
|
| rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(rightRect));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(rightRect), invalidationReason);
|
| }
|
| }
|
| LayoutUnit height = absoluteValue(newBounds.height() - oldBounds.height());
|
| @@ -1590,7 +1629,7 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa
|
| LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY());
|
| if (bottomRect.y() < bottom) {
|
| bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
|
| - repaintUsingContainer(repaintContainer, pixelSnappedIntRect(bottomRect));
|
| + repaintUsingContainer(repaintContainer, pixelSnappedIntRect(bottomRect), invalidationReason);
|
| }
|
| }
|
| return false;
|
|
|