Index: Source/core/paint/LayerPainter.cpp |
diff --git a/Source/core/paint/LayerPainter.cpp b/Source/core/paint/LayerPainter.cpp |
index 8ea130a6d2e19a1f518261f1d798863d14193eee..ca4cdba201ab4e5cfce3007d8e410c5c1fe3a3e5 100644 |
--- a/Source/core/paint/LayerPainter.cpp |
+++ b/Source/core/paint/LayerPainter.cpp |
@@ -78,10 +78,11 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo& |
// If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency |
// layer from the parent now, assuming there is a parent |
if (paintFlags & PaintLayerHaveTransparency) { |
+ // FIXME: can we get rid of this? It would mean transparency starts after clipping in these cases. |
if (m_renderLayer.parent()) |
- beginTransparencyLayers(context, *m_renderLayer.parent(), paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
+ LayerPainter(*m_renderLayer.parent()).beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
else |
- beginTransparencyLayers(context, m_renderLayer, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
+ beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
} |
if (m_renderLayer.enclosingPaginationLayer()) { |
@@ -115,33 +116,38 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo& |
paintLayerContentsAndReflection(context, paintingInfo, paintFlags); |
} |
-void LayerPainter::beginTransparencyLayers(GraphicsContext* context, RenderLayer& renderLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) |
+bool LayerPainter::shouldCreateTransparencyLayerForBlendMode() |
{ |
- bool createTransparencyLayerForBlendMode = renderLayer.stackingNode()->isStackingContext() && renderLayer.hasNonIsolatedDescendantWithBlendMode(); |
- if ((renderLayer.paintsWithTransparency(paintBehavior) || createTransparencyLayerForBlendMode) && renderLayer.usedTransparency()) |
+ return !m_renderLayer.renderer()->isDocumentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLayer.hasNonIsolatedDescendantWithBlendMode(); |
+} |
+ |
+void LayerPainter::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) |
+{ |
+ // Blending operations must be performed only with the nearest ancestor stacking context. |
+ // Note that there is no need to create a transparency layer if we're painting the root. |
+ // FIXME: this should be unified further into RenderLayer::paintsWithTransparency(). |
+ if (!m_renderLayer.paintsWithTransparency(paintBehavior) && !shouldCreateTransparencyLayerForBlendMode()) |
return; |
- RenderLayer* ancestor = renderLayer.transparentPaintingAncestor(); |
- if (ancestor) |
- beginTransparencyLayers(context, *ancestor, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior); |
+ // FIXME: refactor to remove this. |
+ if (m_renderLayer.usedTransparency()) |
+ return; |
- if (renderLayer.paintsWithTransparency(paintBehavior) || createTransparencyLayerForBlendMode) { |
- renderLayer.setUsedTransparency(true); |
- context->save(); |
- LayoutRect clipRect = renderLayer.paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior); |
- context->clip(clipRect); |
+ m_renderLayer.setUsedTransparency(true); |
+ context->save(); |
+ LayoutRect clipRect = m_renderLayer.paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior); |
+ context->clip(clipRect); |
- if (renderLayer.renderer()->hasBlendMode()) |
- context->setCompositeOperation(context->compositeOperation(), renderLayer.renderer()->style()->blendMode()); |
+ if (m_renderLayer.renderer()->hasBlendMode()) |
+ context->setCompositeOperation(context->compositeOperation(), m_renderLayer.renderer()->style()->blendMode()); |
- context->beginTransparencyLayer(renderLayer.renderer()->opacity()); |
+ context->beginTransparencyLayer(m_renderLayer.renderer()->opacity()); |
- if (renderLayer.renderer()->hasBlendMode()) |
- context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal); |
+ if (m_renderLayer.renderer()->hasBlendMode()) |
+ context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal); |
#ifdef REVEAL_TRANSPARENCY_LAYERS |
- context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f)); |
+ context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f)); |
#endif |
- } |
} |
void LayerPainter::paintLayerContentsAndReflection(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
@@ -229,7 +235,6 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingLayerDescendant()); |
ASSERT(!(paintFlags & PaintLayerAppliedTransform)); |
- bool haveTransparency = paintFlags & PaintLayerHaveTransparency; |
bool isSelfPaintingLayer = m_renderLayer.isSelfPaintingLayer(); |
bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars; |
bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase; |
@@ -267,12 +272,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
ClipPathHelper clipPathHelper(context, m_renderLayer, paintingInfo, rootRelativeBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); |
- // Blending operations must be performed only with the nearest ancestor stacking context. |
- // Note that there is no need to create a transparency layer if we're painting the root. |
- bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocumentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLayer.hasNonIsolatedDescendantWithBlendMode(); |
- |
- if (createTransparencyLayerForBlendMode) |
- beginTransparencyLayers(context, m_renderLayer, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
+ beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
LayerPaintingInfo localPaintingInfo(paintingInfo); |
@@ -314,7 +314,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
paintBehavior |= PaintBehaviorRootBackgroundOnly; |
if (shouldPaintBackground) { |
- paintBackgroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect, haveTransparency, |
+ paintBackgroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect, |
localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags); |
} |
@@ -322,7 +322,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags); |
if (shouldPaintOwnContents) { |
- paintForegroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect, haveTransparency, |
+ paintForegroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect, |
localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags); |
} |
@@ -348,7 +348,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
} |
// End our transparency layer |
- if ((haveTransparency || createTransparencyLayerForBlendMode) && m_renderLayer.usedTransparency() |
+ if (((paintFlags & PaintLayerHaveTransparency) || shouldCreateTransparencyLayerForBlendMode()) && m_renderLayer.usedTransparency() |
&& !(m_renderLayer.reflectionInfo() && m_renderLayer.reflectionInfo()->isPaintingInsideReflection())) { |
context->endLayer(); |
context->restore(); |
@@ -702,33 +702,18 @@ void LayerPainter::paintFragmentWithPhase(PaintPhase phase, const LayerFragment& |
} |
void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, |
- const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
+ const LayoutRect& transparencyPaintDirtyRect, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) |
{ |
for (const auto& fragment: layerFragments) { |
- // Begin transparency layers lazily now that we know we have to paint something. |
- if (haveTransparency) |
- beginTransparencyLayers(context, m_renderLayer, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); |
- |
paintFragmentWithPhase(PaintPhaseBlockBackground, fragment, context, fragment.backgroundRect, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags, HasNotClipped); |
} |
} |
void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, |
- const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
+ const LayoutRect& transparencyPaintDirtyRect, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags paintFlags) |
{ |
- // Begin transparency if we have something to paint. |
- if (haveTransparency) { |
- for (size_t i = 0; i < layerFragments.size(); ++i) { |
- const LayerFragment& fragment = layerFragments.at(i); |
- if (!fragment.foregroundRect.isEmpty()) { |
- beginTransparencyLayers(context, m_renderLayer, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); |
- break; |
- } |
- } |
- } |
- |
// Optimize clipping for the single fragment case. |
bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && !layerFragments[0].foregroundRect.isEmpty(); |
ClipState clipState = HasNotClipped; |