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 ]
Bug(none) broadcastchannel/blobs.html [ Pass Failure ]
Bug(none) compositing/3d-cube.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/backface-visibility/backface-visibility-image.html [ Failure ]
Bug(none) compositing/backface-visibility/backface-visibility-webgl.html [ Failure ]
......
......@@ -74,7 +74,7 @@ CompositingReasonFinder::potentialCompositingReasonsFromStyle(
const ComputedStyle& style = layoutObject->styleRef();
if (requiresCompositingForTransform(layoutObject))
if (requiresCompositingForTransform(*layoutObject))
reasons |= CompositingReason3DTransform;
if (style.backfaceVisibility() == BackfaceVisibilityHidden)
......@@ -132,12 +132,12 @@ CompositingReasonFinder::potentialCompositingReasonsFromStyle(
}
bool CompositingReasonFinder::requiresCompositingForTransform(
LayoutObject* layoutObject) const {
const LayoutObject& layoutObject) {
// 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
// support them.
return layoutObject->hasTransformRelatedProperty() &&
layoutObject->style()->has3DTransform();
return layoutObject.hasTransformRelatedProperty() &&
layoutObject.styleRef().has3DTransform();
}
CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(
......@@ -171,7 +171,7 @@ CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(
}
bool CompositingReasonFinder::requiresCompositingForAnimation(
const ComputedStyle& style) const {
const ComputedStyle& style) {
if (style.subtreeWillChangeContents())
return style.isRunningAnimationOnCompositor();
......
......@@ -31,14 +31,13 @@ class CompositingReasonFinder {
bool hasOverflowScrollTrigger() const;
bool requiresCompositingForScrollableFrame() const;
bool requiresCompositingForAnimation(const ComputedStyle&) const;
static bool requiresCompositingForAnimation(const ComputedStyle&);
static bool requiresCompositingForTransform(const LayoutObject&);
private:
bool isMainFrame() const;
CompositingReasons nonStyleDeterminedDirectReasons(const PaintLayer*) const;
bool requiresCompositingForTransform(LayoutObject*) const;
bool requiresCompositingForScrollDependentPosition(const PaintLayer*) const;
LayoutView& m_layoutView;
......
......@@ -9,6 +9,7 @@
#include "core/frame/Settings.h"
#include "core/layout/LayoutInline.h"
#include "core/layout/LayoutView.h"
#include "core/layout/compositing/CompositingReasonFinder.h"
#include "core/layout/svg/LayoutSVGRoot.h"
#include "core/paint/FindPropertiesNeedingUpdate.h"
#include "core/paint/ObjectPaintProperties.h"
......@@ -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(
const LayoutObject& object,
PaintPropertyTreeBuilderContext& context) {
......@@ -322,7 +336,16 @@ void PaintPropertyTreeBuilder::updateTransform(
if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) {
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;
style.applyTransform(
matrix, toLayoutBox(object).size(),
......@@ -342,7 +365,8 @@ void PaintPropertyTreeBuilder::updateTransform(
context.forceSubtreeUpdate |= properties.updateTransform(
context.current.transform, matrix,
transformOrigin(toLayoutBox(object)),
context.current.shouldFlattenInheritedTransform, renderingContextID);
context.current.shouldFlattenInheritedTransform, renderingContextID,
compositingReasons);
} else {
if (auto* properties = object.getMutableForPainting().paintProperties())
context.forceSubtreeUpdate |= properties->clearTransform();
......
......@@ -334,7 +334,12 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
}
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");
const ObjectPaintProperties* transformProperties =
......@@ -349,9 +354,86 @@ TEST_P(PaintPropertyTreeBuilderTest, Transform) {
transformProperties->paintOffsetTranslation()->matrix());
EXPECT_EQ(frameScrollTranslation(),
transformProperties->paintOffsetTranslation()->parent());
EXPECT_TRUE(transformProperties->transform()->hasDirectCompositingReasons());
EXPECT_FALSE(frameScrollTranslation()->hasDirectCompositingReasons());
CHECK_EXACT_VISUAL_RECT(LayoutRect(173, 556, 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; "
"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) {
......
<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 @@
#include "platform/PlatformExport.h"
#include "platform/geometry/FloatPoint3D.h"
#include "platform/graphics/CompositingReasons.h"
#include "platform/transforms/TransformationMatrix.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
......@@ -32,17 +33,20 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
const TransformationMatrix& matrix,
const FloatPoint3D& origin,
bool flattensInheritedTransform = false,
unsigned renderingContextID = 0) {
unsigned renderingContextID = 0,
CompositingReasons directCompositingReasons = CompositingReasonNone) {
return adoptRef(new TransformPaintPropertyNode(
matrix, origin, std::move(parent), flattensInheritedTransform,
renderingContextID));
renderingContextID, directCompositingReasons));
}
void update(PassRefPtr<const TransformPaintPropertyNode> parent,
const TransformationMatrix& matrix,
const FloatPoint3D& origin,
bool flattensInheritedTransform = false,
unsigned renderingContextID = 0) {
void update(
PassRefPtr<const TransformPaintPropertyNode> parent,
const TransformationMatrix& matrix,
const FloatPoint3D& origin,
bool flattensInheritedTransform = false,
unsigned renderingContextID = 0,
CompositingReasons directCompositingReasons = CompositingReasonNone) {
DCHECK(!isRoot());
DCHECK(parent != this);
m_parent = parent;
......@@ -50,6 +54,7 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
m_origin = origin;
m_flattensInheritedTransform = flattensInheritedTransform;
m_renderingContextID = renderingContextID;
m_directCompositingReasons = directCompositingReasons;
}
const TransformationMatrix& matrix() const { return m_matrix; }
......@@ -67,6 +72,10 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
return m_flattensInheritedTransform;
}
bool hasDirectCompositingReasons() const {
return m_directCompositingReasons != CompositingReasonNone;
}
// Content whose transform nodes have a common rendering context ID are 3D
// sorted. If this is 0, content will not be 3D sorted.
unsigned renderingContextID() const { return m_renderingContextID; }
......@@ -76,9 +85,9 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
// The clone function is used by FindPropertiesNeedingUpdate.h for recording
// a transform node before it has been updated, to later detect changes.
PassRefPtr<TransformPaintPropertyNode> clone() const {
return adoptRef(new TransformPaintPropertyNode(m_matrix, m_origin, m_parent,
m_flattensInheritedTransform,
m_renderingContextID));
return adoptRef(new TransformPaintPropertyNode(
m_matrix, m_origin, m_parent, m_flattensInheritedTransform,
m_renderingContextID, m_directCompositingReasons));
}
// The equality operator is used by FindPropertiesNeedingUpdate.h for checking
......@@ -99,18 +108,21 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
const FloatPoint3D& origin,
PassRefPtr<const TransformPaintPropertyNode> parent,
bool flattensInheritedTransform,
unsigned renderingContextID)
unsigned renderingContextID,
CompositingReasons directCompositingReasons)
: m_matrix(matrix),
m_origin(origin),
m_parent(parent),
m_flattensInheritedTransform(flattensInheritedTransform),
m_renderingContextID(renderingContextID) {}
m_renderingContextID(renderingContextID),
m_directCompositingReasons(directCompositingReasons) {}
TransformationMatrix m_matrix;
FloatPoint3D m_origin;
RefPtr<const TransformPaintPropertyNode> m_parent;
bool m_flattensInheritedTransform;
unsigned m_renderingContextID;
CompositingReasons m_directCompositingReasons;
};
// 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