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

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

Issue 2404213004: Implement incremental paint property tree rebuilding (Closed)
Patch Set: Fix bug in how svg local to border box was updated, no longer crash in tests Created 4 years, 2 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
Index: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index a2325fe77835be20065d047ae322709a7a324c04..4f4d86acf14ccd0056b187c6c532b50e58c3540c 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -13,6 +13,7 @@
#include "core/layout/svg/LayoutSVGRoot.h"
#include "core/paint/ObjectPaintProperties.h"
#include "core/paint/PaintLayer.h"
+#include "core/paint/PaintPropertyUnderInvalidationChecks.h"
#include "core/paint/SVGRootPainter.h"
#include "platform/transforms/TransformationMatrix.h"
#include "wtf/PtrUtil.h"
@@ -135,7 +136,7 @@ ScrollPaintPropertyNode* updateFrameViewScroll(
return frameView.scroll();
}
-void PaintPropertyTreeBuilder::buildTreeNodes(
+void PaintPropertyTreeBuilder::updateProperties(
FrameView& frameView,
PaintPropertyTreeBuilderContext& context) {
if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
@@ -143,16 +144,28 @@ void PaintPropertyTreeBuilder::buildTreeNodes(
if (!layoutView)
return;
- TransformationMatrix frameTranslate;
- frameTranslate.translate(frameView.x() + layoutView->location().x() +
- context.current.paintOffset.x(),
- frameView.y() + layoutView->location().y() +
- context.current.paintOffset.y());
- context.current.transform =
- layoutView->getMutableForPainting()
- .ensurePaintProperties()
- .updatePaintOffsetTranslation(context.current.transform,
- frameTranslate, FloatPoint3D());
+#ifndef NDEBUG
chrishtr 2016/10/21 22:03:09 #if DCHECK_IS_ON
pdr. 2016/10/26 03:10:48 Done
+ auto underInvalidationChecker =
+ ObjectUnderInvalidationCheckScope::createIfNeeded(*layoutView);
+#endif
+
+ if (layoutView->paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ const auto* properties = layoutView->paintProperties();
+ if (properties && properties->paintOffsetTranslation())
chrishtr 2016/10/21 22:03:09 This conditional is not needed, and therefore line
pdr. 2016/10/26 03:10:48 This approach is very nice. Done.
+ context.current.transform = properties->paintOffsetTranslation();
+ } else {
+ TransformationMatrix frameTranslate;
+ frameTranslate.translate(frameView.x() + layoutView->location().x() +
+ context.current.paintOffset.x(),
+ frameView.y() + layoutView->location().y() +
+ context.current.paintOffset.y());
+ context.current.transform =
+ layoutView->getMutableForPainting()
+ .ensurePaintProperties()
+ .updatePaintOffsetTranslation(context.current.transform,
+ frameTranslate, FloatPoint3D());
+ }
context.current.paintOffset = LayoutPoint();
context.current.renderingContextID = 0;
context.current.shouldFlattenInheritedTransform = true;
@@ -163,42 +176,59 @@ void PaintPropertyTreeBuilder::buildTreeNodes(
return;
}
- TransformationMatrix frameTranslate;
- frameTranslate.translate(frameView.x() + context.current.paintOffset.x(),
- frameView.y() + context.current.paintOffset.y());
- context.current.transform = updateFrameViewPreTranslation(
- frameView, context.current.transform, frameTranslate, FloatPoint3D());
-
- FloatRoundedRect contentClip(
- IntRect(IntPoint(), frameView.visibleContentSize()));
- context.current.clip = updateFrameViewContentClip(
- frameView, context.current.clip, frameView.preTranslation(), contentClip);
-
- // Record the fixed properties before any scrolling occurs.
- const auto* fixedTransformNode = context.current.transform;
- auto* fixedScrollNode = context.current.scroll;
-
- ScrollOffset scrollOffset = frameView.scrollOffset();
- if (frameView.isScrollable() || !scrollOffset.isZero()) {
- TransformationMatrix frameScroll;
- frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
- context.current.transform = updateFrameViewScrollTranslation(
- frameView, frameView.preTranslation(), frameScroll, FloatPoint3D());
-
- IntSize scrollClip = frameView.visibleContentSize();
- IntSize scrollBounds = frameView.contentsSize();
- bool userScrollableHorizontal =
- frameView.userInputScrollable(HorizontalScrollbar);
- bool userScrollableVertical =
- frameView.userInputScrollable(VerticalScrollbar);
- context.current.scroll = updateFrameViewScroll(
- frameView, context.current.scroll, frameView.scrollTranslation(),
- scrollClip, scrollBounds, userScrollableHorizontal,
- userScrollableVertical);
+#ifndef NDEBUG
+ auto underInvalidationChecker =
+ FrameViewUnderInvalidationCheckScope::createIfNeeded(&frameView);
+#endif
+
+ const auto* initialTransformNode = context.current.transform;
+ auto* initialScrollNode = context.current.scroll;
+
+ if (frameView.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (const auto* preTranslation = frameView.preTranslation())
+ context.current.transform = preTranslation;
+ if (const auto* clip = frameView.contentClip())
+ context.current.clip = clip;
+ if (const auto* scrollTranslation = frameView.scrollTranslation())
+ context.current.transform = scrollTranslation;
+ if (auto* scroll = frameView.scroll())
+ context.current.scroll = scroll;
} else {
- // Ensure pre-existing properties are cleared when there is no scrolling.
- frameView.setScrollTranslation(nullptr);
- frameView.setScroll(nullptr);
+ TransformationMatrix frameTranslate;
+ frameTranslate.translate(frameView.x() + context.current.paintOffset.x(),
+ frameView.y() + context.current.paintOffset.y());
+ context.current.transform = updateFrameViewPreTranslation(
+ frameView, context.current.transform, frameTranslate, FloatPoint3D());
+
+ FloatRoundedRect contentClip(
+ IntRect(IntPoint(), frameView.visibleContentSize()));
+ context.current.clip =
+ updateFrameViewContentClip(frameView, context.current.clip,
+ frameView.preTranslation(), contentClip);
+
+ ScrollOffset scrollOffset = frameView.scrollOffset();
+ if (frameView.isScrollable() || !scrollOffset.isZero()) {
+ TransformationMatrix frameScroll;
+ frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
+ context.current.transform = updateFrameViewScrollTranslation(
+ frameView, frameView.preTranslation(), frameScroll, FloatPoint3D());
+
+ IntSize scrollClip = frameView.visibleContentSize();
+ IntSize scrollBounds = frameView.contentsSize();
+ bool userScrollableHorizontal =
+ frameView.userInputScrollable(HorizontalScrollbar);
+ bool userScrollableVertical =
+ frameView.userInputScrollable(VerticalScrollbar);
+ context.current.scroll = updateFrameViewScroll(
+ frameView, context.current.scroll, frameView.scrollTranslation(),
+ scrollClip, scrollBounds, userScrollableHorizontal,
+ userScrollableVertical);
+ } else {
+ // Ensure pre-existing properties are cleared when there is no scrolling.
+ frameView.setScrollTranslation(nullptr);
+ frameView.setScroll(nullptr);
+ }
}
// Initialize the context for current, absolute and fixed position cases.
@@ -210,8 +240,10 @@ void PaintPropertyTreeBuilder::buildTreeNodes(
context.absolutePosition = context.current;
context.containerForAbsolutePosition = nullptr;
context.fixedPosition = context.current;
- context.fixedPosition.transform = fixedTransformNode;
- context.fixedPosition.scroll = fixedScrollNode;
+ context.fixedPosition.transform = frameView.preTranslation()
+ ? frameView.preTranslation()
+ : initialTransformNode;
+ context.fixedPosition.scroll = initialScrollNode;
std::unique_ptr<PropertyTreeState> contentsState(
new PropertyTreeState(context.current.transform, context.current.clip,
@@ -239,16 +271,25 @@ void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(
LayoutPoint fractionalPaintOffset =
LayoutPoint(context.current.paintOffset - roundedPaintOffset);
- context.current.transform =
- object.getMutableForPainting()
- .ensurePaintProperties()
- .updatePaintOffsetTranslation(
- context.current.transform,
- TransformationMatrix().translate(roundedPaintOffset.x(),
- roundedPaintOffset.y()),
- FloatPoint3D(),
- context.current.shouldFlattenInheritedTransform,
- context.current.renderingContextID);
+ // TODO(pdr): Refactor this check to be higher so the layer and
+ // paintsWithTransform checks can be skipped if there's no invalidation.
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ const auto* properties = object.paintProperties();
+ if (properties && properties->paintOffsetTranslation())
+ context.current.transform = properties->paintOffsetTranslation();
+ } else {
+ context.current.transform =
+ object.getMutableForPainting()
+ .ensurePaintProperties()
+ .updatePaintOffsetTranslation(
+ context.current.transform,
+ TransformationMatrix().translate(roundedPaintOffset.x(),
+ roundedPaintOffset.y()),
+ FloatPoint3D(),
+ context.current.shouldFlattenInheritedTransform,
+ context.current.renderingContextID);
+ }
context.current.paintOffset = fractionalPaintOffset;
return;
}
@@ -257,8 +298,10 @@ void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(
if (object.isLayoutView())
return;
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearPaintOffsetTranslation();
+ if (!object.paintPropertiesValid()) {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearPaintOffsetTranslation();
+ }
}
static FloatPoint3D transformOrigin(const LayoutBox& box) {
chrishtr 2016/10/21 22:03:09 This method is now getting very long, refactor it?
pdr. 2016/10/26 03:10:48 Done. Split out the svg-specific code into its own
@@ -278,29 +321,68 @@ void PaintPropertyTreeBuilder::updateTransform(
DCHECK(object.isSVGForeignObject() ||
context.current.paintOffset == LayoutPoint());
- // FIXME(pdr): Check for the presence of a transform instead of the value.
- // Checking for an identity matrix will cause the property tree structure to
- // change during animations if the animation passes through the identity
- // matrix.
- // FIXME(pdr): Refactor this so all non-root SVG objects use the same
- // transform function.
- const AffineTransform& transform = object.isSVGForeignObject()
- ? object.localSVGTransform()
- : object.localToSVGParentTransform();
- if (!transform.isIdentity()) {
- // The origin is included in the local transform, so leave origin empty.
- context.current.transform =
- object.getMutableForPainting()
- .ensurePaintProperties()
- .updateTransform(context.current.transform,
- TransformationMatrix(transform), FloatPoint3D());
- context.current.renderingContextID = 0;
- context.current.shouldFlattenInheritedTransform = false;
- return;
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (object.paintProperties() && object.paintProperties()->transform()) {
+ context.current.transform = object.paintProperties()->transform();
+ context.current.shouldFlattenInheritedTransform = false;
+ context.current.renderingContextID = 0;
+ }
+ } else {
+ // FIXME(pdr): Check for the presence of a transform instead of the value.
+ // Checking for an identity matrix will cause the property tree structure
+ // to change during animations if the animation passes through the
+ // identity matrix.
+ // FIXME(pdr): Refactor this so all non-root SVG objects use the same
+ // transform function.
+ const AffineTransform& transform =
+ object.isSVGForeignObject() ? object.localSVGTransform()
+ : object.localToSVGParentTransform();
+ if (!transform.isIdentity()) {
+ // The origin is included in the local transform, so leave origin empty.
+ context.current.transform =
+ object.getMutableForPainting()
+ .ensurePaintProperties()
+ .updateTransform(context.current.transform,
+ TransformationMatrix(transform),
+ FloatPoint3D());
+ context.current.shouldFlattenInheritedTransform = false;
+ context.current.renderingContextID = 0;
+ } else {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearTransform();
+ }
}
- } else {
- const ComputedStyle& style = object.styleRef();
- if (object.isBox() && (style.hasTransform() || style.preserves3D())) {
+ return;
+ }
+
+ const ComputedStyle& style = object.styleRef();
+ if (object.isBox() && (style.hasTransform() || style.preserves3D())) {
+ unsigned renderingContextID = context.current.renderingContextID;
+ unsigned renderingContextIDForChildren = 0;
+ bool flattensInheritedTransform =
+ context.current.shouldFlattenInheritedTransform;
+ bool childrenFlattenInheritedTransform = true;
+
+ // TODO(trchen): transform-style should only be respected if a PaintLayer
+ // is created.
+ if (style.preserves3D()) {
+ // If a node with transform-style: preserve-3d does not exist in an
+ // existing rendering context, it establishes a new one.
+ if (!renderingContextID)
+ renderingContextID = PtrHash<const LayoutObject>::hash(&object);
+ renderingContextIDForChildren = renderingContextID;
+ childrenFlattenInheritedTransform = false;
+ }
+ context.current.renderingContextID = renderingContextIDForChildren;
+ context.current.shouldFlattenInheritedTransform =
+ childrenFlattenInheritedTransform;
+
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (object.paintProperties() && object.paintProperties()->transform())
+ context.current.transform = object.paintProperties()->transform();
+ } else {
TransformationMatrix matrix;
style.applyTransform(
matrix, toLayoutBox(object).size(),
@@ -308,83 +390,79 @@ void PaintPropertyTreeBuilder::updateTransform(
ComputedStyle::IncludeMotionPath,
ComputedStyle::IncludeIndependentTransformProperties);
FloatPoint3D origin = transformOrigin(toLayoutBox(object));
-
- unsigned renderingContextID = context.current.renderingContextID;
- unsigned renderingContextIDForChildren = 0;
- bool flattensInheritedTransform =
- context.current.shouldFlattenInheritedTransform;
- bool childrenFlattenInheritedTransform = true;
-
- // TODO(trchen): transform-style should only be respected if a PaintLayer
- // is created.
- if (style.preserves3D()) {
- // If a node with transform-style: preserve-3d does not exist in an
- // existing rendering context, it establishes a new one.
- if (!renderingContextID)
- renderingContextID = PtrHash<const LayoutObject>::hash(&object);
- renderingContextIDForChildren = renderingContextID;
- childrenFlattenInheritedTransform = false;
- }
-
context.current.transform =
object.getMutableForPainting()
.ensurePaintProperties()
.updateTransform(context.current.transform, matrix, origin,
flattensInheritedTransform, renderingContextID);
- context.current.renderingContextID = renderingContextIDForChildren;
- context.current.shouldFlattenInheritedTransform =
- childrenFlattenInheritedTransform;
- return;
+ }
+ } else {
+ if (!object.paintPropertiesValid()) {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearTransform();
}
}
-
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearTransform();
}
void PaintPropertyTreeBuilder::updateEffect(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
- if (!object.styleRef().hasOpacity()) {
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearEffect();
- return;
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (object.paintProperties() && object.paintProperties()->effect())
+ context.currentEffect = object.paintProperties()->effect();
+ } else {
+ if (object.styleRef().hasOpacity()) {
+ context.currentEffect =
+ object.getMutableForPainting().ensurePaintProperties().updateEffect(
+ context.currentEffect, object.styleRef().opacity());
+ } else {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearEffect();
+ }
}
-
- context.currentEffect =
- object.getMutableForPainting().ensurePaintProperties().updateEffect(
- context.currentEffect, object.styleRef().opacity());
}
void PaintPropertyTreeBuilder::updateCssClip(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
- if (object.hasClip()) {
- // Create clip node for descendants that are not fixed position.
- // We don't have to setup context.absolutePosition.clip here because this
- // object must be a container for absolute position descendants, and will
- // copy from in-flow context later at updateOutOfFlowContext() step.
- DCHECK(object.canContainAbsolutePositionObjects());
- LayoutRect clipRect =
- toLayoutBox(object).clipRect(context.current.paintOffset);
- context.current.clip =
- object.getMutableForPainting().ensurePaintProperties().updateCssClip(
- context.current.clip, context.current.transform,
- FloatRoundedRect(FloatRect(clipRect)));
- return;
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (object.paintProperties() && object.paintProperties()->cssClip())
+ context.current.clip = object.paintProperties()->cssClip();
+ } else {
+ if (object.hasClip()) {
+ // Create clip node for descendants that are not fixed position.
+ // We don't have to setup context.absolutePosition.clip here because this
+ // object must be a container for absolute position descendants, and will
+ // copy from in-flow context later at updateOutOfFlowContext() step.
+ DCHECK(object.canContainAbsolutePositionObjects());
+ LayoutRect clipRect =
+ toLayoutBox(object).clipRect(context.current.paintOffset);
+ context.current.clip =
+ object.getMutableForPainting().ensurePaintProperties().updateCssClip(
+ context.current.clip, context.current.transform,
+ FloatRoundedRect(FloatRect(clipRect)));
+ } else {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearCssClip();
+ }
}
-
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearCssClip();
}
void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
+ if (object.paintPropertiesValid())
+ return;
+
// Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
// we don't need them at the moment.
- if (!object.isBox() && !object.hasLayer())
+ if (!object.isBox() && !object.hasLayer()) {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearLocalBorderBoxProperties();
chrishtr 2016/10/21 22:03:09 Why is this change needed but wasn't in the old co
pdr. 2016/10/26 03:10:48 This is just a cleanup so we don't leave unnecessa
return;
+ }
std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset>
borderBoxContext =
@@ -402,6 +480,9 @@ void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(
void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(
const LayoutObject& object,
const PaintPropertyTreeBuilderContext& context) {
+ if (object.paintPropertiesValid())
+ return;
+
IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) {
if (PaintLayerScrollableArea* scrollableArea =
@@ -426,10 +507,13 @@ void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(
void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
+ // TODO(pdr): Add property under-invalidation checking for main thread scroll
+ // reasons and ensure reason changes invalidate property trees.
if (context.current.scroll &&
- !object.document().settings()->threadedScrollingEnabled())
+ !object.document().settings()->threadedScrollingEnabled()) {
context.current.scroll->addMainThreadScrollingReasons(
MainThreadScrollingReason::kThreadedScrollingDisabled);
+ }
if (object.isBackgroundAttachmentFixedObject()) {
auto* scrollNode = context.current.scroll;
@@ -451,6 +535,14 @@ void PaintPropertyTreeBuilder::updateOverflowClip(
return;
const LayoutBox& box = toLayoutBox(object);
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ const auto* properties = object.paintProperties();
+ if (properties && properties->overflowClip())
+ context.current.clip = properties->overflowClip();
+ return;
+ }
+
// The <input> elements can't have contents thus CSS overflow property doesn't
// apply. However for layout purposes we do generate child layout objects for
// them, e.g. button label. We should clip the overflow from those children.
@@ -503,23 +595,32 @@ void PaintPropertyTreeBuilder::updatePerspective(
PaintPropertyTreeBuilderContext& context) {
const ComputedStyle& style = object.styleRef();
if (!object.isBox() || !style.hasPerspective()) {
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearPerspective();
+ if (!object.paintPropertiesValid()) {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearPerspective();
+ }
return;
}
- // The perspective node must not flatten (else nothing will get
- // perspective), but it should still extend the rendering context as most
- // transform nodes do.
- TransformationMatrix matrix =
- TransformationMatrix().applyPerspective(style.perspective());
- FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) +
- toLayoutSize(context.current.paintOffset);
- context.current.transform =
- object.getMutableForPainting().ensurePaintProperties().updatePerspective(
- context.current.transform, matrix, origin,
- context.current.shouldFlattenInheritedTransform,
- context.current.renderingContextID);
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (object.paintProperties() && object.paintProperties()->perspective())
+ context.current.transform = object.paintProperties()->perspective();
+ } else {
+ // The perspective node must not flatten (else nothing will get
+ // perspective), but it should still extend the rendering context as most
+ // transform nodes do.
+ TransformationMatrix matrix =
+ TransformationMatrix().applyPerspective(style.perspective());
+ FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) +
+ toLayoutSize(context.current.paintOffset);
+ context.current.transform =
+ object.getMutableForPainting()
+ .ensurePaintProperties()
+ .updatePerspective(context.current.transform, matrix, origin,
+ context.current.shouldFlattenInheritedTransform,
+ context.current.renderingContextID);
+ }
context.current.shouldFlattenInheritedTransform = false;
}
@@ -529,32 +630,53 @@ void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(
if (!object.isSVGRoot())
return;
- AffineTransform transformToBorderBox =
- SVGRootPainter(toLayoutSVGRoot(object))
- .transformToPixelSnappedBorderBox(context.current.paintOffset);
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ const auto* properties = object.paintProperties();
+ if (properties && properties->svgLocalToBorderBoxTransform()) {
+ context.current.transform = properties->svgLocalToBorderBoxTransform();
+ context.current.shouldFlattenInheritedTransform = false;
+ context.current.renderingContextID = 0;
+ }
+ } else {
+ AffineTransform transformToBorderBox =
+ SVGRootPainter(toLayoutSVGRoot(object))
+ .transformToPixelSnappedBorderBox(context.current.paintOffset);
+
+ if (transformToBorderBox.isIdentity()) {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearSvgLocalToBorderBoxTransform();
+ } else {
+ context.current.transform = object.getMutableForPainting()
+ .ensurePaintProperties()
+ .updateSvgLocalToBorderBoxTransform(
+ context.current.transform,
+ transformToBorderBox, FloatPoint3D());
+ context.current.shouldFlattenInheritedTransform = false;
+ context.current.renderingContextID = 0;
+ }
+ }
// The paint offset is included in |transformToBorderBox| so SVG does not need
// to handle paint offset internally.
context.current.paintOffset = LayoutPoint();
-
- if (transformToBorderBox.isIdentity()) {
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearSvgLocalToBorderBoxTransform();
- return;
- }
-
- context.current.transform =
- object.getMutableForPainting()
- .ensurePaintProperties()
- .updateSvgLocalToBorderBoxTransform(
- context.current.transform, transformToBorderBox, FloatPoint3D());
- context.current.shouldFlattenInheritedTransform = false;
- context.current.renderingContextID = 0;
}
void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ if (object.paintProperties() && object.paintProperties()->scroll()) {
+ context.current.transform = object.paintProperties()->transform();
+ const auto* scroll = object.paintProperties()->scroll();
+ // TODO(pdr): Remove this const cast.
+ context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll);
+ context.current.shouldFlattenInheritedTransform = false;
+ }
+ return;
+ }
+
if (object.hasOverflowClip()) {
const LayoutBox& box = toLayoutBox(object);
const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea();
@@ -628,20 +750,29 @@ void PaintPropertyTreeBuilder::updateOutOfFlowContext(
if (context.fixedPosition.clip == cssClip->parent()) {
context.fixedPosition.clip = cssClip;
} else {
- context.fixedPosition.clip =
- object.getMutableForPainting()
- .ensurePaintProperties()
- .updateCssClipFixedPosition(
- context.fixedPosition.clip,
- const_cast<TransformPaintPropertyNode*>(
- cssClip->localTransformSpace()),
- cssClip->clipRect());
+ if (object.paintPropertiesValid()) {
+ // No invalidation so update the context using existing properties.
+ const auto* properties = object.paintProperties();
+ if (properties && properties->cssClipFixedPosition())
+ context.fixedPosition.clip = properties->cssClipFixedPosition();
+ } else {
+ context.fixedPosition.clip =
+ object.getMutableForPainting()
+ .ensurePaintProperties()
+ .updateCssClipFixedPosition(
+ context.fixedPosition.clip,
+ const_cast<TransformPaintPropertyNode*>(
+ cssClip->localTransformSpace()),
+ cssClip->clipRect());
+ }
return;
}
}
- if (auto* properties = object.getMutableForPainting().paintProperties())
- properties->clearCssClipFixedPosition();
+ if (!object.paintPropertiesValid()) {
+ if (auto* properties = object.getMutableForPainting().paintProperties())
+ properties->clearCssClipFixedPosition();
+ }
}
// Override ContainingBlockContext based on the properties of a containing block
@@ -766,12 +897,17 @@ static void deriveBorderBoxFromContainerContext(
}
}
-void PaintPropertyTreeBuilder::buildTreeNodesForSelf(
+void PaintPropertyTreeBuilder::updatePropertiesForSelf(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
if (!object.isBoxModelObject() && !object.isSVG())
return;
+#ifndef NDEBUG
+ auto underInvalidationChecker =
+ ObjectUnderInvalidationCheckScope::createIfNeeded(object);
+#endif
+
deriveBorderBoxFromContainerContext(object, context);
updatePaintOffsetTranslation(object, context);
@@ -783,12 +919,17 @@ void PaintPropertyTreeBuilder::buildTreeNodesForSelf(
updateMainThreadScrollingReasons(object, context);
}
-void PaintPropertyTreeBuilder::buildTreeNodesForChildren(
+void PaintPropertyTreeBuilder::updatePropertiesForChildren(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
if (!object.isBoxModelObject() && !object.isSVG())
return;
+#ifndef NDEBUG
+ auto underInvalidationChecker =
+ ObjectUnderInvalidationCheckScope::createIfNeeded(object);
+#endif
+
updateOverflowClip(object, context);
updatePerspective(object, context);
updateSvgLocalToBorderBoxTransform(object, context);

Powered by Google App Engine
This is Rietveld 408576698