| 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/PaintLayerPainter.h" | 6 #include "core/paint/PaintLayerPainter.h" |
| 7 | 7 |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/layout/ClipPathOperation.h" | 9 #include "core/layout/ClipPathOperation.h" |
| 10 #include "core/layout/LayoutBlock.h" | 10 #include "core/layout/LayoutBlock.h" |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !m_paintLayer.layou
tObject()->isLayoutView() && !m_paintLayer.layoutObject()->isDocumentElement()) | 213 if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !m_paintLayer.layou
tObject()->isLayoutView() && !m_paintLayer.layoutObject()->isDocumentElement()) |
| 214 return result; | 214 return result; |
| 215 | 215 |
| 216 // TODO(skyostil): Unify this early-out logic with subsequence caching. | 216 // TODO(skyostil): Unify this early-out logic with subsequence caching. |
| 217 if (m_paintLayer.layoutObject()->isLayoutPart() && toLayoutPart(m_paintLayer
.layoutObject())->isThrottledFrameView()) | 217 if (m_paintLayer.layoutObject()->isLayoutPart() && toLayoutPart(m_paintLayer
.layoutObject())->isThrottledFrameView()) |
| 218 return FullyPainted; | 218 return FullyPainted; |
| 219 | 219 |
| 220 // Ensure our lists are up-to-date. | 220 // Ensure our lists are up-to-date. |
| 221 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); | 221 m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); |
| 222 | 222 |
| 223 bool clipRectsChanged = false; |
| 224 LayoutSize subpixelAccumulation = m_paintLayer.compositingState() == PaintsI
ntoOwnBacking ? m_paintLayer.subpixelAccumulation() : paintingInfoArg.subPixelAc
cumulation; |
| 225 ShouldRespectOverflowClip respectOverflowClip = shouldRespectOverflowClip(pa
intFlags, m_paintLayer.layoutObject()); |
| 226 if (paintFlags & PaintLayerUncachedClipRects) { |
| 227 m_paintLayer.setPreviousPaintingClipRects(nullptr); |
| 228 } else { |
| 229 ClipRects* clipRects = m_paintLayer.clipper().paintingClipRects(painting
InfoArg.rootLayer, respectOverflowClip, subpixelAccumulation); |
| 230 if (!m_paintLayer.needsRepaint()) { |
| 231 ClipRects* previousClipRects = m_paintLayer.previousPaintingClipRect
s(); |
| 232 if (clipRects != previousClipRects && (!clipRects || !previousClipRe
cts || *clipRects != *previousClipRects)) |
| 233 clipRectsChanged = true; |
| 234 } |
| 235 m_paintLayer.setPreviousPaintingClipRects(clipRects); |
| 236 } |
| 237 |
| 223 Optional<SubsequenceRecorder> subsequenceRecorder; | 238 Optional<SubsequenceRecorder> subsequenceRecorder; |
| 224 if (!paintingInfoArg.disableSubsequenceCache | 239 if (!context->printing() |
| 225 && !context->printing() | |
| 226 && !(paintingInfoArg.globalPaintFlags() & GlobalPaintFlattenCompositingL
ayers) | 240 && !(paintingInfoArg.globalPaintFlags() & GlobalPaintFlattenCompositingL
ayers) |
| 227 && !(paintFlags & (PaintLayerPaintingReflection | PaintLayerPaintingRoot
BackgroundOnly | PaintLayerPaintingOverlayScrollbars)) | 241 && !(paintFlags & (PaintLayerPaintingReflection | PaintLayerPaintingRoot
BackgroundOnly | PaintLayerPaintingOverlayScrollbars | PaintLayerUncachedClipRec
ts)) |
| 228 && m_paintLayer.stackingNode()->isStackingContext() | 242 && m_paintLayer.stackingNode()->isStackingContext() |
| 229 && PaintLayerStackingNodeIterator(*m_paintLayer.stackingNode(), AllChild
ren).next()) { | 243 && PaintLayerStackingNodeIterator(*m_paintLayer.stackingNode(), AllChild
ren).next()) { |
| 230 if (!m_paintLayer.needsRepaint() | 244 if (!m_paintLayer.needsRepaint() |
| 245 && !clipRectsChanged |
| 231 && paintingInfoArg.scrollOffsetAccumulation == m_paintLayer.previous
ScrollOffsetAccumulationForPainting() | 246 && paintingInfoArg.scrollOffsetAccumulation == m_paintLayer.previous
ScrollOffsetAccumulationForPainting() |
| 232 && SubsequenceRecorder::useCachedSubsequenceIfPossible(*context, m_p
aintLayer)) | 247 && SubsequenceRecorder::useCachedSubsequenceIfPossible(*context, m_p
aintLayer)) |
| 233 return result; | 248 return result; |
| 234 subsequenceRecorder.emplace(*context, m_paintLayer); | 249 subsequenceRecorder.emplace(*context, m_paintLayer); |
| 235 } | 250 } |
| 236 | 251 |
| 237 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; | 252 PaintLayerPaintingInfo paintingInfo = paintingInfoArg; |
| 238 | 253 |
| 239 // This is a workaround of ancestor clip change issue (crbug.com/533717). | |
| 240 // TODO(wangxianzhu): | |
| 241 // - spv1: This disables subsequence cache for all descendants of LayoutView
with root-layer-scrolls because | |
| 242 // LayoutView has overflow clip. Should find another workaround method wor
king with root-layer-scrolls | |
| 243 // if it ships before slimming paint v2. crbug.com/552030. | |
| 244 // - spv2: Ensure subsequence cache works with ancestor clip change. crbug.c
om/536138. | |
| 245 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_paintLayer.layout
Object()->hasClipOrOverflowClip()) | |
| 246 paintingInfo.disableSubsequenceCache = true; | |
| 247 | |
| 248 LayoutPoint offsetFromRoot; | 254 LayoutPoint offsetFromRoot; |
| 249 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 255 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
| 250 | 256 offsetFromRoot.move(subpixelAccumulation); |
| 251 if (m_paintLayer.compositingState() == PaintsIntoOwnBacking) | |
| 252 offsetFromRoot.move(m_paintLayer.subpixelAccumulation()); | |
| 253 else | |
| 254 offsetFromRoot.move(paintingInfo.subPixelAccumulation); | |
| 255 | 257 |
| 256 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); | 258 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); |
| 257 if (!paintingInfo.paintDirtyRect.contains(bounds)) | 259 if (!paintingInfo.paintDirtyRect.contains(bounds)) |
| 258 result = MaybeNotFullyPainted; | 260 result = MaybeNotFullyPainted; |
| 259 | 261 |
| 260 LayoutRect rootRelativeBounds; | 262 LayoutRect rootRelativeBounds; |
| 261 bool rootRelativeBoundsComputed = false; | 263 bool rootRelativeBoundsComputed = false; |
| 262 | 264 |
| 263 if (paintingInfo.ancestorHasClipPathClipping && m_paintLayer.layoutObject()-
>style()->position() != StaticPosition) | 265 if (paintingInfo.ancestorHasClipPathClipping && m_paintLayer.layoutObject()-
>style()->position() != StaticPosition) |
| 264 UseCounter::count(m_paintLayer.layoutObject()->document(), UseCounter::C
lipPathOfPositionedElement); | 266 UseCounter::count(m_paintLayer.layoutObject()->document(), UseCounter::C
lipPathOfPositionedElement); |
| 265 | 267 |
| 266 // These helpers output clip and compositing operations using a RAII pattern
. Stack-allocated-varibles are destructed in the reverse order of construction, | 268 // These helpers output clip and compositing operations using a RAII pattern
. Stack-allocated-varibles are destructed in the reverse order of construction, |
| 267 // so they are nested properly. | 269 // so they are nested properly. |
| 268 ClipPathHelper clipPathHelper(context, m_paintLayer, paintingInfo, rootRelat
iveBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); | 270 ClipPathHelper clipPathHelper(context, m_paintLayer, paintingInfo, rootRelat
iveBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); |
| 269 | 271 |
| 270 Optional<CompositingRecorder> compositingRecorder; | 272 Optional<CompositingRecorder> compositingRecorder; |
| 271 // Blending operations must be performed only with the nearest ancestor stac
king context. | 273 // Blending operations must be performed only with the nearest ancestor stac
king context. |
| 272 // Note that there is no need to composite if we're painting the root. | 274 // Note that there is no need to composite if we're painting the root. |
| 273 // FIXME: this should be unified further into PaintLayer::paintsWithTranspar
ency(). | 275 // FIXME: this should be unified further into PaintLayer::paintsWithTranspar
ency(). |
| 274 bool shouldCompositeForBlendMode = (!m_paintLayer.layoutObject()->isDocument
Element() || m_paintLayer.layoutObject()->isSVGRoot()) && m_paintLayer.stackingN
ode()->isStackingContext() && m_paintLayer.hasNonIsolatedDescendantWithBlendMode
(); | 276 bool shouldCompositeForBlendMode = (!m_paintLayer.layoutObject()->isDocument
Element() || m_paintLayer.layoutObject()->isSVGRoot()) && m_paintLayer.stackingN
ode()->isStackingContext() && m_paintLayer.hasNonIsolatedDescendantWithBlendMode
(); |
| 275 if (shouldCompositeForBlendMode || m_paintLayer.paintsWithTransparency(paint
ingInfo.globalPaintFlags())) { | 277 if (shouldCompositeForBlendMode || m_paintLayer.paintsWithTransparency(paint
ingInfo.globalPaintFlags())) { |
| 276 FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent(pain
tingInfo.rootLayer, paintingInfo.subPixelAccumulation, paintingInfo.globalPaintF
lags())); | 278 FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent(pain
tingInfo.rootLayer, paintingInfo.subPixelAccumulation, paintingInfo.globalPaintF
lags())); |
| 277 compositingRecorder.emplace(*context, *m_paintLayer.layoutObject(), | 279 compositingRecorder.emplace(*context, *m_paintLayer.layoutObject(), |
| 278 WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_paintLayer.la
youtObject()->style()->blendMode()), | 280 WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_paintLayer.la
youtObject()->style()->blendMode()), |
| 279 m_paintLayer.layoutObject()->opacity(), &compositingBounds); | 281 m_paintLayer.layoutObject()->opacity(), &compositingBounds); |
| 280 } | 282 } |
| 281 | 283 |
| 282 PaintLayerPaintingInfo localPaintingInfo(paintingInfo); | 284 PaintLayerPaintingInfo localPaintingInfo(paintingInfo); |
| 283 if (m_paintLayer.compositingState() == PaintsIntoOwnBacking) | 285 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; |
| 284 localPaintingInfo.subPixelAccumulation = m_paintLayer.subpixelAccumulati
on(); | |
| 285 | 286 |
| 286 PaintLayerFragments layerFragments; | 287 PaintLayerFragments layerFragments; |
| 287 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars)
{ | 288 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars)
{ |
| 288 // Collect the fragments. This will compute the clip rectangles and pain
t offsets for each layer fragment. | 289 // Collect the fragments. This will compute the clip rectangles and pain
t offsets for each layer fragment. |
| 289 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects
) ? UncachedClipRects : PaintingClipRects; | 290 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects
) ? UncachedClipRects : PaintingClipRects; |
| 290 ShouldRespectOverflowClip respectOverflowClip = shouldRespectOverflowCli
p(paintFlags, m_paintLayer.layoutObject()); | |
| 291 if (fragmentPolicy == ForceSingleFragment) | 291 if (fragmentPolicy == ForceSingleFragment) |
| 292 m_paintLayer.appendSingleFragmentIgnoringPagination(layerFragments,
localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, cacheSlot, Ignore
OverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.su
bPixelAccumulation); | 292 m_paintLayer.appendSingleFragmentIgnoringPagination(layerFragments,
localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, cacheSlot, Ignore
OverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.su
bPixelAccumulation); |
| 293 else | 293 else |
| 294 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.root
Layer, localPaintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize,
respectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation); | 294 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.root
Layer, localPaintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize,
respectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation); |
| 295 if (shouldPaintContent) { | 295 if (shouldPaintContent) { |
| 296 // TODO(wangxianzhu): This is for old slow scrolling. Implement simi
lar optimization for slimming paint v2. | 296 // TODO(wangxianzhu): This is for old slow scrolling. Implement simi
lar optimization for slimming paint v2. |
| 297 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFra
gments, localPaintingInfo, paintFlags, offsetFromRoot); | 297 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFra
gments, localPaintingInfo, paintFlags, offsetFromRoot); |
| 298 if (!shouldPaintContent) | 298 if (!shouldPaintContent) |
| 299 result = MaybeNotFullyPainted; | 299 result = MaybeNotFullyPainted; |
| 300 } | 300 } |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 708 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
| 709 return; | 709 return; |
| 710 | 710 |
| 711 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize(), paintingRoot); | 711 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe
ct(damageRect)), paintFlags, LayoutSize(), paintingRoot); |
| 712 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 712 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 713 | 713 |
| 714 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 714 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 715 } | 715 } |
| 716 | 716 |
| 717 } // namespace blink | 717 } // namespace blink |
| OLD | NEW |