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

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

Issue 2238883006: SPv2: Use GeometryMapper to implement PaintLayerClipper. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: none Created 4 years, 2 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/PaintLayerClipper.cpp
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
index e9c5f0efd901958fc5669532ea44fbc6c199493f..e9b29d8d2b6b501fe39fb090b64d67be21af6011 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -48,6 +48,7 @@
#include "core/frame/Settings.h"
#include "core/layout/LayoutView.h"
#include "core/layout/svg/LayoutSVGRoot.h"
+#include "core/paint/ObjectPaintProperties.h"
#include "core/paint/PaintLayer.h"
namespace blink {
@@ -84,7 +85,8 @@ static void applyClipRects(const ClipRectsContext& context,
(layoutObject.isSVGRoot() &&
toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) ||
(layoutObject.styleRef().containsPaint() && layoutObject.isBox())) {
- ClipRect newOverflowClip =
+ ClipRect newOverflowClip;
+ newOverflowClip =
Xianzhu 2016/10/06 00:13:32 Is this change necessary?
chrishtr 2016/10/06 17:11:08 Reverted.
toLayoutBox(layoutObject)
.overflowClipRect(offset, context.overlayScrollbarClipBehavior);
newOverflowClip.setHasRadius(layoutObject.styleRef().hasBorderRadius());
@@ -115,6 +117,11 @@ static void applyClipRects(const ClipRectsContext& context,
}
}
+PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer,
+ bool useGeometryMapper)
+ : m_layer(layer),
+ m_geometryMapper(useGeometryMapper ? new GeometryMapper : nullptr) {}
+
ClipRects* PaintLayerClipper::clipRectsIfCached(
const ClipRectsContext& context) const {
DCHECK(context.usesCache());
@@ -171,6 +178,8 @@ ClipRects& PaintLayerClipper::getClipRects(
}
void PaintLayerClipper::clearClipRectsIncludingDescendants() {
+ if (m_geometryMapper)
+ m_geometryMapper.reset(new GeometryMapper);
m_layer.clearClipRectsCache();
for (PaintLayer* layer = m_layer.firstChild(); layer;
@@ -181,6 +190,9 @@ void PaintLayerClipper::clearClipRectsIncludingDescendants() {
void PaintLayerClipper::clearClipRectsIncludingDescendants(
ClipRectsCacheSlot cacheSlot) {
+ if (m_geometryMapper)
+ m_geometryMapper.reset(new GeometryMapper);
+
if (ClipRectsCache* cache = m_layer.clipRectsCache())
cache->clear(cacheSlot);
@@ -192,9 +204,31 @@ void PaintLayerClipper::clearClipRectsIncludingDescendants(
LayoutRect PaintLayerClipper::localClipRect(
const PaintLayer* clippingRootLayer) const {
+ ClipRectsContext context(clippingRootLayer, PaintingClipRects);
+ if (m_geometryMapper) {
+ ClipRect clipRect = applyOverflowClipToBackgroundRectWithGeometryMapper(
+ context, clipRectWithGeometryMapper(context, false));
+
+ // The rect now needs to be transformed to the local space of this PaintLayer.
Xianzhu 2016/10/06 00:13:32 Nit: 80 chars
chrishtr 2016/10/06 17:11:08 Fixed.
+ bool success = false;
+ FloatRect clippedRectInLocalSpace =
+ m_geometryMapper->mapRectToDestinationSpace(
+ FloatRect(clipRect.rect()), clippingRootLayer->layoutObject()
+ ->objectPaintProperties()
+ ->localBorderBoxProperties()
+ ->propertyTreeState,
+ m_layer.layoutObject()
+ ->objectPaintProperties()
+ ->localBorderBoxProperties()
+ ->propertyTreeState,
+ success);
+ DCHECK(success);
+
+ return LayoutRect(clippedRectInLocalSpace);
+ }
+
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect;
- ClipRectsContext context(clippingRootLayer, PaintingClipRects);
calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()),
layerBounds, backgroundRect, foregroundRect);
@@ -210,6 +244,71 @@ LayoutRect PaintLayerClipper::localClipRect(
return clipRect;
}
+#ifdef CHECK_CLIP_RECTS
+#define CHECK_RECTS_EQ(expected, actual) \
+ CHECK((expected.isEmpty() && actual.isEmpty()) || expected == actual) \
+ << "expected=" << expected.toString() << " actual=" << actual.toString()
+#endif
+
+void PaintLayerClipper::mapLocalToRootWithGeometryMapper(
+ const ClipRectsContext& context,
+ LayoutRect& layoutRect) const {
+ DCHECK(m_geometryMapper);
+ bool success;
+
+ const ObjectPaintProperties::PropertyTreeStateWithOffset*
+ layerBorderBoxProperties = m_layer.layoutObject()
+ ->objectPaintProperties()
+ ->localBorderBoxProperties();
+ FloatRect localRect(layoutRect);
+ localRect.moveBy(FloatPoint(layerBorderBoxProperties->paintOffset));
+
+ layoutRect = LayoutRect(m_geometryMapper->mapRectToDestinationSpace(
+ localRect, layerBorderBoxProperties->propertyTreeState,
+ context.rootLayer->layoutObject()
+ ->objectPaintProperties()
+ ->localBorderBoxProperties()
+ ->propertyTreeState,
+ success));
+ DCHECK(success);
+}
+
+void PaintLayerClipper::calculateRectsWithGeometryMapper(
+ const ClipRectsContext& context,
+ const LayoutRect& paintDirtyRect,
+ LayoutRect& layerBounds,
+ ClipRect& backgroundRect,
+ ClipRect& foregroundRect,
+ const LayoutPoint* offsetFromRoot) const {
+ backgroundRect = applyOverflowClipToBackgroundRectWithGeometryMapper(
+ context, clipRectWithGeometryMapper(context, false));
+ backgroundRect.move(
+ context.subPixelAccumulation); // TODO(chrishtr): is this needed?
+ backgroundRect.intersect(paintDirtyRect);
+
+ foregroundRect.move(
+ context.subPixelAccumulation); // TODO(chrishtr): is this needed?
+ foregroundRect = clipRectWithGeometryMapper(context, true);
+ foregroundRect.intersect(paintDirtyRect);
+ LayoutPoint offset;
+ if (offsetFromRoot)
+ offset = *offsetFromRoot;
+ else
+ m_layer.convertToLayerCoords(context.rootLayer, offset);
+ layerBounds = LayoutRect(offset, LayoutSize(m_layer.size()));
+
+#ifdef CHECK_CLIP_RECTS
+ ClipRect testBackgroundRect, testForegroundRect;
+ LayoutRect testLayerBounds;
+ PaintLayerClipper(m_layer, false)
+ .calculateRects(context, paintDirtyRect, testLayerBounds,
+ testBackgroundRect, testForegroundRect);
+ CHECK_RECTS_EQ(testBackgroundRect, backgroundRect);
+ CHECK_RECTS_EQ(testForegroundRect, foregroundRect);
+ CHECK_RECTS_EQ(testLayerBounds, layerBounds);
+#endif
+}
+
void PaintLayerClipper::calculateRects(
const ClipRectsContext& context,
const LayoutRect& paintDirtyRect,
@@ -217,6 +316,13 @@ void PaintLayerClipper::calculateRects(
ClipRect& backgroundRect,
ClipRect& foregroundRect,
const LayoutPoint* offsetFromRoot) const {
+ if (m_geometryMapper) {
+ calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds,
+ backgroundRect, foregroundRect,
+ offsetFromRoot);
+ return;
+ }
+
bool isClippingRoot = &m_layer == context.rootLayer;
LayoutBoxModelObject& layoutObject = *m_layer.layoutObject();
@@ -327,8 +433,77 @@ static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects,
return parentRects.overflowClipRect();
}
+ClipRect PaintLayerClipper::clipRectWithGeometryMapper(
+ const ClipRectsContext& context,
+ bool isForeground) const {
+ DCHECK(m_geometryMapper);
+ LayoutRect source(LayoutRect::infiniteIntRect());
+ bool success = false;
+ const ObjectPaintProperties* properties =
+ m_layer.layoutObject()->objectPaintProperties();
+ PropertyTreeState propertyTreeState =
+ properties->localBorderBoxProperties()->propertyTreeState;
+
+ if (properties->cssClip())
+ propertyTreeState.setClip(properties->cssClip());
+
+ const LayoutObject& layoutObject = *m_layer.layoutObject();
+ if (shouldRespectOverflowClip(context) && isForeground &&
+ (layoutObject.hasOverflowClip() ||
+ layoutObject.styleRef().containsPaint())) {
+ if (properties->overflowClip())
+ propertyTreeState.setClip(properties->overflowClip());
+ }
+
+ const ObjectPaintProperties* ancestorProperties =
+ context.rootLayer->layoutObject()->objectPaintProperties();
+ PropertyTreeState destinationPropertyTreeState =
+ ancestorProperties->localBorderBoxProperties()->propertyTreeState;
+ if (!context.rootLayer->clipper().shouldRespectOverflowClip(context)) {
+ if (ancestorProperties->overflowClip())
+ destinationPropertyTreeState.setClip(ancestorProperties->overflowClip());
+ }
+ FloatRect clippedRectInRootLayerSpace =
+ m_geometryMapper->mapToVisualRectInDestinationSpace(
+ FloatRect(source), propertyTreeState, destinationPropertyTreeState,
+ success);
+ DCHECK(success);
+ return ClipRect(LayoutRect(clippedRectInRootLayerSpace));
+}
+
+ClipRect PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper(
+ const ClipRectsContext& context,
+ const ClipRect& clip) const {
+ const LayoutObject& layoutObject = *m_layer.layoutObject();
+ FloatRect clipRect(clip.rect());
+ if ((layoutObject.hasOverflowClip() ||
+ layoutObject.styleRef().containsPaint()) &&
+ shouldRespectOverflowClip(context)) {
+ LayoutRect layerBoundsWithVisualOverflow =
+ layoutObject.isLayoutView()
+ ? toLayoutView(layoutObject).viewRect()
+ : toLayoutBox(layoutObject).visualOverflowRect();
+ toLayoutBox(layoutObject)
+ .flipForWritingMode(
+ layerBoundsWithVisualOverflow); // PaintLayer are in physical coordinates, so the overflow has to be flipped.
Xianzhu 2016/10/06 00:13:32 Nit: 80 chars
chrishtr 2016/10/06 17:11:08 Fixed.
+ mapLocalToRootWithGeometryMapper(context, layerBoundsWithVisualOverflow);
+ clipRect.intersect(FloatRect(layerBoundsWithVisualOverflow));
+ }
+
+ return ClipRect(LayoutRect(clipRect));
+}
+
ClipRect PaintLayerClipper::backgroundClipRect(
const ClipRectsContext& context) const {
+ if (m_geometryMapper) {
+ ClipRect backgroundClipRect = clipRectWithGeometryMapper(context, false);
+#ifdef CHECK_CLIP_RECTS
+ ClipRect testBackgroundClipRect =
+ PaintLayerClipper(m_layer, false).backgroundClipRect(context);
+ CHECK_RECTS_EQ(testBackgroundClipRect, backgroundClipRect);
+#endif
+ return backgroundClipRect;
+ }
DCHECK(m_layer.parent());
LayoutView* layoutView = m_layer.layoutObject()->view();
DCHECK(layoutView);
@@ -380,6 +555,7 @@ ClipRects& PaintLayerClipper::paintingClipRects(
const PaintLayer* rootLayer,
ShouldRespectOverflowClipType respectOverflowClip,
const LayoutSize& subpixelAccumulation) const {
+ DCHECK(!m_geometryMapper);
ClipRectsContext context(rootLayer, PaintingClipRects,
IgnoreOverlayScrollbarSize, subpixelAccumulation);
if (respectOverflowClip == IgnoreOverflowClip)

Powered by Google App Engine
This is Rietveld 408576698