static bool shouldCreateSubsequence(const PaintLayer& paintLayer, GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) { // Caching is not needed during printing. if (context.printing()) return false; // Don't create subsequence for a composited layer because if it can be cached, // we can skip the whole painting in GraphicsLayer::paint() with CachedDisplayItemList. // This also avoids conflict of PaintLayer::previousXXX() when paintLayer is composited // scrolling and is painted twice for GraphicsLayers of container and scrolling contents. if (paintLayer.compositingState() == PaintsIntoOwnBacking) return false; // Don't create subsequence during special painting to avoid cache conflict with normal painting. if (paintingInfo.globalPaintFlags() & GlobalPaintFlattenCompositingLayers) return false; if (paintFlags & (PaintLayerPaintingReflection | PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingOverlayScrollbars | PaintLayerUncachedClipRects)) return false; // Create subsequence for only stacking contexts whose painting are atomic. if (!paintLayer.stackingNode()->isStackingContext()) return false; // The layer doesn't have children. Subsequence caching is not worth because normally the actual painting will be cheap. if (!PaintLayerStackingNodeIterator(*paintLayer.stackingNode(), AllChildren).next()) return false; return true; }
PaintLayerPainter::PaintResult PaintLayerPainter::paintLayer(GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) { // https://code.google.com/p/chromium/issues/detail?id=343772 DisableCompositingQueryAsserts disabler; if (m_paintLayer.compositingState() != NotComposited) { if (paintingInfo.globalPaintFlags() & GlobalPaintFlattenCompositingLayers) { // FIXME: ok, but what about GlobalPaintFlattenCompositingLayers? That's for printing and drag-image. // FIXME: why isn't the code here global, as opposed to being set on each paintLayer() call? paintFlags |= PaintLayerUncachedClipRects; } } // Non self-painting layers without self-painting descendants don't need to be painted as their // layoutObject() should properly paint itself. if (!m_paintLayer.isSelfPaintingLayer() && !m_paintLayer.hasSelfPaintingLayerDescendant()) return FullyPainted; if (shouldSuppressPaintingLayer(&m_paintLayer)) return FullyPainted; if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer.layoutObject())->frameView()->shouldThrottleRendering()) return FullyPainted; // If this layer is totally invisible then there is nothing to paint. if (!m_paintLayer.layoutObject()->opacity() && !m_paintLayer.layoutObject()->hasBackdropFilter()) return FullyPainted; if (m_paintLayer.paintsWithTransparency(paintingInfo.globalPaintFlags())) paintFlags |= PaintLayerHaveTransparency; LayerFixedPositionRecorder fixedPositionRecorder(context, *m_paintLayer.layoutObject()); // PaintLayerAppliedTransform is used in LayoutReplica, to avoid applying the transform twice. if (m_paintLayer.paintsWithTransform(paintingInfo.globalPaintFlags()) && !(paintFlags & PaintLayerAppliedTransform)) return paintLayerWithTransform(context, paintingInfo, paintFlags); return paintLayerContentsAndReflection(context, paintingInfo, paintFlags); }
void PaintLayerPainter::paintFragmentWithPhase(PaintPhase phase, const PaintLayerFragment& fragment, GraphicsContext& context, const ClipRect& clipRect, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, ClipState clipState) { ASSERT(m_paintLayer.isSelfPaintingLayer()); Optional<LayerClipRecorder> clipRecorder; if (clipState != HasClipped && paintingInfo.clipToDirtyRect && needsToClip(paintingInfo, clipRect)) { DisplayItem::Type clipType = DisplayItem::paintPhaseToClipLayerFragmentType(phase); LayerClipRecorder::BorderRadiusClippingRule clippingRule; switch (phase) { case PaintPhaseSelfBlockBackgroundOnly: // Background painting will handle clipping to self. case PaintPhaseSelfOutlineOnly: case PaintPhaseMask: // Mask painting will handle clipping to self. clippingRule = LayerClipRecorder::DoNotIncludeSelfForBorderRadius; break; default: clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; break; } clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, clipRect, &paintingInfo, fragment.paginationOffset, paintFlags, clippingRule); } LayoutRect newCullRect(clipRect.rect()); Optional<ScrollRecorder> scrollRecorder; LayoutPoint paintOffset = toPoint(fragment.layerBounds.location() - m_paintLayer.layoutBoxLocation()); if (!paintingInfo.scrollOffsetAccumulation.isZero()) { // As a descendant of the root layer, m_paintLayer's painting is not controlled by the ScrollRecorders // created by BlockPainter of the ancestor layers up to the root layer, so we need to issue ScrollRecorder // for this layer seperately, with the scroll offset accumulated from the root layer to the parent of this // layer, to get the same result as ScrollRecorder in BlockPainter. paintOffset += paintingInfo.scrollOffsetAccumulation; newCullRect.move(paintingInfo.scrollOffsetAccumulation); scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, paintingInfo.scrollOffsetAccumulation); } PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, paintingInfo.globalPaintFlags(), paintFlags, paintingInfo.rootLayer->layoutObject()); m_paintLayer.layoutObject()->paint(paintInfo, paintOffset); }
PaintLayerPainter::PaintResult PaintLayerPainter::paintChildren(unsigned childrenToVisit, GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) { PaintResult result = FullyPainted; if (!m_paintLayer.hasSelfPaintingLayerDescendant()) return result; #if ENABLE(ASSERT) LayerListMutationDetector mutationChecker(m_paintLayer.stackingNode()); #endif PaintLayerStackingNodeIterator iterator(*m_paintLayer.stackingNode(), childrenToVisit); PaintLayerStackingNode* child = iterator.next(); if (!child) return result; IntSize scrollOffsetAccumulationForChildren = paintingInfo.scrollOffsetAccumulation; if (m_paintLayer.layoutObject()->hasOverflowClip()) scrollOffsetAccumulationForChildren += m_paintLayer.layoutBox()->scrolledContentOffset(); for (; child; child = iterator.next()) { PaintLayerPainter childPainter(*child->layer()); // If this Layer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents() // and CompositedLayerMapping::doPaintTask(). if (!childPainter.shouldPaintLayerInSoftwareMode(paintingInfo.globalPaintFlags(), paintFlags)) continue; PaintLayerPaintingInfo childPaintingInfo = paintingInfo; childPaintingInfo.scrollOffsetAccumulation = scrollOffsetAccumulationForChildren; // Rare case: accumulate scroll offset of non-stacking-context ancestors up to m_paintLayer. for (PaintLayer* parentLayer = child->layer()->parent(); parentLayer != &m_paintLayer; parentLayer = parentLayer->parent()) { if (parentLayer->layoutObject()->hasOverflowClip()) childPaintingInfo.scrollOffsetAccumulation += parentLayer->layoutBox()->scrolledContentOffset(); } if (childPainter.paintLayer(context, childPaintingInfo, paintFlags) == MayBeClippedByPaintDirtyRect) result = MayBeClippedByPaintDirtyRect; } return result; }
PaintLayerPainter::PaintResult PaintLayerPainter::paintFragmentByApplyingTransform(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& fragmentTranslation) { // This involves subtracting out the position of the layer in our current coordinate space, but preserving // the accumulated error for sub-pixel layout. LayoutPoint delta; m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, delta); delta.moveBy(fragmentTranslation); TransformationMatrix transform(m_paintLayer.renderableTransform(paintingInfo.globalPaintFlags())); IntPoint roundedDelta = roundedIntPoint(delta); transform.translateRight(roundedDelta.x(), roundedDelta.y()); LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta); // TODO(jbroman): Put the real transform origin here, instead of using a // matrix with the origin baked in. FloatPoint3D transformOrigin; Transform3DRecorder transform3DRecorder(*context, *m_paintLayer.layoutObject(), DisplayItem::Transform3DElementTransform, transform, transformOrigin); // Now do a paint with the root layer shifted to be us. PaintLayerPaintingInfo transformedPaintingInfo(&m_paintLayer, LayoutRect(enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect))), paintingInfo.globalPaintFlags(), adjustedSubPixelAccumulation, paintingInfo.paintingRoot); transformedPaintingInfo.ancestorHasClipPathClipping = paintingInfo.ancestorHasClipPathClipping; return paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags, ForceSingleFragment); }
PaintLayerPainter::PaintResult PaintLayerPainter::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) { PaintResult result = FullyPainted; if (!m_paintLayer.hasSelfPaintingLayerDescendant()) return result; #if ENABLE(ASSERT) LayerListMutationDetector mutationChecker(m_paintLayer.stackingNode()); #endif PaintLayerStackingNodeIterator iterator(*m_paintLayer.stackingNode(), childrenToVisit); PaintLayerStackingNode* child = iterator.next(); if (!child) return result; DisplayItem::Type subsequenceType; if (childrenToVisit == NegativeZOrderChildren) { subsequenceType = DisplayItem::SubsequenceNegativeZOrder; } else { ASSERT(childrenToVisit == (NormalFlowChildren | PositiveZOrderChildren)); subsequenceType = DisplayItem::SubsequenceNormalFlowAndPositiveZOrder; } Optional<SubsequenceRecorder> subsequenceRecorder; if (!paintingInfo.disableSubsequenceCache && !(paintingInfo.globalPaintFlags() & GlobalPaintFlattenCompositingLayers) && !(paintFlags & PaintLayerPaintingReflection) && !(paintFlags & PaintLayerPaintingRootBackgroundOnly)) { if (!m_paintLayer.needsRepaint() && paintingInfo.scrollOffsetAccumulation == m_paintLayer.previousScrollOffsetAccumulationForPainting() && SubsequenceRecorder::useCachedSubsequenceIfPossible(*context, m_paintLayer, subsequenceType)) return result; subsequenceRecorder.emplace(*context, m_paintLayer, subsequenceType); } IntSize scrollOffsetAccumulationForChildren = paintingInfo.scrollOffsetAccumulation; if (m_paintLayer.layoutObject()->hasOverflowClip()) scrollOffsetAccumulationForChildren += m_paintLayer.layoutBox()->scrolledContentOffset(); bool disableChildSubsequenceCache = !RuntimeEnabledFeatures::slimmingPaintV2Enabled() && (m_paintLayer.layoutObject()->hasOverflowClip() || m_paintLayer.layoutObject()->hasClip()); for (; child; child = iterator.next()) { PaintLayerPainter childPainter(*child->layer()); // If this Layer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents() // and CompositedLayerMapping::doPaintTask(). if (!childPainter.shouldPaintLayerInSoftwareMode(paintingInfo.globalPaintFlags(), paintFlags)) continue; PaintLayerPaintingInfo childPaintingInfo = paintingInfo; childPaintingInfo.disableSubsequenceCache = disableChildSubsequenceCache; childPaintingInfo.scrollOffsetAccumulation = scrollOffsetAccumulationForChildren; // Rare case: accumulate scroll offset of non-stacking-context ancestors up to m_paintLayer. for (PaintLayer* parentLayer = child->layer()->parent(); parentLayer != &m_paintLayer; parentLayer = parentLayer->parent()) { if (parentLayer->layoutObject()->hasOverflowClip()) childPaintingInfo.scrollOffsetAccumulation += parentLayer->layoutBox()->scrolledContentOffset(); } if (childPainter.paintLayer(context, childPaintingInfo, paintFlags) == MaybeNotFullyPainted) result = MaybeNotFullyPainted; } // Set subsequence not cacheable if the bounding box of this layer and descendants is not fully contained // by paintRect, because later paintRect changes may expose new contents which will need repainting. if (result == MaybeNotFullyPainted && subsequenceRecorder) subsequenceRecorder->setUncacheable(); return result; }
PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerWithTransform(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) { TransformationMatrix layerTransform = m_paintLayer.renderableTransform(paintingInfo.globalPaintFlags()); // If the transform can't be inverted, then don't paint anything. if (!layerTransform.isInvertible()) return FullyPainted; // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer here. // m_paintLayer may be the "root", and then we should avoid looking at its parent. PaintLayer* parentLayer = m_paintLayer.parent(); ClipRect ancestorBackgroundClipRect; if (parentLayer) { // Calculate the clip rectangle that the ancestors establish. ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize); if (shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()) == IgnoreOverflowClip) clipRectsContext.setIgnoreOverflowClip(); ancestorBackgroundClipRect = m_paintLayer.clipper().backgroundClipRect(clipRectsContext); } PaintLayer* paginationLayer = m_paintLayer.enclosingPaginationLayer(); PaintLayerFragments fragments; if (paginationLayer) { // FIXME: This is a mess. Look closely at this code and the code in Layer and fix any // issues in it & refactor to make it obvious from code structure what it does and that it's // correct. ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects; ShouldRespectOverflowClip respectOverflowClip = shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()); // Calculate the transformed bounding box in the current coordinate space, to figure out // which fragmentainers (e.g. columns) we need to visit. LayoutRect transformedExtent = PaintLayer::transparencyClipBox(&m_paintLayer, paginationLayer, PaintLayer::PaintingTransparencyClipBox, PaintLayer::RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.globalPaintFlags()); // FIXME: we don't check if paginationLayer is within paintingInfo.rootLayer here. paginationLayer->collectFragments(fragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, 0, paintingInfo.subPixelAccumulation, &transformedExtent); } else { // We don't need to collect any fragments in the regular way here. We have already // calculated a clip rectangle for the ancestry if it was needed, and clipping this // layer is something that can be done further down the path, when the transform has // been applied. PaintLayerFragment fragment; fragment.backgroundRect = paintingInfo.paintDirtyRect; fragments.append(fragment); } bool needsScope = fragments.size() > 1; PaintResult result = FullyPainted; for (const auto& fragment : fragments) { Optional<ScopeRecorder> scopeRecorder; if (needsScope) scopeRecorder.emplace(*context); Optional<LayerClipRecorder> clipRecorder; if (parentLayer) { ClipRect clipRectForFragment(ancestorBackgroundClipRect); clipRectForFragment.moveBy(fragment.paginationOffset); clipRectForFragment.intersect(fragment.backgroundRect); if (clipRectForFragment.isEmpty()) continue; if (needsToClip(paintingInfo, clipRectForFragment)) { if (m_paintLayer.layoutObject()->style()->position() != StaticPosition && clipRectForFragment.isClippedByClipCss()) UseCounter::count(m_paintLayer.layoutObject()->document(), UseCounter::ClipCssOfPositionedElement); clipRecorder.emplace(*context, *parentLayer->layoutObject(), DisplayItem::ClipLayerParent, clipRectForFragment, &paintingInfo, fragment.paginationOffset, paintFlags); } } if (paintFragmentByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset) == MaybeNotFullyPainted) result = MaybeNotFullyPainted; } return result; }
PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContentsInternal(GraphicsContext* context, const PaintLayerPaintingInfo& paintingInfoArg, PaintLayerFlags paintFlags, FragmentPolicy fragmentPolicy) { ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLayerDescendant()); ASSERT(!(paintFlags & PaintLayerAppliedTransform)); bool isSelfPaintingLayer = m_paintLayer.isSelfPaintingLayer(); bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars; bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase; bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase; bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase; bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents; // Outline always needs to be painted even if we have no visible content. Also, // the outline is painted in the background phase during composited scrolling. // If it were painted in the foreground phase, it would move with the scrolled // content. When not composited scrolling, the outline is painted in the // foreground phase. Since scrolled contents are moved by paint invalidation in this // case, the outline won't get 'dragged along'. bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars && ((isPaintingScrollingContent && isPaintingCompositedBackground) || (!isPaintingScrollingContent && isPaintingCompositedForeground)); bool shouldPaintContent = m_paintLayer.hasVisibleContent() && isSelfPaintingLayer && !isPaintingOverlayScrollbars; PaintResult result = FullyPainted; if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !m_paintLayer.layoutObject()->isLayoutView() && !m_paintLayer.layoutObject()->isDocumentElement()) return result; PaintLayerPaintingInfo paintingInfo = paintingInfoArg; // Ensure our lists are up-to-date. m_paintLayer.stackingNode()->updateLayerListsIfNeeded(); LayoutPoint offsetFromRoot; m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); if (m_paintLayer.compositingState() == PaintsIntoOwnBacking) offsetFromRoot.move(m_paintLayer.subpixelAccumulation()); else offsetFromRoot.move(paintingInfo.subPixelAccumulation); LayoutRect bounds = m_paintLayer.physicalBoundingBox(offsetFromRoot); if (!paintingInfo.paintDirtyRect.contains(bounds)) result = MaybeNotFullyPainted; LayoutRect rootRelativeBounds; bool rootRelativeBoundsComputed = false; if (paintingInfo.ancestorHasClipPathClipping && m_paintLayer.layoutObject()->style()->position() != StaticPosition) UseCounter::count(m_paintLayer.layoutObject()->document(), UseCounter::ClipPathOfPositionedElement); // These helpers output clip and compositing operations using a RAII pattern. Stack-allocated-varibles are destructed in the reverse order of construction, // so they are nested properly. ClipPathHelper clipPathHelper(context, m_paintLayer, paintingInfo, rootRelativeBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); Optional<CompositingRecorder> compositingRecorder; // Blending operations must be performed only with the nearest ancestor stacking context. // Note that there is no need to composite if we're painting the root. // FIXME: this should be unified further into PaintLayer::paintsWithTransparency(). bool shouldCompositeForBlendMode = (!m_paintLayer.layoutObject()->isDocumentElement() || m_paintLayer.layoutObject()->isSVGRoot()) && m_paintLayer.stackingNode()->isStackingContext() && m_paintLayer.hasNonIsolatedDescendantWithBlendMode(); if (shouldCompositeForBlendMode || m_paintLayer.paintsWithTransparency(paintingInfo.globalPaintFlags())) { FloatRect compositingBounds = FloatRect(m_paintLayer.paintingExtent(paintingInfo.rootLayer, paintingInfo.subPixelAccumulation, paintingInfo.globalPaintFlags())); compositingRecorder.emplace(*context, *m_paintLayer.layoutObject(), WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_paintLayer.layoutObject()->style()->blendMode()), m_paintLayer.layoutObject()->opacity(), &compositingBounds); } PaintLayerPaintingInfo localPaintingInfo(paintingInfo); if (m_paintLayer.compositingState() == PaintsIntoOwnBacking) localPaintingInfo.subPixelAccumulation = m_paintLayer.subpixelAccumulation(); PaintLayerFragments layerFragments; if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment. ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects; ShouldRespectOverflowClip respectOverflowClip = shouldRespectOverflowClip(paintFlags, m_paintLayer.layoutObject()); if (fragmentPolicy == ForceSingleFragment) m_paintLayer.appendSingleFragmentIgnoringPagination(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation); else m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation); if (shouldPaintContent) { // TODO(wangxianzhu): This is for old slow scrolling. Implement similar optimization for slimming paint v2. shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFragments, localPaintingInfo, paintFlags, offsetFromRoot); if (!shouldPaintContent) result = MaybeNotFullyPainted; } } bool selectionOnly = localPaintingInfo.globalPaintFlags() & GlobalPaintSelectionOnly; // If this layer's layoutObject is a child of the paintingRoot, we paint unconditionally, which // is done by passing a nil paintingRoot down to our layoutObject (as if no paintingRoot was ever set). // Else, our layout tree may or may not contain the painting root, so we pass that root along // so it will be tested against as we descend through the layoutObjects. LayoutObject* paintingRootForLayoutObject = 0; if (localPaintingInfo.paintingRoot && !m_paintLayer.layoutObject()->isDescendantOf(localPaintingInfo.paintingRoot)) paintingRootForLayoutObject = localPaintingInfo.paintingRoot; { // Begin block for the lifetime of any filter. FilterPainter filterPainter(m_paintLayer, context, offsetFromRoot, layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect, localPaintingInfo, paintFlags, rootRelativeBounds, rootRelativeBoundsComputed); bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly; bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground); bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPaintContent; bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForeground; bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; if (shouldPaintBackground) { paintBackgroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect, localPaintingInfo, paintingRootForLayoutObject, paintFlags); } if (shouldPaintNegZOrderList) { if (paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags) == MaybeNotFullyPainted) result = MaybeNotFullyPainted; } if (shouldPaintOwnContents) { paintForegroundForFragments(layerFragments, context, paintingInfo.paintDirtyRect, localPaintingInfo, paintingRootForLayoutObject, selectionOnly, paintFlags); } if (shouldPaintOutline) paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintingRootForLayoutObject, paintFlags); if (shouldPaintNormalFlowAndPosZOrderLists) { if (paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags) == MaybeNotFullyPainted) result = MaybeNotFullyPainted; } if (shouldPaintOverlayScrollbars) paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags); } // FilterPainter block bool shouldPaintMask = (paintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && m_paintLayer.layoutObject()->hasMask() && !selectionOnly; bool shouldPaintClippingMask = (paintFlags & PaintLayerPaintingChildClippingMaskPhase) && shouldPaintContent && !selectionOnly; if (shouldPaintMask) paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForLayoutObject, paintFlags); if (shouldPaintClippingMask) { // Paint the border radius mask for the fragments. paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForLayoutObject, paintFlags); } m_paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfoArg.scrollOffsetAccumulation); return result; }