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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 if (m_renderLayer.parent()) | 81 if (m_renderLayer.parent()) |
82 LayerPainter(*m_renderLayer.parent()).beginTransparencyLayers(co
ntext, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixe
lAccumulation, paintingInfo.paintBehavior); | 82 beginTransparencyLayers(context, *m_renderLayer.parent(), painti
ngInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation
, paintingInfo.paintBehavior); |
83 else | 83 else |
84 beginTransparencyLayers(context, paintingInfo.rootLayer, paintin
gInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehav
ior); | 84 beginTransparencyLayers(context, m_renderLayer, paintingInfo.roo
tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, painting
Info.paintBehavior); |
85 } | 85 } |
86 | 86 |
87 if (m_renderLayer.enclosingPaginationLayer()) { | 87 if (m_renderLayer.enclosingPaginationLayer()) { |
88 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags
); | 88 paintTransformedLayerIntoFragments(context, paintingInfo, paintFlags
); |
89 return; | 89 return; |
90 } | 90 } |
91 | 91 |
92 // Make sure the parent's clip rects have been calculated. | 92 // Make sure the parent's clip rects have been calculated. |
93 ClipRect clipRect = paintingInfo.paintDirtyRect; | 93 ClipRect clipRect = paintingInfo.paintDirtyRect; |
94 | 94 |
(...skipping 13 matching lines...) Expand all Loading... |
108 } | 108 } |
109 | 109 |
110 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); | 110 paintLayerByApplyingTransform(context, paintingInfo, paintFlags); |
111 | 111 |
112 return; | 112 return; |
113 } | 113 } |
114 | 114 |
115 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); | 115 paintLayerContentsAndReflection(context, paintingInfo, paintFlags); |
116 } | 116 } |
117 | 117 |
118 void LayerPainter::beginTransparencyLayers(GraphicsContext* context, const Rende
rLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelA
ccumulation, PaintBehavior paintBehavior) | 118 void LayerPainter::beginTransparencyLayers(GraphicsContext* context, RenderLayer
& renderLayer, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, c
onst LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) |
119 { | 119 { |
120 bool createTransparencyLayerForBlendMode = m_renderLayer.stackingNode()->isS
tackingContext() && m_renderLayer.hasNonIsolatedDescendantWithBlendMode(); | 120 bool createTransparencyLayerForBlendMode = renderLayer.stackingNode()->isSta
ckingContext() && renderLayer.hasNonIsolatedDescendantWithBlendMode(); |
121 if ((m_renderLayer.paintsWithTransparency(paintBehavior) || createTransparen
cyLayerForBlendMode) && m_renderLayer.usedTransparency()) | 121 if ((renderLayer.paintsWithTransparency(paintBehavior) || createTransparency
LayerForBlendMode) && renderLayer.usedTransparency()) |
122 return; | 122 return; |
123 | 123 |
124 RenderLayer* ancestor = m_renderLayer.transparentPaintingAncestor(); | 124 RenderLayer* ancestor = renderLayer.transparentPaintingAncestor(); |
125 if (ancestor) | 125 if (ancestor) |
126 LayerPainter(*ancestor).beginTransparencyLayers(context, rootLayer, pain
tDirtyRect, subPixelAccumulation, paintBehavior); | 126 beginTransparencyLayers(context, *ancestor, rootLayer, paintDirtyRect, s
ubPixelAccumulation, paintBehavior); |
127 | 127 |
128 if (m_renderLayer.paintsWithTransparency(paintBehavior) || createTransparenc
yLayerForBlendMode) { | 128 if (renderLayer.paintsWithTransparency(paintBehavior) || createTransparencyL
ayerForBlendMode) { |
129 m_renderLayer.setUsedTransparency(true); | 129 renderLayer.setUsedTransparency(true); |
130 context->save(); | 130 context->save(); |
131 LayoutRect clipRect = m_renderLayer.paintingExtent(rootLayer, paintDirty
Rect, subPixelAccumulation, paintBehavior); | 131 LayoutRect clipRect = renderLayer.paintingExtent(rootLayer, paintDirtyRe
ct, subPixelAccumulation, paintBehavior); |
132 context->clip(clipRect); | 132 context->clip(clipRect); |
133 | 133 |
134 if (m_renderLayer.renderer()->hasBlendMode()) | 134 if (renderLayer.renderer()->hasBlendMode()) |
135 context->setCompositeOperation(context->compositeOperation(), m_rend
erLayer.renderer()->style()->blendMode()); | 135 context->setCompositeOperation(context->compositeOperation(), render
Layer.renderer()->style()->blendMode()); |
136 | 136 |
137 context->beginTransparencyLayer(m_renderLayer.renderer()->opacity()); | 137 context->beginTransparencyLayer(renderLayer.renderer()->opacity()); |
138 | 138 |
139 if (m_renderLayer.renderer()->hasBlendMode()) | 139 if (renderLayer.renderer()->hasBlendMode()) |
140 context->setCompositeOperation(context->compositeOperation(), WebBle
ndModeNormal); | 140 context->setCompositeOperation(context->compositeOperation(), WebBle
ndModeNormal); |
141 #ifdef REVEAL_TRANSPARENCY_LAYERS | 141 #ifdef REVEAL_TRANSPARENCY_LAYERS |
142 context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f)); | 142 context->fillRect(clipRect, Color(0.0f, 0.0f, 0.5f, 0.2f)); |
143 #endif | 143 #endif |
144 } | 144 } |
145 } | 145 } |
146 | 146 |
147 void LayerPainter::paintLayerContentsAndReflection(GraphicsContext* context, con
st LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) | 147 void LayerPainter::paintLayerContentsAndReflection(GraphicsContext* context, con
st LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
148 { | 148 { |
149 ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingL
ayerDescendant()); | 149 ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingL
ayerDescendant()); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 } | 244 } |
245 } | 245 } |
246 } | 246 } |
247 } | 247 } |
248 | 248 |
249 // Blending operations must be performed only with the nearest ancestor stac
king context. | 249 // Blending operations must be performed only with the nearest ancestor stac
king context. |
250 // Note that there is no need to create a transparency layer if we're painti
ng the root. | 250 // Note that there is no need to create a transparency layer if we're painti
ng the root. |
251 bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocu
mentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLa
yer.hasNonIsolatedDescendantWithBlendMode(); | 251 bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocu
mentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLa
yer.hasNonIsolatedDescendantWithBlendMode(); |
252 | 252 |
253 if (createTransparencyLayerForBlendMode) | 253 if (createTransparencyLayerForBlendMode) |
254 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa
intDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); | 254 beginTransparencyLayers(context, m_renderLayer, paintingInfo.rootLayer,
paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.pai
ntBehavior); |
255 | 255 |
256 LayerPaintingInfo localPaintingInfo(paintingInfo); | 256 LayerPaintingInfo localPaintingInfo(paintingInfo); |
257 | 257 |
258 LayerFragments layerFragments; | 258 LayerFragments layerFragments; |
259 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars)
{ | 259 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars)
{ |
260 // Collect the fragments. This will compute the clip rectangles and pain
t offsets for each layer fragment. | 260 // Collect the fragments. This will compute the clip rectangles and pain
t offsets for each layer fragment. |
261 m_renderLayer.collectFragments(layerFragments, localPaintingInfo.rootLay
er, localPaintingInfo.paintDirtyRect, | 261 m_renderLayer.collectFragments(layerFragments, localPaintingInfo.rootLay
er, localPaintingInfo.paintDirtyRect, |
262 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : Pai
ntingClipRects, IgnoreOverlayScrollbarSize, | 262 (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : Pai
ntingClipRects, IgnoreOverlayScrollbarSize, |
263 shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer()), &of
fsetFromRoot, localPaintingInfo.subPixelAccumulation); | 263 shouldRespectOverflowClip(paintFlags, m_renderLayer.renderer()), &of
fsetFromRoot, localPaintingInfo.subPixelAccumulation); |
264 if (shouldPaintContent) | 264 if (shouldPaintContent) |
265 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFra
gments, localPaintingInfo, paintFlags, offsetFromRoot); | 265 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFra
gments, localPaintingInfo, paintFlags, offsetFromRoot); |
266 } | 266 } |
267 | 267 |
268 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelecti
onOnly; | 268 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectio
nOnly; |
269 // If this layer's renderer is a child of the paintingRoot, we render uncond
itionally, which | 269 // If this layer's renderer is a child of the paintingRoot, we render uncond
itionally, which |
270 // is done by passing a nil paintingRoot down to our renderer (as if no pain
tingRoot was ever set). | 270 // is done by passing a nil paintingRoot down to our renderer (as if no pain
tingRoot was ever set). |
271 // Else, our renderer tree may or may not contain the painting root, so we p
ass that root along | 271 // Else, our renderer tree may or may not contain the painting root, so we p
ass that root along |
272 // so it will be tested against as we descend through the renderers. | 272 // so it will be tested against as we descend through the renderers. |
273 RenderObject* paintingRootForRenderer = 0; | 273 RenderObject* paintingRootForRenderer = 0; |
274 if (localPaintingInfo.paintingRoot && !m_renderLayer.renderer()->isDescendan
tOf(localPaintingInfo.paintingRoot)) | 274 if (localPaintingInfo.paintingRoot && !m_renderLayer.renderer()->isDescendan
tOf(localPaintingInfo.paintingRoot)) |
275 paintingRootForRenderer = localPaintingInfo.paintingRoot; | 275 paintingRootForRenderer = localPaintingInfo.paintingRoot; |
276 | 276 |
277 { // Begin block for the lifetime of any filter. | 277 { // Begin block for the lifetime of any filter. |
278 OwnPtr<FilterPainter> filterPainter; | 278 FilterPainter filterPainter(m_renderLayer, context, offsetFromRoot, laye
rFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect, localPaint
ingInfo, paintFlags, |
279 if (m_renderLayer.filterRenderer() && m_renderLayer.paintsWithFilters())
{ | 279 rootRelativeBounds, rootRelativeBoundsComputed); |
280 ASSERT(m_renderLayer.filterInfo()); | |
281 | |
282 if (!rootRelativeBoundsComputed) | |
283 rootRelativeBounds = m_renderLayer.physicalBoundingBoxIncludingR
eflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | |
284 | |
285 // Do transparency and clipping before starting filter processing. | |
286 if (haveTransparency) { | |
287 // If we have a filter and transparency, we have to eagerly star
t a transparency layer here, rather than risk a child layer lazily starts one af
ter filter processing. | |
288 beginTransparencyLayers(context, localPaintingInfo.rootLayer, pa
intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.
paintBehavior); | |
289 } | |
290 | |
291 // We'll handle clipping to the dirty rect before filter rasterizati
on. | |
292 // Filter processing will automatically expand the clip rect and the
offscreen to accommodate any filter outsets. | |
293 // FIXME: It is incorrect to just clip to the damageRect here once m
ultiple fragments are involved. | |
294 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : la
yerFragments[0].backgroundRect; | |
295 | |
296 // Subsequent code should not clip to the dirty rect, since we've al
ready | |
297 // done it above, and doing it later will defeat the outsets. | |
298 localPaintingInfo.clipToDirtyRect = false; | |
299 filterPainter = adoptPtr(new FilterPainter(m_renderLayer, context, r
ootRelativeBounds, backgroundRect, localPaintingInfo, paintFlags)); | |
300 } | |
301 | 280 |
302 ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText))
; | 281 ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText))
; |
303 | 282 |
304 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPai
ntContent && !selectionOnly; | 283 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPai
ntContent && !selectionOnly; |
305 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintin
gOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackgr
ound); | 284 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintin
gOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackgr
ound); |
306 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPa
intContent; | 285 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPa
intContent; |
307 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForegr
ound; | 286 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForegr
ound; |
308 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; | 287 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; |
309 | 288 |
310 PaintBehavior paintBehavior = PaintBehaviorNormal; | 289 PaintBehavior paintBehavior = PaintBehaviorNormal; |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.loca
tion() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(painti
ngInfo.subPixelAccumulation, m_renderLayer.compositingState()))); | 683 m_renderLayer.renderer()->paint(paintInfo, toPoint(fragment.layerBounds.loca
tion() - m_renderLayer.renderBoxLocation() + subPixelAccumulationIfNeeded(painti
ngInfo.subPixelAccumulation, m_renderLayer.compositingState()))); |
705 } | 684 } |
706 | 685 |
707 void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme
nts, GraphicsContext* context, | 686 void LayerPainter::paintBackgroundForFragments(const LayerFragments& layerFragme
nts, GraphicsContext* context, |
708 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L
ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, | 687 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L
ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
709 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) | 688 RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags) |
710 { | 689 { |
711 for (const auto& fragment: layerFragments) { | 690 for (const auto& fragment: layerFragments) { |
712 // Begin transparency layers lazily now that we know we have to paint so
mething. | 691 // Begin transparency layers lazily now that we know we have to paint so
mething. |
713 if (haveTransparency) | 692 if (haveTransparency) |
714 beginTransparencyLayers(context, localPaintingInfo.rootLayer, transp
arencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.
paintBehavior); | 693 beginTransparencyLayers(context, m_renderLayer, localPaintingInfo.ro
otLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, loc
alPaintingInfo.paintBehavior); |
715 | 694 |
716 paintFragmentWithPhase(PaintPhaseBlockBackground, fragment, context, fra
gment.backgroundRect, localPaintingInfo, paintBehavior, paintingRootForRenderer,
paintFlags, HasNotClipped); | 695 paintFragmentWithPhase(PaintPhaseBlockBackground, fragment, context, fra
gment.backgroundRect, localPaintingInfo, paintBehavior, paintingRootForRenderer,
paintFlags, HasNotClipped); |
717 } | 696 } |
718 } | 697 } |
719 | 698 |
720 void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme
nts, GraphicsContext* context, | 699 void LayerPainter::paintForegroundForFragments(const LayerFragments& layerFragme
nts, GraphicsContext* context, |
721 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L
ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, | 700 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L
ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, |
722 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags p
aintFlags) | 701 RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags p
aintFlags) |
723 { | 702 { |
724 // Begin transparency if we have something to paint. | 703 // Begin transparency if we have something to paint. |
725 if (haveTransparency) { | 704 if (haveTransparency) { |
726 for (size_t i = 0; i < layerFragments.size(); ++i) { | 705 for (size_t i = 0; i < layerFragments.size(); ++i) { |
727 const LayerFragment& fragment = layerFragments.at(i); | 706 const LayerFragment& fragment = layerFragments.at(i); |
728 if (!fragment.foregroundRect.isEmpty()) { | 707 if (!fragment.foregroundRect.isEmpty()) { |
729 beginTransparencyLayers(context, localPaintingInfo.rootLayer, tr
ansparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingI
nfo.paintBehavior); | 708 beginTransparencyLayers(context, m_renderLayer, localPaintingInf
o.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation,
localPaintingInfo.paintBehavior); |
730 break; | 709 break; |
731 } | 710 } |
732 } | 711 } |
733 } | 712 } |
734 | 713 |
735 // Optimize clipping for the single fragment case. | 714 // Optimize clipping for the single fragment case. |
736 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size()
== 1 && !layerFragments[0].foregroundRect.isEmpty(); | 715 bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size()
== 1 && !layerFragments[0].foregroundRect.isEmpty(); |
737 ClipState clipState = HasNotClipped; | 716 ClipState clipState = HasNotClipped; |
738 OwnPtr<ClipRecorder> clipRecorder; | 717 OwnPtr<ClipRecorder> clipRecorder; |
739 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { | 718 if (shouldClip && needsToClip(localPaintingInfo, layerFragments[0].foregroun
dRect)) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 | 807 |
829 OwnPtr<ClipRecorder> clipRecorder; | 808 OwnPtr<ClipRecorder> clipRecorder; |
830 if (needsToClip(paintingInfo, clipRect)) | 809 if (needsToClip(paintingInfo, clipRect)) |
831 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con
text, DisplayItem::ClipLayerFragmentParent, clipRect)); | 810 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con
text, DisplayItem::ClipLayerFragmentParent, clipRect)); |
832 | 811 |
833 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen
t.paginationOffset); | 812 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen
t.paginationOffset); |
834 } | 813 } |
835 } | 814 } |
836 | 815 |
837 } // namespace blink | 816 } // namespace blink |
OLD | NEW |