Index: Source/core/rendering/compositing/CompositedLayerMapping.cpp |
diff --git a/Source/core/rendering/compositing/CompositedLayerMapping.cpp b/Source/core/rendering/compositing/CompositedLayerMapping.cpp |
index 5c12881a8f0c78500ba03cc1f7248613ecdc5f7d..b12a2a76779eca480e6afdf7a1d1366534d4edda 100644 |
--- a/Source/core/rendering/compositing/CompositedLayerMapping.cpp |
+++ b/Source/core/rendering/compositing/CompositedLayerMapping.cpp |
@@ -601,7 +601,11 @@ void CompositedLayerMapping::updateSquashingLayerGeometry(const IntPoint& delta) |
// FIXME: find a better design to avoid this redundant value - most likely it will make |
// sense to move the paint task info into RenderLayer's m_compositingProperties. |
m_squashedLayers[i].renderLayer->setOffsetFromSquashingLayerOrigin(m_squashedLayers[i].offsetFromRenderer); |
+ |
} |
+ |
+ for (size_t i = 0; i < m_squashedLayers.size(); ++i) |
+ m_squashedLayers[i].localClipRectForSquashedLayer = localClipRectForSquashedLayer(m_squashedLayers[i]); |
} |
void CompositedLayerMapping::updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType updateType, const RenderLayer* compositingContainer) |
@@ -1834,6 +1838,39 @@ void CompositedLayerMapping::setContentsNeedDisplayInRect(const IntRect& r) |
ApplyToGraphicsLayers(this, functor, ApplyToContentLayers); |
} |
+const GraphicsLayerPaintInfo* CompositedLayerMapping::containingSquashedLayer(const RenderObject* renderObject) const |
+{ |
+ for (size_t i = 0; i < m_squashedLayers.size(); ++i) { |
+ if (renderObject->isDescendantOf(m_squashedLayers[i].renderLayer->renderer())) { |
+ return &m_squashedLayers[i]; |
+ break; |
+ } |
+ } |
+ return 0; |
+} |
+ |
+IntRect CompositedLayerMapping::localClipRectForSquashedLayer(const GraphicsLayerPaintInfo& paintInfo) const |
+{ |
+ const RenderObject* clippingContainer = paintInfo.renderLayer->renderer()->clippingContainer(); |
+ if (clippingContainer == m_owningLayer.renderer()->clippingContainer()) |
+ return PaintInfo::infiniteRect(); |
+ |
+ ASSERT(clippingContainer); |
+ |
+ const GraphicsLayerPaintInfo* ancestorPaintInfo = containingSquashedLayer(clippingContainer); |
+ // Must be there, otherwise CompositingLayerAssigner::canSquashIntoCurrentSquashingOwner would have disallowed squashing. |
+ ASSERT(ancestorPaintInfo); |
+ |
+ ClipRectsContext clipRectsContext(ancestorPaintInfo->renderLayer, TemporaryClipRects); |
Ian Vollick
2014/05/08 20:56:19
This could hurt perf. Even if we don't figure out
chrishtr
2014/05/08 20:58:15
Added a FIXME.
|
+ IntRect parentClipRect = pixelSnappedIntRect(paintInfo.renderLayer->clipper().backgroundClipRect(clipRectsContext).rect()); |
+ ASSERT(parentClipRect != PaintInfo::infiniteRect()); |
+ |
+ // Convert from ancestor to local coordinates. |
+ IntSize ancestorToLocalOffset = paintInfo.offsetFromRenderer - ancestorPaintInfo->offsetFromRenderer; |
+ parentClipRect.move(ancestorToLocalOffset); |
+ return parentClipRect; |
+} |
+ |
void CompositedLayerMapping::doPaintTask(GraphicsLayerPaintInfo& paintInfo, GraphicsContext* context, |
const IntRect& clip) // In the coords of rootLayer. |
{ |
@@ -1902,10 +1939,10 @@ void CompositedLayerMapping::doPaintTask(GraphicsLayerPaintInfo& paintInfo, Grap |
LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, paintInfo.renderLayer->subpixelAccumulation()); |
// RenderLayer::paintLayer assumes that the caller clips to the passed rect. Squashed layers need to do this clipping in software, |
- // since there is no graphics layer to clip them precisely. |
- // FIXME: in some cases this clip is not necessary. For example if the dirty rect is not the same as the bounds of the layer, |
- // RenderLayer will clip it (see RenderLayer::clipToRect). Put in more work if this becomes a performance issue. |
+ // since there is no graphics layer to clip them precisely. Furthermore, in some cases we squash layers that need clipping in software |
+ // from clipping ancestors (see CompositedLayerMapping::localClipRectForSquashedLayer()). |
context->save(); |
+ dirtyRect.intersect(paintInfo.localClipRectForSquashedLayer); |
context->clip(dirtyRect); |
paintInfo.renderLayer->paintLayer(context, paintingInfo, paintFlags); |
context->restore(); |