PaintInvalidationState::PaintInvalidationState(PaintInvalidationState& next, LayoutBoxModelObject& layoutObject, const LayoutBoxModelObject& paintInvalidationContainer) : m_clipped(false) , m_cachedOffsetsEnabled(true) , m_forcedSubtreeInvalidationWithinContainer(next.m_forcedSubtreeInvalidationWithinContainer) , m_forcedSubtreeInvalidationRectUpdateWithinContainer(next.m_forcedSubtreeInvalidationRectUpdateWithinContainer) , m_viewClippingAndScrollOffsetDisabled(false) , m_paintInvalidationContainer(paintInvalidationContainer) , m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets()) , m_enclosingSelfPaintingLayer(next.enclosingSelfPaintingLayer(layoutObject)) { // FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054 bool establishesPaintInvalidationContainer = layoutObject == m_paintInvalidationContainer; bool fixed = layoutObject.style()->position() == FixedPosition; if (!layoutObject.supportsPaintInvalidationStateCachedOffsets() || !next.m_cachedOffsetsEnabled) m_cachedOffsetsEnabled = false; if (establishesPaintInvalidationContainer) { // When we hit a new paint invalidation container, we don't need to // continue forcing a check for paint invalidation, since we're // descending into a different invalidation container. (For instance if // our parents were moved, the entire container will just move.) m_forcedSubtreeInvalidationWithinContainer = false; } else { if (m_cachedOffsetsEnabled) { if (fixed) { FloatPoint fixedOffset = layoutObject.localToAncestorPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries); m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()); } else { LayoutSize offset = layoutObject.isBox() && !layoutObject.isTableRow() ? toLayoutBox(layoutObject).locationOffset() : LayoutSize(); m_paintOffset = next.m_paintOffset + offset; } if (layoutObject.isOutOfFlowPositioned() && !fixed) { if (LayoutObject* container = layoutObject.container()) { if (container->style()->hasInFlowPosition() && container->isLayoutInline()) m_paintOffset += toLayoutInline(container)->offsetForInFlowPositionedInline(toLayoutBox(layoutObject)); } } if (layoutObject.style()->hasInFlowPosition() && layoutObject.hasLayer()) m_paintOffset += layoutObject.layer()->offsetForInFlowPosition(); } m_clipped = !fixed && next.m_clipped; if (m_clipped) m_clipRect = next.m_clipRect; } if (m_cachedOffsetsEnabled && layoutObject.isSVGRoot()) { const LayoutSVGRoot& svgRoot = toLayoutSVGRoot(layoutObject); m_svgTransform = AffineTransform(svgRoot.localToBorderBoxTransform()); if (svgRoot.shouldApplyViewportClip()) addClipRectRelativeToPaintOffset(LayoutSize(svgRoot.pixelSnappedSize())); } applyClipIfNeeded(layoutObject); // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present. }
PaintInvalidationState::PaintInvalidationState(PaintInvalidationState& next, const LayoutSVGModelObject& layoutObject) : m_clipped(next.m_clipped) , m_cachedOffsetsEnabled(next.m_cachedOffsetsEnabled) , m_ancestorHadPaintInvalidationForLocationChange(next.m_ancestorHadPaintInvalidationForLocationChange) , m_clipRect(next.m_clipRect) , m_paintOffset(next.m_paintOffset) , m_paintInvalidationContainer(next.m_paintInvalidationContainer) , m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets()) { ASSERT(layoutObject != m_paintInvalidationContainer); if (m_cachedOffsetsEnabled) m_svgTransform = adoptPtr(new AffineTransform(next.svgTransform() * layoutObject.localToParentTransform())); }
PaintInvalidationState::PaintInvalidationState(PaintInvalidationState& next, const LayoutSVGModelObject& layoutObject) : m_clipped(next.m_clipped) , m_cachedOffsetsEnabled(next.m_cachedOffsetsEnabled) , m_forcedSubtreeInvalidationWithinContainer(next.m_forcedSubtreeInvalidationWithinContainer) , m_forcedSubtreeInvalidationRectUpdateWithinContainer(next.m_forcedSubtreeInvalidationRectUpdateWithinContainer) , m_viewClippingAndScrollOffsetDisabled(false) , m_clipRect(next.m_clipRect) , m_paintOffset(next.m_paintOffset) , m_paintInvalidationContainer(next.m_paintInvalidationContainer) , m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets()) { ASSERT(layoutObject != m_paintInvalidationContainer); if (m_cachedOffsetsEnabled) m_svgTransform = adoptPtr(new AffineTransform(next.svgTransform() * layoutObject.localToParentTransform())); }
void RenderView::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState) { ASSERT(!needsLayout()); // We specifically need to issue paint invalidations for the viewRect since other renderers // short-circuit on full-paint invalidation. LayoutRect dirtyRect = viewRect(); if (doingFullPaintInvalidation() && !dirtyRect.isEmpty()) { const RenderLayerModelObject* paintInvalidationContainer = &paintInvalidationState.paintInvalidationContainer(); RenderLayer::mapRectToPaintInvalidationBacking(this, paintInvalidationContainer, dirtyRect, &paintInvalidationState); invalidatePaintUsingContainer(paintInvalidationContainer, dirtyRect, PaintInvalidationFull); } RenderBlock::invalidateTreeIfNeeded(paintInvalidationState); }
void RenderLayerModelObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState) { ASSERT(!needsLayout()); if (!shouldCheckForPaintInvalidation(paintInvalidationState)) return; bool establishesNewPaintInvalidationContainer = isPaintInvalidationContainer(); const RenderLayerModelObject& newPaintInvalidationContainer = *adjustCompositedContainerForSpecialAncestors(establishesNewPaintInvalidationContainer ? this : &paintInvalidationState.paintInvalidationContainer()); ASSERT(&newPaintInvalidationContainer == containerForPaintInvalidation()); InvalidationReason reason = invalidatePaintIfNeeded(paintInvalidationState, newPaintInvalidationContainer); clearPaintInvalidationState(paintInvalidationState); PaintInvalidationState childTreeWalkState(paintInvalidationState, *this, newPaintInvalidationContainer); if (reason == InvalidationLocationChange || reason == InvalidationFull) childTreeWalkState.setForceCheckForPaintInvalidation(); invalidatePaintOfSubtreesIfNeeded(childTreeWalkState); }
void RenderLayerModelObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState) { ASSERT(!needsLayout()); if (!shouldCheckForPaintInvalidation(paintInvalidationState)) return; bool establishesNewPaintInvalidationContainer = isPaintInvalidationContainer(); const RenderLayerModelObject& newPaintInvalidationContainer = *adjustCompositedContainerForSpecialAncestors(establishesNewPaintInvalidationContainer ? this : &paintInvalidationState.paintInvalidationContainer()); // FIXME: This assert should be re-enabled when we move paint invalidation to after compositing update. crbug.com/360286 // ASSERT(&newPaintInvalidationContainer == containerForPaintInvalidation()); PaintInvalidationReason reason = invalidatePaintIfNeeded(paintInvalidationState, newPaintInvalidationContainer); clearPaintInvalidationState(paintInvalidationState); PaintInvalidationState childTreeWalkState(paintInvalidationState, *this, newPaintInvalidationContainer); if (reason == PaintInvalidationLocationChange) childTreeWalkState.setForceCheckForPaintInvalidation(); invalidatePaintOfSubtreesIfNeeded(childTreeWalkState); }