Chromium Code Reviews| Index: Source/core/rendering/LayoutRepainter.cpp |
| diff --git a/Source/core/rendering/LayoutRepainter.cpp b/Source/core/rendering/LayoutRepainter.cpp |
| index fc06e0b3b2176fbbbe35076eae926ecd23fd03e0..33b8cef9d38a9d380e9925fc1eccf7f6237609b5 100644 |
| --- a/Source/core/rendering/LayoutRepainter.cpp |
| +++ b/Source/core/rendering/LayoutRepainter.cpp |
| @@ -26,6 +26,8 @@ |
| #include "config.h" |
| #include "core/rendering/LayoutRepainter.h" |
| +#include "core/rendering/RenderBlockFlow.h" |
| +#include "core/rendering/RenderBox.h" |
| #include "core/rendering/RenderObject.h" |
| namespace WebCore { |
| @@ -34,6 +36,9 @@ LayoutRepainter::LayoutRepainter(RenderObject& object, bool checkForRepaint) |
| : m_object(object) |
| , m_repaintContainer(0) |
| , m_checkForRepaint(checkForRepaint) |
| + , m_logicalWidth(-1) |
|
eseidel
2014/02/24 21:45:45
My instinct would have been to preface these with
Julien - ping for review
2014/03/06 21:03:02
Good suggestion.
|
| + , m_logicalHeight(-1) |
|
eseidel
2014/02/24 21:45:45
I would use a const int kDidNotChange = -1; to mak
Julien - ping for review
2014/03/06 21:03:02
Done.
|
| + , m_selfNeededLayout(object.selfNeedsLayout()) |
| { |
| if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| return; |
| @@ -42,6 +47,11 @@ LayoutRepainter::LayoutRepainter(RenderObject& object, bool checkForRepaint) |
| m_repaintContainer = m_object.containerForRepaint(); |
| m_oldBounds = m_object.clippedOverflowRectForRepaint(m_repaintContainer); |
| m_oldOutlineBox = m_object.outlineBoundsForRepaint(m_repaintContainer); |
| + if (m_object.isBox()) { |
| + const RenderBox& box = *toRenderBox(&m_object); |
| + m_logicalWidth = box.logicalWidth(); |
| + m_logicalHeight = box.logicalHeight(); |
| + } |
| } |
| } |
| @@ -50,7 +60,46 @@ bool LayoutRepainter::repaintAfterLayout() |
| if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| return false; |
| - return m_checkForRepaint ? m_object.repaintAfterLayoutIfNeeded(m_repaintContainer, m_object.selfNeedsLayout(), m_oldBounds, m_oldOutlineBox) : false; |
| + if (!m_checkForRepaint) |
| + return false; |
| + |
| + if (canSkipRepaint()) |
| + return false; |
| + |
| + return m_object.repaintAfterLayoutIfNeeded(m_repaintContainer, m_object.selfNeedsLayout(), m_oldBounds, m_oldOutlineBox); |
| +} |
| + |
| +bool LayoutRepainter::canSkipRepaint() const |
| +{ |
| + // If we needed layout, our content could have changed so we have to repaint. |
| + if (m_selfNeededLayout) |
| + return false; |
| + |
| + if (m_logicalWidth == -1) { |
| + ASSERT(m_logicalHeight == -1); |
| + return false; |
| + } |
| + |
| + ASSERT(m_logicalWidth != -1); |
| + ASSERT(m_logicalHeight != -1); |
| + |
| + // We don't repaint box containers that are not marked for self-layout and didn't change size. |
| + // This is valid because: |
| + // - if their content changed, they would be marked for self-layout. |
| + // - their descendant(s) that actually changed should repaint themselves correctly. |
| + // FIXME: It should be possible to avoid repainting size changes but we have to be careful with |
| + // some cases (e.g. gradient or repeated backgrounds). |
| + const RenderBox& box = *toRenderBox(&m_object); |
| + if (m_logicalWidth != box.logicalWidth() || m_logicalHeight != box.logicalHeight()) |
| + return false; |
| + |
| + if (!m_object.isRenderBlockFlow()) |
| + return true; |
| + |
| + const RenderBlockFlow& block = *toRenderBlockFlow(&box); |
| + // FIXME: We currently disable this optimization for floats as they need to be |
| + // correctly repainted by their (not marked for self-layout) block-flow container. |
| + return !block.containsFloats(); |
|
eseidel
2014/02/24 21:45:45
I might have abstracted this into a nicely named h
Julien - ping for review
2014/03/06 21:03:02
Added hasChildrenNeedingRepaintFromContainingBlock
|
| } |
| } // namespace WebCore |