Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(662)

Unified Diff: third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp

Issue 2588853002: Fix border radius on composited children. (Closed)
Patch Set: SPV2 expectations Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698