Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1164)

Unified Diff: Source/core/paint/LayerPainter.cpp

Issue 727633002: Get rid of the one remaining extra call to LayerPainter::beginTransparencyLayers. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/paint/LayerPainter.h ('k') | Source/core/rendering/RenderLayer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/paint/LayerPainter.cpp
diff --git a/Source/core/paint/LayerPainter.cpp b/Source/core/paint/LayerPainter.cpp
index ca4cdba201ab4e5cfce3007d8e410c5c1fe3a3e5..5eff16940344142d3fb548d2f40dd70b0c311e30 100644
--- a/Source/core/paint/LayerPainter.cpp
+++ b/Source/core/paint/LayerPainter.cpp
@@ -75,17 +75,8 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
if (!layerTransform.isInvertible())
return;
- // 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())
- LayerPainter(*m_renderLayer.parent()).beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
mstensho (USE GERRIT) 2014/11/14 12:20:51 I think this change is actually what causes the in
chrishtr 2014/11/14 20:11:37 Done.
- else
- beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
- }
-
if (m_renderLayer.enclosingPaginationLayer()) {
+ // FIXME: unify this one-off path with the code below.
mstensho (USE GERRIT) 2014/11/14 12:20:52 I'm on it. :)
chrishtr 2014/11/14 20:11:37 ack!
paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags);
return;
}
@@ -116,24 +107,58 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
paintLayerContentsAndReflection(context, paintingInfo, paintFlags);
}
-bool LayerPainter::shouldCreateTransparencyLayerForBlendMode()
-{
- 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)
+bool shouldUseTransparencyLayer(RenderLayer& renderLayer, PaintBehavior paintBehavior)
mstensho (USE GERRIT) 2014/11/14 12:20:51 static? Static inline, even?
chrishtr 2014/11/14 20:11:36 Inlined.
{
// 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;
+ bool shouldUseTransparencyLayerForBlendMode = !renderLayer.renderer()->isDocumentElement() && renderLayer.stackingNode()->isStackingContext() && renderLayer.hasNonIsolatedDescendantWithBlendMode();
+ return renderLayer.paintsWithTransparency(paintBehavior) || shouldUseTransparencyLayerForBlendMode;
mstensho (USE GERRIT) 2014/11/14 12:20:51 Might as well flip the expressions here. No need t
chrishtr 2014/11/14 20:11:36 Done.
+}
- // FIXME: refactor to remove this.
- if (m_renderLayer.usedTransparency())
+class TransparencyLayerHelper {
+public:
+ TransparencyLayerHelper(GraphicsContext* context, RenderLayer& renderLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
+ : m_transparencyLayerInProgress(false)
+ , m_context(context)
+ {
+ if (!shouldUseTransparencyLayer(renderLayer, paintBehavior))
+ return;
+
+ context->save();
+ LayoutRect clipRect = renderLayer.paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
+ context->clip(clipRect);
+
+ if (renderLayer.renderer()->hasBlendMode())
+ context->setCompositeOperation(context->compositeOperation(), renderLayer.renderer()->style()->blendMode());
+
+ context->beginTransparencyLayer(renderLayer.renderer()->opacity());
+
+ if (renderLayer.renderer()->hasBlendMode())
+ context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal);
+#ifdef REVEAL_TRANSPARENCY_LAYERS
+ context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f));
+#endif
+ m_transparencyLayerInProgress = true;
+ }
+
+ ~TransparencyLayerHelper()
+ {
+ if (m_transparencyLayerInProgress) {
mstensho (USE GERRIT) 2014/11/14 12:20:51 Couldn't you just NULL m_context if there's no tra
chrishtr 2014/11/14 20:11:36 Feels ugly to me.
mstensho (USE GERRIT) 2014/11/14 23:03:21 Acknowledged.
+ m_context->endLayer();
+ m_context->restore();
+ }
+ }
+private:
+ bool m_transparencyLayerInProgress;
+ GraphicsContext* m_context;
+};
+
+void LayerPainter::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
mstensho (USE GERRIT) 2014/11/14 12:20:51 Bye-bye to this then. :)
chrishtr 2014/11/14 20:11:36 Yeah, forgot to delete. Sorry for the sloppy work
mstensho (USE GERRIT) 2014/11/14 23:03:21 No worries. Didn't keep me from seeing the inner b
+{
+ if (!shouldUseTransparencyLayer(m_renderLayer, paintBehavior))
return;
- m_renderLayer.setUsedTransparency(true);
context->save();
LayoutRect clipRect = m_renderLayer.paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
context->clip(clipRect);
@@ -272,88 +297,81 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint
ClipPathHelper clipPathHelper(context, m_renderLayer, paintingInfo, rootRelativeBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags);
- beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
-
- LayerPaintingInfo localPaintingInfo(paintingInfo);
-
- LayerFragments layerFragments;
- if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
- // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment.
- m_renderLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
- (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
- shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
- if (shouldPaintContent)
- shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFragments, localPaintingInfo, paintFlags, offsetFromRoot);
- }
-
- bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
- // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
- // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
- // Else, our renderer tree may or may not contain the painting root, so we pass that root along
- // so it will be tested against as we descend through the renderers.
- RenderObject* paintingRootForRenderer = 0;
- if (localPaintingInfo.paintingRoot && !m_renderLayer.renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
- paintingRootForRenderer = localPaintingInfo.paintingRoot;
-
- { // Begin block for the lifetime of any filter.
- FilterPainter filterPainter(m_renderLayer, context, offsetFromRoot, layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect, localPaintingInfo, paintFlags,
- rootRelativeBounds, rootRelativeBoundsComputed);
-
- ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText));
-
- bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
- bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground);
- bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent;
- bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground;
- bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars;
-
- PaintBehavior paintBehavior = PaintBehaviorNormal;
- if (paintFlags & PaintLayerPaintingSkipRootBackground)
- paintBehavior |= PaintBehaviorSkipRootBackground;
- else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
- paintBehavior |= PaintBehaviorRootBackgroundOnly;
-
- if (shouldPaintBackground) {
- paintBackgroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect,
- localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+ {
mstensho (USE GERRIT) 2014/11/14 12:20:51 No need for this scope.
chrishtr 2014/11/14 20:11:36 The reason I have a scope is to distinguish it fro
mstensho (USE GERRIT) 2014/11/14 23:03:22 Aren't the objects guaranteed to be destroyed in r
chrishtr 2014/11/14 23:05:45 Probably, but I couldn't say that for sure without
mstensho (USE GERRIT) 2014/11/14 23:24:13 https://isocpp.org/wiki/faq/dtors#order-dtors-for-
+ TransparencyLayerHelper transparencyLayerHelper(context, m_renderLayer, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
+
+ LayerPaintingInfo localPaintingInfo(paintingInfo);
+
+ LayerFragments layerFragments;
+ if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
+ // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment.
+ m_renderLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
+ (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
+ shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
+ if (shouldPaintContent)
+ shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFragments, localPaintingInfo, paintFlags, offsetFromRoot);
}
- if (shouldPaintNegZOrderList)
- paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags);
-
- if (shouldPaintOwnContents) {
- paintForegroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect,
- localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags);
- }
+ bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
+ // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
+ // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
+ // Else, our renderer tree may or may not contain the painting root, so we pass that root along
+ // so it will be tested against as we descend through the renderers.
+ RenderObject* paintingRootForRenderer = 0;
+ if (localPaintingInfo.paintingRoot && !m_renderLayer.renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
+ paintingRootForRenderer = localPaintingInfo.paintingRoot;
+
+ { // Begin block for the lifetime of any filter.
+ FilterPainter filterPainter(m_renderLayer, context, offsetFromRoot, layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect, localPaintingInfo, paintFlags,
+ rootRelativeBounds, rootRelativeBoundsComputed);
+
+ ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText));
+
+ bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
+ bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground);
+ bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent;
+ bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground;
+ bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars;
+
+ PaintBehavior paintBehavior = PaintBehaviorNormal;
+ if (paintFlags & PaintLayerPaintingSkipRootBackground)
+ paintBehavior |= PaintBehaviorSkipRootBackground;
+ else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
+ paintBehavior |= PaintBehaviorRootBackgroundOnly;
+
+ if (shouldPaintBackground) {
+ paintBackgroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect,
+ localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+ }
- if (shouldPaintOutline)
- paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+ if (shouldPaintNegZOrderList)
+ paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags);
- if (shouldPaintNormalFlowAndPosZOrderLists)
- paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags);
+ if (shouldPaintOwnContents) {
+ paintForegroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect,
+ localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags);
+ }
- if (shouldPaintOverlayScrollbars)
- paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
- } // Filter painter block
+ if (shouldPaintOutline)
+ paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
- bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && m_renderLayer.renderer()->hasMask() && !selectionOnly;
- bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly;
+ if (shouldPaintNormalFlowAndPosZOrderLists)
+ paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags);
- if (shouldPaintMask)
- paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
+ if (shouldPaintOverlayScrollbars)
+ paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
+ } // FilterPainter block
- if (shouldPaintClippingMask) {
- // Paint the border radius mask for the fragments.
- paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
- }
+ bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && m_renderLayer.renderer()->hasMask() && !selectionOnly;
+ bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly;
- // End our transparency layer
- if (((paintFlags & PaintLayerHaveTransparency) || shouldCreateTransparencyLayerForBlendMode()) && m_renderLayer.usedTransparency()
- && !(m_renderLayer.reflectionInfo() && m_renderLayer.reflectionInfo()->isPaintingInsideReflection())) {
- context->endLayer();
- context->restore();
- m_renderLayer.setUsedTransparency(false);
- }
+ if (shouldPaintMask)
+ paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
+ if (shouldPaintClippingMask) {
+ // Paint the border radius mask for the fragments.
+ paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
+ }
+ } // TransparencyLayerHelper block
}
static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
« no previous file with comments | « Source/core/paint/LayerPainter.h ('k') | Source/core/rendering/RenderLayer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698