| Index: third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| index e0830d1db4773a05e1f77c26c237425d53387bd9..5daa2a67b53539f117afbabeb3a8eac051904dba 100644
|
| --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| @@ -21,8 +21,10 @@
|
| namespace blink {
|
|
|
| static bool supportsCachedOffsets(const LayoutObject& object) {
|
| - // Can't compute paint offsets across objects with transforms, but if they are paint invalidation containers, we don't actually need
|
| - // to compute *across* the container, just up to it. (Also, such objects are the containing block for all children.)
|
| + // Can't compute paint offsets across objects with transforms, but if they are
|
| + // paint invalidation containers, we don't actually need to compute *across*
|
| + // the container, just up to it. (Also, such objects are the containing block
|
| + // for all children.)
|
| return !(object.hasTransformRelatedProperty() &&
|
| !object.isPaintInvalidationContainer()) &&
|
| !object.hasFilterInducingProperty() && !object.isLayoutFlowThread() &&
|
| @@ -115,9 +117,11 @@ PaintInvalidationState::PaintInvalidationState(
|
| DCHECK(&m_paintingLayer == currentObject.paintingLayer());
|
|
|
| if (currentObject == parentState.m_currentObject) {
|
| -// Sometimes we create a new PaintInvalidationState from parentState on the same object
|
| -// (e.g. LayoutView, and the HorriblySlowRectMapping cases in LayoutBlock::invalidatePaintOfSubtreesIfNeeded()).
|
| -// TODO(wangxianzhu): Avoid this for RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled().
|
| +// Sometimes we create a new PaintInvalidationState from parentState on the same
|
| +// object (e.g. LayoutView, and the HorriblySlowRectMapping cases in
|
| +// LayoutBlock::invalidatePaintOfSubtreesIfNeeded()).
|
| +// TODO(wangxianzhu): Avoid this for
|
| +// RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled().
|
| #if ENABLE(ASSERT)
|
| m_didUpdateForChildren = parentState.m_didUpdateForChildren;
|
| #endif
|
| @@ -134,26 +138,31 @@ PaintInvalidationState::PaintInvalidationState(
|
| m_paintInvalidationContainerForStackedContents =
|
| toLayoutBoxModelObject(¤tObject);
|
| } else if (currentObject.isLayoutView()) {
|
| - // m_paintInvalidationContainerForStackedContents is only for stacked descendants in its own frame,
|
| - // because it doesn't establish stacking context for stacked contents in sub-frames.
|
| - // Contents stacked in the root stacking context in this frame should use this frame's paintInvalidationContainer.
|
| + // m_paintInvalidationContainerForStackedContents is only for stacked
|
| + // descendants in its own frame, because it doesn't establish stacking
|
| + // context for stacked contents in sub-frames. Contents stacked in the root
|
| + // stacking context in this frame should use this frame's
|
| + // paintInvalidationContainer.
|
| m_paintInvalidationContainerForStackedContents =
|
| m_paintInvalidationContainer;
|
| - } else if (
|
| - currentObject.styleRef().isStacked()
|
| - // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked.
|
| - && currentObject.hasLayer() &&
|
| - m_paintInvalidationContainer !=
|
| - m_paintInvalidationContainerForStackedContents) {
|
| - // The current object is stacked, so we should use m_paintInvalidationContainerForStackedContents as its
|
| - // paint invalidation container on which the current object is painted.
|
| + } else if (currentObject.styleRef().isStacked() &&
|
| + // This is to exclude some objects (e.g. LayoutText) inheriting
|
| + // stacked style from parent but aren't actually stacked.
|
| + currentObject.hasLayer() &&
|
| + m_paintInvalidationContainer !=
|
| + m_paintInvalidationContainerForStackedContents) {
|
| + // The current object is stacked, so we should use
|
| + // m_paintInvalidationContainerForStackedContents as its paint invalidation
|
| + // container on which the current object is painted.
|
| m_paintInvalidationContainer =
|
| m_paintInvalidationContainerForStackedContents;
|
| - // We are changing paintInvalidationContainer to m_paintInvalidationContainerForStackedContents. Must disable
|
| - // cached offsets because we didn't track paint offset from m_paintInvalidationContainerForStackedContents.
|
| + // We are changing paintInvalidationContainer to
|
| + // m_paintInvalidationContainerForStackedContents. Must disable cached
|
| + // offsets because we didn't track paint offset from
|
| + // m_paintInvalidationContainerForStackedContents.
|
| // TODO(wangxianzhu): There are optimization opportunities:
|
| - // - Like what we do for fixed-position, calculate the paint offset in slow path and enable fast path for
|
| - // descendants if possible; or
|
| + // - Like what we do for fixed-position, calculate the paint offset in slow
|
| + // path and enable fast path for descendants if possible; or
|
| // - Track offset between the two paintInvalidationContainers.
|
| m_cachedOffsetsEnabled = false;
|
| if (m_forcedSubtreeInvalidationFlags &
|
| @@ -173,8 +182,8 @@ PaintInvalidationState::PaintInvalidationState(
|
| if (currentObject.isSVGRoot()) {
|
| m_svgTransform =
|
| toLayoutSVGRoot(currentObject).localToBorderBoxTransform();
|
| - // Don't early return here, because the SVGRoot object needs to execute the later code
|
| - // as a normal LayoutBox.
|
| + // Don't early return here, because the SVGRoot object needs to execute
|
| + // the later code as a normal LayoutBox.
|
| } else {
|
| DCHECK(currentObject != m_paintInvalidationContainer);
|
| m_svgTransform *= currentObject.localToSVGParentTransform();
|
| @@ -197,10 +206,12 @@ PaintInvalidationState::PaintInvalidationState(
|
| m_forcedSubtreeInvalidationFlags = 0;
|
| if (currentObject != m_containerForAbsolutePosition &&
|
| m_cachedOffsetsForAbsolutePositionEnabled && m_cachedOffsetsEnabled) {
|
| - // The current object is the new paintInvalidationContainer for absolute-position descendants but is not their container.
|
| - // Call updateForCurrentObject() before resetting m_paintOffset to get paint offset of the current object
|
| - // from the original paintInvalidationContainerForStackingContents, then use this paint offset to adjust
|
| - // m_paintOffsetForAbsolutePosition.
|
| + // The current object is the new paintInvalidationContainer for
|
| + // absolute-position descendants but is not their container.
|
| + // Call updateForCurrentObject() before resetting m_paintOffset to get
|
| + // paint offset of the current object from the original
|
| + // paintInvalidationContainerForStackingContents, then use this paint
|
| + // offset to adjust m_paintOffsetForAbsolutePosition.
|
| updateForCurrentObject(parentState);
|
| m_paintOffsetForAbsolutePosition -= m_paintOffset;
|
| if (m_clippedForAbsolutePosition)
|
| @@ -240,12 +251,14 @@ void PaintInvalidationState::updateForCurrentObject(
|
| if (position == FixedPosition) {
|
| if (m_paintInvalidationContainer != m_currentObject.view() &&
|
| m_paintInvalidationContainer->view() == m_currentObject.view()) {
|
| - // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for fixed-position when paintInvalidationContainer
|
| - // is under the containing LayoutView.
|
| + // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for
|
| + // fixed-position when paintInvalidationContainer is under the containing
|
| + // LayoutView.
|
| m_cachedOffsetsEnabled = false;
|
| return;
|
| }
|
| - // Use slow path to get the offset of the fixed-position, and enable fast path for descendants.
|
| + // Use slow path to get the offset of the fixed-position, and enable fast
|
| + // path for descendants.
|
| FloatPoint fixedOffset = m_currentObject.localToAncestorPoint(
|
| FloatPoint(), m_paintInvalidationContainer, TraverseDocumentBoundaries);
|
| if (m_paintInvalidationContainer->isBox()) {
|
| @@ -254,9 +267,10 @@ void PaintInvalidationState::updateForCurrentObject(
|
| fixedOffset.move(box->scrolledContentOffset());
|
| }
|
| m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
|
| - // In the above way to get paint offset, we can't get accurate clip rect, so just assume no clip.
|
| - // Clip on fixed-position is rare, in case that paintInvalidationContainer crosses frame boundary
|
| - // and the LayoutView is clipped by something in owner document.
|
| + // In the above way to get paint offset, we can't get accurate clip rect, so
|
| + // just assume no clip. Clip on fixed-position is rare, in case that
|
| + // paintInvalidationContainer crosses frame boundary and the LayoutView is
|
| + // clipped by something in owner document.
|
| if (m_clipped) {
|
| m_clipped = false;
|
| #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY
|
| @@ -327,11 +341,13 @@ void PaintInvalidationState::updateForChildren(PaintInvalidationReason reason) {
|
| m_clipRectForAbsolutePosition = m_clipRect;
|
| }
|
| } else {
|
| - // Cached offsets for absolute-position are from m_paintInvalidationContainer,
|
| - // which can't be used if the absolute-position descendants will use a different
|
| + // Cached offsets for absolute-position are from
|
| + // m_paintInvalidationContainer, which can't be used if the
|
| + // absolute-position descendants will use a different
|
| // paintInvalidationContainer.
|
| - // TODO(wangxianzhu): Same optimization opportunities as under isStacked() condition
|
| - // in the PaintInvalidationState::PaintInvalidationState(... LayoutObject&...).
|
| + // TODO(wangxianzhu): Same optimization opportunities as under isStacked()
|
| + // condition in the PaintInvalidationState::PaintInvalidationState(...
|
| + // LayoutObject&...).
|
| m_cachedOffsetsForAbsolutePositionEnabled = false;
|
| }
|
| }
|
| @@ -367,17 +383,20 @@ void PaintInvalidationState::updateForNormalChildren() {
|
| if (!box.hasClipRelatedProperty())
|
| return;
|
|
|
| - // Do not clip or scroll for the paint invalidation container, because the semantics of visual rects do not include clipping or
|
| - // scrolling on that object.
|
| + // Do not clip or scroll for the paint invalidation container, because the
|
| + // semantics of visual rects do not include clipping or scrolling on that
|
| + // object.
|
| if (box != m_paintInvalidationContainer) {
|
| - // This won't work fully correctly for fixed-position elements, who should receive CSS clip but for whom the current object
|
| - // is not in the containing block chain.
|
| + // This won't work fully correctly for fixed-position elements, who should
|
| + // receive CSS clip but for whom the current object is not in the containing
|
| + // block chain.
|
| addClipRectRelativeToPaintOffset(box.clippingRect());
|
| if (box.hasOverflowClip())
|
| m_paintOffset -= box.scrolledContentOffset();
|
| }
|
|
|
| - // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
|
| + // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if
|
| + // present.
|
| }
|
|
|
| static FloatPoint slowLocalToAncestorPoint(const LayoutObject& object,
|
| @@ -458,8 +477,9 @@ LayoutRect PaintInvalidationState::computePaintInvalidationRectInBackingForSVG()
|
| assertFastPathAndSlowPathRectsEqual(rect, slowPathRect);
|
| #endif
|
| } else {
|
| - // TODO(wangxianzhu): Sometimes m_cachedOffsetsEnabled==false doesn't mean we can't use cached
|
| - // m_svgTransform. We can use hybrid fast path (for SVG) and slow path (for things above the SVGRoot).
|
| + // TODO(wangxianzhu): Sometimes m_cachedOffsetsEnabled==false doesn't mean
|
| + // we can't use cached m_svgTransform. We can use hybrid fast path (for SVG)
|
| + // and slow path (for things above the SVGRoot).
|
| rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(
|
| m_currentObject, *m_paintInvalidationContainer);
|
| }
|
| @@ -557,20 +577,23 @@ void PaintInvalidationState::assertFastPathAndSlowPathRectsEqual(
|
| if (!m_canCheckFastPathSlowPathEquality)
|
| return;
|
|
|
| - // TODO(crbug.com/597903): Fast path and slow path should generate equal empty rects.
|
| + // TODO(crbug.com/597903): Fast path and slow path should generate equal empty
|
| + // rects.
|
| if (fastPathRect.isEmpty() && slowPathRect.isEmpty())
|
| return;
|
|
|
| if (fastPathRect == slowPathRect)
|
| return;
|
|
|
| - // LayoutUnit uses saturated arithmetic operations. If any interim or final result is saturated,
|
| - // the same operations in different order produce different results. Don't compare results
|
| - // if any of them may have been saturated.
|
| + // LayoutUnit uses saturated arithmetic operations. If any interim or final
|
| + // result is saturated, the same operations in different order produce
|
| + // different results. Don't compare results if any of them may have been
|
| + // saturated.
|
| if (mayHaveBeenSaturated(fastPathRect) || mayHaveBeenSaturated(slowPathRect))
|
| return;
|
|
|
| - // Tolerate the difference between the two paths when crossing frame boundaries.
|
| + // Tolerate the difference between the two paths when crossing frame
|
| + // boundaries.
|
| if (m_currentObject.view() != m_paintInvalidationContainer->view()) {
|
| LayoutRect inflatedFastPathRect = fastPathRect;
|
| inflatedFastPathRect.inflate(1);
|
|
|