Commit 808643f3 authored by wangxianzhu's avatar wangxianzhu Committed by Commit bot

Reuse existing paint property node is possible

This is required by subsequence caching for spv2. When we copy a cached
subsequence, we won't do actual paint and will use the existing
PaintChunkProperties which points to the paint property nodes created
during the previous paint. We are sure that the values of these property
nodes didn't change since the previous paint because we can use the
cached subsequence.

To meet this requirement, when building the paint property tree, instead
of rebuilding the whole tree by creating all new nodes, we should reuse
the existing nodes if their values don't change. The reused nodes should
be placed in the new tree.

In the future we may also reuse a whole subtree of property nodes.

BUG=596983

Review-Url: https://codereview.chromium.org/2144823006
Cr-Commit-Position: refs/heads/master@{#407243}
parent 50ebc130
...@@ -92,12 +92,12 @@ private: ...@@ -92,12 +92,12 @@ private:
void setPerspective(PassRefPtr<TransformPaintPropertyNode> perspective) { m_perspective = perspective; } void setPerspective(PassRefPtr<TransformPaintPropertyNode> perspective) { m_perspective = perspective; }
void setSvgLocalToBorderBoxTransform(PassRefPtr<TransformPaintPropertyNode> transform) void setSvgLocalToBorderBoxTransform(PassRefPtr<TransformPaintPropertyNode> transform)
{ {
DCHECK(!scrollTranslation()) << "SVG elements cannot scroll so there should never be both a scroll translation and an SVG local to border box transform."; DCHECK(!scrollTranslation() || !transform) << "SVG elements cannot scroll so there should never be both a scroll translation and an SVG local to border box transform.";
m_svgLocalToBorderBoxTransform = transform; m_svgLocalToBorderBoxTransform = transform;
} }
void setScrollTranslation(PassRefPtr<TransformPaintPropertyNode> translation) void setScrollTranslation(PassRefPtr<TransformPaintPropertyNode> translation)
{ {
DCHECK(!svgLocalToBorderBoxTransform()) << "SVG elements cannot scroll so there should never be both a scroll translation and an SVG local to border box transform."; DCHECK(!svgLocalToBorderBoxTransform() || !translation) << "SVG elements cannot scroll so there should never be both a scroll translation and an SVG local to border box transform.";
m_scrollTranslation = translation; m_scrollTranslation = translation;
} }
void setScrollbarPaintOffset(PassRefPtr<TransformPaintPropertyNode> paintOffset) { m_scrollbarPaintOffset = paintOffset; } void setScrollbarPaintOffset(PassRefPtr<TransformPaintPropertyNode> paintOffset) { m_scrollbarPaintOffset = paintOffset; }
......
...@@ -21,17 +21,18 @@ namespace blink { ...@@ -21,17 +21,18 @@ namespace blink {
void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPropertyTreeBuilderContext& context)
{ {
RefPtr<TransformPaintPropertyNode> transformRoot = TransformPaintPropertyNode::create(TransformationMatrix(), FloatPoint3D(), nullptr); if (!rootFrame.rootTransform() || rootFrame.rootTransform()->parent()) {
context.current.transform = context.absolutePosition.transform = context.fixedPosition.transform = transformRoot.get(); rootFrame.setRootTransform(TransformPaintPropertyNode::create(nullptr, TransformationMatrix(), FloatPoint3D()));
rootFrame.setRootTransform(std::move(transformRoot)); rootFrame.setRootClip(ClipPaintPropertyNode::create(nullptr, rootFrame.rootTransform(), FloatRoundedRect(LayoutRect::infiniteIntRect())));
rootFrame.setRootEffect(EffectPaintPropertyNode::create(nullptr, 1.0));
RefPtr<ClipPaintPropertyNode> clipRoot = ClipPaintPropertyNode::create(transformRoot, FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr); } else {
context.current.clip = context.absolutePosition.clip = context.fixedPosition.clip = clipRoot.get(); DCHECK(rootFrame.rootClip() && !rootFrame.rootClip()->parent());
rootFrame.setRootClip(std::move(clipRoot)); DCHECK(rootFrame.rootEffect() && !rootFrame.rootEffect()->parent());
}
RefPtr<EffectPaintPropertyNode> effectRoot = EffectPaintPropertyNode::create(1.0, nullptr); context.current.transform = context.absolutePosition.transform = context.fixedPosition.transform = rootFrame.rootTransform();
context.currentEffect = effectRoot.get(); context.current.clip = context.absolutePosition.clip = context.fixedPosition.clip = rootFrame.rootClip();
rootFrame.setRootEffect(std::move(effectRoot)); context.currentEffect = rootFrame.rootEffect();
} }
void PaintPropertyTreeBuilder::buildTreeNodes(FrameView& frameView, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::buildTreeNodes(FrameView& frameView, PaintPropertyTreeBuilderContext& context)
...@@ -42,58 +43,84 @@ void PaintPropertyTreeBuilder::buildTreeNodes(FrameView& frameView, PaintPropert ...@@ -42,58 +43,84 @@ void PaintPropertyTreeBuilder::buildTreeNodes(FrameView& frameView, PaintPropert
TransformationMatrix frameTranslate; TransformationMatrix frameTranslate;
frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), frameView.y() + context.current.paintOffset.y()); frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), frameView.y() + context.current.paintOffset.y());
RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.current.transform); if (TransformPaintPropertyNode* existingPreTranslation = frameView.preTranslation())
existingPreTranslation->update(context.current.transform, frameTranslate, FloatPoint3D());
else
frameView.setPreTranslation(TransformPaintPropertyNode::create(context.current.transform, frameTranslate, FloatPoint3D()));
FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSize())); FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSize()));
RefPtr<ClipPaintPropertyNode> newClipNodeForContentClip = ClipPaintPropertyNode::create(newTransformNodeForPreTranslation.get(), contentClip, context.current.clip); if (ClipPaintPropertyNode* existingContentClip = frameView.contentClip())
existingContentClip->update(context.current.clip, frameView.preTranslation(), contentClip);
else
frameView.setContentClip(ClipPaintPropertyNode::create(context.current.clip, frameView.preTranslation(), contentClip));
DoubleSize scrollOffset = frameView.scrollOffsetDouble(); DoubleSize scrollOffset = frameView.scrollOffsetDouble();
TransformationMatrix frameScroll; TransformationMatrix frameScroll;
frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); frameScroll.translate(-scrollOffset.width(), -scrollOffset.height());
RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeForPreTranslation); if (TransformPaintPropertyNode* existingScrollTranslation = frameView.scrollTranslation())
existingScrollTranslation->update(frameView.preTranslation(), frameScroll, FloatPoint3D());
else
frameView.setScrollTranslation(TransformPaintPropertyNode::create(frameView.preTranslation(), frameScroll, FloatPoint3D()));
// Initialize the context for current, absolute and fixed position cases. // Initialize the context for current, absolute and fixed position cases.
// They are the same, except that scroll translation does not apply to // They are the same, except that scroll translation does not apply to
// fixed position descendants. // fixed position descendants.
context.current.transform = newTransformNodeForScrollTranslation.get(); context.current.transform = frameView.scrollTranslation();
context.current.paintOffset = LayoutPoint(); context.current.paintOffset = LayoutPoint();
context.current.clip = newClipNodeForContentClip.get(); context.current.clip = frameView.contentClip();
context.absolutePosition = context.current; context.absolutePosition = context.current;
context.containerForAbsolutePosition = nullptr; context.containerForAbsolutePosition = nullptr;
context.fixedPosition = context.current; context.fixedPosition = context.current;
context.fixedPosition.transform = newTransformNodeForPreTranslation.get(); context.fixedPosition.transform = frameView.preTranslation();
}
frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); template <typename PropertyNode, void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>)>
frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release()); void PaintPropertyTreeBuilder::clearPaintProperty(const LayoutObject& object)
frameView.setContentClip(newClipNodeForContentClip.release()); {
if (ObjectPaintProperties* existingProperties = object.objectPaintProperties())
(existingProperties->*Setter)(nullptr);
}
template <
typename PropertyNode,
PropertyNode* (ObjectPaintProperties::*Getter)() const,
void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>),
typename... Args>
void PaintPropertyTreeBuilder::updateOrCreatePaintProperty(const LayoutObject& object, const PaintPropertyTreeBuilderContext& context, PropertyNode*& contextProperty, const Args&... args)
{
ObjectPaintProperties* existingProperties = object.objectPaintProperties();
PropertyNode* existingPropertyNode = existingProperties ? (existingProperties->*Getter)() : nullptr;
if (existingPropertyNode) {
existingPropertyNode->update(contextProperty, args...);
contextProperty = existingPropertyNode;
} else {
RefPtr<PropertyNode> newPropertyNode = PropertyNode::create(contextProperty, args...);
contextProperty = newPropertyNode.get();
(object.getMutableForPainting().ensureObjectPaintProperties().*Setter)(newPropertyNode.release());
}
} }
void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{ {
if (object.isBoxModelObject()) { if (object.isBoxModelObject() && context.current.paintOffset != LayoutPoint()) {
// TODO(trchen): Eliminate PaintLayer dependency. // TODO(trchen): Eliminate PaintLayer dependency.
PaintLayer* layer = toLayoutBoxModelObject(object).layer(); PaintLayer* layer = toLayoutBoxModelObject(object).layer();
if (!layer || !layer->paintsWithTransform(GlobalPaintNormalPhase)) if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) {
// We should use the same subpixel paint offset values for snapping regardless of whether a
// transform is present. If there is a transform we round the paint offset but keep around
// the residual fractional component for the transformed content to paint with.
// In spv1 this was called "subpixel accumulation". For more information, see
// PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragmentByApplyingTransform.
IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset - roundedPaintOffset);
updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::paintOffsetTranslation, &ObjectPaintProperties::setPaintOffsetTranslation>(
object, context, context.current.transform, TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D());
context.current.paintOffset = fractionalPaintOffset;
return; return;
}
} }
clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setPaintOffsetTranslation>(object);
if (context.current.paintOffset == LayoutPoint())
return;
// We should use the same subpixel paint offset values for snapping regardless of whether a
// transform is present. If there is a transform we round the paint offset but keep around
// the residual fractional component for the transformed content to paint with.
// In spv1 this was called "subpixel accumulation". For more information, see
// PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragmentByApplyingTransform.
IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset - roundedPaintOffset);
RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPropertyNode::create(
TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()),
FloatPoint3D(), context.current.transform);
context.current.transform = paintOffsetTranslation.get();
context.current.paintOffset = fractionalPaintOffset;
object.getMutableForPainting().ensureObjectPaintProperties().setPaintOffsetTranslation(paintOffsetTranslation.release());
} }
static FloatPoint3D transformOrigin(const LayoutBox& box) static FloatPoint3D transformOrigin(const LayoutBox& box)
...@@ -117,56 +144,52 @@ void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint ...@@ -117,56 +144,52 @@ void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint
// the animation passes through the identity matrix. // the animation passes through the identity matrix.
// FIXME(pdr): Refactor this so all non-root SVG objects use the same transform function. // FIXME(pdr): Refactor this so all non-root SVG objects use the same transform function.
const AffineTransform& transform = object.isSVGForeignObject() ? object.localSVGTransform() : object.localToSVGParentTransform(); const AffineTransform& transform = object.isSVGForeignObject() ? object.localSVGTransform() : object.localToSVGParentTransform();
if (transform.isIdentity()) if (!transform.isIdentity()) {
// The origin is included in the local transform, so leave origin empty.
updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::transform, &ObjectPaintProperties::setTransform>(
object, context, context.current.transform, TransformationMatrix(transform), FloatPoint3D());
return; return;
}
// The origin is included in the local transform, so use an empty origin. } else {
RefPtr<TransformPaintPropertyNode> svgTransform = TransformPaintPropertyNode::create( const ComputedStyle& style = object.styleRef();
transform, FloatPoint3D(0, 0, 0), context.current.transform); if (object.isBox() && style.hasTransform()) {
context.current.transform = svgTransform.get(); TransformationMatrix matrix;
object.getMutableForPainting().ensureObjectPaintProperties().setTransform(svgTransform.release()); style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::ExcludeTransformOrigin,
return; ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTransformProperties);
FloatPoint3D origin = transformOrigin(toLayoutBox(object));
updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::transform, &ObjectPaintProperties::setTransform>(
object, context, context.current.transform, matrix, origin);
return;
}
} }
clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setTransform>(object);
const ComputedStyle& style = object.styleRef();
if (!object.isBox() || !style.hasTransform())
return;
TransformationMatrix matrix;
style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::ExcludeTransformOrigin,
ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTransformProperties);
RefPtr<TransformPaintPropertyNode> transformNode = TransformPaintPropertyNode::create(
matrix, transformOrigin(toLayoutBox(object)), context.current.transform);
context.current.transform = transformNode.get();
object.getMutableForPainting().ensureObjectPaintProperties().setTransform(transformNode.release());
} }
void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{ {
if (!object.styleRef().hasOpacity()) if (!object.styleRef().hasOpacity()) {
clearPaintProperty<EffectPaintPropertyNode, &ObjectPaintProperties::setEffect>(object);
return; return;
RefPtr<EffectPaintPropertyNode> effectNode = EffectPaintPropertyNode::create(object.styleRef().opacity(), context.currentEffect); }
context.currentEffect = effectNode.get();
object.getMutableForPainting().ensureObjectPaintProperties().setEffect(effectNode.release()); updateOrCreatePaintProperty<EffectPaintPropertyNode, &ObjectPaintProperties::effect, &ObjectPaintProperties::setEffect>(
object, context, context.currentEffect, object.styleRef().opacity());
} }
void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{ {
if (!object.hasClip()) 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);
updateOrCreatePaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::cssClip, &ObjectPaintProperties::setCssClip>(
object, context, context.current.clip, context.current.transform, FloatRoundedRect(FloatRect(clipRect)));
return; return;
ASSERT(object.canContainAbsolutePositionObjects()); }
clearPaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::setCssClip>(object);
// 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.
LayoutRect clipRect = toLayoutBox(object).clipRect(context.current.paintOffset);
RefPtr<ClipPaintPropertyNode> clipNode = ClipPaintPropertyNode::create(
context.current.transform,
FloatRoundedRect(FloatRect(clipRect)),
context.current.clip);
context.current.clip = clipNode.get();
object.getMutableForPainting().ensureObjectPaintProperties().setCssClip(clipNode.release());
} }
void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& object, const PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& object, const PaintPropertyTreeBuilderContext& context)
...@@ -186,20 +209,20 @@ void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o ...@@ -186,20 +209,20 @@ void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o
void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& object, const PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& object, const PaintPropertyTreeBuilderContext& context)
{ {
IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset);
if (roundedPaintOffset == IntPoint()) if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) {
return; if (PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).getScrollableArea()) {
if (scrollableArea->horizontalScrollbar() || scrollableArea->verticalScrollbar()) {
if (!object.isBoxModelObject()) auto paintOffset = TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y());
return; // Make a copy of context.current.transform because we don't want to set the scrollbarPaintOffset node
PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).getScrollableArea(); // as the current transform.
if (!scrollableArea) TransformPaintPropertyNode* parentTransform = context.current.transform;
return; updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::scrollbarPaintOffset, &ObjectPaintProperties::setScrollbarPaintOffset>(
if (!scrollableArea->horizontalScrollbar() && !scrollableArea->verticalScrollbar()) object, context, parentTransform, paintOffset, FloatPoint3D());
return; return;
}
auto paintOffset = TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()); }
object.getMutableForPainting().ensureObjectPaintProperties().setScrollbarPaintOffset( }
TransformPaintPropertyNode::create(paintOffset, FloatPoint3D(), context.current.transform)); clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setScrollbarPaintOffset>(object);
} }
void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
...@@ -213,27 +236,26 @@ void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa ...@@ -213,27 +236,26 @@ void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa
// We should clip the overflow from those children. This is called control clip and we // We should clip the overflow from those children. This is called control clip and we
// technically treat them like overflow clip. // technically treat them like overflow clip.
LayoutRect clipRect; LayoutRect clipRect;
if (box.hasControlClip()) if (box.hasControlClip()) {
clipRect = box.controlClipRect(context.current.paintOffset); clipRect = box.controlClipRect(context.current.paintOffset);
else if (box.hasOverflowClip()) } else if (box.hasOverflowClip()) {
clipRect = box.overflowClipRect(context.current.paintOffset); clipRect = box.overflowClipRect(context.current.paintOffset);
else } else {
clearPaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::setOverflowClip>(object);
return; return;
}
// This need to be in top-level block to hold the reference until we finish creating the normal clip node.
RefPtr<ClipPaintPropertyNode> borderRadiusClip; RefPtr<ClipPaintPropertyNode> borderRadiusClip;
if (box.styleRef().hasBorderRadius()) { if (box.styleRef().hasBorderRadius()) {
auto innerBorder = box.styleRef().getRoundedInnerBorderFor( auto innerBorder = box.styleRef().getRoundedInnerBorderFor(
LayoutRect(context.current.paintOffset, box.size())); LayoutRect(context.current.paintOffset, box.size()));
borderRadiusClip = ClipPaintPropertyNode::create( borderRadiusClip = ClipPaintPropertyNode::create(context.current.clip, context.current.transform, innerBorder);
context.current.transform, innerBorder, context.current.clip); context.current.clip = borderRadiusClip.get();
} }
RefPtr<ClipPaintPropertyNode> overflowClip = ClipPaintPropertyNode::create( updateOrCreatePaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::overflowClip, &ObjectPaintProperties::setOverflowClip>(
context.current.transform, object, context, context.current.clip, context.current.transform, FloatRoundedRect(FloatRect(clipRect)));
FloatRoundedRect(FloatRect(clipRect)),
borderRadiusClip ? borderRadiusClip.release() : context.current.clip);
context.current.clip = overflowClip.get();
object.getMutableForPainting().ensureObjectPaintProperties().setOverflowClip(overflowClip.release());
} }
static FloatPoint perspectiveOrigin(const LayoutBox& box) static FloatPoint perspectiveOrigin(const LayoutBox& box)
...@@ -248,15 +270,14 @@ static FloatPoint perspectiveOrigin(const LayoutBox& box) ...@@ -248,15 +270,14 @@ static FloatPoint perspectiveOrigin(const LayoutBox& box)
void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{ {
const ComputedStyle& style = object.styleRef(); const ComputedStyle& style = object.styleRef();
if (!object.isBox() || !style.hasPerspective()) if (!object.isBox() || !style.hasPerspective()) {
clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setPerspective>(object);
return; return;
}
RefPtr<TransformPaintPropertyNode> perspective = TransformPaintPropertyNode::create( FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.current.paintOffset);
TransformationMatrix().applyPerspective(style.perspective()), updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::perspective, &ObjectPaintProperties::setPerspective>(
perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.current.paintOffset), object, context, context.current.transform, TransformationMatrix().applyPerspective(style.perspective()), origin);
context.current.transform);
context.current.transform = perspective.get();
object.getMutableForPainting().ensureObjectPaintProperties().setPerspective(perspective.release());
} }
void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
...@@ -270,33 +291,30 @@ void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb ...@@ -270,33 +291,30 @@ void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
// offset internally. // offset internally.
context.current.paintOffset = LayoutPoint(); context.current.paintOffset = LayoutPoint();
if (transformToBorderBox.isIdentity()) if (transformToBorderBox.isIdentity()) {
clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setSvgLocalToBorderBoxTransform>(object);
return; return;
}
RefPtr<TransformPaintPropertyNode> svgLocalToBorderBoxTransform = TransformPaintPropertyNode::create( updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::svgLocalToBorderBoxTransform, &ObjectPaintProperties::setSvgLocalToBorderBoxTransform>(
transformToBorderBox, FloatPoint3D(0, 0, 0), context.current.transform); object, context, context.current.transform, transformToBorderBox, FloatPoint3D());
context.current.transform = svgLocalToBorderBoxTransform.get();
context.current.paintOffset = LayoutPoint();
object.getMutableForPainting().ensureObjectPaintProperties().setSvgLocalToBorderBoxTransform(svgLocalToBorderBoxTransform.release());
} }
void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{ {
if (!object.isBoxModelObject() || !object.hasOverflowClip()) if (object.isBoxModelObject() && object.hasOverflowClip()) {
return; PaintLayer* layer = toLayoutBoxModelObject(object).layer();
DCHECK(layer);
PaintLayer* layer = toLayoutBoxModelObject(object).layer(); DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset();
ASSERT(layer);
DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset();
if (scrollOffset.isZero() && !layer->scrollsOverflow())
return;
RefPtr<TransformPaintPropertyNode> scrollTranslation = TransformPaintPropertyNode::create( if (!scrollOffset.isZero() || layer->scrollsOverflow()) {
TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.height()), TransformationMatrix matrix = TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.height());
FloatPoint3D(), updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::scrollTranslation, &ObjectPaintProperties::setScrollTranslation>(
context.current.transform); object, context, context.current.transform, matrix, FloatPoint3D());
context.current.transform = scrollTranslation.get(); return;
object.getMutableForPainting().ensureObjectPaintProperties().setScrollTranslation(scrollTranslation.release()); }
}
clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setScrollTranslation>(object);
} }
void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
...@@ -322,16 +340,13 @@ void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object ...@@ -322,16 +340,13 @@ void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
// context has exactly the same clip. Reuse if possible. // context has exactly the same clip. Reuse if possible.
if (context.fixedPosition.clip == cssClip->parent()) { if (context.fixedPosition.clip == cssClip->parent()) {
context.fixedPosition.clip = cssClip; context.fixedPosition.clip = cssClip;
} else {
updateOrCreatePaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::cssClipFixedPosition, &ObjectPaintProperties::setCssClipFixedPosition>(
object, context, context.fixedPosition.clip, const_cast<TransformPaintPropertyNode*>(cssClip->localTransformSpace()), cssClip->clipRect());
return; return;
} }
RefPtr<ClipPaintPropertyNode> clipFixedPosition = ClipPaintPropertyNode::create(
const_cast<TransformPaintPropertyNode*>(cssClip->localTransformSpace()),
cssClip->clipRect(),
context.fixedPosition.clip);
context.fixedPosition.clip = clipFixedPosition.get();
object.getMutableForPainting().ensureObjectPaintProperties().setCssClipFixedPosition(clipFixedPosition.release());
} }
clearPaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::setCssClipFixedPosition>(object);
} }
static void deriveBorderBoxFromContainerContext(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) static void deriveBorderBoxFromContainerContext(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
...@@ -385,8 +400,6 @@ static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain ...@@ -385,8 +400,6 @@ static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain
void PaintPropertyTreeBuilder::buildTreeNodes(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) void PaintPropertyTreeBuilder::buildTreeNodes(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{ {
object.getMutableForPainting().clearObjectPaintProperties();
if (!object.isBoxModelObject() && !object.isSVG()) if (!object.isBoxModelObject() && !object.isSVG())
return; return;
......
...@@ -15,6 +15,7 @@ namespace blink { ...@@ -15,6 +15,7 @@ namespace blink {
class FrameView; class FrameView;
class LayoutObject; class LayoutObject;
class ObjectPaintProperties;
// The context for PaintPropertyTreeBuilder. // The context for PaintPropertyTreeBuilder.
// It's responsible for bookkeeping tree state in other order, for example, the most recent // It's responsible for bookkeeping tree state in other order, for example, the most recent
...@@ -67,6 +68,16 @@ public: ...@@ -67,6 +68,16 @@ public:
void buildTreeNodes(const LayoutObject&, PaintPropertyTreeBuilderContext&); void buildTreeNodes(const LayoutObject&, PaintPropertyTreeBuilderContext&);
private: private:
template <typename PropertyNode, void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>)>
static void clearPaintProperty(const LayoutObject&);
template <
typename PropertyNode,
PropertyNode* (ObjectPaintProperties::*Getter)() const,
void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>),
typename... Args>
static void updateOrCreatePaintProperty(const LayoutObject&, const PaintPropertyTreeBuilderContext&, PropertyNode*& contextProperty, const Args&...);
static void updatePaintOffsetTranslation(const LayoutObject&, PaintPropertyTreeBuilderContext&); static void updatePaintOffsetTranslation(const LayoutObject&, PaintPropertyTreeBuilderContext&);
static void updateTransform(const LayoutObject&, PaintPropertyTreeBuilderContext&); static void updateTransform(const LayoutObject&, PaintPropertyTreeBuilderContext&);
static void updateEffect(const LayoutObject&, PaintPropertyTreeBuilderContext&); static void updateEffect(const LayoutObject&, PaintPropertyTreeBuilderContext&);
......
...@@ -1109,4 +1109,78 @@ TEST_F(PaintPropertyTreeBuilderTest, SvgPixelSnappingShouldResetPaintOffset) ...@@ -1109,4 +1109,78 @@ TEST_F(PaintPropertyTreeBuilderTest, SvgPixelSnappingShouldResetPaintOffset)
EXPECT_EQ(svgWithTransformProperties->transform(), rectWithTransformProperties->transform()->parent()); EXPECT_EQ(svgWithTransformProperties->transform(), rectWithTransformProperties->transform()->parent());
} }
TEST_F(PaintPropertyTreeBuilderTest, CachedProperties)
{
setBodyInnerHTML(
"<div id='a' style='transform: translate(33px, 44px)'>"
" <div id='b' style='transform: translate(55px, 66px)'>"
" <div id='c' style='transform: translate(77px, 88px)'>C<div>"
" </div>"
"</div>");
Element* a = document().getElementById("a");
ObjectPaintProperties* aProperties = a->layoutObject()->objectPaintProperties();
TransformPaintPropertyNode* aTransformNode = aProperties->transform();
EXPECT_EQ(TransformationMatrix().translate(33, 44), aTransformNode->matrix());
Element* b = document().getElementById("b");
ObjectPaintProperties* bProperties = b->layoutObject()->objectPaintProperties();
TransformPaintPropertyNode* bTransformNode = bProperties->transform();
EXPECT_EQ(TransformationMatrix().translate(55, 66), bTransformNode->matrix());
Element* c = document().getElementById("c");
ObjectPaintProperties* cProperties = c->layoutObject()->objectPaintProperties();
TransformPaintPropertyNode* cTransformNode = cProperties->transform();
EXPECT_EQ(TransformationMatrix().translate(77, 88), cTransformNode->matrix());
// Change transform of b. B's transform node should be a new node with the new value,
// and a and c's transform nodes should be unchanged (with c's parent adjusted).
b->setAttribute(HTMLNames::styleAttr, "transform: translate(111px, 222px)");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(aProperties, a->layoutObject()->objectPaintProperties());
EXPECT_EQ(aTransformNode, aProperties->transform());
EXPECT_EQ(bProperties, b->layoutObject()->objectPaintProperties());
bTransformNode = bProperties->transform();
EXPECT_EQ(TransformationMatrix().translate(111, 222), bTransformNode->matrix());
EXPECT_EQ(aTransformNode, bTransformNode->parent());
EXPECT_EQ(cProperties, c->layoutObject()->objectPaintProperties());
EXPECT_EQ(cTransformNode, cProperties->transform());
EXPECT_EQ(bTransformNode, cTransformNode->parent());
// Remove transform from b. B's transform node should be removed from the tree,
// and a and c's transform nodes should be unchanged (with c's parent adjusted).
b->setAttribute(HTMLNames::styleAttr, "");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(aProperties, a->layoutObject()->objectPaintProperties());
EXPECT_EQ(aTransformNode, aProperties->transform());
EXPECT_EQ(bProperties, b->layoutObject()->objectPaintProperties());
EXPECT_EQ(nullptr, bProperties->transform());
EXPECT_EQ(cProperties, c->layoutObject()->objectPaintProperties());
EXPECT_EQ(cTransformNode, cProperties->transform());
EXPECT_EQ(aTransformNode, cTransformNode->parent());
// Re-add transform to b. B's transform node should be inserted into the tree,
// and a and c's transform nodes should be unchanged (with c's parent adjusted).
b->setAttribute(HTMLNames::styleAttr, "transform: translate(4px, 5px)");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(aProperties, a->layoutObject()->objectPaintProperties());
EXPECT_EQ(aTransformNode, aProperties->transform());
EXPECT_EQ(bProperties, b->layoutObject()->objectPaintProperties());
bTransformNode = bProperties->transform();
EXPECT_EQ(TransformationMatrix().translate(4, 5), bTransformNode->matrix());
EXPECT_EQ(aTransformNode, bTransformNode->parent());
EXPECT_EQ(cProperties, c->layoutObject()->objectPaintProperties());
EXPECT_EQ(cTransformNode, cProperties->transform());
EXPECT_EQ(bTransformNode, cTransformNode->parent());
}
} // namespace blink } // namespace blink
...@@ -37,7 +37,7 @@ gfx::Transform translation(SkMScalar x, SkMScalar y) ...@@ -37,7 +37,7 @@ gfx::Transform translation(SkMScalar x, SkMScalar y)
EffectPaintPropertyNode* dummyRootEffect() EffectPaintPropertyNode* dummyRootEffect()
{ {
DEFINE_STATIC_REF(EffectPaintPropertyNode, node, EffectPaintPropertyNode::create(1.0)); DEFINE_STATIC_REF(EffectPaintPropertyNode, node, EffectPaintPropertyNode::create(nullptr, 1.0));
return node; return node;
} }
...@@ -102,7 +102,7 @@ TEST_F(PaintArtifactCompositorTest, OneTransform) ...@@ -102,7 +102,7 @@ TEST_F(PaintArtifactCompositorTest, OneTransform)
{ {
// A 90 degree clockwise rotation about (100, 100). // A 90 degree clockwise rotation about (100, 100).
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(
TransformationMatrix().rotate(90), FloatPoint3D(100, 100, 0)); nullptr, TransformationMatrix().rotate(90), FloatPoint3D(100, 100, 0));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(transform, nullptr, dummyRootEffect()) artifact.chunk(transform, nullptr, dummyRootEffect())
...@@ -142,9 +142,9 @@ TEST_F(PaintArtifactCompositorTest, TransformCombining) ...@@ -142,9 +142,9 @@ TEST_F(PaintArtifactCompositorTest, TransformCombining)
{ {
// A translation by (5, 5) within a 2x scale about (10, 10). // A translation by (5, 5) within a 2x scale about (10, 10).
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(
TransformationMatrix().scale(2), FloatPoint3D(10, 10, 0)); nullptr, TransformationMatrix().scale(2), FloatPoint3D(10, 10, 0));
RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(
TransformationMatrix().translate(5, 5), FloatPoint3D(), transform1); transform1, TransformationMatrix().translate(5, 5), FloatPoint3D());
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(transform1, nullptr, dummyRootEffect()) artifact.chunk(transform1, nullptr, dummyRootEffect())
...@@ -175,9 +175,9 @@ TEST_F(PaintArtifactCompositorTest, TransformCombining) ...@@ -175,9 +175,9 @@ TEST_F(PaintArtifactCompositorTest, TransformCombining)
TEST_F(PaintArtifactCompositorTest, LayerOriginCancellation) TEST_F(PaintArtifactCompositorTest, LayerOriginCancellation)
{ {
RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(100, 100, 100, 100)); nullptr, nullptr, FloatRoundedRect(100, 100, 100, 100));
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(
TransformationMatrix().scale(2), FloatPoint3D()); nullptr, TransformationMatrix().scale(2), FloatPoint3D());
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(transform, clip, nullptr) artifact.chunk(transform, clip, nullptr)
...@@ -203,7 +203,7 @@ TEST_F(PaintArtifactCompositorTest, LayerOriginCancellation) ...@@ -203,7 +203,7 @@ TEST_F(PaintArtifactCompositorTest, LayerOriginCancellation)
TEST_F(PaintArtifactCompositorTest, OneClip) TEST_F(PaintArtifactCompositorTest, OneClip)
{ {
RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(100, 100, 300, 200)); nullptr, nullptr, FloatRoundedRect(100, 100, 300, 200));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, clip, nullptr) artifact.chunk(nullptr, clip, nullptr)
...@@ -226,9 +226,9 @@ TEST_F(PaintArtifactCompositorTest, OneClip) ...@@ -226,9 +226,9 @@ TEST_F(PaintArtifactCompositorTest, OneClip)
TEST_F(PaintArtifactCompositorTest, NestedClips) TEST_F(PaintArtifactCompositorTest, NestedClips)
{ {
RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(100, 100, 700, 700)); nullptr, nullptr, FloatRoundedRect(100, 100, 700, 700));
RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(200, 200, 700, 100), clip1); clip1, nullptr, FloatRoundedRect(200, 200, 700, 100));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, clip1, dummyRootEffect()) artifact.chunk(nullptr, clip1, dummyRootEffect())
...@@ -289,8 +289,8 @@ TEST_F(PaintArtifactCompositorTest, DeeplyNestedClips) ...@@ -289,8 +289,8 @@ TEST_F(PaintArtifactCompositorTest, DeeplyNestedClips)
Vector<RefPtr<ClipPaintPropertyNode>> clips; Vector<RefPtr<ClipPaintPropertyNode>> clips;
for (unsigned i = 1; i <= 10; i++) { for (unsigned i = 1; i <= 10; i++) {
clips.append(ClipPaintPropertyNode::create( clips.append(ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(5 * i, 0, 100, 200 - 10 * i), clips.isEmpty() ? nullptr : clips.last(),
clips.isEmpty() ? nullptr : clips.last())); nullptr, FloatRoundedRect(5 * i, 0, 100, 200 - 10 * i)));
} }
TestPaintArtifact artifact; TestPaintArtifact artifact;
...@@ -319,11 +319,11 @@ TEST_F(PaintArtifactCompositorTest, DeeplyNestedClips) ...@@ -319,11 +319,11 @@ TEST_F(PaintArtifactCompositorTest, DeeplyNestedClips)
TEST_F(PaintArtifactCompositorTest, SiblingClips) TEST_F(PaintArtifactCompositorTest, SiblingClips)
{ {
RefPtr<ClipPaintPropertyNode> commonClip = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> commonClip = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(0, 0, 800, 600)); nullptr, nullptr, FloatRoundedRect(0, 0, 800, 600));
RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(0, 0, 400, 600), commonClip); commonClip, nullptr, FloatRoundedRect(0, 0, 400, 600));
RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(400, 0, 400, 600), commonClip); commonClip, nullptr, FloatRoundedRect(400, 0, 400, 600));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, clip1, nullptr) artifact.chunk(nullptr, clip1, nullptr)
...@@ -454,7 +454,7 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneTransform) ...@@ -454,7 +454,7 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneTransform)
{ {
// A 90 degree clockwise rotation about (100, 100). // A 90 degree clockwise rotation about (100, 100).
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(
TransformationMatrix().rotate(90), FloatPoint3D(100, 100, 0)); nullptr, TransformationMatrix().rotate(90), FloatPoint3D(100, 100, 0));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(transform, nullptr, dummyRootEffect()) artifact.chunk(transform, nullptr, dummyRootEffect())
...@@ -494,9 +494,9 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformCombining) ...@@ -494,9 +494,9 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformCombining)
{ {
// A translation by (5, 5) within a 2x scale about (10, 10). // A translation by (5, 5) within a 2x scale about (10, 10).
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(
TransformationMatrix().scale(2), FloatPoint3D(10, 10, 0)); nullptr, TransformationMatrix().scale(2), FloatPoint3D(10, 10, 0));
RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(
TransformationMatrix().translate(5, 5), FloatPoint3D(), transform1); transform1, TransformationMatrix().translate(5, 5), FloatPoint3D());
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(transform1, nullptr, dummyRootEffect()) artifact.chunk(transform1, nullptr, dummyRootEffect())
...@@ -530,7 +530,7 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformCombining) ...@@ -530,7 +530,7 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, TransformCombining)
TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip) TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip)
{ {
RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(100, 100, 300, 200)); nullptr, nullptr, FloatRoundedRect(100, 100, 300, 200));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, clip, nullptr) artifact.chunk(nullptr, clip, nullptr)
...@@ -552,9 +552,9 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip) ...@@ -552,9 +552,9 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneClip)
TEST_F(PaintArtifactCompositorTestWithPropertyTrees, NestedClips) TEST_F(PaintArtifactCompositorTestWithPropertyTrees, NestedClips)
{ {
RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(100, 100, 700, 700)); nullptr, nullptr, FloatRoundedRect(100, 100, 700, 700));
RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(200, 200, 700, 100), clip1); clip1, nullptr, FloatRoundedRect(200, 200, 700, 100));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, clip1, dummyRootEffect()) artifact.chunk(nullptr, clip1, dummyRootEffect())
...@@ -608,8 +608,8 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, DeeplyNestedClips) ...@@ -608,8 +608,8 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, DeeplyNestedClips)
Vector<RefPtr<ClipPaintPropertyNode>> clips; Vector<RefPtr<ClipPaintPropertyNode>> clips;
for (unsigned i = 1; i <= 10; i++) { for (unsigned i = 1; i <= 10; i++) {
clips.append(ClipPaintPropertyNode::create( clips.append(ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(5 * i, 0, 100, 200 - 10 * i), clips.isEmpty() ? nullptr : clips.last(),
clips.isEmpty() ? nullptr : clips.last())); nullptr, FloatRoundedRect(5 * i, 0, 100, 200 - 10 * i)));
} }
TestPaintArtifact artifact; TestPaintArtifact artifact;
...@@ -638,11 +638,11 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, DeeplyNestedClips) ...@@ -638,11 +638,11 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, DeeplyNestedClips)
TEST_F(PaintArtifactCompositorTestWithPropertyTrees, SiblingClips) TEST_F(PaintArtifactCompositorTestWithPropertyTrees, SiblingClips)
{ {
RefPtr<ClipPaintPropertyNode> commonClip = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> commonClip = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(0, 0, 800, 600)); nullptr, nullptr, FloatRoundedRect(0, 0, 800, 600));
RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(0, 0, 400, 600), commonClip); commonClip, nullptr, FloatRoundedRect(0, 0, 400, 600));
RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(400, 0, 400, 600), commonClip); commonClip, nullptr, FloatRoundedRect(400, 0, 400, 600));
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, clip1, dummyRootEffect()) artifact.chunk(nullptr, clip1, dummyRootEffect())
...@@ -695,9 +695,9 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, ForeignLayerPassesThrough) ...@@ -695,9 +695,9 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, ForeignLayerPassesThrough)
TEST_F(PaintArtifactCompositorTestWithPropertyTrees, EffectTreeConversion) TEST_F(PaintArtifactCompositorTestWithPropertyTrees, EffectTreeConversion)
{ {
RefPtr<EffectPaintPropertyNode> effect1 = EffectPaintPropertyNode::create(0.5, dummyRootEffect()); RefPtr<EffectPaintPropertyNode> effect1 = EffectPaintPropertyNode::create(dummyRootEffect(), 0.5);
RefPtr<EffectPaintPropertyNode> effect2 = EffectPaintPropertyNode::create(0.3, effect1.get()); RefPtr<EffectPaintPropertyNode> effect2 = EffectPaintPropertyNode::create(effect1, 0.3);
RefPtr<EffectPaintPropertyNode> effect3 = EffectPaintPropertyNode::create(0.2, dummyRootEffect()); RefPtr<EffectPaintPropertyNode> effect3 = EffectPaintPropertyNode::create(dummyRootEffect(), 0.2);
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, nullptr, effect2.get()) artifact.chunk(nullptr, nullptr, effect2.get())
......
...@@ -17,16 +17,23 @@ ...@@ -17,16 +17,23 @@
namespace blink { namespace blink {
// A clip rect created by a css property such as "overflow" or "clip". // A clip rect created by a css property such as "overflow" or "clip".
// Along with a refernce to the transform space the clip rect is based on, // Along with a reference to the transform space the clip rect is based on,
// and an (optional) parent ClipPaintPropertyNode for inherited clips. // and an (optional) parent ClipPaintPropertyNode for inherited clips.
class PLATFORM_EXPORT ClipPaintPropertyNode : public RefCounted<ClipPaintPropertyNode> { class PLATFORM_EXPORT ClipPaintPropertyNode : public RefCounted<ClipPaintPropertyNode> {
public: public:
static PassRefPtr<ClipPaintPropertyNode> create( static PassRefPtr<ClipPaintPropertyNode> create(
PassRefPtr<ClipPaintPropertyNode> parent,
PassRefPtr<TransformPaintPropertyNode> localTransformSpace, PassRefPtr<TransformPaintPropertyNode> localTransformSpace,
const FloatRoundedRect& clipRect, const FloatRoundedRect& clipRect)
PassRefPtr<ClipPaintPropertyNode> parent = nullptr)
{ {
return adoptRef(new ClipPaintPropertyNode(localTransformSpace, clipRect, parent)); return adoptRef(new ClipPaintPropertyNode(parent, localTransformSpace, clipRect));
}
void update(PassRefPtr<ClipPaintPropertyNode> parent, PassRefPtr<TransformPaintPropertyNode> localTransformSpace, const FloatRoundedRect& clipRect)
{
m_parent = parent;
m_localTransformSpace = localTransformSpace;
m_clipRect = clipRect;
} }
const TransformPaintPropertyNode* localTransformSpace() const { return m_localTransformSpace.get(); } const TransformPaintPropertyNode* localTransformSpace() const { return m_localTransformSpace.get(); }
...@@ -36,12 +43,12 @@ public: ...@@ -36,12 +43,12 @@ public:
const ClipPaintPropertyNode* parent() const { return m_parent.get(); } const ClipPaintPropertyNode* parent() const { return m_parent.get(); }
private: private:
ClipPaintPropertyNode(PassRefPtr<TransformPaintPropertyNode> localTransformSpace, const FloatRoundedRect& clipRect, PassRefPtr<ClipPaintPropertyNode> parent) ClipPaintPropertyNode(PassRefPtr<ClipPaintPropertyNode> parent, PassRefPtr<TransformPaintPropertyNode> localTransformSpace, const FloatRoundedRect& clipRect)
: m_localTransformSpace(localTransformSpace), m_clipRect(clipRect), m_parent(parent) { } : m_parent(parent), m_localTransformSpace(localTransformSpace), m_clipRect(clipRect) { }
RefPtr<TransformPaintPropertyNode> m_localTransformSpace;
const FloatRoundedRect m_clipRect;
RefPtr<ClipPaintPropertyNode> m_parent; RefPtr<ClipPaintPropertyNode> m_parent;
RefPtr<TransformPaintPropertyNode> m_localTransformSpace;
FloatRoundedRect m_clipRect;
}; };
// Redeclared here to avoid ODR issues. // Redeclared here to avoid ODR issues.
......
...@@ -19,9 +19,15 @@ namespace blink { ...@@ -19,9 +19,15 @@ namespace blink {
// TODO(pdr): Support more effects than just opacity. // TODO(pdr): Support more effects than just opacity.
class PLATFORM_EXPORT EffectPaintPropertyNode : public RefCounted<EffectPaintPropertyNode> { class PLATFORM_EXPORT EffectPaintPropertyNode : public RefCounted<EffectPaintPropertyNode> {
public: public:
static PassRefPtr<EffectPaintPropertyNode> create(float opacity, PassRefPtr<EffectPaintPropertyNode> parent = nullptr) static PassRefPtr<EffectPaintPropertyNode> create(PassRefPtr<EffectPaintPropertyNode> parent, float opacity)
{ {
return adoptRef(new EffectPaintPropertyNode(opacity, parent)); return adoptRef(new EffectPaintPropertyNode(parent, opacity));
}
void update(PassRefPtr<EffectPaintPropertyNode> parent, float opacity)
{
m_parent = parent;
m_opacity = opacity;
} }
float opacity() const { return m_opacity; } float opacity() const { return m_opacity; }
...@@ -30,11 +36,11 @@ public: ...@@ -30,11 +36,11 @@ public:
const EffectPaintPropertyNode* parent() const { return m_parent.get(); } const EffectPaintPropertyNode* parent() const { return m_parent.get(); }
private: private:
EffectPaintPropertyNode(float opacity, PassRefPtr<EffectPaintPropertyNode> parent) EffectPaintPropertyNode(PassRefPtr<EffectPaintPropertyNode> parent, float opacity)
: m_opacity(opacity), m_parent(parent) { } : m_parent(parent), m_opacity(opacity) { }
const float m_opacity;
RefPtr<EffectPaintPropertyNode> m_parent; RefPtr<EffectPaintPropertyNode> m_parent;
float m_opacity;
}; };
// Redeclared here to avoid ODR issues. // Redeclared here to avoid ODR issues.
......
...@@ -35,9 +35,9 @@ public: ...@@ -35,9 +35,9 @@ public:
private: private:
void SetUp() override void SetUp() override
{ {
rootTransformNode = TransformPaintPropertyNode::create(TransformationMatrix(), FloatPoint3D(), nullptr); rootTransformNode = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(), FloatPoint3D());
rootClipNode = ClipPaintPropertyNode::create(rootTransformNode, FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr); rootClipNode = ClipPaintPropertyNode::create(nullptr, rootTransformNode, FloatRoundedRect(LayoutRect::infiniteIntRect()));
rootEffectNode = EffectPaintPropertyNode::create(1.0, nullptr); rootEffectNode = EffectPaintPropertyNode::create(nullptr, 1.0);
geometryMapper = wrapUnique(new GeometryMapper()); geometryMapper = wrapUnique(new GeometryMapper());
} }
...@@ -80,7 +80,7 @@ TEST_F(GeometryMapperTest, Root) ...@@ -80,7 +80,7 @@ TEST_F(GeometryMapperTest, Root)
TEST_F(GeometryMapperTest, IdentityTransform) TEST_F(GeometryMapperTest, IdentityTransform)
{ {
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(TransformationMatrix(), FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, TransformationMatrix(), FloatPoint3D());
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.transform = transform.get(); localState.transform = transform.get();
...@@ -93,7 +93,7 @@ TEST_F(GeometryMapperTest, TranslationTransform) ...@@ -93,7 +93,7 @@ TEST_F(GeometryMapperTest, TranslationTransform)
{ {
TransformationMatrix transformMatrix; TransformationMatrix transformMatrix;
transformMatrix.translate(20, 10); transformMatrix.translate(20, 10);
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(transformMatrix, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, transformMatrix, FloatPoint3D());
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.transform = transform.get(); localState.transform = transform.get();
...@@ -113,7 +113,7 @@ TEST_F(GeometryMapperTest, RotationAndScaleTransform) ...@@ -113,7 +113,7 @@ TEST_F(GeometryMapperTest, RotationAndScaleTransform)
TransformationMatrix transformMatrix; TransformationMatrix transformMatrix;
transformMatrix.rotate(45); transformMatrix.rotate(45);
transformMatrix.scale(2); transformMatrix.scale(2);
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(transformMatrix, FloatPoint3D(0, 0, 0), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, transformMatrix, FloatPoint3D(0, 0, 0));
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.transform = transform.get(); localState.transform = transform.get();
...@@ -128,7 +128,7 @@ TEST_F(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) ...@@ -128,7 +128,7 @@ TEST_F(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin)
TransformationMatrix transformMatrix; TransformationMatrix transformMatrix;
transformMatrix.rotate(45); transformMatrix.rotate(45);
transformMatrix.scale(2); transformMatrix.scale(2);
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(transformMatrix, FloatPoint3D(50, 50, 0), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, transformMatrix, FloatPoint3D(50, 50, 0));
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.transform = transform.get(); localState.transform = transform.get();
...@@ -143,11 +143,11 @@ TEST_F(GeometryMapperTest, NestedTransforms) ...@@ -143,11 +143,11 @@ TEST_F(GeometryMapperTest, NestedTransforms)
{ {
TransformationMatrix rotateTransform; TransformationMatrix rotateTransform;
rotateTransform.rotate(45); rotateTransform.rotate(45);
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D());
TransformationMatrix scaleTransform; TransformationMatrix scaleTransform;
scaleTransform.scale(2); scaleTransform.scale(2);
RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(scaleTransform, FloatPoint3D(), transform1); RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(transform1, scaleTransform, FloatPoint3D());
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.transform = transform2.get(); localState.transform = transform2.get();
...@@ -166,11 +166,11 @@ TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) ...@@ -166,11 +166,11 @@ TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination)
{ {
TransformationMatrix rotateTransform; TransformationMatrix rotateTransform;
rotateTransform.rotate(45); rotateTransform.rotate(45);
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D());
TransformationMatrix scaleTransform; TransformationMatrix scaleTransform;
scaleTransform.scale(2); scaleTransform.scale(2);
RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(scaleTransform, FloatPoint3D(), transform1); RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(transform1, scaleTransform, FloatPoint3D());
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.transform = transform2.get(); localState.transform = transform2.get();
...@@ -186,7 +186,7 @@ TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) ...@@ -186,7 +186,7 @@ TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination)
TEST_F(GeometryMapperTest, SimpleClip) TEST_F(GeometryMapperTest, SimpleClip)
{ {
RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootTransformNode, FloatRoundedRect(10, 10, 50, 50), rootClipNode); RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipNode, rootTransformNode, FloatRoundedRect(10, 10, 50, 50));
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.clip = clip.get(); localState.clip = clip.get();
...@@ -207,9 +207,9 @@ TEST_F(GeometryMapperTest, ClipBeforeTransform) ...@@ -207,9 +207,9 @@ TEST_F(GeometryMapperTest, ClipBeforeTransform)
{ {
TransformationMatrix rotateTransform; TransformationMatrix rotateTransform;
rotateTransform.rotate(45); rotateTransform.rotate(45);
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D());
RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(transform.get(), FloatRoundedRect(10, 10, 50, 50), rootClipNode); RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipNode, transform.get(), FloatRoundedRect(10, 10, 50, 50));
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.clip = clip.get(); localState.clip = clip.get();
...@@ -233,9 +233,9 @@ TEST_F(GeometryMapperTest, ClipAfterTransform) ...@@ -233,9 +233,9 @@ TEST_F(GeometryMapperTest, ClipAfterTransform)
{ {
TransformationMatrix rotateTransform; TransformationMatrix rotateTransform;
rotateTransform.rotate(45); rotateTransform.rotate(45);
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D());
RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200), rootClipNode); RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipNode, rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200));
PropertyTreeState localState = rootPropertyTreeState(); PropertyTreeState localState = rootPropertyTreeState();
localState.clip = clip.get(); localState.clip = clip.get();
...@@ -257,13 +257,13 @@ TEST_F(GeometryMapperTest, ClipAfterTransform) ...@@ -257,13 +257,13 @@ TEST_F(GeometryMapperTest, ClipAfterTransform)
TEST_F(GeometryMapperTest, TwoClipsWithTransformBetween) TEST_F(GeometryMapperTest, TwoClipsWithTransformBetween)
{ {
RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200), rootClipNode); RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(rootClipNode, rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200));
TransformationMatrix rotateTransform; TransformationMatrix rotateTransform;
rotateTransform.rotate(45); rotateTransform.rotate(45);
RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D());
RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(transform.get(), FloatRoundedRect(10, 10, 200, 200), clip1.get()); RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(clip1, transform.get(), FloatRoundedRect(10, 10, 200, 200));
FloatRect input(0, 0, 100, 100); FloatRect input(0, 0, 100, 100);
...@@ -317,11 +317,11 @@ TEST_F(GeometryMapperTest, SiblingTransforms) ...@@ -317,11 +317,11 @@ TEST_F(GeometryMapperTest, SiblingTransforms)
// These transforms are siblings. Thus mapping from one to the other requires going through the root. // These transforms are siblings. Thus mapping from one to the other requires going through the root.
TransformationMatrix rotateTransform1; TransformationMatrix rotateTransform1;
rotateTransform1.rotate(45); rotateTransform1.rotate(45);
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rotateTransform1, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform1, FloatPoint3D());
TransformationMatrix rotateTransform2; TransformationMatrix rotateTransform2;
rotateTransform2.rotate(-45); rotateTransform2.rotate(-45);
RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(rotateTransform2, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, rotateTransform2, FloatPoint3D());
PropertyTreeState transform1State = rootPropertyTreeState(); PropertyTreeState transform1State = rootPropertyTreeState();
transform1State.transform = transform1; transform1State.transform = transform1;
......
...@@ -120,10 +120,10 @@ TEST_F(PaintArtifactToSkCanvasTest, TransformCombining) ...@@ -120,10 +120,10 @@ TEST_F(PaintArtifactToSkCanvasTest, TransformCombining)
TransformationMatrix matrix1; TransformationMatrix matrix1;
matrix1.scale(2); matrix1.scale(2);
FloatPoint3D origin1(10, 10, 0); FloatPoint3D origin1(10, 10, 0);
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(matrix1, origin1); RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(nullptr, matrix1, origin1);
TransformationMatrix matrix2; TransformationMatrix matrix2;
matrix2.translate(5, 5); matrix2.translate(5, 5);
RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(matrix2, FloatPoint3D(), transform1.get()); RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::create(transform1, matrix2, FloatPoint3D());
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(transform1.get(), nullptr, nullptr) artifact.chunk(transform1.get(), nullptr, nullptr)
...@@ -147,8 +147,8 @@ TEST_F(PaintArtifactToSkCanvasTest, OpacityEffectsCombining) ...@@ -147,8 +147,8 @@ TEST_F(PaintArtifactToSkCanvasTest, OpacityEffectsCombining)
} }
// Build an opacity effect tree. // Build an opacity effect tree.
RefPtr<EffectPaintPropertyNode> opacityEffect1 = EffectPaintPropertyNode::create(0.5); RefPtr<EffectPaintPropertyNode> opacityEffect1 = EffectPaintPropertyNode::create(nullptr, 0.5);
RefPtr<EffectPaintPropertyNode> opacityEffect2 = EffectPaintPropertyNode::create(0.25, opacityEffect1); RefPtr<EffectPaintPropertyNode> opacityEffect2 = EffectPaintPropertyNode::create(opacityEffect1, 0.25);
TestPaintArtifact artifact; TestPaintArtifact artifact;
artifact.chunk(nullptr, nullptr, opacityEffect1.get()) artifact.chunk(nullptr, nullptr, opacityEffect1.get())
...@@ -181,10 +181,10 @@ TEST_F(PaintArtifactToSkCanvasTest, ChangingOpacityEffects) ...@@ -181,10 +181,10 @@ TEST_F(PaintArtifactToSkCanvasTest, ChangingOpacityEffects)
// 0.1 a c 0.3 // 0.1 a c 0.3
// | | // | |
// 0.2 b d 0.4 // 0.2 b d 0.4
RefPtr<EffectPaintPropertyNode> opacityEffectA = EffectPaintPropertyNode::create(0.1); RefPtr<EffectPaintPropertyNode> opacityEffectA = EffectPaintPropertyNode::create(nullptr, 0.1);
RefPtr<EffectPaintPropertyNode> opacityEffectB = EffectPaintPropertyNode::create(0.2, opacityEffectA); RefPtr<EffectPaintPropertyNode> opacityEffectB = EffectPaintPropertyNode::create(opacityEffectA, 0.2);
RefPtr<EffectPaintPropertyNode> opacityEffectC = EffectPaintPropertyNode::create(0.3); RefPtr<EffectPaintPropertyNode> opacityEffectC = EffectPaintPropertyNode::create(nullptr, 0.3);
RefPtr<EffectPaintPropertyNode> opacityEffectD = EffectPaintPropertyNode::create(0.4, opacityEffectC); RefPtr<EffectPaintPropertyNode> opacityEffectD = EffectPaintPropertyNode::create(opacityEffectC, 0.4);
// Build a two-chunk artifact directly. // Build a two-chunk artifact directly.
// chunk1 references opacity node b, chunk2 references opacity node d. // chunk1 references opacity node b, chunk2 references opacity node d.
...@@ -220,13 +220,13 @@ TEST_F(PaintArtifactToSkCanvasTest, ClipWithScrollEscaping) ...@@ -220,13 +220,13 @@ TEST_F(PaintArtifactToSkCanvasTest, ClipWithScrollEscaping)
// Setup transform tree. // Setup transform tree.
RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create( RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::create(
TransformationMatrix().translate(0, -100), FloatPoint3D()); nullptr, TransformationMatrix().translate(0, -100), FloatPoint3D());
// Setup clip tree. // Setup clip tree.
RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
transform1.get(), FloatRoundedRect(100, 200, 100, 100)); nullptr, transform1.get(), FloatRoundedRect(100, 200, 100, 100));
RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create( RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(
nullptr, FloatRoundedRect(150, 150, 100, 100), clip1.get()); clip1, nullptr, FloatRoundedRect(150, 150, 100, 100));
MockCanvas canvas(kCanvasWidth, kCanvasHeight); MockCanvas canvas(kCanvasWidth, kCanvasHeight);
......
...@@ -108,13 +108,13 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) ...@@ -108,13 +108,13 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging)
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransform; PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); simpleTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform); chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties anotherTransform; PaintChunkProperties anotherTransform;
anotherTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); anotherTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(nullptr, anotherTransform); chunker.updateCurrentPaintChunkProperties(nullptr, anotherTransform);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
...@@ -133,21 +133,21 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) ...@@ -133,21 +133,21 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges)
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransform; PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 0, 0, 0, 0, 0), FloatPoint3D(9, 8, 7)); simpleTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 0, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform); chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransformAndEffect; PaintChunkProperties simpleTransformAndEffect;
simpleTransformAndEffect.transform = simpleTransform.transform; simpleTransformAndEffect.transform = simpleTransform.transform;
simpleTransformAndEffect.effect = EffectPaintPropertyNode::create(0.5f); simpleTransformAndEffect.effect = EffectPaintPropertyNode::create(nullptr, 0.5f);
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffect); chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffect);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransformAndEffectWithUpdatedTransform; PaintChunkProperties simpleTransformAndEffectWithUpdatedTransform;
simpleTransformAndEffectWithUpdatedTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(1, 1, 0, 0, 0, 0), FloatPoint3D(9, 8, 7)); simpleTransformAndEffectWithUpdatedTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(1, 1, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
simpleTransformAndEffectWithUpdatedTransform.effect = EffectPaintPropertyNode::create(simpleTransformAndEffect.effect->opacity()); simpleTransformAndEffectWithUpdatedTransform.effect = EffectPaintPropertyNode::create(nullptr, simpleTransformAndEffect.effect->opacity());
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffectWithUpdatedTransform); chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffectWithUpdatedTransform);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
...@@ -177,7 +177,7 @@ TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms) ...@@ -177,7 +177,7 @@ TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms)
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransform; PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); simpleTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform); chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
...@@ -201,11 +201,11 @@ TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) ...@@ -201,11 +201,11 @@ TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems)
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties firstTransform; PaintChunkProperties firstTransform;
firstTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); firstTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(nullptr, firstTransform); chunker.updateCurrentPaintChunkProperties(nullptr, firstTransform);
PaintChunkProperties secondTransform; PaintChunkProperties secondTransform;
secondTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1)); secondTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1));
chunker.updateCurrentPaintChunkProperties(nullptr, secondTransform); chunker.updateCurrentPaintChunkProperties(nullptr, secondTransform);
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
...@@ -263,7 +263,7 @@ TEST_F(PaintChunkerTest, ChunkIds) ...@@ -263,7 +263,7 @@ TEST_F(PaintChunkerTest, ChunkIds)
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransform; PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); simpleTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform); chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform);
chunker.incrementDisplayItemIndex(i1); chunker.incrementDisplayItemIndex(i1);
...@@ -296,7 +296,7 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) ...@@ -296,7 +296,7 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache)
chunker.incrementDisplayItemIndex(NormalTestDisplayItem()); chunker.incrementDisplayItemIndex(NormalTestDisplayItem());
PaintChunkProperties simpleTransform; PaintChunkProperties simpleTransform;
simpleTransform.transform = TransformPaintPropertyNode::create(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); simpleTransform.transform = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform); chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform);
chunker.incrementDisplayItemIndex(i1); chunker.incrementDisplayItemIndex(i1);
......
...@@ -27,20 +27,20 @@ public: ...@@ -27,20 +27,20 @@ public:
private: private:
void SetUp() override void SetUp() override
{ {
rootTransformNode = TransformPaintPropertyNode::create(TransformationMatrix(), FloatPoint3D(), nullptr); rootTransformNode = TransformPaintPropertyNode::create(nullptr, TransformationMatrix(), FloatPoint3D());
rootClipNode = ClipPaintPropertyNode::create(rootTransformNode, FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr); rootClipNode = ClipPaintPropertyNode::create(nullptr, rootTransformNode, FloatRoundedRect(LayoutRect::infiniteIntRect()));
rootEffectNode = EffectPaintPropertyNode::create(1.0, nullptr); rootEffectNode = EffectPaintPropertyNode::create(nullptr, 1.0);
} }
}; };
TEST_F(PropertyTreeStateTest, LeastCommonAncestor) TEST_F(PropertyTreeStateTest, LeastCommonAncestor)
{ {
TransformationMatrix matrix; TransformationMatrix matrix;
RefPtr<TransformPaintPropertyNode> child1 = TransformPaintPropertyNode::create(matrix, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> child1 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, matrix, FloatPoint3D());
RefPtr<TransformPaintPropertyNode> child2 = TransformPaintPropertyNode::create(matrix, FloatPoint3D(), rootPropertyTreeState().transform); RefPtr<TransformPaintPropertyNode> child2 = TransformPaintPropertyNode::create(rootPropertyTreeState().transform, matrix, FloatPoint3D());
RefPtr<TransformPaintPropertyNode> childOfChild1 = TransformPaintPropertyNode::create(matrix, FloatPoint3D(), child1); RefPtr<TransformPaintPropertyNode> childOfChild1 = TransformPaintPropertyNode::create(child1, matrix, FloatPoint3D());
RefPtr<TransformPaintPropertyNode> childOfChild2 = TransformPaintPropertyNode::create(matrix, FloatPoint3D(), child2); RefPtr<TransformPaintPropertyNode> childOfChild2 = TransformPaintPropertyNode::create(child2, matrix, FloatPoint3D());
EXPECT_EQ(rootPropertyTreeState().transform, propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(childOfChild1.get(), childOfChild2.get())); EXPECT_EQ(rootPropertyTreeState().transform, propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(childOfChild1.get(), childOfChild2.get()));
EXPECT_EQ(rootPropertyTreeState().transform, propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(childOfChild1.get(), child2.get())); EXPECT_EQ(rootPropertyTreeState().transform, propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(childOfChild1.get(), child2.get()));
......
...@@ -21,9 +21,16 @@ namespace blink { ...@@ -21,9 +21,16 @@ namespace blink {
// for the root. // for the root.
class PLATFORM_EXPORT TransformPaintPropertyNode : public RefCounted<TransformPaintPropertyNode> { class PLATFORM_EXPORT TransformPaintPropertyNode : public RefCounted<TransformPaintPropertyNode> {
public: public:
static PassRefPtr<TransformPaintPropertyNode> create(const TransformationMatrix& matrix, const FloatPoint3D& origin, PassRefPtr<TransformPaintPropertyNode> parent = nullptr) static PassRefPtr<TransformPaintPropertyNode> create(PassRefPtr<TransformPaintPropertyNode> parent, const TransformationMatrix& matrix, const FloatPoint3D& origin)
{ {
return adoptRef(new TransformPaintPropertyNode(matrix, origin, parent)); return adoptRef(new TransformPaintPropertyNode(parent, matrix, origin));
}
void update(PassRefPtr<TransformPaintPropertyNode> parent, const TransformationMatrix& matrix, const FloatPoint3D& origin)
{
m_parent = parent;
m_matrix = matrix;
m_origin = origin;
} }
const TransformationMatrix& matrix() const { return m_matrix; } const TransformationMatrix& matrix() const { return m_matrix; }
...@@ -34,13 +41,12 @@ public: ...@@ -34,13 +41,12 @@ public:
TransformPaintPropertyNode* parent() const { return m_parent.get(); } TransformPaintPropertyNode* parent() const { return m_parent.get(); }
private: private:
TransformPaintPropertyNode(PassRefPtr<TransformPaintPropertyNode> parent, const TransformationMatrix& matrix, const FloatPoint3D& origin)
: m_parent(parent), m_matrix(matrix), m_origin(origin) { }
TransformPaintPropertyNode(const TransformationMatrix& matrix, const FloatPoint3D& origin, PassRefPtr<TransformPaintPropertyNode> parent)
: m_matrix(matrix), m_origin(origin), m_parent(parent) { }
const TransformationMatrix m_matrix;
const FloatPoint3D m_origin;
RefPtr<TransformPaintPropertyNode> m_parent; RefPtr<TransformPaintPropertyNode> m_parent;
TransformationMatrix m_matrix;
FloatPoint3D m_origin;
}; };
// Redeclared here to avoid ODR issues. // Redeclared here to avoid ODR issues.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment