| Index: third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| index 93fc1fc50f8104c5db3e548ec07256bf3fd67305..d1230d559749ac8654ac950300551e1afe27aacc 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| @@ -9,6 +9,7 @@
|
| #include "core/paint/ClipPathClipper.h"
|
| #include "core/paint/FilterPainter.h"
|
| #include "core/paint/LayerClipRecorder.h"
|
| +#include "core/paint/LayoutObjectDrawingRecorder.h"
|
| #include "core/paint/ObjectPaintProperties.h"
|
| #include "core/paint/PaintInfo.h"
|
| #include "core/paint/PaintLayer.h"
|
| @@ -361,7 +362,8 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| // scrolling contents and scrollbars.
|
| if (m_paintLayer.layoutObject()->hasClipPath() &&
|
| (!m_paintLayer.needsCompositedScrolling() ||
|
| - (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) {
|
| + (paintFlags & (PaintLayerPaintingChildClippingMaskPhase |
|
| + PaintLayerPaintingAncestorClippingMaskPhase)))) {
|
| paintingInfo.ancestorHasClipPathClipping = true;
|
|
|
| LayoutRect referenceBox(m_paintLayer.boxForClipPath());
|
| @@ -412,19 +414,35 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects)
|
| ? UncachedClipRects
|
| : PaintingClipRects;
|
| + LayoutPoint offsetToClipper;
|
| + PaintLayer* paintLayerForFragments = &m_paintLayer;
|
| + if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
|
| + // Compute fragments and their clips with respect to the clipping
|
| + // container. The paint rect is in this layer's space, so convert it
|
| + // to the clipper's layer's space. The rootLayer is also changed to
|
| + // the clipper's layer to simplify coordinate system adjustments.
|
| + // The change to rootLayer must persist to correctly record the clips.
|
| + paintLayerForFragments =
|
| + m_paintLayer.clippingContainer()->enclosingLayer();
|
| + localPaintingInfo.rootLayer = paintLayerForFragments;
|
| + m_paintLayer.convertToLayerCoords(localPaintingInfo.rootLayer,
|
| + offsetToClipper);
|
| + localPaintingInfo.paintDirtyRect.moveBy(offsetToClipper);
|
| + }
|
| +
|
| // TODO(trchen): We haven't decided how to handle visual fragmentation with
|
| // SPv2. Related thread
|
| // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuWFf-mxM
|
| if (fragmentPolicy == ForceSingleFragment ||
|
| RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| - m_paintLayer.appendSingleFragmentIgnoringPagination(
|
| + paintLayerForFragments->appendSingleFragmentIgnoringPagination(
|
| layerFragments, localPaintingInfo.rootLayer,
|
| localPaintingInfo.paintDirtyRect, cacheSlot,
|
| IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
|
| localPaintingInfo.subPixelAccumulation);
|
| } else if (isFixedPositionObjectInPagedMedia()) {
|
| PaintLayerFragments singleFragment;
|
| - m_paintLayer.appendSingleFragmentIgnoringPagination(
|
| + paintLayerForFragments->appendSingleFragmentIgnoringPagination(
|
| singleFragment, localPaintingInfo.rootLayer,
|
| localPaintingInfo.paintDirtyRect, cacheSlot,
|
| IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
|
| @@ -432,11 +450,23 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| repeatFixedPositionObjectInPages(singleFragment[0], paintingInfo,
|
| layerFragments);
|
| } else {
|
| - m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer,
|
| - localPaintingInfo.paintDirtyRect, cacheSlot,
|
| - IgnoreOverlayScrollbarSize,
|
| - respectOverflowClip, &offsetFromRoot,
|
| - localPaintingInfo.subPixelAccumulation);
|
| + paintLayerForFragments->collectFragments(
|
| + layerFragments, localPaintingInfo.rootLayer,
|
| + localPaintingInfo.paintDirtyRect, cacheSlot,
|
| + IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
|
| + localPaintingInfo.subPixelAccumulation);
|
| + }
|
| +
|
| + if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
|
| + // Fragment offsets have been computed in the clipping container's
|
| + // layer's coordinate system, but for the rest of painting we need
|
| + // them in the layer coordinate. So move them and the foreground rect
|
| + // that is also in the clipper's space.
|
| + LayoutSize negativeOffset(-offsetToClipper.x(), -offsetToClipper.y());
|
| + for (auto& fragment : layerFragments) {
|
| + fragment.foregroundRect.move(negativeOffset);
|
| + fragment.paginationOffset.move(negativeOffset);
|
| + }
|
| }
|
|
|
| if (shouldPaintContent) {
|
| @@ -537,7 +567,8 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| shouldPaintContent && m_paintLayer.layoutObject()->hasMask() &&
|
| !selectionOnly;
|
| bool shouldPaintClippingMask =
|
| - (paintFlags & PaintLayerPaintingChildClippingMaskPhase) &&
|
| + (paintFlags & (PaintLayerPaintingChildClippingMaskPhase |
|
| + PaintLayerPaintingAncestorClippingMaskPhase)) &&
|
| shouldPaintContent && !selectionOnly;
|
|
|
| if (shouldPaintMask)
|
| @@ -722,7 +753,7 @@ PaintResult PaintLayerPainter::paintLayerWithTransform(
|
| if (needsToClip(paintingInfo, clipRectForFragment)) {
|
| clipRecorder.emplace(context, *parentLayer->layoutObject(),
|
| DisplayItem::kClipLayerParent, clipRectForFragment,
|
| - &paintingInfo, fragment.paginationOffset,
|
| + paintingInfo.rootLayer, fragment.paginationOffset,
|
| paintFlags);
|
| }
|
| }
|
| @@ -860,7 +891,7 @@ void PaintLayerPainter::paintOverflowControlsForFragments(
|
| if (needsToClip(localPaintingInfo, fragment.backgroundRect)) {
|
| clipRecorder.emplace(context, *m_paintLayer.layoutObject(),
|
| DisplayItem::kClipLayerOverflowControls,
|
| - fragment.backgroundRect, &localPaintingInfo,
|
| + fragment.backgroundRect, localPaintingInfo.rootLayer,
|
| fragment.paginationOffset, paintFlags);
|
| }
|
|
|
| @@ -910,9 +941,21 @@ void PaintLayerPainter::paintFragmentWithPhase(
|
| break;
|
| }
|
|
|
| + // TODO(schenney): Nested border-radius clips are not applied to composited
|
| + // children, probably due to an incorrect clipRoot.
|
| + // https://bugs.chromium.org/p/chromium/issues/detail?id=672561
|
| clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType,
|
| - clipRect, &paintingInfo, fragment.paginationOffset,
|
| - paintFlags, clippingRule);
|
| + clipRect, paintingInfo.rootLayer,
|
| + fragment.paginationOffset, paintFlags, clippingRule);
|
| + }
|
| +
|
| + // If we are painting a mask for any reason and we have already processed the
|
| + // clips, there is no need to go through the remaining painting pipeline.
|
| + // We know that the mask just needs the area bounded by the clip rects to be
|
| + // filled with black.
|
| + if (clipRecorder && phase == PaintPhaseClippingMask) {
|
| + fillMaskingFragment(context, clipRect);
|
| + return;
|
| }
|
|
|
| LayoutRect newCullRect(clipRect.rect());
|
| @@ -984,7 +1027,8 @@ void PaintLayerPainter::paintForegroundForFragments(
|
| needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) {
|
| clipRecorder.emplace(context, *m_paintLayer.layoutObject(),
|
| DisplayItem::kClipLayerForeground,
|
| - layerFragments[0].foregroundRect, &localPaintingInfo,
|
| + layerFragments[0].foregroundRect,
|
| + localPaintingInfo.rootLayer,
|
| layerFragments[0].paginationOffset, paintFlags);
|
| clipState = HasClipped;
|
| }
|
| @@ -1130,4 +1174,17 @@ void PaintLayerPainter::paintOverlayScrollbars(
|
| m_paintLayer.setContainsDirtyOverlayScrollbars(false);
|
| }
|
|
|
| +void PaintLayerPainter::fillMaskingFragment(GraphicsContext& context,
|
| + const ClipRect& clipRect) {
|
| + const LayoutBox* layoutBox = toLayoutBox(m_paintLayer.layoutObject());
|
| + if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
|
| + context, *layoutBox, PaintPhaseClippingMask))
|
| + return;
|
| +
|
| + IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect());
|
| + LayoutObjectDrawingRecorder drawingRecorder(
|
| + context, *layoutBox, PaintPhaseClippingMask, snappedClipRect);
|
| + context.fillRect(snappedClipRect, Color::black);
|
| +}
|
| +
|
| } // namespace blink
|
|
|