OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/paint/LayerPainter.h" | 6 #include "core/paint/LayerPainter.h" |
7 | 7 |
8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
9 #include "core/page/Page.h" | 9 #include "core/page/Page.h" |
10 #include "core/paint/FilterPainter.h" | 10 #include "core/paint/FilterPainter.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying th e transform twice. | 71 // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying th e transform twice. |
72 if (m_renderLayer.paintsWithTransform(paintingInfo.paintBehavior) && !(paint Flags & PaintLayerAppliedTransform)) { | 72 if (m_renderLayer.paintsWithTransform(paintingInfo.paintBehavior) && !(paint Flags & PaintLayerAppliedTransform)) { |
73 TransformationMatrix layerTransform = m_renderLayer.renderableTransform( paintingInfo.paintBehavior); | 73 TransformationMatrix layerTransform = m_renderLayer.renderableTransform( paintingInfo.paintBehavior); |
74 // If the transform can't be inverted, then don't paint anything. | 74 // If the transform can't be inverted, then don't paint anything. |
75 if (!layerTransform.isInvertible()) | 75 if (!layerTransform.isInvertible()) |
76 return; | 76 return; |
77 | 77 |
78 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency | 78 // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency |
79 // layer from the parent now, assuming there is a parent | 79 // layer from the parent now, assuming there is a parent |
80 if (paintFlags & PaintLayerHaveTransparency) { | 80 if (paintFlags & PaintLayerHaveTransparency) { |
81 // FIXME: can we get rid of this? It would mean transparency starts after clipping in these cases. | |
mstensho (USE GERRIT)
2014/11/13 19:06:21
Did you try to just remove it? :)
I think this is
chrishtr
2014/11/13 19:40:57
No I didn't. I'll try in a followup, wanted to mak
mstensho (USE GERRIT)
2014/11/13 19:49:28
Acknowledged.
| |
81 if (m_renderLayer.parent()) | 82 if (m_renderLayer.parent()) |
82 beginTransparencyLayers(context, *m_renderLayer.parent(), painti ngInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation , paintingInfo.paintBehavior); | 83 LayerPainter(*m_renderLayer.parent()).beginTransparencyLayers(co ntext, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixe lAccumulation, paintingInfo.paintBehavior); |
83 else | 84 else |
84 beginTransparencyLayers(context, m_renderLayer, paintingInfo.roo tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, painting Info.paintBehavior); | 85 beginTransparencyLayers(context, paintingInfo.rootLayer, paintin gInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehav ior); |
85 } | 86 } |
86 | 87 |
87 if (m_renderLayer.enclosingPaginationLayer()) { | 88 if (m_renderLayer.enclosingPaginationLayer()) { |
88 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags ); | 89 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags ); |
89 return; | 90 return; |
90 } | 91 } |
91 | 92 |
92 // Make sure the parent's clip rects have been calculated. | 93 // Make sure the parent's clip rects have been calculated. |
93 ClipRect clipRect = paintingInfo.paintDirtyRect; | 94 ClipRect clipRect = paintingInfo.paintDirtyRect; |
94 | 95 |
(...skipping 13 matching lines...) Expand all Loading... | |
108 } | 109 } |
109 | 110 |
110 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); | 111 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); |
111 | 112 |
112 return; | 113 return; |
113 } | 114 } |
114 | 115 |
115 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); | 116 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); |
116 } | 117 } |
117 | 118 |
118 void LayerPainter::beginTransparencyLayers(GraphicsContext* context, RenderLayer & renderLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, c onst LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) | 119 bool LayerPainter::shouldCreateTransparencyLayerForBlendMode() |
119 { | 120 { |
120 bool createTransparencyLayerForBlendMode = renderLayer.stackingNode()->isSta ckingContext() && renderLayer.hasNonIsolatedDescendantWithBlendMode(); | 121 return !m_renderLayer.renderer()->isDocumentElement() && m_renderLayer.stack ingNode()->isStackingContext() && m_renderLayer.hasNonIsolatedDescendantWithBlen dMode(); |
121 if ((renderLayer.paintsWithTransparency(paintBehavior) || createTransparency LayerForBlendMode) && renderLayer.usedTransparency()) | 122 } |
123 | |
124 void LayerPainter::beginTransparencyLayers(GraphicsContext* context, const Rende rLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelA ccumulation, PaintBehavior paintBehavior) | |
125 { | |
126 // Blending operations must be performed only with the nearest ancestor stac king context. | |
127 // Note that there is no need to create a transparency layer if we're painti ng the root. | |
128 // FIXME: this should be unified further into RenderLayer::paintsWithTranspa rency(). | |
129 if (!m_renderLayer.paintsWithTransparency(paintBehavior) && !shouldCreateTra nsparencyLayerForBlendMode()) | |
122 return; | 130 return; |
123 | 131 |
124 RenderLayer* ancestor = renderLayer.transparentPaintingAncestor(); | 132 // FIXME: refactor to remove this. |
mstensho (USE GERRIT)
2014/11/13 19:06:21
+1
If you can get rid of the transparency layer b
chrishtr
2014/11/13 19:40:57
Exactly.
| |
125 if (ancestor) | 133 if (m_renderLayer.usedTransparency()) |
126 beginTransparencyLayers(context, *ancestor, rootLayer, paintDirtyRect, s ubPixelAccumulation, paintBehavior); | 134 return; |
127 | 135 |
128 if (renderLayer.paintsWithTransparency(paintBehavior) || createTransparencyL ayerForBlendMode) { | 136 m_renderLayer.setUsedTransparency(true); |
129 renderLayer.setUsedTransparency(true); | 137 context->save(); |
130 context->save(); | 138 LayoutRect clipRect = m_renderLayer.paintingExtent(rootLayer, paintDirtyRect , subPixelAccumulation, paintBehavior); |
131 LayoutRect clipRect = renderLayer.paintingExtent(rootLayer, paintDirtyRe ct, subPixelAccumulation, paintBehavior); | 139 context->clip(clipRect); |
132 context->clip(clipRect); | |
133 | 140 |
134 if (renderLayer.renderer()->hasBlendMode()) | 141 if (m_renderLayer.renderer()->hasBlendMode()) |
135 context->setCompositeOperation(context->compositeOperation(), render Layer.renderer()->style()->blendMode()); | 142 context->setCompositeOperation(context->compositeOperation(), m_renderLa yer.renderer()->style()->blendMode()); |
136 | 143 |
137 context->beginTransparencyLayer(renderLayer.renderer()->opacity()); | 144 context->beginTransparencyLayer(m_renderLayer.renderer()->opacity()); |
138 | 145 |
139 if (renderLayer.renderer()->hasBlendMode()) | 146 if (m_renderLayer.renderer()->hasBlendMode()) |
140 context->setCompositeOperation(context->compositeOperation(), WebBle ndModeNormal); | 147 context->setCompositeOperation(context->compositeOperation(), WebBlendMo deNormal); |
141 #ifdef REVEAL_TRANSPARENCY_LAYERS | 148 #ifdef REVEAL_TRANSPARENCY_LAYERS |
142 context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f)); | 149 context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f)); |
143 #endif | 150 #endif |
144 } | |
145 } | 151 } |
146 | 152 |
147 void LayerPainter::paintLayerContentsAndReflection(GraphicsContext* context, con st LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) | 153 void LayerPainter::paintLayerContentsAndReflection(GraphicsContext* context, con st LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
148 { | 154 { |
149 ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingL ayerDescendant()); | 155 ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingL ayerDescendant()); |
150 | 156 |
151 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform) ; | 157 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform) ; |
152 | 158 |
153 // Paint the reflection first if we have one. | 159 // Paint the reflection first if we have one. |
154 if (m_renderLayer.reflectionInfo()) | 160 if (m_renderLayer.reflectionInfo()) |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 m_renderLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 266 m_renderLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
261 | 267 |
262 if (m_renderLayer.compositingState() == PaintsIntoOwnBacking) | 268 if (m_renderLayer.compositingState() == PaintsIntoOwnBacking) |
263 offsetFromRoot.move(m_renderLayer.subpixelAccumulation()); | 269 offsetFromRoot.move(m_renderLayer.subpixelAccumulation()); |
264 | 270 |
265 LayoutRect rootRelativeBounds; | 271 LayoutRect rootRelativeBounds; |
266 bool rootRelativeBoundsComputed = false; | 272 bool rootRelativeBoundsComputed = false; |
267 | 273 |
268 ClipPathHelper clipPathHelper(context, m_renderLayer, paintingInfo, rootRela tiveBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); | 274 ClipPathHelper clipPathHelper(context, m_renderLayer, paintingInfo, rootRela tiveBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); |
269 | 275 |
270 // Blending operations must be performed only with the nearest ancestor stac king context. | 276 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintD irtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
271 // Note that there is no need to create a transparency layer if we're painti ng the root. | |
272 bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocu mentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLa yer.hasNonIsolatedDescendantWithBlendMode(); | |
273 | |
274 if (createTransparencyLayerForBlendMode) | |
275 beginTransparencyLayers(context, m_renderLayer, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.pai ntBehavior); | |
276 | 277 |
277 LayerPaintingInfo localPaintingInfo(paintingInfo); | 278 LayerPaintingInfo localPaintingInfo(paintingInfo); |
278 | 279 |
279 LayerFragments layerFragments; | 280 LayerFragments layerFragments; |
280 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { | 281 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { |
281 // Collect the fragments. This will compute the clip rectangles and pain t offsets for each layer fragment. | 282 // Collect the fragments. This will compute the clip rectangles and pain t offsets for each layer fragment. |
282 m_renderLayer.collectFragments(layerFragments, localPaintingInfo.rootLay er, localPaintingInfo.paintDirtyRect, | 283 m_renderLayer.collectFragments(layerFragments, localPaintingInfo.rootLay er, localPaintingInfo.paintDirtyRect, |
283 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : Pai ntingClipRects, IgnoreOverlayScrollbarSize, | 284 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : Pai ntingClipRects, IgnoreOverlayScrollbarSize, |
284 shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer()), &of fsetFromRoot, localPaintingInfo.subPixelAccumulation); | 285 shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer()), &of fsetFromRoot, localPaintingInfo.subPixelAccumulation); |
285 if (shouldPaintContent) | 286 if (shouldPaintContent) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 | 342 |
342 if (shouldPaintMask) | 343 if (shouldPaintMask) |
343 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer, paintFlags); | 344 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer, paintFlags); |
344 | 345 |
345 if (shouldPaintClippingMask) { | 346 if (shouldPaintClippingMask) { |
346 // Paint the border radius mask for the fragments. | 347 // Paint the border radius mask for the fragments. |
347 paintChildClippingMaskForFragments(layerFragments, context, localPaintin gInfo, paintingRootForRenderer, paintFlags); | 348 paintChildClippingMaskForFragments(layerFragments, context, localPaintin gInfo, paintingRootForRenderer, paintFlags); |
348 } | 349 } |
349 | 350 |
350 // End our transparency layer | 351 // End our transparency layer |
351 if ((haveTransparency || createTransparencyLayerForBlendMode) && m_renderLay er.usedTransparency() | 352 if ((haveTransparency || shouldCreateTransparencyLayerForBlendMode()) && m_r enderLayer.usedTransparency() |
352 && !(m_renderLayer.reflectionInfo() && m_renderLayer.reflectionInfo()->i sPaintingInsideReflection())) { | 353 && !(m_renderLayer.reflectionInfo() && m_renderLayer.reflectionInfo()->i sPaintingInsideReflection())) { |
353 context->endLayer(); | 354 context->endLayer(); |
354 context->restore(); | 355 context->restore(); |
355 m_renderLayer.setUsedTransparency(false); | 356 m_renderLayer.setUsedTransparency(false); |
356 } | 357 } |
357 } | 358 } |
358 | 359 |
359 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye r) | 360 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye r) |
360 { | 361 { |
361 if (startLayer == endLayer) | 362 if (startLayer == endLayer) |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, clipTy pe, clipRect)); | 696 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, clipTy pe, clipRect)); |
696 if (clipRect.hasRadius()) | 697 if (clipRect.hasRadius()) |
697 applyRoundedRectClips(m_renderLayer, paintingInfo, context, paintFla gs, *clipRecorder, clippingRule); | 698 applyRoundedRectClips(m_renderLayer, paintingInfo, context, paintFla gs, *clipRecorder, clippingRule); |
698 } | 699 } |
699 | 700 |
700 PaintInfo paintInfo(context, pixelSnappedIntRect(clipRect.rect()), phase, pa intBehavior, paintingRootForRenderer, 0, paintingInfo.rootLayer->renderer()); | 701 PaintInfo paintInfo(context, pixelSnappedIntRect(clipRect.rect()), phase, pa intBehavior, paintingRootForRenderer, 0, paintingInfo.rootLayer->renderer()); |
701 m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.loca tion() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(painti ngInfo.subPixelAccumulation, m_renderLayer.compositingState()))); | 702 m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.loca tion() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(painti ngInfo.subPixelAccumulation, m_renderLayer.compositingState()))); |
702 } | 703 } |
703 | 704 |
704 void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme nts, GraphicsContext* context, | 705 void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme nts, GraphicsContext* context, |
705 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, | 706 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
mstensho (USE GERRIT)
2014/11/13 19:06:21
haveTransparency parameter no longer needed.
| |
706 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) | 707 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) |
707 { | 708 { |
708 for (const auto& fragment: layerFragments) { | 709 for (const auto& fragment: layerFragments) { |
709 // Begin transparency layers lazily now that we know we have to paint so mething. | |
710 if (haveTransparency) | |
711 beginTransparencyLayers(context, m_renderLayer, localPaintingInfo.ro otLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, loc alPaintingInfo.paintBehavior); | |
712 | |
713 paintFragmentWithPhase(PaintPhaseBlockBackground, fragment, context, fra gment.backgroundRect, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags, HasNotClipped); | 710 paintFragmentWithPhase(PaintPhaseBlockBackground, fragment, context, fra gment.backgroundRect, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags, HasNotClipped); |
714 } | 711 } |
715 } | 712 } |
716 | 713 |
717 void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme nts, GraphicsContext* context, | 714 void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme nts, GraphicsContext* context, |
718 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, | 715 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
mstensho (USE GERRIT)
2014/11/13 19:06:21
haveTransparency parameter no longer needed.
chrishtr
2014/11/13 19:40:57
Done.
| |
719 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags p aintFlags) | 716 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags p aintFlags) |
720 { | 717 { |
721 // Begin transparency if we have something to paint. | |
722 if (haveTransparency) { | |
723 for (size_t i = 0; i < layerFragments.size(); ++i) { | |
724 const LayerFragment& fragment = layerFragments.at(i); | |
725 if (!fragment.foregroundRect.isEmpty()) { | |
726 beginTransparencyLayers(context, m_renderLayer, localPaintingInf o.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior); | |
727 break; | |
728 } | |
729 } | |
730 } | |
731 | |
732 // Optimize clipping for the single fragment case. | 718 // Optimize clipping for the single fragment case. |
733 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && !layerFragments[0].foregroundRect.isEmpty(); | 719 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && !layerFragments[0].foregroundRect.isEmpty(); |
734 ClipState clipState = HasNotClipped; | 720 ClipState clipState = HasNotClipped; |
735 OwnPtr<ClipRecorder> clipRecorder; | 721 OwnPtr<ClipRecorder> clipRecorder; |
736 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun dRect)) { | 722 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun dRect)) { |
737 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, Displa yItem::ClipLayerForeground, layerFragments[0].foregroundRect)); | 723 clipRecorder = adoptPtr(new ClipRecorder(&m_renderLayer, context, Displa yItem::ClipLayerForeground, layerFragments[0].foregroundRect)); |
738 if (layerFragments[0].foregroundRect.hasRadius()) | 724 if (layerFragments[0].foregroundRect.hasRadius()) |
739 applyRoundedRectClips(m_renderLayer, localPaintingInfo, context, pai ntFlags, *clipRecorder); | 725 applyRoundedRectClips(m_renderLayer, localPaintingInfo, context, pai ntFlags, *clipRecorder); |
740 clipState = HasClipped; | 726 clipState = HasClipped; |
741 } | 727 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
825 | 811 |
826 OwnPtr<ClipRecorder> clipRecorder; | 812 OwnPtr<ClipRecorder> clipRecorder; |
827 if (needsToClip(paintingInfo, clipRect)) | 813 if (needsToClip(paintingInfo, clipRect)) |
828 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con text, DisplayItem::ClipLayerFragmentParent, clipRect)); | 814 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con text, DisplayItem::ClipLayerFragmentParent, clipRect)); |
829 | 815 |
830 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen t.paginationOffset); | 816 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen t.paginationOffset); |
831 } | 817 } |
832 } | 818 } |
833 | 819 |
834 } // namespace blink | 820 } // namespace blink |
OLD | NEW |