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

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

Issue 2194273002: Fix border radius on composited children. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Now working on basic test cases Created 4 years, 1 month 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 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());

Powered by Google App Engine
This is Rietveld 408576698