| Index: sky/engine/core/rendering/RenderBox.cpp
|
| diff --git a/sky/engine/core/rendering/RenderBox.cpp b/sky/engine/core/rendering/RenderBox.cpp
|
| index d97b921c5b138d3576e7737a8451761dc49b1021..4d4a814a9b0154c1612437f15f66275769d55bb5 100644
|
| --- a/sky/engine/core/rendering/RenderBox.cpp
|
| +++ b/sky/engine/core/rendering/RenderBox.cpp
|
| @@ -741,6 +741,53 @@ void RenderBox::paintLayer(GraphicsContext* context, const LayerPaintingInfo& pa
|
| layer()->parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
|
| }
|
|
|
| +static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, const LayoutSize& subPixelAccumulation);
|
| +
|
| +static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
|
| + const LayoutSize& subPixelAccumulation)
|
| +{
|
| + // Note: we don't have to walk z-order lists since transparent elements always establish
|
| + // a stacking container. This means we can just walk the layer tree directly.
|
| + for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling())
|
| + clipRect.unite(transparencyClipBox(curr, rootLayer, subPixelAccumulation));
|
| +}
|
| +
|
| +static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer,
|
| + const LayoutSize& subPixelAccumulation)
|
| +{
|
| + // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
|
| + // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
|
| + // would be better to respect clips.
|
| +
|
| + if (rootLayer != layer && layer->transform()) {
|
| + // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
|
| + // the transformed layer and all of its children.
|
| + const RenderLayer* rootLayerForTransform = rootLayer;
|
| + LayoutPoint delta;
|
| + layer->convertToLayerCoords(rootLayerForTransform, delta);
|
| +
|
| + delta.move(subPixelAccumulation);
|
| + IntPoint pixelSnappedDelta = roundedIntPoint(delta);
|
| + TransformationMatrix transform;
|
| + transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
|
| + transform = transform * *layer->transform();
|
| +
|
| + // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
|
| + // paints unfragmented.y
|
| + LayoutRect clipRect = layer->physicalBoundingBox(layer);
|
| + expandClipRectForDescendantsAndReflection(clipRect, layer, layer, subPixelAccumulation);
|
| + layer->renderer()->style()->filterOutsets().expandRect(clipRect);
|
| + LayoutRect result = transform.mapRect(clipRect);
|
| + return result;
|
| + }
|
| +
|
| + LayoutRect clipRect = layer->physicalBoundingBox(rootLayer);
|
| + expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, subPixelAccumulation);
|
| + layer->renderer()->style()->filterOutsets().expandRect(clipRect);
|
| + clipRect.move(subPixelAccumulation);
|
| + return clipRect;
|
| +}
|
| +
|
| void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo)
|
| {
|
| float deviceScaleFactor = blink::deviceScaleFactor(frame());
|
| @@ -788,8 +835,13 @@ void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPainting
|
| }
|
| }
|
|
|
| - if (layer()->isTransparent())
|
| - layer()->beginTransparencyLayers(context, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.subPixelAccumulation);
|
| + if (layer()->isTransparent()) {
|
| + context->save();
|
| + LayoutRect clipRect = intersection(paintingInfo.paintDirtyRect,
|
| + transparencyClipBox(layer(), localPaintingInfo.rootLayer, localPaintingInfo.subPixelAccumulation));
|
| + context->clip(clipRect);
|
| + context->beginTransparencyLayer(opacity());
|
| + }
|
|
|
| layer()->clipToRect(localPaintingInfo, context, contentRect);
|
|
|
|
|