本文整理汇总了C++中PaintLayer::layoutObject方法的典型用法代码示例。如果您正苦于以下问题:C++ PaintLayer::layoutObject方法的具体用法?C++ PaintLayer::layoutObject怎么用?C++ PaintLayer::layoutObject使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PaintLayer
的用法示例。
在下文中一共展示了PaintLayer::layoutObject方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: boxReflectionForPaintLayer
BoxReflection boxReflectionForPaintLayer(const PaintLayer& layer,
const ComputedStyle& style) {
const StyleReflection* reflectStyle = style.boxReflect();
LayoutRect frameLayoutRect = toLayoutBox(layer.layoutObject())->frameRect();
FloatRect frameRect(frameLayoutRect);
BoxReflection::ReflectionDirection direction =
BoxReflection::VerticalReflection;
float offset = 0;
switch (reflectStyle->direction()) {
case ReflectionAbove:
direction = BoxReflection::VerticalReflection;
offset = -floatValueForLength(reflectStyle->offset(), frameRect.height());
break;
case ReflectionBelow:
direction = BoxReflection::VerticalReflection;
offset = 2 * frameRect.height() +
floatValueForLength(reflectStyle->offset(), frameRect.height());
break;
case ReflectionLeft:
direction = BoxReflection::HorizontalReflection;
offset = -floatValueForLength(reflectStyle->offset(), frameRect.width());
break;
case ReflectionRight:
direction = BoxReflection::HorizontalReflection;
offset = 2 * frameRect.width() +
floatValueForLength(reflectStyle->offset(), frameRect.width());
break;
}
sk_sp<SkPicture> mask;
const NinePieceImage& maskNinePiece = reflectStyle->mask();
if (maskNinePiece.hasImage()) {
LayoutRect maskRect(LayoutPoint(), frameLayoutRect.size());
LayoutRect maskBoundingRect(maskRect);
maskBoundingRect.expand(style.imageOutsets(maskNinePiece));
FloatRect maskBoundingFloatRect(maskBoundingRect);
// TODO(jbroman): SkPictureBuilder + DrawingRecorder seems excessive.
// If NinePieceImagePainter operated on SkCanvas, we'd only need an
// SkPictureRecorder here.
SkPictureBuilder recorder(maskBoundingFloatRect);
{
GraphicsContext& context = recorder.context();
DrawingRecorder drawingRecorder(context, *layer.layoutObject(),
DisplayItem::kReflectionMask,
maskBoundingFloatRect);
NinePieceImagePainter(*layer.layoutObject())
.paint(recorder.context(), maskRect, style, maskNinePiece,
SkXfermode::kSrcOver_Mode);
}
mask = recorder.endRecording();
}
return BoxReflection(direction, offset, std::move(mask));
}
示例2: filterOperations
FilterPainter::FilterPainter(PaintLayer& layer, GraphicsContext* context, const LayoutPoint& offsetFromRoot, const ClipRect& clipRect, PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags,
LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
: m_filterInProgress(false)
, m_context(context)
, m_layoutObject(layer.layoutObject())
{
if (!layer.filterEffectBuilder() || !layer.paintsWithFilters())
return;
ASSERT(layer.filterInfo());
SkiaImageFilterBuilder builder;
RefPtrWillBeRawPtr<FilterEffect> lastEffect = layer.filterEffectBuilder()->lastEffect();
lastEffect->determineFilterPrimitiveSubregion(MapRectForward);
RefPtr<SkImageFilter> imageFilter = builder.build(lastEffect.get(), ColorSpaceDeviceRGB);
if (!imageFilter)
return;
if (!rootRelativeBoundsComputed) {
rootRelativeBounds = layer.physicalBoundingBoxIncludingReflectionAndStackingChildren(offsetFromRoot);
rootRelativeBoundsComputed = true;
}
// We'll handle clipping to the dirty rect before filter rasterization.
// Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets.
// FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
// Subsequent code should not clip to the dirty rect, since we've already
// done it above, and doing it later will defeat the outsets.
paintingInfo.clipToDirtyRect = false;
if (clipRect.rect() != paintingInfo.paintDirtyRect || clipRect.hasRadius()) {
m_clipRecorder = adoptPtr(new LayerClipRecorder(*context, *layer.layoutObject(), DisplayItem::ClipLayerFilter, clipRect, &paintingInfo, LayoutPoint(), paintFlags));
}
ASSERT(m_layoutObject);
ASSERT(context->displayItemList());
if (!context->displayItemList()->displayItemConstructionIsDisabled()) {
FilterOperations filterOperations(layer.computeFilterOperations(m_layoutObject->styleRef()));
OwnPtr<WebFilterOperations> webFilterOperations = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations());
builder.buildFilterOperations(filterOperations, webFilterOperations.get());
// FIXME: It's possible to have empty WebFilterOperations here even
// though the SkImageFilter produced above is non-null, since the
// layer's FilterEffectBuilder can have a stale representation of
// the layer's filter. See crbug.com/502026.
if (webFilterOperations->isEmpty())
return;
context->displayItemList()->createAndAppend<BeginFilterDisplayItem>(*m_layoutObject, imageFilter, FloatRect(rootRelativeBounds), webFilterOperations.release());
}
m_filterInProgress = true;
}
示例3: ClipPathHelper
ClipPathHelper(GraphicsContext* context, const PaintLayer& paintLayer, PaintLayerPaintingInfo& paintingInfo, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed,
const LayoutPoint& offsetFromRoot, PaintLayerFlags paintFlags)
: m_resourceClipper(0), m_paintLayer(paintLayer), m_context(context)
{
const ComputedStyle& style = paintLayer.layoutObject()->styleRef();
// Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container.
// It must, however, still be applied to the mask layer, so that the compositor can properly mask the
// scrolling contents and scrollbars.
if (!paintLayer.layoutObject()->hasClipPath() || (paintLayer.needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase)))
return;
m_clipperState = SVGClipPainter::ClipperNotApplied;
paintingInfo.ancestorHasClipPathClipping = true;
ASSERT(style.clipPath());
if (style.clipPath()->type() == ClipPathOperation::SHAPE) {
ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style.clipPath());
if (clipPath->isValid()) {
if (!rootRelativeBoundsComputed) {
rootRelativeBounds = paintLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(offsetFromRoot);
rootRelativeBoundsComputed = true;
}
m_clipPathRecorder.emplace(*context, *paintLayer.layoutObject(), clipPath->path(FloatRect(rootRelativeBounds)));
}
} else if (style.clipPath()->type() == ClipPathOperation::REFERENCE) {
ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style.clipPath());
Document& document = paintLayer.layoutObject()->document();
// FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
Element* element = document.getElementById(referenceClipPathOperation->fragment());
if (isSVGClipPathElement(element) && element->layoutObject()) {
if (!rootRelativeBoundsComputed) {
rootRelativeBounds = paintLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(offsetFromRoot);
rootRelativeBoundsComputed = true;
}
m_resourceClipper = toLayoutSVGResourceClipper(toLayoutSVGResourceContainer(element->layoutObject()));
if (!SVGClipPainter(*m_resourceClipper).prepareEffect(*paintLayer.layoutObject(), FloatRect(rootRelativeBounds),
FloatRect(rootRelativeBounds), context, m_clipperState)) {
// No need to post-apply the clipper if this failed.
m_resourceClipper = 0;
}
}
}
}
示例4: rebuild
void GraphicsLayerTreeBuilder::rebuild(PaintLayer& layer, AncestorInfo info)
{
// Make the layer compositing if necessary, and set up clipping and content layers.
// Note that we can only do work here that is independent of whether the descendant layers
// have been processed. computeCompositingRequirements() will already have done the paint invalidation if necessary.
layer.stackingNode()->updateLayerListsIfNeeded();
const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
CompositedLayerMapping* currentCompositedLayerMapping = layer.compositedLayerMapping();
// If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
// Otherwise children continue to append to the child list of the enclosing layer.
GraphicsLayerVector layerChildren;
AncestorInfo infoForChildren(info);
if (hasCompositedLayerMapping) {
infoForChildren.childLayersOfEnclosingCompositedLayer = &layerChildren;
infoForChildren.enclosingCompositedLayer = &layer;
}
#if ENABLE(ASSERT)
LayerListMutationDetector mutationChecker(layer.stackingNode());
#endif
if (layer.stackingNode()->isStackingContext()) {
PaintLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
while (PaintLayerStackingNode* curNode = iterator.next())
rebuild(*curNode->layer(), infoForChildren);
// If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
infoForChildren.childLayersOfEnclosingCompositedLayer->append(currentCompositedLayerMapping->foregroundLayer());
}
PaintLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
while (PaintLayerStackingNode* curNode = iterator.next())
rebuild(*curNode->layer(), infoForChildren);
if (hasCompositedLayerMapping) {
bool parented = false;
if (layer.layoutObject()->isLayoutPart())
parented = PaintLayerCompositor::attachFrameContentLayersToIframeLayer(toLayoutPart(layer.layoutObject()));
if (!parented)
currentCompositedLayerMapping->setSublayers(layerChildren);
if (shouldAppendLayer(layer))
info.childLayersOfEnclosingCompositedLayer->append(currentCompositedLayerMapping->childForSuperlayers());
}
if (layer.scrollParent()
&& layer.scrollParent()->hasCompositedLayerMapping()
&& layer.scrollParent()->compositedLayerMapping()->needsToReparentOverflowControls()
&& layer.scrollParent()->getScrollableArea()->topmostScrollChild() == &layer)
info.childLayersOfEnclosingCompositedLayer->append(layer.scrollParent()->compositedLayerMapping()->detachLayerForOverflowControls(*info.enclosingCompositedLayer));
}
示例5: shouldAppendLayer
static bool shouldAppendLayer(const PaintLayer& layer)
{
Node* node = layer.layoutObject()->node();
if (node && isHTMLVideoElement(*node)) {
HTMLVideoElement* element = toHTMLVideoElement(node);
if (element->isFullscreen() && element->usesOverlayFullscreenVideo())
return false;
}
return true;
}
示例6: collectRoundedRectClips
void LayerClipRecorder::collectRoundedRectClips(PaintLayer& paintLayer, const PaintLayerPaintingInfo& localPaintingInfo, GraphicsContext& context, const LayoutPoint& fragmentOffset, PaintLayerFlags paintFlags,
BorderRadiusClippingRule rule, Vector<FloatRoundedRect>& roundedRectClips)
{
// If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
// any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
// containing block chain so we check that also.
for (PaintLayer* layer = rule == IncludeSelfForBorderRadius ? &paintLayer : paintLayer.parent(); layer; layer = layer->parent()) {
// Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not
// want to apply a border-radius clip to the layer contents itself, because that would require re-rastering
// every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
// that it can in turn clip the scrolled contents in the compositor.
if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
break;
if (layer->layoutObject()->hasOverflowClip() && layer->layoutObject()->style()->hasBorderRadius() && inContainingBlockChain(&paintLayer, layer)) {
LayoutPoint delta(fragmentOffset);
layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
roundedRectClips.append(layer->layoutObject()->style()->getRoundedInnerBorderFor(LayoutRect(delta, LayoutSize(layer->size()))));
}
if (layer == localPaintingInfo.rootLayer)
break;
}
}
示例7: paintSelection
void BlockFlowPainter::paintSelection(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT(paintInfo.phase == PaintPhaseForeground);
if (!m_layoutBlockFlow.shouldPaintSelectionGaps())
return;
LayoutUnit lastTop = 0;
LayoutUnit lastLeft = m_layoutBlockFlow.logicalLeftSelectionOffset(&m_layoutBlockFlow, lastTop);
LayoutUnit lastRight = m_layoutBlockFlow.logicalRightSelectionOffset(&m_layoutBlockFlow, lastTop);
LayoutRect bounds = m_layoutBlockFlow.visualOverflowRect();
bounds.moveBy(paintOffset);
// Only create a DrawingRecorder and ClipScope if skipRecording is false. This logic is needed
// because selectionGaps(...) needs to be called even when we do not record.
bool skipRecording = LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutBlockFlow, DisplayItem::SelectionGap, paintOffset);
Optional<LayoutObjectDrawingRecorder> drawingRecorder;
Optional<ClipScope> clipScope;
if (!skipRecording) {
drawingRecorder.emplace(paintInfo.context, m_layoutBlockFlow, DisplayItem::SelectionGap, FloatRect(bounds), paintOffset);
clipScope.emplace(paintInfo.context);
}
LayoutRect gapRectsBounds = m_layoutBlockFlow.selectionGaps(&m_layoutBlockFlow, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight,
skipRecording ? nullptr : &paintInfo,
skipRecording ? nullptr : &(*clipScope));
// TODO(wkorman): Rework below to process paint invalidation rects during layout rather than paint.
if (!gapRectsBounds.isEmpty()) {
PaintLayer* layer = m_layoutBlockFlow.enclosingLayer();
gapRectsBounds.moveBy(-paintOffset);
if (!m_layoutBlockFlow.hasLayer()) {
LayoutRect localBounds(gapRectsBounds);
m_layoutBlockFlow.flipForWritingMode(localBounds);
gapRectsBounds = LayoutRect(m_layoutBlockFlow.localToAncestorQuad(FloatRect(localBounds), layer->layoutObject()).enclosingBoundingBox());
if (layer->layoutObject()->hasOverflowClip())
gapRectsBounds.move(layer->layoutBox()->scrolledContentOffset());
}
layer->addBlockSelectionGapsBounds(gapRectsBounds);
}
}
示例8: paintChildren
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;
}
示例9: paintContents
void FramePainter::paintContents(GraphicsContext& context, const GlobalPaintFlags globalPaintFlags, const IntRect& rect)
{
Document* document = frameView().frame().document();
#ifndef NDEBUG
bool fillWithRed;
if (document->printing())
fillWithRed = false; // Printing, don't fill with red (can't remember why).
else if (frameView().frame().owner())
fillWithRed = false; // Subframe, don't fill with red.
else if (frameView().isTransparent())
fillWithRed = false; // Transparent, don't fill with red.
else if (globalPaintFlags & GlobalPaintSelectionOnly)
fillWithRed = false; // Selections are transparent, don't fill with red.
else
fillWithRed = true;
if (fillWithRed && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, *frameView().layoutView(), DisplayItem::DebugRedFill, LayoutPoint())) {
IntRect contentRect(IntPoint(), frameView().contentsSize());
LayoutObjectDrawingRecorder drawingRecorder(context, *frameView().layoutView(), DisplayItem::DebugRedFill, contentRect, LayoutPoint());
}
#endif
LayoutView* layoutView = frameView().layoutView();
if (!layoutView) {
WTF_LOG_ERROR("called FramePainter::paint with nil layoutObject");
return;
}
if (!frameView().shouldThrottleRendering()) {
RELEASE_ASSERT(!frameView().needsLayout());
ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean);
}
TRACE_EVENT1("devtools.timeline", "Paint", "data", InspectorPaintEvent::data(layoutView, LayoutRect(rect), 0));
bool isTopLevelPainter = !s_inPaintContents;
s_inPaintContents = true;
FontCachePurgePreventer fontCachePurgePreventer;
// TODO(jchaffraix): GlobalPaintFlags should be const during a paint
// phase. Thus we should set this flag upfront (crbug.com/510280).
GlobalPaintFlags localPaintFlags = globalPaintFlags;
if (document->printing())
localPaintFlags |= GlobalPaintFlattenCompositingLayers | GlobalPaintPrinting;
PaintLayer* rootLayer = layoutView->layer();
#if ENABLE(ASSERT)
if (!frameView().shouldThrottleRendering())
layoutView->assertSubtreeIsLaidOut();
LayoutObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*rootLayer->layoutObject());
#endif
PaintLayerPainter layerPainter(*rootLayer);
float deviceScaleFactor = blink::deviceScaleFactor(rootLayer->layoutObject()->frame());
context.setDeviceScaleFactor(deviceScaleFactor);
layerPainter.paint(context, LayoutRect(rect), localPaintFlags);
if (rootLayer->containsDirtyOverlayScrollbars())
layerPainter.paintOverlayScrollbars(context, LayoutRect(rect), localPaintFlags);
// Regions may have changed as a result of the visibility/z-index of element changing.
if (document->annotatedRegionsDirty())
frameView().updateDocumentAnnotatedRegions();
if (isTopLevelPainter) {
// Everything that happens after paintContents completions is considered
// to be part of the next frame.
memoryCache()->updateFramePaintTimestamp();
s_inPaintContents = false;
}
InspectorInstrumentation::didPaint(layoutView, 0, context, LayoutRect(rect));
}
示例10: updateRecursive
void CompositingRequirementsUpdater::updateRecursive(PaintLayer* ancestorLayer, PaintLayer* layer, OverlapMap& overlapMap, RecursionData& currentRecursionData,
bool& descendantHas3DTransform, Vector<PaintLayer*>& unclippedDescendants, IntRect& absoluteDescendantBoundingBox)
{
PaintLayerCompositor* compositor = m_layoutView.compositor();
layer->stackingNode()->updateLayerListsIfNeeded();
CompositingReasons reasonsToComposite = CompositingReasonNone;
CompositingReasons directReasons = m_compositingReasonFinder.directReasons(layer);
// Video is special. It's the only PaintLayer type that can both have
// PaintLayer children and whose children can't use its backing to render
// into. These children (the controls) always need to be promoted into their
// own layers to draw on top of the accelerated video.
if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->layoutObject()->isVideo())
directReasons |= CompositingReasonVideoOverlay;
if (currentRecursionData.m_hasCompositedScrollingAncestor && layer->layoutObject()->styleRef().hasViewportConstrainedPosition())
directReasons |= CompositingReasonPositionFixed;
bool canBeComposited = compositor->canBeComposited(layer);
if (canBeComposited) {
reasonsToComposite |= directReasons;
if (layer->isRootLayer() && compositor->rootShouldAlwaysComposite())
reasonsToComposite |= CompositingReasonRoot;
if (reasonsToComposite && layer->scrollsOverflow() && !layer->needsCompositedScrolling()) {
// We will only set needsCompositedScrolling if we don't care about
// the LCD text hit, we may be able to switch to the compositor
// driven path if we're alread composited for other reasons and are
// therefore using grayscale AA.
//
// FIXME: it should also be possible to promote if the layer can
// still use LCD text when promoted, but detecting when the
// compositor can do this is tricky. Currently, the layer must be
// both opaque and may only have an integer translation as its
// transform. Both opacity and screen space transform are inherited
// properties, so this cannot be determined from local information.
layer->scrollableArea()->updateNeedsCompositedScrolling(PaintLayerScrollableArea::IgnoreLCDText);
if (layer->needsCompositedScrolling())
reasonsToComposite |= CompositingReasonOverflowScrollingTouch;
}
}
if ((reasonsToComposite & CompositingReasonOverflowScrollingTouch) && !layer->isRootLayer())
currentRecursionData.m_hasCompositedScrollingAncestor = true;
// Next, accumulate reasons related to overlap.
// If overlap testing is used, this reason will be overridden. If overlap testing is not
// used, we must assume we overlap if there is anything composited behind us in paint-order.
CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;
if (currentRecursionData.m_hasCompositedScrollingAncestor) {
Vector<size_t> unclippedDescendantsToRemove;
for (size_t i = 0; i < unclippedDescendants.size(); i++) {
PaintLayer* unclippedDescendant = unclippedDescendants.at(i);
// If we've reached the containing block of one of the unclipped
// descendants, that element is no longer relevant to whether or not we
// should opt in. Unfortunately we can't easily remove from the list
// while we're iterating, so we have to store it for later removal.
if (unclippedDescendant->layoutObject()->containingBlock() == layer->layoutObject()) {
unclippedDescendantsToRemove.append(i);
continue;
}
if (layer->scrollsWithRespectTo(unclippedDescendant))
reasonsToComposite |= CompositingReasonAssumedOverlap;
}
// Remove irrelevant unclipped descendants in reverse order so our stored
// indices remain valid.
for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++)
unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1));
if (reasonsToComposite & CompositingReasonOutOfFlowClipping)
unclippedDescendants.append(layer);
}
const IntRect& absBounds = layer->clippedAbsoluteBoundingBox();
absoluteDescendantBoundingBox = absBounds;
if (currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons))
overlapCompositingReason = overlapMap.overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
reasonsToComposite |= overlapCompositingReason;
// The children of this layer don't need to composite, unless there is
// a compositing layer among them, so start by inheriting the compositing
// ancestor with m_subtreeIsCompositing set to false.
RecursionData childRecursionData = currentRecursionData;
childRecursionData.m_subtreeIsCompositing = false;
bool willBeCompositedOrSquashed = canBeComposited && requiresCompositingOrSquashing(reasonsToComposite);
if (willBeCompositedOrSquashed) {
// This layer now acts as the ancestor for kids.
childRecursionData.m_compositingAncestor = layer;
// Here we know that all children and the layer's own contents can blindly paint into
// this layer's backing, until a descendant is composited. So, we don't need to check
// for overlap with anything behind this layer.
//.........这里部分代码省略.........
示例11: paintChildren
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;
}
示例12: paintLayerWithTransform
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;
}