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(); |