Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Unified Diff: third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp

Issue 2654643002: Invalidate subsequence caching & empty paint phases if clips changed. (Closed)
Patch Set: Merge branch 'master' into repaintonclip Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/paint/PrePaintTreeWalk.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
index 847539ad9f67180619b83ba3bbc4e0d46fa306da..8ad86c9dd2d91cfb90b6bca7e06a6f55e10b0674 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -22,7 +22,9 @@ struct PrePaintTreeWalkContext {
: treeBuilderContext(parentContext.treeBuilderContext),
paintInvalidatorContext(treeBuilderContext,
parentContext.paintInvalidatorContext),
- ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer) {}
+ ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer),
+ ancestorTransformedOrRootPaintLayer(
+ parentContext.ancestorTransformedOrRootPaintLayer) {}
PaintPropertyTreeBuilderContext treeBuilderContext;
PaintInvalidatorContext paintInvalidatorContext;
@@ -31,6 +33,7 @@ struct PrePaintTreeWalkContext {
// is the root layer. Note that it is tree ancestor, not containing
// block or stacking ancestor.
PaintLayer* ancestorOverflowPaintLayer;
+ PaintLayer* ancestorTransformedOrRootPaintLayer;
};
void PrePaintTreeWalk::walk(FrameView& rootFrame) {
@@ -52,8 +55,10 @@ void PrePaintTreeWalk::walk(FrameView& frameView,
}
PrePaintTreeWalkContext context(parentContext);
- // ancestorOverflowLayer does not cross frame boundaries.
+ // ancestorOverflowLayer does not cross frame
+ // boundaries.
context.ancestorOverflowPaintLayer = nullptr;
+ context.ancestorTransformedOrRootPaintLayer = frameView.layoutView()->layer();
m_propertyTreeBuilder.updateProperties(frameView, context.treeBuilderContext);
m_paintInvalidator.invalidatePaintIfNeeded(frameView,
context.paintInvalidatorContext);
@@ -89,6 +94,108 @@ static void updateAuxiliaryObjectProperties(const LayoutObject& object,
context.ancestorOverflowPaintLayer = paintLayer;
}
+ClipRect PrePaintTreeWalk::clipRectForContext(
+ const PaintPropertyTreeBuilderContext::ContainingBlockContext& context,
+ const EffectPaintPropertyNode* effect,
+ const PropertyTreeState& ancestorState,
+ const LayoutPoint& ancestorPaintOffset,
+ bool& hasClip) {
+ // Only return a non-infinite clip if clips differ. This ensures
+ // no accuracy issues due to transforms applied to infinite rects.
+ if (GeometryMapper::lowestCommonAncestor(
+ context.clip, ancestorState.clip()) == context.clip)
+ return ClipRect(LayoutRect(LayoutRect::infiniteIntRect()));
+
+ hasClip = true;
+
+ PropertyTreeState localState(context.transform, context.clip, effect,
+ context.scroll);
+
+ // TODO(chrishtr): remove need for this.
+ LayoutRect localRect(LayoutRect::infiniteIntRect());
+
+ LayoutRect rect(m_geometryMapper.sourceToDestinationVisualRect(
+ FloatRect(localRect), localState, ancestorState));
+ rect.moveBy(-ancestorPaintOffset);
+ return rect;
+}
+
+void PrePaintTreeWalk::invalidatePaintLayerProperties(
+ const LayoutObject& object,
+ const PaintLayer& ancestorTransformedOrRootPaintLayer,
+ const PaintPropertyTreeBuilderContext& context) {
+ if (!object.hasLayer() || !object.isBoxModelObject())
+ return;
+
+ if (ancestorTransformedOrRootPaintLayer.layoutObject()->hasClip())
+ return;
+
+ PaintLayer& paintLayer = *toLayoutBoxModelObject(object).layer();
+ PropertyTreeState ancestorState =
+ *ancestorTransformedOrRootPaintLayer.layoutObject()
+ ->paintProperties()
+ ->localBorderBoxProperties();
+ ShouldRespectOverflowClipType respectOverflowClip = RespectOverflowClip;
+ if (ancestorTransformedOrRootPaintLayer.compositingState() ==
+ PaintsIntoOwnBacking &&
+ ancestorTransformedOrRootPaintLayer.layoutObject()
+ ->paintProperties()
+ ->overflowClip()) {
+ // Use contentsProperties because we are ignoring any overflow clip applied
+ // to ancestorTransformedOrRootPaintLayer.
+ ancestorState.setClip(ancestorTransformedOrRootPaintLayer.layoutObject()
+ ->paintProperties()
+ ->overflowClip());
+ respectOverflowClip = IgnoreOverflowClip;
+ }
+
+#ifdef CHECK_CLIP_RECTS
+ ClipRects& oldClipRects = paintLayer.clipper().paintingClipRects(
+ &ancestorTransformedOrRootPaintLayer, respectOverflowClip, LayoutSize());
+#endif
+
+ bool hasClip = false;
+ RefPtr<ClipRects> clipRects = ClipRects::create();
+ clipRects->setOverflowClipRect(clipRectForContext(
+ context.current, context.currentEffect, ancestorState,
+ ancestorTransformedOrRootPaintLayer.layoutObject()->paintOffset(),
+ hasClip));
+#ifdef CHECK_CLIP_RECTS
+ CHECK(!hasClip ||
+ clipRects->overflowClipRect() == oldClipRects.overflowClipRect())
+ << "rect= " << clipRects->overflowClipRect().toString();
+#endif
+
+ clipRects->setFixedClipRect(clipRectForContext(
+ context.fixedPosition, context.currentEffect, ancestorState,
+ ancestorTransformedOrRootPaintLayer.layoutObject()->paintOffset(),
+ hasClip));
+#ifdef CHECK_CLIP_RECTS
+ CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect())
+ << " fixed=" << clipRects->fixedClipRect().toString();
+#endif
+
+ clipRects->setPosClipRect(clipRectForContext(
+ context.absolutePosition, context.currentEffect, ancestorState,
+ ancestorTransformedOrRootPaintLayer.layoutObject()->paintOffset(),
+ hasClip));
+#ifdef CHECK_CLIP_RECTS
+ CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect())
+ << " abs=" << clipRects->posClipRect().toString();
+#endif
+
+ ClipRects* previousClipRects = paintLayer.previousPaintingClipRects();
+
+ if (!previousClipRects || *clipRects != *previousClipRects) {
+ paintLayer.setNeedsRepaint();
+ paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false);
+ paintLayer.setPreviousPaintPhaseFloatEmpty(false);
+ paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false);
+ }
+
+ paintLayer.setPreviousPaintingClipRects(*clipRects);
+}
+
void PrePaintTreeWalk::walk(const LayoutObject& object,
const PrePaintTreeWalkContext& parentContext) {
PrePaintTreeWalkContext context(parentContext);
@@ -120,6 +227,18 @@ void PrePaintTreeWalk::walk(const LayoutObject& object,
m_propertyTreeBuilder.updatePropertiesForChildren(object,
context.treeBuilderContext);
+ if (object.isBoxModelObject() && object.hasLayer()) {
+ if (object.styleRef().hasTransform() ||
+ &object == context.paintInvalidatorContext.paintInvalidationContainer) {
+ context.ancestorTransformedOrRootPaintLayer =
+ toLayoutBoxModelObject(object).layer();
+ }
+ }
+
+ invalidatePaintLayerProperties(object,
+ *context.ancestorTransformedOrRootPaintLayer,
+ context.treeBuilderContext);
+
for (const LayoutObject* child = object.slowFirstChild(); child;
child = child->nextSibling()) {
if (child->isLayoutMultiColumnSpannerPlaceholder()) {
« no previous file with comments | « third_party/WebKit/Source/core/paint/PrePaintTreeWalk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698