Chromium Code Reviews| Index: Source/core/paint/LayerPainter.cpp |
| diff --git a/Source/core/paint/LayerPainter.cpp b/Source/core/paint/LayerPainter.cpp |
| index d00ce6861dcc3d923586b85163ba3eb9cb1e601f..aba2781df0fcb88a7df6c24c58872b045c1fe13d 100644 |
| --- a/Source/core/paint/LayerPainter.cpp |
| +++ b/Source/core/paint/LayerPainter.cpp |
| @@ -98,7 +98,7 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo& |
| clipRect.intersect(paintingInfo.paintDirtyRect); |
| // Push the parent coordinate space's clip. |
| - LayerPainter(*m_renderLayer.parent()).clipToRect(paintingInfo, context, clipRect, paintFlags); |
| + LayerPainter(*m_renderLayer.parent()).clipToRect(paintingInfo, context, clipRect, paintFlags, ClipDisplayItem::LayerParent); |
| } |
| paintLayerByApplyingTransform(context, paintingInfo, paintFlags); |
| @@ -276,11 +276,12 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
| // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one after filter processing. |
| beginTransparencyLayers(context, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); |
| } |
| + |
| // We'll handle clipping to the dirty rect before filter rasterization. |
| // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets. |
| // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved. |
| ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect; |
| - clipToRect(localPaintingInfo, context, backgroundRect, paintFlags); |
| + clipToRect(localPaintingInfo, context, backgroundRect, paintFlags, ClipDisplayItem::LayerFilter); |
| // Subsequent code should not clip to the dirty rect, since we've already |
| // done it above, and doing it later will defeat the outsets. |
| localPaintingInfo.clipToDirtyRect = false; |
| @@ -381,12 +382,12 @@ static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye |
| } |
| void LayerPainter::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect, |
| - PaintLayerFlags paintFlags, BorderRadiusClippingRule rule) |
| + PaintLayerFlags paintFlags, ClipDisplayItem::ClipType clipType, BorderRadiusClippingRule rule) |
| { |
| if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius()) |
| return; |
| - context->save(); |
| - context->clip(pixelSnappedIntRect(clipRect.rect())); |
| + |
| + StartClipRecorder startClipRecorder(&m_renderLayer, context, clipType, clipRect); |
|
pdr.
2014/10/16 17:38:12
This may be cleaner if it is just a static functio
|
| if (!clipRect.hasRadius()) |
| return; |
| @@ -405,7 +406,7 @@ void LayerPainter::clipToRect(const LayerPaintingInfo& localPaintingInfo, Graphi |
| if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(&m_renderLayer, layer)) { |
| LayoutPoint delta; |
| layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta); |
| - context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size()))); |
| + startClipRecorder.addRoundedRectClip(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size()))); |
| } |
| if (layer == localPaintingInfo.rootLayer) |
| @@ -417,7 +418,7 @@ void LayerPainter::restoreClip(GraphicsContext* context, const LayoutRect& paint |
| { |
| if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius()) |
| return; |
| - context->restore(); |
| + EndClipRecorder endClipRecorder(&m_renderLayer, context); |
| } |
| void LayerPainter::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags localPaintFlags, |
| @@ -513,7 +514,8 @@ void LayerPainter::paintOverflowControlsForFragments(const LayerFragments& layer |
| { |
| for (size_t i = 0; i < layerFragments.size(); ++i) { |
| const LayerFragment& fragment = layerFragments.at(i); |
| - clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags); |
| + |
| + clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, ClipDisplayItem::LayerOverflowControls); |
| if (RenderLayerScrollableArea* scrollableArea = m_renderLayer.scrollableArea()) |
| scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true); |
| restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect); |
| @@ -676,7 +678,7 @@ void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme |
| if (localPaintingInfo.clipToDirtyRect) { |
| // Paint our background first, before painting any child layers. |
| // Establish the clip used to paint our background. |
| - clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self. |
| + clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, ClipDisplayItem::LayerBackground, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self. |
| } |
| // Paint the background. |
| @@ -707,7 +709,7 @@ void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme |
| // Optimize clipping for the single fragment case. |
| bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty(); |
| if (shouldClip) |
| - clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags); |
| + clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags, ClipDisplayItem::LayerForeground); |
| // We have to loop through every fragment multiple times, since we have to issue paint invalidations in each specific phase in order for |
| // interleaving of the fragments to work properly. |
| @@ -734,8 +736,24 @@ void LayerPainter::paintForegroundForFragmentsWithPhase(PaintPhase phase, const |
| if (!fragment.shouldPaintContent || fragment.foregroundRect.isEmpty()) |
| continue; |
| - if (shouldClip) |
| - clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags); |
| + if (shouldClip) { |
| + // Note: this method only clips when there is more than one fragment. |
| + ClipDisplayItem::ClipType clipType = (ClipDisplayItem::ClipType)0; |
| + switch (phase) { |
| + case PaintPhaseFloat: |
| + clipType = ClipDisplayItem::LayerFragmentFloat; |
| + break; |
| + case PaintPhaseForeground: |
| + clipType = ClipDisplayItem::LayerFragmentForeground; |
| + break; |
| + case PaintPhaseChildOutlines: |
| + clipType = ClipDisplayItem::LayerFragmentChildOutline; |
| + break; |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + } |
| + clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, clipType); |
| + } |
| PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); |
| m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.compositingState()))); |
| @@ -755,7 +773,7 @@ void LayerPainter::paintOutlineForFragments(const LayerFragments& layerFragments |
| // Paint our own outline |
| PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); |
| - clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, DoNotIncludeSelfForBorderRadius); |
| + clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, ClipDisplayItem::LayerFragmentOutline, DoNotIncludeSelfForBorderRadius); |
| m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, m_renderLayer.compositingState()))); |
| restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect); |
| } |
| @@ -770,7 +788,7 @@ void LayerPainter::paintMaskForFragments(const LayerFragments& layerFragments, G |
| continue; |
| if (localPaintingInfo.clipToDirtyRect) |
| - clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self. |
| + clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, ClipDisplayItem::LayerFragmentMask, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self. |
| // Paint the mask. |
| // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. |
| @@ -791,7 +809,7 @@ void LayerPainter::paintChildClippingMaskForFragments(const LayerFragments& laye |
| continue; |
| if (localPaintingInfo.clipToDirtyRect) |
| - clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self. |
| + clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, ClipDisplayItem::LayerFragmentClippingMask, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self. |
| // Paint the the clipped mask. |
| PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer()); |
| @@ -841,7 +859,7 @@ void LayerPainter::paintTransformedLayerIntoFragments(GraphicsContext* context, |
| clipRect.intersect(parentClipRect); |
| } |
| - LayerPainter(*m_renderLayer.parent()).clipToRect(paintingInfo, context, clipRect, paintFlags); |
| + LayerPainter(*m_renderLayer.parent()).clipToRect(paintingInfo, context, clipRect, paintFlags, ClipDisplayItem::LayerFragmentParent); |
| paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset); |
| LayerPainter(*m_renderLayer.parent()).restoreClip(context, paintingInfo.paintDirtyRect, clipRect); |
| } |