| 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 e1c8fdce368965828ee0faf852f8e417f6fe30fb..388ef49fd8c5c23e62d4c4ab754c3a035fd66f11 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
|
| @@ -229,6 +229,27 @@ static bool shouldRepaintSubsequence(
|
| return needsRepaint;
|
| }
|
|
|
| +LayoutPoint PaintLayerPainter::fragmentOffsetForAncestorClipMask(
|
| + const LayoutPoint& originalFragmentOffset) {
|
| + // The clipping container that will be used to define the clip and the
|
| + // child layer with respect to which the fragment offset is defined share
|
| + // a layer root. When the clip is recorded we will be using the clipping
|
| + // container's layer's offset to the root to position the clip. Hence we
|
| + // must convert the fragment offset into a corresponding offset in the
|
| + // clipping container's layer coordinates. To do that, we find the
|
| + // originalFragmentOffset's coordinate in the root layer, fragmentDelta.
|
| + // We also find the offset of the clipping container's origin in the root
|
| + // layer's coordinates, clippingDelta. clippingDelta - fragmentDelta gives
|
| + // the fragment's position in the root layer. But we need the position in
|
| + // the clipping layer coords, and we subtract clippingDelta to get that. The
|
| + // resulting offset is -fragmentDelta.
|
| + DCHECK_EQ(m_paintLayer.root(),
|
| + m_paintLayer.clippingContainer()->enclosingLayer()->root());
|
| + LayoutPoint fragmentDelta(originalFragmentOffset);
|
| + m_paintLayer.convertToLayerCoords(m_paintLayer.root(), fragmentDelta);
|
| + return LayoutPoint(-fragmentDelta.x(), -fragmentDelta.y());
|
| +}
|
| +
|
| PaintResult PaintLayerPainter::paintLayerContents(
|
| GraphicsContext& context,
|
| const PaintLayerPaintingInfo& paintingInfoArg,
|
| @@ -353,7 +374,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());
|
| @@ -409,19 +431,48 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| // 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
|
| + PaintLayer* paintLayerForFragmentsAndClip = &m_paintLayer;
|
| + LayoutPoint offsetFromRootForFragmentsAndClip = offsetFromRoot;
|
| + if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
|
| + // Compute fragments and their clips with respect to the clipping
|
| + // container, and then convert them back to this layer's space.
|
| + // We need a new offset from root.
|
| + paintLayerForFragmentsAndClip =
|
| + m_paintLayer.clippingContainer()->enclosingLayer();
|
| + LayoutPoint clippersOffsetToRoot;
|
| + paintLayerForFragmentsAndClip->convertToLayerCoords(m_paintLayer.root(),
|
| + clippersOffsetToRoot);
|
| + LayoutPoint thisOffsetToRoot;
|
| + m_paintLayer.convertToLayerCoords(m_paintLayer.root(), thisOffsetToRoot);
|
| + offsetFromRootForFragmentsAndClip =
|
| + LayoutPoint(clippersOffsetToRoot.x() - thisOffsetToRoot.x(),
|
| + clippersOffsetToRoot.y() - thisOffsetToRoot.y());
|
| + }
|
| +
|
| if (fragmentPolicy == ForceSingleFragment ||
|
| - RuntimeEnabledFeatures::slimmingPaintV2Enabled())
|
| - m_paintLayer.appendSingleFragmentIgnoringPagination(
|
| + RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| + paintLayerForFragmentsAndClip->appendSingleFragmentIgnoringPagination(
|
| layerFragments, localPaintingInfo.rootLayer,
|
| localPaintingInfo.paintDirtyRect, cacheSlot,
|
| - IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
|
| + IgnoreOverlayScrollbarSize, respectOverflowClip,
|
| + &offsetFromRootForFragmentsAndClip,
|
| localPaintingInfo.subPixelAccumulation);
|
| - else
|
| - m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer,
|
| - localPaintingInfo.paintDirtyRect, cacheSlot,
|
| - IgnoreOverlayScrollbarSize,
|
| - respectOverflowClip, &offsetFromRoot,
|
| - localPaintingInfo.subPixelAccumulation);
|
| + } else {
|
| + paintLayerForFragmentsAndClip->collectFragments(
|
| + layerFragments, localPaintingInfo.rootLayer,
|
| + localPaintingInfo.paintDirtyRect, cacheSlot,
|
| + IgnoreOverlayScrollbarSize, respectOverflowClip,
|
| + &offsetFromRootForFragmentsAndClip,
|
| + localPaintingInfo.subPixelAccumulation);
|
| + }
|
| +
|
| + // Reset the layerBounds because they were set using the clipper's layer
|
| + if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
|
| + for (auto& fragment : layerFragments) {
|
| + fragment.layerBounds =
|
| + LayoutRect(offsetFromRoot, LayoutSize(m_paintLayer.size()));
|
| + }
|
| + }
|
|
|
| if (shouldPaintContent) {
|
| // TODO(wangxianzhu): This is for old slow scrolling. Implement similar
|
| @@ -525,7 +576,8 @@ PaintResult PaintLayerPainter::paintLayerContents(
|
| shouldPaintContent && m_paintLayer.layoutObject()->hasMask() &&
|
| !selectionOnly;
|
| bool shouldPaintClippingMask =
|
| - (paintFlags & PaintLayerPaintingChildClippingMaskPhase) &&
|
| + (paintFlags & (PaintLayerPaintingChildClippingMaskPhase |
|
| + PaintLayerPaintingAncestorClippingMaskPhase)) &&
|
| shouldPaintContent && !selectionOnly;
|
|
|
| if (shouldPaintMask)
|
| @@ -604,6 +656,7 @@ PaintResult PaintLayerPainter::paintLayerWithTransform(
|
| object->container() == view && view->pageLogicalHeight();
|
| PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer();
|
| PaintLayerFragments fragments;
|
| +
|
| // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position
|
| // objects in paged media with vertical writing modes.
|
| if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) {
|
| @@ -888,9 +941,21 @@ void PaintLayerPainter::paintFragmentWithPhase(
|
| break;
|
| }
|
|
|
| - clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType,
|
| - clipRect, &paintingInfo, fragment.paginationOffset,
|
| - paintFlags, clippingRule);
|
| + // When painting the clipping mask for a composited child, we pass
|
| + // the clipping container object as the layoutObject to provide the clip.
|
| + // The recorder assumes the fragment is positioned in that objects's
|
| + // layer coordinates, so we also convert that.
|
| + if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
|
| + clipRecorder.emplace(
|
| + context, *(toLayoutBoxModelObject(m_paintLayer.clippingContainer())),
|
| + clipType, clipRect, &paintingInfo,
|
| + fragmentOffsetForAncestorClipMask(fragment.paginationOffset),
|
| + paintFlags, clippingRule);
|
| + } else {
|
| + clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType,
|
| + clipRect, &paintingInfo, fragment.paginationOffset,
|
| + paintFlags, clippingRule);
|
| + }
|
| }
|
|
|
| LayoutRect newCullRect(clipRect.rect());
|
|
|