Commit 78f6bee5 authored by chrishtr's avatar chrishtr Committed by Commit bot

Set a direct compositing reason for 3D transform paint property tree nodes.

As part of this, starts allocating a transform node to represent direct
compositing of will-change:transform elements and their stacking children.

BUG=668342
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2

Review-Url: https://codereview.chromium.org/2571043002
Cr-Commit-Position: refs/heads/master@{#438771}
parent 0ffae0a7
...@@ -79,6 +79,7 @@ Bug(none) xmlviewer/ [ Skip ] ...@@ -79,6 +79,7 @@ Bug(none) xmlviewer/ [ Skip ]
Bug(none) broadcastchannel/blobs.html [ Pass Failure ] Bug(none) broadcastchannel/blobs.html [ Pass Failure ]
Bug(none) compositing/3d-cube.html [ Failure ] Bug(none) compositing/3d-cube.html [ Failure ]
Bug(none) compositing/absolute-inside-out-of-view-fixed.html [ Failure ] Bug(none) compositing/absolute-inside-out-of-view-fixed.html [ Failure ]
crbug.com/668342 compositing/always-composite-fixed-position-when-descendants-composite.html [ Failure ]
Bug(none) compositing/animation/hidden-composited.html [ Failure ] Bug(none) compositing/animation/hidden-composited.html [ Failure ]
Bug(none) compositing/backface-visibility/backface-visibility-image.html [ Failure ] Bug(none) compositing/backface-visibility/backface-visibility-image.html [ Failure ]
Bug(none) compositing/backface-visibility/backface-visibility-webgl.html [ Failure ] Bug(none) compositing/backface-visibility/backface-visibility-webgl.html [ Failure ]
......
...@@ -74,7 +74,7 @@ CompositingReasonFinder::potentialCompositingReasonsFromStyle( ...@@ -74,7 +74,7 @@ CompositingReasonFinder::potentialCompositingReasonsFromStyle(
const ComputedStyle& style = layoutObject->styleRef(); const ComputedStyle& style = layoutObject->styleRef();
if (requiresCompositingForTransform(layoutObject)) if (requiresCompositingForTransform(*layoutObject))
reasons |= CompositingReason3DTransform; reasons |= CompositingReason3DTransform;
if (style.backfaceVisibility() == BackfaceVisibilityHidden) if (style.backfaceVisibility() == BackfaceVisibilityHidden)
...@@ -132,12 +132,12 @@ CompositingReasonFinder::potentialCompositingReasonsFromStyle( ...@@ -132,12 +132,12 @@ CompositingReasonFinder::potentialCompositingReasonsFromStyle(
} }
bool CompositingReasonFinder::requiresCompositingForTransform( bool CompositingReasonFinder::requiresCompositingForTransform(
LayoutObject* layoutObject) const { const LayoutObject& layoutObject) {
// Note that we ask the layoutObject if it has a transform, because the style // Note that we ask the layoutObject if it has a transform, because the style
// may have transforms, but the layoutObject may be an inline that doesn't // may have transforms, but the layoutObject may be an inline that doesn't
// support them. // support them.
return layoutObject->hasTransformRelatedProperty() && return layoutObject.hasTransformRelatedProperty() &&
layoutObject->style()->has3DTransform(); layoutObject.styleRef().has3DTransform();
} }
CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons( CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(
...@@ -171,7 +171,7 @@ CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons( ...@@ -171,7 +171,7 @@ CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(
} }
bool CompositingReasonFinder::requiresCompositingForAnimation( bool CompositingReasonFinder::requiresCompositingForAnimation(
const ComputedStyle& style) const { const ComputedStyle& style) {
if (style.subtreeWillChangeContents()) if (style.subtreeWillChangeContents())
return style.isRunningAnimationOnCompositor(); return style.isRunningAnimationOnCompositor();
......
...@@ -31,14 +31,13 @@ class CompositingReasonFinder { ...@@ -31,14 +31,13 @@ class CompositingReasonFinder {
bool hasOverflowScrollTrigger() const; bool hasOverflowScrollTrigger() const;
bool requiresCompositingForScrollableFrame() const; bool requiresCompositingForScrollableFrame() const;
bool requiresCompositingForAnimation(const ComputedStyle&) const; static bool requiresCompositingForAnimation(const ComputedStyle&);
static bool requiresCompositingForTransform(const LayoutObject&);
private: private:
bool isMainFrame() const; bool isMainFrame() const;
CompositingReasons nonStyleDeterminedDirectReasons(const PaintLayer*) const; CompositingReasons nonStyleDeterminedDirectReasons(const PaintLayer*) const;
bool requiresCompositingForTransform(LayoutObject*) const;
bool requiresCompositingForScrollDependentPosition(const PaintLayer*) const; bool requiresCompositingForScrollDependentPosition(const PaintLayer*) const;
LayoutView& m_layoutView; LayoutView& m_layoutView;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "core/frame/Settings.h" #include "core/frame/Settings.h"
#include "core/layout/LayoutInline.h" #include "core/layout/LayoutInline.h"
#include "core/layout/LayoutView.h" #include "core/layout/LayoutView.h"
#include "core/layout/compositing/CompositingReasonFinder.h"
#include "core/layout/svg/LayoutSVGRoot.h" #include "core/layout/svg/LayoutSVGRoot.h"
#include "core/paint/FindPropertiesNeedingUpdate.h" #include "core/paint/FindPropertiesNeedingUpdate.h"
#include "core/paint/ObjectPaintProperties.h" #include "core/paint/ObjectPaintProperties.h"
...@@ -312,6 +313,19 @@ void PaintPropertyTreeBuilder::updateTransformForNonRootSVG( ...@@ -312,6 +313,19 @@ void PaintPropertyTreeBuilder::updateTransformForNonRootSVG(
} }
} }
static CompositingReasons compositingReasonsForTransform(
const LayoutObject& object) {
CompositingReasons compositingReasons = CompositingReasonNone;
if (CompositingReasonFinder::requiresCompositingForTransform(object))
compositingReasons |= CompositingReason3DTransform;
if (object.styleRef().hasWillChangeCompositingHint() &&
!object.styleRef().subtreeWillChangeContents())
compositingReasons |= CompositingReasonWillChangeCompositingHint;
return compositingReasons;
}
void PaintPropertyTreeBuilder::updateTransform( void PaintPropertyTreeBuilder::updateTransform(
const LayoutObject& object, const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) { PaintPropertyTreeBuilderContext& context) {
...@@ -322,7 +336,16 @@ void PaintPropertyTreeBuilder::updateTransform( ...@@ -322,7 +336,16 @@ void PaintPropertyTreeBuilder::updateTransform(
if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) { if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) {
const ComputedStyle& style = object.styleRef(); const ComputedStyle& style = object.styleRef();
if (object.isBox() && (style.hasTransform() || style.preserves3D())) {
CompositingReasons compositingReasons =
compositingReasonsForTransform(object);
// A transform node is allocated for transforms, preserves-3d and any
// direct compositing reason. The latter is required because this is the
// only way to represent compositing both an element and its stacking
// descendants.
if (object.isBox() && (style.hasTransform() || style.preserves3D() ||
compositingReasons != CompositingReasonNone)) {
TransformationMatrix matrix; TransformationMatrix matrix;
style.applyTransform( style.applyTransform(
matrix, toLayoutBox(object).size(), matrix, toLayoutBox(object).size(),
...@@ -342,7 +365,8 @@ void PaintPropertyTreeBuilder::updateTransform( ...@@ -342,7 +365,8 @@ void PaintPropertyTreeBuilder::updateTransform(
context.forceSubtreeUpdate |= properties.updateTransform( context.forceSubtreeUpdate |= properties.updateTransform(
context.current.transform, matrix, context.current.transform, matrix,
transformOrigin(toLayoutBox(object)), transformOrigin(toLayoutBox(object)),
context.current.shouldFlattenInheritedTransform, renderingContextID); context.current.shouldFlattenInheritedTransform, renderingContextID,
compositingReasons);
} else { } else {
if (auto* properties = object.getMutableForPainting().paintProperties()) if (auto* properties = object.getMutableForPainting().paintProperties())
context.forceSubtreeUpdate |= properties->clearTransform(); context.forceSubtreeUpdate |= properties->clearTransform();
......
...@@ -334,7 +334,12 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) { ...@@ -334,7 +334,12 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
} }
TEST_P(PaintPropertyTreeBuilderTest, Transform) { TEST_P(PaintPropertyTreeBuilderTest, Transform) {
loadTestData("transform.html"); setBodyInnerHTML(
"<style> body { margin: 0 } </style>"
"<div id='transform' style='margin-left: 50px; margin-top: 100px;"
" width: 400px; height: 300px;"
" transform: translate3D(123px, 456px, 789px)'>"
"</div>");
Element* transform = document().getElementById("transform"); Element* transform = document().getElementById("transform");
const ObjectPaintProperties* transformProperties = const ObjectPaintProperties* transformProperties =
...@@ -349,9 +354,86 @@ TEST_P(PaintPropertyTreeBuilderTest, Transform) { ...@@ -349,9 +354,86 @@ TEST_P(PaintPropertyTreeBuilderTest, Transform) {
transformProperties->paintOffsetTranslation()->matrix()); transformProperties->paintOffsetTranslation()->matrix());
EXPECT_EQ(frameScrollTranslation(), EXPECT_EQ(frameScrollTranslation(),
transformProperties->paintOffsetTranslation()->parent()); transformProperties->paintOffsetTranslation()->parent());
EXPECT_TRUE(transformProperties->transform()->hasDirectCompositingReasons());
EXPECT_FALSE(frameScrollTranslation()->hasDirectCompositingReasons());
CHECK_EXACT_VISUAL_RECT(LayoutRect(173, 556, 400, 300), CHECK_EXACT_VISUAL_RECT(LayoutRect(173, 556, 400, 300),
transform->layoutObject(), transform->layoutObject(),
document().view()->layoutView()); document().view()->layoutView());
transform->setAttribute(
HTMLNames::styleAttr,
"margin-left: 50px; margin-top: 100px; width: 400px; height: 300px;");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(nullptr, transform->layoutObject()->paintProperties()->transform());
transform->setAttribute(
HTMLNames::styleAttr,
"margin-left: 50px; margin-top: 100px; width: 400px; height: 300px; "
"transform: translate3D(123px, 456px, 789px)");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(
TransformationMatrix().translate3d(123, 456, 789),
transform->layoutObject()->paintProperties()->transform()->matrix());
}
TEST_P(PaintPropertyTreeBuilderTest, WillChangeTransform) {
setBodyInnerHTML(
"<style> body { margin: 0 } </style>"
"<div id='transform' style='margin-left: 50px; margin-top: 100px;"
" width: 400px; height: 300px;"
" will-change: transform'>"
"</div>");
Element* transform = document().getElementById("transform");
const ObjectPaintProperties* transformProperties =
transform->layoutObject()->paintProperties();
EXPECT_EQ(TransformationMatrix(), transformProperties->transform()->matrix());
EXPECT_EQ(FloatPoint3D(200, 150, 0),
transformProperties->transform()->origin());
EXPECT_EQ(nullptr, transformProperties->paintOffsetTranslation());
EXPECT_TRUE(transformProperties->transform()->hasDirectCompositingReasons());
CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 400, 300),
transform->layoutObject(),
document().view()->layoutView());
transform->setAttribute(
HTMLNames::styleAttr,
"margin-left: 50px; margin-top: 100px; width: 400px; height: 300px;");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(nullptr, transform->layoutObject()->paintProperties()->transform());
transform->setAttribute(
HTMLNames::styleAttr,
"margin-left: 50px; margin-top: 100px; width: 400px; height: 300px; "
"will-change: transform");
document().view()->updateAllLifecyclePhases();
EXPECT_EQ(
TransformationMatrix(),
transform->layoutObject()->paintProperties()->transform()->matrix());
}
TEST_P(PaintPropertyTreeBuilderTest, WillChangeContents) {
setBodyInnerHTML(
"<style> body { margin: 0 } </style>"
"<div id='transform' style='margin-left: 50px; margin-top: 100px;"
" width: 400px; height: 300px;"
" will-change: transform, contents'>"
"</div>");
Element* transform = document().getElementById("transform");
const ObjectPaintProperties* transformProperties =
transform->layoutObject()->paintProperties();
EXPECT_EQ(nullptr, transformProperties->transform());
EXPECT_EQ(nullptr, transformProperties->paintOffsetTranslation());
CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 400, 300),
transform->layoutObject(),
document().view()->layoutView());
} }
TEST_P(PaintPropertyTreeBuilderTest, RelativePositionInline) { TEST_P(PaintPropertyTreeBuilderTest, RelativePositionInline) {
......
<style>
body {
margin: 0;
}
#transform {
margin-left: 50px;
margin-top: 100px;
width: 400px;
height: 300px;
transform: translate3D(123px, 456px, 789px);
}
</style>
<div id="transform">
</div>
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "platform/PlatformExport.h" #include "platform/PlatformExport.h"
#include "platform/geometry/FloatPoint3D.h" #include "platform/geometry/FloatPoint3D.h"
#include "platform/graphics/CompositingReasons.h"
#include "platform/transforms/TransformationMatrix.h" #include "platform/transforms/TransformationMatrix.h"
#include "wtf/PassRefPtr.h" #include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h" #include "wtf/RefCounted.h"
...@@ -32,17 +33,20 @@ class PLATFORM_EXPORT TransformPaintPropertyNode ...@@ -32,17 +33,20 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
const TransformationMatrix& matrix, const TransformationMatrix& matrix,
const FloatPoint3D& origin, const FloatPoint3D& origin,
bool flattensInheritedTransform = false, bool flattensInheritedTransform = false,
unsigned renderingContextID = 0) { unsigned renderingContextID = 0,
CompositingReasons directCompositingReasons = CompositingReasonNone) {
return adoptRef(new TransformPaintPropertyNode( return adoptRef(new TransformPaintPropertyNode(
matrix, origin, std::move(parent), flattensInheritedTransform, matrix, origin, std::move(parent), flattensInheritedTransform,
renderingContextID)); renderingContextID, directCompositingReasons));
} }
void update(PassRefPtr<const TransformPaintPropertyNode> parent, void update(
const TransformationMatrix& matrix, PassRefPtr<const TransformPaintPropertyNode> parent,
const FloatPoint3D& origin, const TransformationMatrix& matrix,
bool flattensInheritedTransform = false, const FloatPoint3D& origin,
unsigned renderingContextID = 0) { bool flattensInheritedTransform = false,
unsigned renderingContextID = 0,
CompositingReasons directCompositingReasons = CompositingReasonNone) {
DCHECK(!isRoot()); DCHECK(!isRoot());
DCHECK(parent != this); DCHECK(parent != this);
m_parent = parent; m_parent = parent;
...@@ -50,6 +54,7 @@ class PLATFORM_EXPORT TransformPaintPropertyNode ...@@ -50,6 +54,7 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
m_origin = origin; m_origin = origin;
m_flattensInheritedTransform = flattensInheritedTransform; m_flattensInheritedTransform = flattensInheritedTransform;
m_renderingContextID = renderingContextID; m_renderingContextID = renderingContextID;
m_directCompositingReasons = directCompositingReasons;
} }
const TransformationMatrix& matrix() const { return m_matrix; } const TransformationMatrix& matrix() const { return m_matrix; }
...@@ -67,6 +72,10 @@ class PLATFORM_EXPORT TransformPaintPropertyNode ...@@ -67,6 +72,10 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
return m_flattensInheritedTransform; return m_flattensInheritedTransform;
} }
bool hasDirectCompositingReasons() const {
return m_directCompositingReasons != CompositingReasonNone;
}
// Content whose transform nodes have a common rendering context ID are 3D // Content whose transform nodes have a common rendering context ID are 3D
// sorted. If this is 0, content will not be 3D sorted. // sorted. If this is 0, content will not be 3D sorted.
unsigned renderingContextID() const { return m_renderingContextID; } unsigned renderingContextID() const { return m_renderingContextID; }
...@@ -76,9 +85,9 @@ class PLATFORM_EXPORT TransformPaintPropertyNode ...@@ -76,9 +85,9 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
// The clone function is used by FindPropertiesNeedingUpdate.h for recording // The clone function is used by FindPropertiesNeedingUpdate.h for recording
// a transform node before it has been updated, to later detect changes. // a transform node before it has been updated, to later detect changes.
PassRefPtr<TransformPaintPropertyNode> clone() const { PassRefPtr<TransformPaintPropertyNode> clone() const {
return adoptRef(new TransformPaintPropertyNode(m_matrix, m_origin, m_parent, return adoptRef(new TransformPaintPropertyNode(
m_flattensInheritedTransform, m_matrix, m_origin, m_parent, m_flattensInheritedTransform,
m_renderingContextID)); m_renderingContextID, m_directCompositingReasons));
} }
// The equality operator is used by FindPropertiesNeedingUpdate.h for checking // The equality operator is used by FindPropertiesNeedingUpdate.h for checking
...@@ -99,18 +108,21 @@ class PLATFORM_EXPORT TransformPaintPropertyNode ...@@ -99,18 +108,21 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
const FloatPoint3D& origin, const FloatPoint3D& origin,
PassRefPtr<const TransformPaintPropertyNode> parent, PassRefPtr<const TransformPaintPropertyNode> parent,
bool flattensInheritedTransform, bool flattensInheritedTransform,
unsigned renderingContextID) unsigned renderingContextID,
CompositingReasons directCompositingReasons)
: m_matrix(matrix), : m_matrix(matrix),
m_origin(origin), m_origin(origin),
m_parent(parent), m_parent(parent),
m_flattensInheritedTransform(flattensInheritedTransform), m_flattensInheritedTransform(flattensInheritedTransform),
m_renderingContextID(renderingContextID) {} m_renderingContextID(renderingContextID),
m_directCompositingReasons(directCompositingReasons) {}
TransformationMatrix m_matrix; TransformationMatrix m_matrix;
FloatPoint3D m_origin; FloatPoint3D m_origin;
RefPtr<const TransformPaintPropertyNode> m_parent; RefPtr<const TransformPaintPropertyNode> m_parent;
bool m_flattensInheritedTransform; bool m_flattensInheritedTransform;
unsigned m_renderingContextID; unsigned m_renderingContextID;
CompositingReasons m_directCompositingReasons;
}; };
// 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