| 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/LocalFrame.h" | 7 #include "core/frame/LocalFrame.h" |
| 8 #include "core/layout/LayoutInline.h" | 8 #include "core/layout/LayoutInline.h" |
| 9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
| 10 #include "core/paint/ClipPathClipper.h" | 10 #include "core/paint/ClipPathClipper.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "platform/graphics/paint/DisplayItemCacheSkipper.h" | 23 #include "platform/graphics/paint/DisplayItemCacheSkipper.h" |
| 24 #include "platform/graphics/paint/PaintChunkProperties.h" | 24 #include "platform/graphics/paint/PaintChunkProperties.h" |
| 25 #include "platform/graphics/paint/ScopedPaintChunkProperties.h" | 25 #include "platform/graphics/paint/ScopedPaintChunkProperties.h" |
| 26 #include "platform/graphics/paint/SubsequenceRecorder.h" | 26 #include "platform/graphics/paint/SubsequenceRecorder.h" |
| 27 #include "platform/graphics/paint/Transform3DDisplayItem.h" | 27 #include "platform/graphics/paint/Transform3DDisplayItem.h" |
| 28 #include "wtf/Optional.h" | 28 #include "wtf/Optional.h" |
| 29 | 29 |
| 30 namespace blink { | 30 namespace blink { |
| 31 | 31 |
| 32 static inline bool shouldSuppressPaintingLayer(const PaintLayer& layer) { | 32 static inline bool shouldSuppressPaintingLayer(const PaintLayer& layer) { |
| 33 // Avoid painting descendants of the root layer when stylesheets haven't loade
d. This avoids some FOUC. | 33 // Avoid painting descendants of the root layer when stylesheets haven't |
| 34 // It's ok not to draw, because later on, when all the stylesheets do load, Do
cument::styleResolverMayHaveChanged() | 34 // loaded. This avoids some FOUC. It's ok not to draw, because later on, when |
| 35 // will invalidate all painted output via a call to LayoutView::invalidatePain
tForViewAndCompositedLayers(). | 35 // all the stylesheets do load, Document::styleResolverMayHaveChanged() will |
| 36 // We also avoid caching subsequences in this mode; see shouldCreateSubsequenc
e(). | 36 // invalidate all painted output via a call to |
| 37 // LayoutView::invalidatePaintForViewAndCompositedLayers(). We also avoid |
| 38 // caching subsequences in this mode; see shouldCreateSubsequence(). |
| 37 if (layer.layoutObject()->document().didLayoutWithPendingStylesheets() && | 39 if (layer.layoutObject()->document().didLayoutWithPendingStylesheets() && |
| 38 !layer.isRootLayer() && !layer.layoutObject()->isDocumentElement()) | 40 !layer.isRootLayer() && !layer.layoutObject()->isDocumentElement()) |
| 39 return true; | 41 return true; |
| 40 | 42 |
| 41 return false; | 43 return false; |
| 42 } | 44 } |
| 43 | 45 |
| 44 void PaintLayerPainter::paint(GraphicsContext& context, | 46 void PaintLayerPainter::paint(GraphicsContext& context, |
| 45 const LayoutRect& damageRect, | 47 const LayoutRect& damageRect, |
| 46 const GlobalPaintFlags globalPaintFlags, | 48 const GlobalPaintFlags globalPaintFlags, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 65 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayer( | 67 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayer( |
| 66 GraphicsContext& context, | 68 GraphicsContext& context, |
| 67 const PaintLayerPaintingInfo& paintingInfo, | 69 const PaintLayerPaintingInfo& paintingInfo, |
| 68 PaintLayerFlags paintFlags) { | 70 PaintLayerFlags paintFlags) { |
| 69 // https://code.google.com/p/chromium/issues/detail?id=343772 | 71 // https://code.google.com/p/chromium/issues/detail?id=343772 |
| 70 DisableCompositingQueryAsserts disabler; | 72 DisableCompositingQueryAsserts disabler; |
| 71 | 73 |
| 72 if (m_paintLayer.compositingState() != NotComposited) { | 74 if (m_paintLayer.compositingState() != NotComposited) { |
| 73 if (paintingInfo.getGlobalPaintFlags() & | 75 if (paintingInfo.getGlobalPaintFlags() & |
| 74 GlobalPaintFlattenCompositingLayers) { | 76 GlobalPaintFlattenCompositingLayers) { |
| 75 // FIXME: ok, but what about GlobalPaintFlattenCompositingLayers? That's f
or printing and drag-image. | 77 // FIXME: ok, but what about GlobalPaintFlattenCompositingLayers? That's |
| 76 // FIXME: why isn't the code here global, as opposed to being set on each
paintLayer() call? | 78 // for printing and drag-image. |
| 79 // FIXME: why isn't the code here global, as opposed to being set on each |
| 80 // paintLayer() call? |
| 77 paintFlags |= PaintLayerUncachedClipRects; | 81 paintFlags |= PaintLayerUncachedClipRects; |
| 78 } | 82 } |
| 79 } | 83 } |
| 80 | 84 |
| 81 // Non self-painting layers without self-painting descendants don't need to be
painted as their | 85 // Non self-painting layers without self-painting descendants don't need to be |
| 82 // layoutObject() should properly paint itself. | 86 // painted as their layoutObject() should properly paint itself. |
| 83 if (!m_paintLayer.isSelfPaintingLayer() && | 87 if (!m_paintLayer.isSelfPaintingLayer() && |
| 84 !m_paintLayer.hasSelfPaintingLayerDescendant()) | 88 !m_paintLayer.hasSelfPaintingLayerDescendant()) |
| 85 return FullyPainted; | 89 return FullyPainted; |
| 86 | 90 |
| 87 if (shouldSuppressPaintingLayer(m_paintLayer)) | 91 if (shouldSuppressPaintingLayer(m_paintLayer)) |
| 88 return FullyPainted; | 92 return FullyPainted; |
| 89 | 93 |
| 90 if (m_paintLayer.layoutObject()->view()->frame() && | 94 if (m_paintLayer.layoutObject()->view()->frame() && |
| 91 m_paintLayer.layoutObject()->view()->frame()->shouldThrottleRendering()) | 95 m_paintLayer.layoutObject()->view()->frame()->shouldThrottleRendering()) |
| 92 return FullyPainted; | 96 return FullyPainted; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 } | 129 } |
| 126 | 130 |
| 127 static bool shouldCreateSubsequence(const PaintLayer& paintLayer, | 131 static bool shouldCreateSubsequence(const PaintLayer& paintLayer, |
| 128 GraphicsContext& context, | 132 GraphicsContext& context, |
| 129 const PaintLayerPaintingInfo& paintingInfo, | 133 const PaintLayerPaintingInfo& paintingInfo, |
| 130 PaintLayerFlags paintFlags) { | 134 PaintLayerFlags paintFlags) { |
| 131 // Caching is not needed during printing. | 135 // Caching is not needed during printing. |
| 132 if (context.printing()) | 136 if (context.printing()) |
| 133 return false; | 137 return false; |
| 134 | 138 |
| 135 // Don't create subsequence for a composited layer because if it can be cached
, | 139 // Don't create subsequence for a composited layer because if it can be |
| 136 // we can skip the whole painting in GraphicsLayer::paint() with CachedDisplay
ItemList. | 140 // cached, we can skip the whole painting in GraphicsLayer::paint() with |
| 137 // This also avoids conflict of PaintLayer::previousXXX() when paintLayer is c
omposited | 141 // CachedDisplayItemList. This also avoids conflict of |
| 138 // scrolling and is painted twice for GraphicsLayers of container and scrollin
g contents. | 142 // PaintLayer::previousXXX() when paintLayer is composited scrolling and is |
| 143 // painted twice for GraphicsLayers of container and scrolling contents. |
| 139 if (paintLayer.compositingState() == PaintsIntoOwnBacking) | 144 if (paintLayer.compositingState() == PaintsIntoOwnBacking) |
| 140 return false; | 145 return false; |
| 141 | 146 |
| 142 // Don't create subsequence during special painting to avoid cache conflict wi
th normal painting. | 147 // Don't create subsequence during special painting to avoid cache conflict |
| 148 // with normal painting. |
| 143 if (paintingInfo.getGlobalPaintFlags() & GlobalPaintFlattenCompositingLayers) | 149 if (paintingInfo.getGlobalPaintFlags() & GlobalPaintFlattenCompositingLayers) |
| 144 return false; | 150 return false; |
| 145 if (paintFlags & | 151 if (paintFlags & |
| 146 (PaintLayerPaintingRootBackgroundOnly | | 152 (PaintLayerPaintingRootBackgroundOnly | |
| 147 PaintLayerPaintingOverlayScrollbars | PaintLayerUncachedClipRects)) | 153 PaintLayerPaintingOverlayScrollbars | PaintLayerUncachedClipRects)) |
| 148 return false; | 154 return false; |
| 149 | 155 |
| 150 // Create subsequence for only stacking contexts whose painting are atomic. | 156 // Create subsequence for only stacking contexts whose painting are atomic. |
| 151 if (!paintLayer.stackingNode()->isStackingContext()) | 157 if (!paintLayer.stackingNode()->isStackingContext()) |
| 152 return false; | 158 return false; |
| 153 | 159 |
| 154 // The layer doesn't have children. Subsequence caching is not worth because n
ormally the actual painting will be cheap. | 160 // The layer doesn't have children. Subsequence caching is not worth because |
| 161 // normally the actual painting will be cheap. |
| 155 if (!PaintLayerStackingNodeIterator(*paintLayer.stackingNode(), AllChildren) | 162 if (!PaintLayerStackingNodeIterator(*paintLayer.stackingNode(), AllChildren) |
| 156 .next()) | 163 .next()) |
| 157 return false; | 164 return false; |
| 158 | 165 |
| 159 // When in FOUC-avoidance mode, don't cache any subsequences, to avoid having | 166 // When in FOUC-avoidance mode, don't cache any subsequences, to avoid having |
| 160 // to invalidate all of them when leaving this mode. There is an early-out in
BlockPainter::paintContents that may result | 167 // to invalidate all of them when leaving this mode. There is an early-out in |
| 161 // in nothing getting painted in thos mode, in addition to early-out logic in
PaintLayerPainter. | 168 // BlockPainter::paintContents that may result in nothing getting painted in |
| 169 // this mode, in addition to early-out logic in PaintLayerPainter. |
| 162 if (paintLayer.layoutObject()->document().didLayoutWithPendingStylesheets()) | 170 if (paintLayer.layoutObject()->document().didLayoutWithPendingStylesheets()) |
| 163 return false; | 171 return false; |
| 164 | 172 |
| 165 return true; | 173 return true; |
| 166 } | 174 } |
| 167 | 175 |
| 168 static bool shouldRepaintSubsequence( | 176 static bool shouldRepaintSubsequence( |
| 169 PaintLayer& paintLayer, | 177 PaintLayer& paintLayer, |
| 170 const PaintLayerPaintingInfo& paintingInfo, | 178 const PaintLayerPaintingInfo& paintingInfo, |
| 171 ShouldRespectOverflowClipType respectOverflowClip, | 179 ShouldRespectOverflowClipType respectOverflowClip, |
| 172 const LayoutSize& subpixelAccumulation, | 180 const LayoutSize& subpixelAccumulation, |
| 173 bool& shouldClearEmptyPaintPhaseFlags) { | 181 bool& shouldClearEmptyPaintPhaseFlags) { |
| 174 bool needsRepaint = false; | 182 bool needsRepaint = false; |
| 175 | 183 |
| 176 // We should set shouldResetEmptyPaintPhaseFlags if some previously unpainted
objects may begin | 184 // We should set shouldResetEmptyPaintPhaseFlags if some previously unpainted |
| 177 // to be painted, causing a previously empty paint phase to become non-empty. | 185 // objects may begin to be painted, causing a previously empty paint phase to |
| 186 // become non-empty. |
| 178 | 187 |
| 179 // Repaint subsequence if the layer is marked for needing repaint. | 188 // Repaint subsequence if the layer is marked for needing repaint. |
| 180 // We don't set needsResetEmptyPaintPhase here, but clear the empty paint phas
e flags | 189 // We don't set needsResetEmptyPaintPhase here, but clear the empty paint |
| 181 // in PaintLayer::setNeedsPaintPhaseXXX(), to ensure that we won't clear | 190 // phase flags in PaintLayer::setNeedsPaintPhaseXXX(), to ensure that we won't |
| 182 // previousPaintPhaseXXXEmpty flags when unrelated things changed which won't | 191 // clear previousPaintPhaseXXXEmpty flags when unrelated things changed which |
| 183 // cause the paint phases to become non-empty. | 192 // won't cause the paint phases to become non-empty. |
| 184 if (paintLayer.needsRepaint()) | 193 if (paintLayer.needsRepaint()) |
| 185 needsRepaint = true; | 194 needsRepaint = true; |
| 186 | 195 |
| 187 // Repaint if layer's clip changes. | 196 // Repaint if layer's clip changes. |
| 188 ClipRects& clipRects = paintLayer.clipper().paintingClipRects( | 197 ClipRects& clipRects = paintLayer.clipper().paintingClipRects( |
| 189 paintingInfo.rootLayer, respectOverflowClip, subpixelAccumulation); | 198 paintingInfo.rootLayer, respectOverflowClip, subpixelAccumulation); |
| 190 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); | 199 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); |
| 191 if (&clipRects != previousClipRects && | 200 if (&clipRects != previousClipRects && |
| 192 (!previousClipRects || clipRects != *previousClipRects)) { | 201 (!previousClipRects || clipRects != *previousClipRects)) { |
| 193 needsRepaint = true; | 202 needsRepaint = true; |
| 194 shouldClearEmptyPaintPhaseFlags = true; | 203 shouldClearEmptyPaintPhaseFlags = true; |
| 195 } | 204 } |
| 196 paintLayer.setPreviousPaintingClipRects(clipRects); | 205 paintLayer.setPreviousPaintingClipRects(clipRects); |
| 197 | 206 |
| 198 // Repaint if previously the layer might be clipped by paintDirtyRect and pain
tDirtyRect changes. | 207 // Repaint if previously the layer might be clipped by paintDirtyRect and |
| 208 // paintDirtyRect changes. |
| 199 if (paintLayer.previousPaintResult() == | 209 if (paintLayer.previousPaintResult() == |
| 200 PaintLayerPainter::MayBeClippedByPaintDirtyRect && | 210 PaintLayerPainter::MayBeClippedByPaintDirtyRect && |
| 201 paintLayer.previousPaintDirtyRect() != paintingInfo.paintDirtyRect) { | 211 paintLayer.previousPaintDirtyRect() != paintingInfo.paintDirtyRect) { |
| 202 needsRepaint = true; | 212 needsRepaint = true; |
| 203 shouldClearEmptyPaintPhaseFlags = true; | 213 shouldClearEmptyPaintPhaseFlags = true; |
| 204 } | 214 } |
| 205 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); | 215 paintLayer.setPreviousPaintDirtyRect(paintingInfo.paintDirtyRect); |
| 206 | 216 |
| 207 // Repaint if scroll offset accumulation changes. | 217 // Repaint if scroll offset accumulation changes. |
| 208 if (paintingInfo.scrollOffsetAccumulation != | 218 if (paintingInfo.scrollOffsetAccumulation != |
| (...skipping 20 matching lines...) Expand all Loading... |
| 229 bool isPaintingOverlayScrollbars = | 239 bool isPaintingOverlayScrollbars = |
| 230 paintFlags & PaintLayerPaintingOverlayScrollbars; | 240 paintFlags & PaintLayerPaintingOverlayScrollbars; |
| 231 bool isPaintingScrollingContent = | 241 bool isPaintingScrollingContent = |
| 232 paintFlags & PaintLayerPaintingCompositingScrollingPhase; | 242 paintFlags & PaintLayerPaintingCompositingScrollingPhase; |
| 233 bool isPaintingCompositedForeground = | 243 bool isPaintingCompositedForeground = |
| 234 paintFlags & PaintLayerPaintingCompositingForegroundPhase; | 244 paintFlags & PaintLayerPaintingCompositingForegroundPhase; |
| 235 bool isPaintingCompositedBackground = | 245 bool isPaintingCompositedBackground = |
| 236 paintFlags & PaintLayerPaintingCompositingBackgroundPhase; | 246 paintFlags & PaintLayerPaintingCompositingBackgroundPhase; |
| 237 bool isPaintingOverflowContents = | 247 bool isPaintingOverflowContents = |
| 238 paintFlags & PaintLayerPaintingOverflowContents; | 248 paintFlags & PaintLayerPaintingOverflowContents; |
| 239 // Outline always needs to be painted even if we have no visible content. Also
, | 249 // Outline always needs to be painted even if we have no visible content. |
| 240 // the outline is painted in the background phase during composited scrolling. | 250 // Also, the outline is painted in the background phase during composited |
| 241 // If it were painted in the foreground phase, it would move with the scrolled | 251 // scrolling. If it were painted in the foreground phase, it would move with |
| 242 // content. When not composited scrolling, the outline is painted in the | 252 // the scrolled content. When not composited scrolling, the outline is painted |
| 243 // foreground phase. Since scrolled contents are moved by paint invalidation i
n this | 253 // in the foreground phase. Since scrolled contents are moved by paint |
| 244 // case, the outline won't get 'dragged along'. | 254 // invalidation in this case, the outline won't get 'dragged along'. |
| 245 bool shouldPaintSelfOutline = | 255 bool shouldPaintSelfOutline = |
| 246 isSelfPaintingLayer && !isPaintingOverlayScrollbars && | 256 isSelfPaintingLayer && !isPaintingOverlayScrollbars && |
| 247 ((isPaintingScrollingContent && isPaintingCompositedBackground) || | 257 ((isPaintingScrollingContent && isPaintingCompositedBackground) || |
| 248 (!isPaintingScrollingContent && isPaintingCompositedForeground)) && | 258 (!isPaintingScrollingContent && isPaintingCompositedForeground)) && |
| 249 m_paintLayer.layoutObject()->styleRef().hasOutline(); | 259 m_paintLayer.layoutObject()->styleRef().hasOutline(); |
| 250 bool shouldPaintContent = m_paintLayer.hasVisibleContent() && | 260 bool shouldPaintContent = m_paintLayer.hasVisibleContent() && |
| 251 isSelfPaintingLayer && !isPaintingOverlayScrollbars; | 261 isSelfPaintingLayer && !isPaintingOverlayScrollbars; |
| 252 | 262 |
| 253 PaintResult result = FullyPainted; | 263 PaintResult result = FullyPainted; |
| 254 | 264 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 | 309 |
| 300 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); | 310 LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); |
| 301 if (!paintingInfo.paintDirtyRect.contains(bounds)) | 311 if (!paintingInfo.paintDirtyRect.contains(bounds)) |
| 302 result = MayBeClippedByPaintDirtyRect; | 312 result = MayBeClippedByPaintDirtyRect; |
| 303 | 313 |
| 304 if (paintingInfo.ancestorHasClipPathClipping && | 314 if (paintingInfo.ancestorHasClipPathClipping && |
| 305 m_paintLayer.layoutObject()->isPositioned()) | 315 m_paintLayer.layoutObject()->isPositioned()) |
| 306 UseCounter::count(m_paintLayer.layoutObject()->document(), | 316 UseCounter::count(m_paintLayer.layoutObject()->document(), |
| 307 UseCounter::ClipPathOfPositionedElement); | 317 UseCounter::ClipPathOfPositionedElement); |
| 308 | 318 |
| 309 // These helpers output clip and compositing operations using a RAII pattern.
Stack-allocated-varibles are destructed in the reverse order of construction, | 319 // These helpers output clip and compositing operations using a RAII pattern. |
| 310 // so they are nested properly. | 320 // Stack-allocated-varibles are destructed in the reverse order of |
| 321 // construction, so they are nested properly. |
| 311 Optional<ClipPathClipper> clipPathClipper; | 322 Optional<ClipPathClipper> clipPathClipper; |
| 312 // Clip-path, like border radius, must not be applied to the contents of a com
posited-scrolling container. | 323 // Clip-path, like border radius, must not be applied to the contents of a |
| 313 // It must, however, still be applied to the mask layer, so that the composito
r can properly mask the | 324 // composited-scrolling container. It must, however, still be applied to the |
| 325 // mask layer, so that the compositor can properly mask the |
| 314 // scrolling contents and scrollbars. | 326 // scrolling contents and scrollbars. |
| 315 if (m_paintLayer.layoutObject()->hasClipPath() && | 327 if (m_paintLayer.layoutObject()->hasClipPath() && |
| 316 (!m_paintLayer.needsCompositedScrolling() || | 328 (!m_paintLayer.needsCompositedScrolling() || |
| 317 (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) { | 329 (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) { |
| 318 paintingInfo.ancestorHasClipPathClipping = true; | 330 paintingInfo.ancestorHasClipPathClipping = true; |
| 319 | 331 |
| 320 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); | 332 LayoutRect referenceBox(m_paintLayer.boxForClipPath()); |
| 321 // Note that this isn't going to work correctly if crossing a column boundar
y. The reference box should be | 333 // Note that this isn't going to work correctly if crossing a column |
| 322 // determined per-fragment, and hence this ought to be performed after fragm
entation. | 334 // boundary. The reference box should be determined per-fragment, and hence |
| 335 // this ought to be performed after fragmentation. |
| 323 if (m_paintLayer.enclosingPaginationLayer()) | 336 if (m_paintLayer.enclosingPaginationLayer()) |
| 324 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( | 337 m_paintLayer.convertFromFlowThreadToVisualBoundingBoxInAncestor( |
| 325 paintingInfo.rootLayer, referenceBox); | 338 paintingInfo.rootLayer, referenceBox); |
| 326 else | 339 else |
| 327 referenceBox.moveBy(offsetFromRoot); | 340 referenceBox.moveBy(offsetFromRoot); |
| 328 clipPathClipper.emplace( | 341 clipPathClipper.emplace( |
| 329 context, *m_paintLayer.layoutObject()->styleRef().clipPath(), | 342 context, *m_paintLayer.layoutObject()->styleRef().clipPath(), |
| 330 *m_paintLayer.layoutObject(), FloatRect(referenceBox), | 343 *m_paintLayer.layoutObject(), FloatRect(referenceBox), |
| 331 FloatPoint(referenceBox.location())); | 344 FloatPoint(referenceBox.location())); |
| 332 } | 345 } |
| 333 | 346 |
| 334 Optional<CompositingRecorder> compositingRecorder; | 347 Optional<CompositingRecorder> compositingRecorder; |
| 335 // Blending operations must be performed only with the nearest ancestor stacki
ng context. | 348 // Blending operations must be performed only with the nearest ancestor |
| 336 // Note that there is no need to composite if we're painting the root. | 349 // stacking context. Note that there is no need to composite if we're |
| 337 // FIXME: this should be unified further into PaintLayer::paintsWithTransparen
cy(). | 350 // painting the root. |
| 351 // FIXME: this should be unified further into |
| 352 // PaintLayer::paintsWithTransparency(). |
| 338 bool shouldCompositeForBlendMode = | 353 bool shouldCompositeForBlendMode = |
| 339 (!m_paintLayer.layoutObject()->isDocumentElement() || | 354 (!m_paintLayer.layoutObject()->isDocumentElement() || |
| 340 m_paintLayer.layoutObject()->isSVGRoot()) && | 355 m_paintLayer.layoutObject()->isSVGRoot()) && |
| 341 m_paintLayer.stackingNode()->isStackingContext() && | 356 m_paintLayer.stackingNode()->isStackingContext() && |
| 342 m_paintLayer.hasNonIsolatedDescendantWithBlendMode(); | 357 m_paintLayer.hasNonIsolatedDescendantWithBlendMode(); |
| 343 if (shouldCompositeForBlendMode || | 358 if (shouldCompositeForBlendMode || |
| 344 m_paintLayer.paintsWithTransparency(paintingInfo.getGlobalPaintFlags())) { | 359 m_paintLayer.paintsWithTransparency(paintingInfo.getGlobalPaintFlags())) { |
| 345 FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent( | 360 FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent( |
| 346 paintingInfo.rootLayer, paintingInfo.subPixelAccumulation, | 361 paintingInfo.rootLayer, paintingInfo.subPixelAccumulation, |
| 347 paintingInfo.getGlobalPaintFlags())); | 362 paintingInfo.getGlobalPaintFlags())); |
| 348 compositingRecorder.emplace( | 363 compositingRecorder.emplace( |
| 349 context, *m_paintLayer.layoutObject(), | 364 context, *m_paintLayer.layoutObject(), |
| 350 WebCoreCompositeToSkiaComposite( | 365 WebCoreCompositeToSkiaComposite( |
| 351 CompositeSourceOver, | 366 CompositeSourceOver, |
| 352 m_paintLayer.layoutObject()->style()->blendMode()), | 367 m_paintLayer.layoutObject()->style()->blendMode()), |
| 353 m_paintLayer.layoutObject()->opacity(), &compositingBounds); | 368 m_paintLayer.layoutObject()->opacity(), &compositingBounds); |
| 354 } | 369 } |
| 355 | 370 |
| 356 PaintLayerPaintingInfo localPaintingInfo(paintingInfo); | 371 PaintLayerPaintingInfo localPaintingInfo(paintingInfo); |
| 357 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; | 372 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; |
| 358 | 373 |
| 359 PaintLayerFragments layerFragments; | 374 PaintLayerFragments layerFragments; |
| 360 if (shouldPaintContent || shouldPaintSelfOutline || | 375 if (shouldPaintContent || shouldPaintSelfOutline || |
| 361 isPaintingOverlayScrollbars) { | 376 isPaintingOverlayScrollbars) { |
| 362 // Collect the fragments. This will compute the clip rectangles and paint of
fsets for each layer fragment. | 377 // Collect the fragments. This will compute the clip rectangles and paint |
| 378 // offsets for each layer fragment. |
| 363 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) | 379 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) |
| 364 ? UncachedClipRects | 380 ? UncachedClipRects |
| 365 : PaintingClipRects; | 381 : PaintingClipRects; |
| 366 // TODO(trchen): We haven't decided how to handle visual fragmentation with
SPv2. | 382 // TODO(trchen): We haven't decided how to handle visual fragmentation with |
| 367 // Related thread https://groups.google.com/a/chromium.org/forum/#!topic/gra
phics-dev/81XuWFf-mxM | 383 // SPv2. Related thread |
| 384 // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuW
Ff-mxM |
| 368 if (fragmentPolicy == ForceSingleFragment || | 385 if (fragmentPolicy == ForceSingleFragment || |
| 369 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 386 RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 370 m_paintLayer.appendSingleFragmentIgnoringPagination( | 387 m_paintLayer.appendSingleFragmentIgnoringPagination( |
| 371 layerFragments, localPaintingInfo.rootLayer, | 388 layerFragments, localPaintingInfo.rootLayer, |
| 372 localPaintingInfo.paintDirtyRect, cacheSlot, | 389 localPaintingInfo.paintDirtyRect, cacheSlot, |
| 373 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, | 390 IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, |
| 374 localPaintingInfo.subPixelAccumulation); | 391 localPaintingInfo.subPixelAccumulation); |
| 375 else | 392 else |
| 376 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, | 393 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, |
| 377 localPaintingInfo.paintDirtyRect, cacheSlot, | 394 localPaintingInfo.paintDirtyRect, cacheSlot, |
| 378 IgnoreOverlayScrollbarSize, | 395 IgnoreOverlayScrollbarSize, |
| 379 respectOverflowClip, &offsetFromRoot, | 396 respectOverflowClip, &offsetFromRoot, |
| 380 localPaintingInfo.subPixelAccumulation); | 397 localPaintingInfo.subPixelAccumulation); |
| 381 | 398 |
| 382 // TODO(trchen): Needs to adjust cull rect between transform spaces. https:/
/crbug.com/593596 | 399 // TODO(trchen): Needs to adjust cull rect between transform spaces. |
| 383 // Disables layer culling for SPv2 for now because the space of the cull rec
t doesn't match | 400 // https://crbug.com/593596 |
| 384 // the space we paint in. Clipping will still be done by clip nodes, so this
won't cause | 401 // Disables layer culling for SPv2 for now because the space of the cull |
| 385 // rendering issues, only performance. | 402 // rect doesn't match the space we paint in. Clipping will still be done by |
| 403 // clip nodes, so this won't cause rendering issues, only performance. |
| 386 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 404 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 387 layerFragments[0].backgroundRect = | 405 layerFragments[0].backgroundRect = |
| 388 LayoutRect(LayoutRect::infiniteIntRect()); | 406 LayoutRect(LayoutRect::infiniteIntRect()); |
| 389 layerFragments[0].foregroundRect = | 407 layerFragments[0].foregroundRect = |
| 390 LayoutRect(LayoutRect::infiniteIntRect()); | 408 LayoutRect(LayoutRect::infiniteIntRect()); |
| 391 } | 409 } |
| 392 | 410 |
| 393 if (shouldPaintContent) { | 411 if (shouldPaintContent) { |
| 394 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar op
timization for slimming paint v2. | 412 // TODO(wangxianzhu): This is for old slow scrolling. Implement similar |
| 413 // optimization for slimming paint v2. |
| 395 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( | 414 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect( |
| 396 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); | 415 layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); |
| 397 if (!shouldPaintContent) | 416 if (!shouldPaintContent) |
| 398 result = MayBeClippedByPaintDirtyRect; | 417 result = MayBeClippedByPaintDirtyRect; |
| 399 } | 418 } |
| 400 } | 419 } |
| 401 | 420 |
| 402 bool selectionOnly = | 421 bool selectionOnly = |
| 403 localPaintingInfo.getGlobalPaintFlags() & GlobalPaintSelectionOnly; | 422 localPaintingInfo.getGlobalPaintFlags() & GlobalPaintSelectionOnly; |
| 404 | 423 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 return clipRect.rect() != localPaintingInfo.paintDirtyRect || | 530 return clipRect.rect() != localPaintingInfo.paintDirtyRect || |
| 512 clipRect.hasRadius(); | 531 clipRect.hasRadius(); |
| 513 } | 532 } |
| 514 | 533 |
| 515 bool PaintLayerPainter::atLeastOneFragmentIntersectsDamageRect( | 534 bool PaintLayerPainter::atLeastOneFragmentIntersectsDamageRect( |
| 516 PaintLayerFragments& fragments, | 535 PaintLayerFragments& fragments, |
| 517 const PaintLayerPaintingInfo& localPaintingInfo, | 536 const PaintLayerPaintingInfo& localPaintingInfo, |
| 518 PaintLayerFlags localPaintFlags, | 537 PaintLayerFlags localPaintFlags, |
| 519 const LayoutPoint& offsetFromRoot) { | 538 const LayoutPoint& offsetFromRoot) { |
| 520 if (m_paintLayer.enclosingPaginationLayer()) | 539 if (m_paintLayer.enclosingPaginationLayer()) |
| 521 return true; // The fragments created have already been found to intersect
with the damage rect. | 540 return true; // The fragments created have already been found to intersect |
| 541 // with the damage rect. |
| 522 | 542 |
| 523 if (&m_paintLayer == localPaintingInfo.rootLayer && | 543 if (&m_paintLayer == localPaintingInfo.rootLayer && |
| 524 (localPaintFlags & PaintLayerPaintingOverflowContents)) | 544 (localPaintFlags & PaintLayerPaintingOverflowContents)) |
| 525 return true; | 545 return true; |
| 526 | 546 |
| 527 for (PaintLayerFragment& fragment : fragments) { | 547 for (PaintLayerFragment& fragment : fragments) { |
| 528 LayoutPoint newOffsetFromRoot = offsetFromRoot + fragment.paginationOffset; | 548 LayoutPoint newOffsetFromRoot = offsetFromRoot + fragment.paginationOffset; |
| 529 // Note that this really only works reliably on the first fragment. If the l
ayer has visible | 549 // Note that this really only works reliably on the first fragment. If the |
| 530 // overflow and a subsequent fragment doesn't intersect with the border box
of the layer | 550 // layer has visible overflow and a subsequent fragment doesn't intersect |
| 531 // (i.e. only contains an overflow portion of the layer), intersection will
fail. The reason | 551 // with the border box of the layer (i.e. only contains an overflow portion |
| 532 // for this is that fragment.layerBounds is set to the border box, not the b
ounding box, of | 552 // of the layer), intersection will fail. The reason for this is that |
| 553 // fragment.layerBounds is set to the border box, not the bounding box, of |
| 533 // the layer. | 554 // the layer. |
| 534 if (m_paintLayer.intersectsDamageRect(fragment.layerBounds, | 555 if (m_paintLayer.intersectsDamageRect(fragment.layerBounds, |
| 535 fragment.backgroundRect.rect(), | 556 fragment.backgroundRect.rect(), |
| 536 newOffsetFromRoot)) | 557 newOffsetFromRoot)) |
| 537 return true; | 558 return true; |
| 538 } | 559 } |
| 539 return false; | 560 return false; |
| 540 } | 561 } |
| 541 | 562 |
| 542 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerWithTransform( | 563 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerWithTransform( |
| 543 GraphicsContext& context, | 564 GraphicsContext& context, |
| 544 const PaintLayerPaintingInfo& paintingInfo, | 565 const PaintLayerPaintingInfo& paintingInfo, |
| 545 PaintLayerFlags paintFlags) { | 566 PaintLayerFlags paintFlags) { |
| 546 // Transforms will be applied by property nodes directly for SPv2. | 567 // Transforms will be applied by property nodes directly for SPv2. |
| 547 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 568 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 548 | 569 |
| 549 TransformationMatrix layerTransform = | 570 TransformationMatrix layerTransform = |
| 550 m_paintLayer.renderableTransform(paintingInfo.getGlobalPaintFlags()); | 571 m_paintLayer.renderableTransform(paintingInfo.getGlobalPaintFlags()); |
| 551 // If the transform can't be inverted, then don't paint anything. | 572 // If the transform can't be inverted, then don't paint anything. |
| 552 if (!layerTransform.isInvertible()) | 573 if (!layerTransform.isInvertible()) |
| 553 return FullyPainted; | 574 return FullyPainted; |
| 554 | 575 |
| 555 // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer h
ere. | 576 // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer |
| 556 // m_paintLayer may be the "root", and then we should avoid looking at its par
ent. | 577 // here. m_paintLayer may be the "root", and then we should avoid looking at |
| 578 // its parent. |
| 557 PaintLayer* parentLayer = m_paintLayer.parent(); | 579 PaintLayer* parentLayer = m_paintLayer.parent(); |
| 558 | 580 |
| 559 ClipRect ancestorBackgroundClipRect; | 581 ClipRect ancestorBackgroundClipRect; |
| 560 if (parentLayer) { | 582 if (parentLayer) { |
| 561 // Calculate the clip rectangle that the ancestors establish. | 583 // Calculate the clip rectangle that the ancestors establish. |
| 562 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, | 584 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, |
| 563 (paintFlags & PaintLayerUncachedClipRects) | 585 (paintFlags & PaintLayerUncachedClipRects) |
| 564 ? UncachedClipRects | 586 ? UncachedClipRects |
| 565 : PaintingClipRects, | 587 : PaintingClipRects, |
| 566 IgnoreOverlayScrollbarSize); | 588 IgnoreOverlayScrollbarSize); |
| 567 if (shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()) == | 589 if (shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()) == |
| 568 IgnoreOverflowClip) | 590 IgnoreOverflowClip) |
| 569 clipRectsContext.setIgnoreOverflowClip(); | 591 clipRectsContext.setIgnoreOverflowClip(); |
| 570 ancestorBackgroundClipRect = | 592 ancestorBackgroundClipRect = |
| 571 m_paintLayer.clipper().backgroundClipRect(clipRectsContext); | 593 m_paintLayer.clipper().backgroundClipRect(clipRectsContext); |
| 572 } | 594 } |
| 573 | 595 |
| 574 LayoutObject* object = m_paintLayer.layoutObject(); | 596 LayoutObject* object = m_paintLayer.layoutObject(); |
| 575 LayoutView* view = object->view(); | 597 LayoutView* view = object->view(); |
| 576 bool isFixedPosObjectInPagedMedia = | 598 bool isFixedPosObjectInPagedMedia = |
| 577 object->style()->position() == FixedPosition && | 599 object->style()->position() == FixedPosition && |
| 578 object->container() == view && view->pageLogicalHeight(); | 600 object->container() == view && view->pageLogicalHeight(); |
| 579 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); | 601 PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); |
| 580 PaintLayerFragments fragments; | 602 PaintLayerFragments fragments; |
| 581 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position
objects | 603 // TODO(crbug.com/619094): Figure out the correct behaviour for fixed position |
| 582 // in paged media with vertical writing modes. | 604 // objects in paged media with vertical writing modes. |
| 583 if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) { | 605 if (isFixedPosObjectInPagedMedia && view->isHorizontalWritingMode()) { |
| 584 // "For paged media, boxes with fixed positions are repeated on every page." | 606 // "For paged media, boxes with fixed positions are repeated on every page." |
| 585 // - https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positio
ning | 607 // https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#fixed-positioni
ng |
| 586 unsigned pages = | 608 unsigned pages = |
| 587 ceilf(view->documentRect().height() / view->pageLogicalHeight()); | 609 ceilf(view->documentRect().height() / view->pageLogicalHeight()); |
| 588 LayoutPoint paginationOffset; | 610 LayoutPoint paginationOffset; |
| 589 for (unsigned i = 0; i < pages; i++) { | 611 for (unsigned i = 0; i < pages; i++) { |
| 590 PaintLayerFragment fragment; | 612 PaintLayerFragment fragment; |
| 591 fragment.backgroundRect = paintingInfo.paintDirtyRect; | 613 fragment.backgroundRect = paintingInfo.paintDirtyRect; |
| 592 fragment.paginationOffset = paginationOffset; | 614 fragment.paginationOffset = paginationOffset; |
| 593 fragments.append(fragment); | 615 fragments.append(fragment); |
| 594 paginationOffset += LayoutPoint(LayoutUnit(), view->pageLogicalHeight()); | 616 paginationOffset += LayoutPoint(LayoutUnit(), view->pageLogicalHeight()); |
| 595 } | 617 } |
| 596 } else if (paginationLayer) { | 618 } else if (paginationLayer) { |
| 597 // FIXME: This is a mess. Look closely at this code and the code in Layer an
d fix any | 619 // FIXME: This is a mess. Look closely at this code and the code in Layer |
| 598 // issues in it & refactor to make it obvious from code structure what it do
es and that it's | 620 // and fix any issues in it & refactor to make it obvious from code |
| 599 // correct. | 621 // structure what it does and that it's correct. |
| 600 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) | 622 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) |
| 601 ? UncachedClipRects | 623 ? UncachedClipRects |
| 602 : PaintingClipRects; | 624 : PaintingClipRects; |
| 603 ShouldRespectOverflowClipType respectOverflowClip = | 625 ShouldRespectOverflowClipType respectOverflowClip = |
| 604 shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()); | 626 shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()); |
| 605 // Calculate the transformed bounding box in the current coordinate space, t
o figure out | 627 // Calculate the transformed bounding box in the current coordinate space, |
| 606 // which fragmentainers (e.g. columns) we need to visit. | 628 // to figure out which fragmentainers (e.g. columns) we need to visit. |
| 607 LayoutRect transformedExtent = PaintLayer::transparencyClipBox( | 629 LayoutRect transformedExtent = PaintLayer::transparencyClipBox( |
| 608 &m_paintLayer, paginationLayer, PaintLayer::PaintingTransparencyClipBox, | 630 &m_paintLayer, paginationLayer, PaintLayer::PaintingTransparencyClipBox, |
| 609 PaintLayer::RootOfTransparencyClipBox, | 631 PaintLayer::RootOfTransparencyClipBox, |
| 610 paintingInfo.subPixelAccumulation, paintingInfo.getGlobalPaintFlags()); | 632 paintingInfo.subPixelAccumulation, paintingInfo.getGlobalPaintFlags()); |
| 611 // FIXME: we don't check if paginationLayer is within paintingInfo.rootLayer
here. | 633 // FIXME: we don't check if paginationLayer is within paintingInfo.rootLayer |
| 634 // here. |
| 612 paginationLayer->collectFragments( | 635 paginationLayer->collectFragments( |
| 613 fragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, | 636 fragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, |
| 614 cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, 0, | 637 cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, 0, |
| 615 paintingInfo.subPixelAccumulation, &transformedExtent); | 638 paintingInfo.subPixelAccumulation, &transformedExtent); |
| 616 } else { | 639 } else { |
| 617 // We don't need to collect any fragments in the regular way here. We have a
lready | 640 // We don't need to collect any fragments in the regular way here. We have |
| 618 // calculated a clip rectangle for the ancestry if it was needed, and clippi
ng this | 641 // already calculated a clip rectangle for the ancestry if it was needed, |
| 619 // layer is something that can be done further down the path, when the trans
form has | 642 // and clipping this layer is something that can be done further down the |
| 620 // been applied. | 643 // path, when the transform has been applied. |
| 621 PaintLayerFragment fragment; | 644 PaintLayerFragment fragment; |
| 622 fragment.backgroundRect = paintingInfo.paintDirtyRect; | 645 fragment.backgroundRect = paintingInfo.paintDirtyRect; |
| 623 fragments.append(fragment); | 646 fragments.append(fragment); |
| 624 } | 647 } |
| 625 | 648 |
| 626 Optional<DisplayItemCacheSkipper> cacheSkipper; | 649 Optional<DisplayItemCacheSkipper> cacheSkipper; |
| 627 if (fragments.size() > 1) | 650 if (fragments.size() > 1) |
| 628 cacheSkipper.emplace(context); | 651 cacheSkipper.emplace(context); |
| 629 | 652 |
| 630 PaintResult result = FullyPainted; | 653 PaintResult result = FullyPainted; |
| 631 for (const auto& fragment : fragments) { | 654 for (const auto& fragment : fragments) { |
| 632 Optional<LayerClipRecorder> clipRecorder; | 655 Optional<LayerClipRecorder> clipRecorder; |
| 633 if (parentLayer) { | 656 if (parentLayer) { |
| 634 ClipRect clipRectForFragment(ancestorBackgroundClipRect); | 657 ClipRect clipRectForFragment(ancestorBackgroundClipRect); |
| 635 // A fixed-position object is repeated on every page, but if it is clipped
by an ancestor layer then | 658 // A fixed-position object is repeated on every page, but if it is clipped |
| 636 // the repetitions are clipped out. | 659 // by an ancestor layer then the repetitions are clipped out. |
| 637 if (!isFixedPosObjectInPagedMedia) | 660 if (!isFixedPosObjectInPagedMedia) |
| 638 clipRectForFragment.moveBy(fragment.paginationOffset); | 661 clipRectForFragment.moveBy(fragment.paginationOffset); |
| 639 clipRectForFragment.intersect(fragment.backgroundRect); | 662 clipRectForFragment.intersect(fragment.backgroundRect); |
| 640 if (clipRectForFragment.isEmpty()) | 663 if (clipRectForFragment.isEmpty()) |
| 641 continue; | 664 continue; |
| 642 if (needsToClip(paintingInfo, clipRectForFragment)) { | 665 if (needsToClip(paintingInfo, clipRectForFragment)) { |
| 643 if (m_paintLayer.layoutObject()->isPositioned() && | 666 if (m_paintLayer.layoutObject()->isPositioned() && |
| 644 clipRectForFragment.isClippedByClipCss()) | 667 clipRectForFragment.isClippedByClipCss()) |
| 645 UseCounter::count(m_paintLayer.layoutObject()->document(), | 668 UseCounter::count(m_paintLayer.layoutObject()->document(), |
| 646 UseCounter::ClipCssOfPositionedElement); | 669 UseCounter::ClipCssOfPositionedElement); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 663 | 686 |
| 664 PaintLayerPainter::PaintResult | 687 PaintLayerPainter::PaintResult |
| 665 PaintLayerPainter::paintFragmentByApplyingTransform( | 688 PaintLayerPainter::paintFragmentByApplyingTransform( |
| 666 GraphicsContext& context, | 689 GraphicsContext& context, |
| 667 const PaintLayerPaintingInfo& paintingInfo, | 690 const PaintLayerPaintingInfo& paintingInfo, |
| 668 PaintLayerFlags paintFlags, | 691 PaintLayerFlags paintFlags, |
| 669 const LayoutPoint& fragmentTranslation) { | 692 const LayoutPoint& fragmentTranslation) { |
| 670 // Transforms will be applied by property nodes directly for SPv2. | 693 // Transforms will be applied by property nodes directly for SPv2. |
| 671 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 694 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 672 | 695 |
| 673 // This involves subtracting out the position of the layer in our current coor
dinate space, but preserving | 696 // This involves subtracting out the position of the layer in our current |
| 674 // the accumulated error for sub-pixel layout. | 697 // coordinate space, but preserving the accumulated error for sub-pixel |
| 698 // layout. |
| 675 LayoutPoint delta; | 699 LayoutPoint delta; |
| 676 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, delta); | 700 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, delta); |
| 677 delta.moveBy(fragmentTranslation); | 701 delta.moveBy(fragmentTranslation); |
| 678 TransformationMatrix transform( | 702 TransformationMatrix transform( |
| 679 m_paintLayer.renderableTransform(paintingInfo.getGlobalPaintFlags())); | 703 m_paintLayer.renderableTransform(paintingInfo.getGlobalPaintFlags())); |
| 680 IntPoint roundedDelta = roundedIntPoint(delta); | 704 IntPoint roundedDelta = roundedIntPoint(delta); |
| 681 transform.translateRight(roundedDelta.x(), roundedDelta.y()); | 705 transform.translateRight(roundedDelta.x(), roundedDelta.y()); |
| 682 LayoutSize adjustedSubPixelAccumulation = | 706 LayoutSize adjustedSubPixelAccumulation = |
| 683 paintingInfo.subPixelAccumulation + (delta - roundedDelta); | 707 paintingInfo.subPixelAccumulation + (delta - roundedDelta); |
| 684 | 708 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 return result; | 749 return result; |
| 726 | 750 |
| 727 IntSize scrollOffsetAccumulationForChildren = | 751 IntSize scrollOffsetAccumulationForChildren = |
| 728 paintingInfo.scrollOffsetAccumulation; | 752 paintingInfo.scrollOffsetAccumulation; |
| 729 if (m_paintLayer.layoutObject()->hasOverflowClip()) | 753 if (m_paintLayer.layoutObject()->hasOverflowClip()) |
| 730 scrollOffsetAccumulationForChildren += | 754 scrollOffsetAccumulationForChildren += |
| 731 m_paintLayer.layoutBox()->scrolledContentOffset(); | 755 m_paintLayer.layoutBox()->scrolledContentOffset(); |
| 732 | 756 |
| 733 for (; child; child = iterator.next()) { | 757 for (; child; child = iterator.next()) { |
| 734 PaintLayerPainter childPainter(*child->layer()); | 758 PaintLayerPainter childPainter(*child->layer()); |
| 735 // If this Layer should paint into its own backing or a grouped backing, tha
t will be done via CompositedLayerMapping::paintContents() | 759 // If this Layer should paint into its own backing or a grouped backing, |
| 736 // and CompositedLayerMapping::doPaintTask(). | 760 // that will be done via CompositedLayerMapping::paintContents() and |
| 761 // CompositedLayerMapping::doPaintTask(). |
| 737 if (!childPainter.shouldPaintLayerInSoftwareMode( | 762 if (!childPainter.shouldPaintLayerInSoftwareMode( |
| 738 paintingInfo.getGlobalPaintFlags(), paintFlags)) | 763 paintingInfo.getGlobalPaintFlags(), paintFlags)) |
| 739 continue; | 764 continue; |
| 740 | 765 |
| 741 PaintLayerPaintingInfo childPaintingInfo = paintingInfo; | 766 PaintLayerPaintingInfo childPaintingInfo = paintingInfo; |
| 742 childPaintingInfo.scrollOffsetAccumulation = | 767 childPaintingInfo.scrollOffsetAccumulation = |
| 743 scrollOffsetAccumulationForChildren; | 768 scrollOffsetAccumulationForChildren; |
| 744 // Rare case: accumulate scroll offset of non-stacking-context ancestors up
to m_paintLayer. | 769 // Rare case: accumulate scroll offset of non-stacking-context ancestors up |
| 770 // to m_paintLayer. |
| 745 for (PaintLayer* parentLayer = child->layer()->parent(); | 771 for (PaintLayer* parentLayer = child->layer()->parent(); |
| 746 parentLayer != &m_paintLayer; parentLayer = parentLayer->parent()) { | 772 parentLayer != &m_paintLayer; parentLayer = parentLayer->parent()) { |
| 747 if (parentLayer->layoutObject()->hasOverflowClip()) | 773 if (parentLayer->layoutObject()->hasOverflowClip()) |
| 748 childPaintingInfo.scrollOffsetAccumulation += | 774 childPaintingInfo.scrollOffsetAccumulation += |
| 749 parentLayer->layoutBox()->scrolledContentOffset(); | 775 parentLayer->layoutBox()->scrolledContentOffset(); |
| 750 } | 776 } |
| 751 | 777 |
| 752 if (childPainter.paintLayer(context, childPaintingInfo, paintFlags) == | 778 if (childPainter.paintLayer(context, childPaintingInfo, paintFlags) == |
| 753 MayBeClippedByPaintDirtyRect) | 779 MayBeClippedByPaintDirtyRect) |
| 754 result = MayBeClippedByPaintDirtyRect; | 780 result = MayBeClippedByPaintDirtyRect; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 ClipState clipState) { | 845 ClipState clipState) { |
| 820 ASSERT(m_paintLayer.isSelfPaintingLayer()); | 846 ASSERT(m_paintLayer.isSelfPaintingLayer()); |
| 821 | 847 |
| 822 Optional<LayerClipRecorder> clipRecorder; | 848 Optional<LayerClipRecorder> clipRecorder; |
| 823 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && | 849 if (clipState != HasClipped && paintingInfo.clipToDirtyRect && |
| 824 needsToClip(paintingInfo, clipRect)) { | 850 needsToClip(paintingInfo, clipRect)) { |
| 825 DisplayItem::Type clipType = | 851 DisplayItem::Type clipType = |
| 826 DisplayItem::paintPhaseToClipLayerFragmentType(phase); | 852 DisplayItem::paintPhaseToClipLayerFragmentType(phase); |
| 827 LayerClipRecorder::BorderRadiusClippingRule clippingRule; | 853 LayerClipRecorder::BorderRadiusClippingRule clippingRule; |
| 828 switch (phase) { | 854 switch (phase) { |
| 829 case PaintPhaseSelfBlockBackgroundOnly: // Background painting will handl
e clipping to self. | 855 case PaintPhaseSelfBlockBackgroundOnly: // Background painting will |
| 856 // handle clipping to self. |
| 830 case PaintPhaseSelfOutlineOnly: | 857 case PaintPhaseSelfOutlineOnly: |
| 831 case PaintPhaseMask: // Mask painting will handle clipping to self. | 858 case PaintPhaseMask: // Mask painting will handle clipping to self. |
| 832 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; | 859 clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; |
| 833 break; | 860 break; |
| 834 default: | 861 default: |
| 835 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; | 862 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; |
| 836 break; | 863 break; |
| 837 } | 864 } |
| 838 | 865 |
| 839 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, | 866 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, |
| 840 clipRect, &paintingInfo, fragment.paginationOffset, | 867 clipRect, &paintingInfo, fragment.paginationOffset, |
| 841 paintFlags, clippingRule); | 868 paintFlags, clippingRule); |
| 842 } | 869 } |
| 843 | 870 |
| 844 LayoutRect newCullRect(clipRect.rect()); | 871 LayoutRect newCullRect(clipRect.rect()); |
| 845 Optional<ScrollRecorder> scrollRecorder; | 872 Optional<ScrollRecorder> scrollRecorder; |
| 846 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); | 873 LayoutPoint paintOffset = -m_paintLayer.layoutBoxLocation(); |
| 847 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 874 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 848 const ObjectPaintProperties* objectPaintProperties = | 875 const ObjectPaintProperties* objectPaintProperties = |
| 849 m_paintLayer.layoutObject()->objectPaintProperties(); | 876 m_paintLayer.layoutObject()->objectPaintProperties(); |
| 850 ASSERT(objectPaintProperties && | 877 ASSERT(objectPaintProperties && |
| 851 objectPaintProperties->localBorderBoxProperties()); | 878 objectPaintProperties->localBorderBoxProperties()); |
| 852 paintOffset += | 879 paintOffset += |
| 853 toSize(objectPaintProperties->localBorderBoxProperties()->paintOffset); | 880 toSize(objectPaintProperties->localBorderBoxProperties()->paintOffset); |
| 854 } else { | 881 } else { |
| 855 paintOffset += toSize(fragment.layerBounds.location()); | 882 paintOffset += toSize(fragment.layerBounds.location()); |
| 856 if (!paintingInfo.scrollOffsetAccumulation.isZero()) { | 883 if (!paintingInfo.scrollOffsetAccumulation.isZero()) { |
| 857 // As a descendant of the root layer, m_paintLayer's painting is not contr
olled by the ScrollRecorders | 884 // As a descendant of the root layer, m_paintLayer's painting is not |
| 858 // created by BlockPainter of the ancestor layers up to the root layer, so
we need to issue ScrollRecorder | 885 // controlled by the ScrollRecorders created by BlockPainter of the |
| 859 // for this layer seperately, with the scroll offset accumulated from the
root layer to the parent of this | 886 // ancestor layers up to the root layer, so we need to issue |
| 860 // layer, to get the same result as ScrollRecorder in BlockPainter. | 887 // ScrollRecorder for this layer seperately, with the scroll offset |
| 888 // accumulated from the root layer to the parent of this layer, to get the |
| 889 // same result as ScrollRecorder in BlockPainter. |
| 861 paintOffset += paintingInfo.scrollOffsetAccumulation; | 890 paintOffset += paintingInfo.scrollOffsetAccumulation; |
| 862 | 891 |
| 863 newCullRect.move(paintingInfo.scrollOffsetAccumulation); | 892 newCullRect.move(paintingInfo.scrollOffsetAccumulation); |
| 864 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, | 893 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, |
| 865 paintingInfo.scrollOffsetAccumulation); | 894 paintingInfo.scrollOffsetAccumulation); |
| 866 } | 895 } |
| 867 } | 896 } |
| 868 PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, | 897 PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, |
| 869 paintingInfo.getGlobalPaintFlags(), paintFlags, | 898 paintingInfo.getGlobalPaintFlags(), paintFlags, |
| 870 paintingInfo.rootLayer->layoutObject()); | 899 paintingInfo.rootLayer->layoutObject()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 Optional<LayerClipRecorder> clipRecorder; | 934 Optional<LayerClipRecorder> clipRecorder; |
| 906 if (shouldClip && | 935 if (shouldClip && |
| 907 needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) { | 936 needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) { |
| 908 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), | 937 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), |
| 909 DisplayItem::kClipLayerForeground, | 938 DisplayItem::kClipLayerForeground, |
| 910 layerFragments[0].foregroundRect, &localPaintingInfo, | 939 layerFragments[0].foregroundRect, &localPaintingInfo, |
| 911 layerFragments[0].paginationOffset, paintFlags); | 940 layerFragments[0].paginationOffset, paintFlags); |
| 912 clipState = HasClipped; | 941 clipState = HasClipped; |
| 913 } | 942 } |
| 914 | 943 |
| 915 // We have to loop through every fragment multiple times, since we have to iss
ue paint invalidations in each specific phase in order for | 944 // We have to loop through every fragment multiple times, since we have to |
| 916 // interleaving of the fragments to work properly. | 945 // issue paint invalidations in each specific phase in order for interleaving |
| 946 // of the fragments to work properly. |
| 917 if (selectionOnly) { | 947 if (selectionOnly) { |
| 918 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments, | 948 paintForegroundForFragmentsWithPhase(PaintPhaseSelection, layerFragments, |
| 919 context, localPaintingInfo, paintFlags, | 949 context, localPaintingInfo, paintFlags, |
| 920 clipState); | 950 clipState); |
| 921 } else { | 951 } else { |
| 922 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() || | 952 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() || |
| 923 m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) { | 953 m_paintLayer.needsPaintPhaseDescendantBlockBackgrounds()) { |
| 924 size_t sizeBefore = | 954 size_t sizeBefore = |
| 925 context.getPaintController().newDisplayItemList().size(); | 955 context.getPaintController().newDisplayItemList().size(); |
| 926 paintForegroundForFragmentsWithPhase( | 956 paintForegroundForFragmentsWithPhase( |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 | 1076 |
| 1047 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, | 1077 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, |
| 1048 LayoutRect(enclosingIntRect(damageRect)), | 1078 LayoutRect(enclosingIntRect(damageRect)), |
| 1049 paintFlags, LayoutSize()); | 1079 paintFlags, LayoutSize()); |
| 1050 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 1080 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 1051 | 1081 |
| 1052 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 1082 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 1053 } | 1083 } |
| 1054 | 1084 |
| 1055 } // namespace blink | 1085 } // namespace blink |
| OLD | NEW |