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 "core/paint/PaintLayerPainter.h" | 5 #include "core/paint/PaintLayerPainter.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/LocalFrame.h" |
8 #include "core/frame/Settings.h" | |
9 #include "core/layout/LayoutBlock.h" | |
10 #include "core/layout/LayoutView.h" | 8 #include "core/layout/LayoutView.h" |
11 #include "core/layout/svg/LayoutSVGResourceClipper.h" | 9 #include "core/paint/ClipPathClipper.h" |
12 #include "core/page/Page.h" | |
13 #include "core/paint/FilterPainter.h" | 10 #include "core/paint/FilterPainter.h" |
14 #include "core/paint/LayerClipRecorder.h" | 11 #include "core/paint/LayerClipRecorder.h" |
15 #include "core/paint/ObjectPaintProperties.h" | 12 #include "core/paint/ObjectPaintProperties.h" |
16 #include "core/paint/PaintInfo.h" | 13 #include "core/paint/PaintInfo.h" |
17 #include "core/paint/PaintLayer.h" | 14 #include "core/paint/PaintLayer.h" |
18 #include "core/paint/SVGClipPainter.h" | |
19 #include "core/paint/ScrollRecorder.h" | 15 #include "core/paint/ScrollRecorder.h" |
20 #include "core/paint/ScrollableAreaPainter.h" | 16 #include "core/paint/ScrollableAreaPainter.h" |
21 #include "core/paint/Transform3DRecorder.h" | 17 #include "core/paint/Transform3DRecorder.h" |
22 #include "core/style/ClipPathOperation.h" | |
23 #include "platform/RuntimeEnabledFeatures.h" | 18 #include "platform/RuntimeEnabledFeatures.h" |
24 #include "platform/geometry/FloatPoint3D.h" | 19 #include "platform/geometry/FloatPoint3D.h" |
25 #include "platform/graphics/GraphicsLayer.h" | 20 #include "platform/graphics/GraphicsLayer.h" |
26 #include "platform/graphics/paint/ClipPathRecorder.h" | |
27 #include "platform/graphics/paint/ClipRecorder.h" | |
28 #include "platform/graphics/paint/CompositingRecorder.h" | 21 #include "platform/graphics/paint/CompositingRecorder.h" |
29 #include "platform/graphics/paint/DisplayItemCacheSkipper.h" | 22 #include "platform/graphics/paint/DisplayItemCacheSkipper.h" |
30 #include "platform/graphics/paint/PaintChunkProperties.h" | 23 #include "platform/graphics/paint/PaintChunkProperties.h" |
31 #include "platform/graphics/paint/ScopedPaintChunkProperties.h" | 24 #include "platform/graphics/paint/ScopedPaintChunkProperties.h" |
32 #include "platform/graphics/paint/SubsequenceRecorder.h" | 25 #include "platform/graphics/paint/SubsequenceRecorder.h" |
33 #include "platform/graphics/paint/Transform3DDisplayItem.h" | 26 #include "platform/graphics/paint/Transform3DDisplayItem.h" |
34 #include "wtf/Optional.h" | 27 #include "wtf/Optional.h" |
35 | 28 |
36 namespace blink { | 29 namespace blink { |
37 | 30 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 result = MayBeClippedByPaintDirtyRect; | 106 result = MayBeClippedByPaintDirtyRect; |
114 } | 107 } |
115 | 108 |
116 localPaintFlags |= PaintLayerPaintingCompositingAllPhases; | 109 localPaintFlags |= PaintLayerPaintingCompositingAllPhases; |
117 if (paintLayerContents(context, paintingInfo, localPaintFlags, fragmentPolic
y) == MayBeClippedByPaintDirtyRect) | 110 if (paintLayerContents(context, paintingInfo, localPaintFlags, fragmentPolic
y) == MayBeClippedByPaintDirtyRect) |
118 result = MayBeClippedByPaintDirtyRect; | 111 result = MayBeClippedByPaintDirtyRect; |
119 | 112 |
120 return result; | 113 return result; |
121 } | 114 } |
122 | 115 |
123 class ClipPathHelper { | |
124 public: | |
125 ClipPathHelper(GraphicsContext& context, const PaintLayer& paintLayer, Paint
LayerPaintingInfo& paintingInfo, LayoutRect& rootRelativeBounds, bool& rootRelat
iveBoundsComputed, | |
126 const LayoutPoint& offsetFromRoot, PaintLayerFlags paintFlags) | |
127 : m_resourceClipper(0), m_paintLayer(paintLayer), m_context(context) | |
128 { | |
129 const ComputedStyle& style = paintLayer.layoutObject()->styleRef(); | |
130 | |
131 // Clip-path, like border radius, must not be applied to the contents of
a composited-scrolling container. | |
132 // It must, however, still be applied to the mask layer, so that the com
positor can properly mask the | |
133 // scrolling contents and scrollbars. | |
134 if (!paintLayer.layoutObject()->hasClipPath() || (paintLayer.needsCompos
itedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))) | |
135 return; | |
136 | |
137 m_clipperState = SVGClipPainter::ClipperNotApplied; | |
138 | |
139 paintingInfo.ancestorHasClipPathClipping = true; | |
140 | |
141 ASSERT(style.clipPath()); | |
142 if (style.clipPath()->type() == ClipPathOperation::SHAPE) { | |
143 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style.cl
ipPath()); | |
144 if (clipPath->isValid()) { | |
145 if (!rootRelativeBoundsComputed) { | |
146 rootRelativeBounds = paintLayer.physicalBoundingBoxIncluding
ReflectionAndStackingChildren(offsetFromRoot); | |
147 rootRelativeBoundsComputed = true; | |
148 } | |
149 m_clipPathRecorder.emplace(context, *paintLayer.layoutObject(),
clipPath->path(FloatRect(rootRelativeBounds))); | |
150 } | |
151 } else if (style.clipPath()->type() == ClipPathOperation::REFERENCE) { | |
152 ReferenceClipPathOperation* referenceClipPathOperation = toReference
ClipPathOperation(style.clipPath()); | |
153 Document& document = paintLayer.layoutObject()->document(); | |
154 // FIXME: It doesn't work with forward or external SVG references (h
ttps://bugs.webkit.org/show_bug.cgi?id=90405) | |
155 Element* element = document.getElementById(referenceClipPathOperatio
n->fragment()); | |
156 if (isSVGClipPathElement(element) && element->layoutObject()) { | |
157 if (!rootRelativeBoundsComputed) { | |
158 rootRelativeBounds = paintLayer.physicalBoundingBoxIncluding
ReflectionAndStackingChildren(offsetFromRoot); | |
159 rootRelativeBoundsComputed = true; | |
160 } | |
161 | |
162 m_resourceClipper = toLayoutSVGResourceClipper(toLayoutSVGResour
ceContainer(element->layoutObject())); | |
163 // When SVG applies the clip and the coordinate system is "user
space on use", we must explicitly pass in | |
164 // the layer offset to have the clip paint in the correct locati
on. When the coordinate system is | |
165 // "object bounding box" the offset is already accounted for in
the rootRelativeBounds. | |
166 FloatPoint layerPositionOffset = m_resourceClipper->clipPathUnit
s() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse ? | |
167 FloatPoint(offsetFromRoot) : FloatPoint(); | |
168 if (!SVGClipPainter(*m_resourceClipper).prepareEffect(*paintLaye
r.layoutObject(), FloatRect(rootRelativeBounds), | |
169 FloatRect(rootRelativeBounds), layerPositionOffset, context,
m_clipperState)) { | |
170 // No need to post-apply the clipper if this failed. | |
171 m_resourceClipper = 0; | |
172 } | |
173 } | |
174 } | |
175 } | |
176 | |
177 ~ClipPathHelper() | |
178 { | |
179 if (m_resourceClipper) | |
180 SVGClipPainter(*m_resourceClipper).finishEffect(*m_paintLayer.layout
Object(), m_context, m_clipperState); | |
181 } | |
182 private: | |
183 LayoutSVGResourceClipper* m_resourceClipper; | |
184 Optional<ClipPathRecorder> m_clipPathRecorder; | |
185 SVGClipPainter::ClipperState m_clipperState; | |
186 const PaintLayer& m_paintLayer; | |
187 GraphicsContext& m_context; | |
188 }; | |
189 | |
190 static bool shouldCreateSubsequence(const PaintLayer& paintLayer, GraphicsContex
t& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFla
gs) | 116 static bool shouldCreateSubsequence(const PaintLayer& paintLayer, GraphicsContex
t& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFla
gs) |
191 { | 117 { |
192 if (!RuntimeEnabledFeatures::paintOptimizationsEnabled()) | 118 if (!RuntimeEnabledFeatures::paintOptimizationsEnabled()) |
193 return false; | 119 return false; |
194 | 120 |
195 // Caching is not needed during printing. | 121 // Caching is not needed during printing. |
196 if (context.printing()) | 122 if (context.printing()) |
197 return false; | 123 return false; |
198 | 124 |
199 // Don't create subsequence for a composited layer because if it can be cach
ed, | 125 // Don't create subsequence for a composited layer because if it can be cach
ed, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 result = MayBeClippedByPaintDirtyRect; | 236 result = MayBeClippedByPaintDirtyRect; |
311 | 237 |
312 LayoutRect rootRelativeBounds; | 238 LayoutRect rootRelativeBounds; |
313 bool rootRelativeBoundsComputed = false; | 239 bool rootRelativeBoundsComputed = false; |
314 | 240 |
315 if (paintingInfo.ancestorHasClipPathClipping && m_paintLayer.layoutObject()-
>isPositioned()) | 241 if (paintingInfo.ancestorHasClipPathClipping && m_paintLayer.layoutObject()-
>isPositioned()) |
316 UseCounter::count(m_paintLayer.layoutObject()->document(), UseCounter::C
lipPathOfPositionedElement); | 242 UseCounter::count(m_paintLayer.layoutObject()->document(), UseCounter::C
lipPathOfPositionedElement); |
317 | 243 |
318 // These helpers output clip and compositing operations using a RAII pattern
. Stack-allocated-varibles are destructed in the reverse order of construction, | 244 // These helpers output clip and compositing operations using a RAII pattern
. Stack-allocated-varibles are destructed in the reverse order of construction, |
319 // so they are nested properly. | 245 // so they are nested properly. |
320 ClipPathHelper clipPathHelper(context, m_paintLayer, paintingInfo, rootRelat
iveBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); | 246 Optional<ClipPathClipper> clipPathClipper; |
| 247 // Clip-path, like border radius, must not be applied to the contents of a c
omposited-scrolling container. |
| 248 // It must, however, still be applied to the mask layer, so that the composi
tor can properly mask the |
| 249 // scrolling contents and scrollbars. |
| 250 if (m_paintLayer.layoutObject()->hasClipPath() && (!m_paintLayer.needsCompos
itedScrolling() || (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) { |
| 251 if (!rootRelativeBoundsComputed) { |
| 252 rootRelativeBounds = m_paintLayer.physicalBoundingBoxIncludingReflec
tionAndStackingChildren(offsetFromRoot); |
| 253 rootRelativeBoundsComputed = true; |
| 254 } |
| 255 paintingInfo.ancestorHasClipPathClipping = true; |
| 256 FloatRect floatRootRelativeBounds(rootRelativeBounds); |
| 257 clipPathClipper.emplace( |
| 258 context, *m_paintLayer.layoutObject(), floatRootRelativeBounds, floa
tRootRelativeBounds, FloatPoint(offsetFromRoot)); |
| 259 } |
321 | 260 |
322 Optional<CompositingRecorder> compositingRecorder; | 261 Optional<CompositingRecorder> compositingRecorder; |
323 // Blending operations must be performed only with the nearest ancestor stac
king context. | 262 // Blending operations must be performed only with the nearest ancestor stac
king context. |
324 // Note that there is no need to composite if we're painting the root. | 263 // Note that there is no need to composite if we're painting the root. |
325 // FIXME: this should be unified further into PaintLayer::paintsWithTranspar
ency(). | 264 // FIXME: this should be unified further into PaintLayer::paintsWithTranspar
ency(). |
326 bool shouldCompositeForBlendMode = (!m_paintLayer.layoutObject()->isDocument
Element() || m_paintLayer.layoutObject()->isSVGRoot()) && m_paintLayer.stackingN
ode()->isStackingContext() && m_paintLayer.hasNonIsolatedDescendantWithBlendMode
(); | 265 bool shouldCompositeForBlendMode = (!m_paintLayer.layoutObject()->isDocument
Element() || m_paintLayer.layoutObject()->isSVGRoot()) && m_paintLayer.stackingN
ode()->isStackingContext() && m_paintLayer.hasNonIsolatedDescendantWithBlendMode
(); |
327 if (shouldCompositeForBlendMode || m_paintLayer.paintsWithTransparency(paint
ingInfo.getGlobalPaintFlags())) { | 266 if (shouldCompositeForBlendMode || m_paintLayer.paintsWithTransparency(paint
ingInfo.getGlobalPaintFlags())) { |
328 FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent(pain
tingInfo.rootLayer, paintingInfo.subPixelAccumulation, paintingInfo.getGlobalPai
ntFlags())); | 267 FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent(pain
tingInfo.rootLayer, paintingInfo.subPixelAccumulation, paintingInfo.getGlobalPai
ntFlags())); |
329 compositingRecorder.emplace(context, *m_paintLayer.layoutObject(), | 268 compositingRecorder.emplace(context, *m_paintLayer.layoutObject(), |
330 WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_paintLayer.la
youtObject()->style()->blendMode()), | 269 WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_paintLayer.la
youtObject()->style()->blendMode()), |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 755 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
817 return; | 756 return; |
818 | 757 |
819 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); | 758 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize()); |
820 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 759 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
821 | 760 |
822 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 761 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
823 } | 762 } |
824 | 763 |
825 } // namespace blink | 764 } // namespace blink |
OLD | NEW |