| 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 |