Chromium Code Reviews| 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 44553cf74390c80e71bbc69a508710e3cb462198..25db2e5ae4df127e140b85e65a75375fecee61a1 100644 |
| --- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp |
| +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp |
| @@ -46,6 +46,7 @@ |
| #include "core/frame/FrameView.h" |
| #include "core/frame/Settings.h" |
| #include "core/layout/LayoutView.h" |
| +#include "core/paint/ObjectPaintProperties.h" |
| #include "core/paint/PaintLayer.h" |
| namespace blink { |
| @@ -94,6 +95,10 @@ static void applyClipRects(const ClipRectsContext& context, const LayoutBoxModel |
| } |
| } |
| +PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer) |
| + : m_layer(layer), m_geometryMapper(RuntimeEnabledFeatures::slimmingPaintV2Enabled() ? new GeometryMapper : nullptr) |
| +{ } |
| + |
| ClipRects* PaintLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const |
| { |
| ASSERT(context.usesCache()); |
| @@ -152,6 +157,8 @@ ClipRects& PaintLayerClipper::getClipRects(const ClipRectsContext& context) cons |
| void PaintLayerClipper::clearClipRectsIncludingDescendants() |
| { |
| + if (m_geometryMapper) |
| + m_geometryMapper.reset(new GeometryMapper); |
|
Xianzhu
2016/08/15 17:09:04
Can you give some performance analysis? Can we sha
chrishtr
2016/10/05 23:28:32
Don't have any yet. I'd prefer to commit this firs
|
| m_layer.clearClipRectsCache(); |
| for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSibling()) { |
| @@ -161,6 +168,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); |
| @@ -171,9 +181,22 @@ void PaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCacheSlot ca |
| LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) const |
| { |
| + ClipRectsContext context(clippingRootLayer, PaintingClipRects); |
| + if (m_geometryMapper) { |
| + ClipRect clipRect = clipRectWithGeometryMapper(context, false); |
| + |
| + // The rect now needs to be transformed to the local space of this PaintLayer. |
| + 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); |
| LayoutRect clipRect = backgroundRect.rect(); |
| @@ -191,6 +214,17 @@ LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) |
| void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, |
| ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offsetFromRoot) const |
| { |
| + if (m_geometryMapper) { |
| + backgroundRect = 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); |
| + return; |
| + } |
| + |
| bool isClippingRoot = &m_layer == context.rootLayer; |
| LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); |
| @@ -281,8 +315,39 @@ static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPos |
| 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 (isForeground) { |
| + if (properties->cssClip()) |
| + propertyTreeState.clip = properties->cssClip(); |
| + else if (properties->overflowClip()) |
| + propertyTreeState.clip = properties->overflowClip(); |
| + } |
| + |
| + const ObjectPaintProperties* ancestorProperties = m_layer.layoutObject()->objectPaintProperties(); |
| + PropertyTreeState destinationPropertyTreeState = ancestorProperties->localBorderBoxProperties()->propertyTreeState; |
| + if (!context.rootLayer->clipper().shouldRespectOverflowClip(context)) { |
| + if (ancestorProperties->overflowClip()) |
| + destinationPropertyTreeState.clip = ancestorProperties->overflowClip(); |
| + } |
| + |
| + FloatRect clippedRectInRootLayerSpace = m_geometryMapper->mapToVisualRectInDestinationSpace( |
| + FloatRect(source), propertyTreeState, destinationPropertyTreeState, success); |
| + DCHECK(success); |
| + return ClipRect(LayoutRect(clippedRectInRootLayerSpace)); |
| +} |
| + |
| ClipRect PaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const |
| { |
| + if (m_geometryMapper) { |
| + return clipRectWithGeometryMapper(context, false); |
| + } |
| + |
| ASSERT(m_layer.parent()); |
| LayoutView* layoutView = m_layer.layoutObject()->view(); |
| ASSERT(layoutView); |
| @@ -326,6 +391,7 @@ bool PaintLayerClipper::shouldRespectOverflowClip(const ClipRectsContext& contex |
| ClipRects& PaintLayerClipper::paintingClipRects(const PaintLayer* rootLayer, ShouldRespectOverflowClipType respectOverflowClip, const LayoutSize& subpixelAccumulation) const |
| { |
| + DCHECK(!m_geometryMapper); |
| ClipRectsContext context(rootLayer, PaintingClipRects, IgnoreOverlayScrollbarSize, subpixelAccumulation); |
| if (respectOverflowClip == IgnoreOverflowClip) |
| context.setIgnoreOverflowClip(); |