Commit 32890c69 authored by Manuel Rego Casasnovas's avatar Manuel Rego Casasnovas Committed by Commit Bot

Enable transformed rasterization for trivial 3D transforms

This patch adds a new compositing reason kTrivial3DTransform
separated from k3DTransform, so we can identify trivial 3D transforms.
It modifies CompositingReasonFinder in order to return
kTrivial3DTransform or k3DTransform as compositing reason.

On top of that the patch enables transformed rasterization
for the new compositing reason kTrivial3DTransform.

BUG=1078401
TEST=CompositedLayerMappingTest.TransformedRasterizationForTrivial3DTransform
TEST=CompositingRequirementsUpdaterTest.NonTrivial3DTransforms
TEST=external/wpt/css/css-transforms/subpixel-transform-changes-004.html

Change-Id: I1acb7846af8d86c26474322818bd80c8bde2d031
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2241111Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Manuel Rego <rego@igalia.com>
Cr-Commit-Position: refs/heads/master@{#777899}
parent 52dea420
......@@ -1417,6 +1417,24 @@ TEST_F(CompositedLayerMappingTest,
target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
}
TEST_F(CompositedLayerMappingTest,
TransformedRasterizationForTrivial3DTransform) {
SetBodyInnerHTML(R"HTML(
<div id="target" style="transform: translate3d(0.3px, 0px, 0px);">
Trivial 3D Transform
</div>
)HTML");
LayoutObject* target = GetLayoutObjectByElementId("target");
ASSERT_TRUE(target && target->IsBox());
PaintLayer* target_layer = ToLayoutBox(target)->Layer();
GraphicsLayer* target_graphics_layer =
target_layer ? target_layer->GraphicsLayerBacking() : nullptr;
ASSERT_TRUE(target_graphics_layer);
EXPECT_TRUE(
target_graphics_layer->CcLayer()->transformed_rasterization_allowed());
}
TEST_F(CompositedLayerMappingTest, ScrollingContainerBoundsChange) {
GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
true);
......
......@@ -45,8 +45,7 @@ CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
const ComputedStyle& style = layout_object.StyleRef();
if (RequiresCompositingFor3DTransform(layout_object))
reasons |= CompositingReason::k3DTransform;
reasons |= CompositingReasonsFor3DTransform(layout_object);
if (style.BackfaceVisibility() == EBackfaceVisibility::kHidden)
reasons |= CompositingReason::kBackfaceVisibilityHidden;
......@@ -128,8 +127,7 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
auto reasons = CompositingReasonsForAnimation(object) |
CompositingReasonsForWillChange(style);
if (RequiresCompositingFor3DTransform(object))
reasons |= CompositingReason::k3DTransform;
reasons |= CompositingReasonsFor3DTransform(object);
auto* layer = ToLayoutBoxModelObject(object).Layer();
if (layer->Has3DTransformedDescendant()) {
......@@ -181,19 +179,28 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
return reasons;
}
bool CompositingReasonFinder::RequiresCompositingFor3DTransform(
CompositingReasons CompositingReasonFinder::CompositingReasonsFor3DTransform(
const LayoutObject& layout_object) {
// 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.
if (!layout_object.HasTransformRelatedProperty())
return false;
return CompositingReason::kNone;
// Don't composite "trivial" 3D transforms such as translateZ(0).
if (Platform::Current()->IsLowEndDevice())
return layout_object.StyleRef().HasNonTrivial3DTransformOperation();
if (Platform::Current()->IsLowEndDevice()) {
return layout_object.StyleRef().HasNonTrivial3DTransformOperation()
? CompositingReason::k3DTransform
: CompositingReason::kNone;
}
return layout_object.StyleRef().Has3DTransformOperation();
if (layout_object.StyleRef().Has3DTransformOperation()) {
return layout_object.StyleRef().HasNonTrivial3DTransformOperation()
? CompositingReason::k3DTransform
: CompositingReason::kTrivial3DTransform;
}
return CompositingReason::kNone;
}
CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
......
......@@ -36,7 +36,8 @@ class CORE_EXPORT CompositingReasonFinder {
static CompositingReasons CompositingReasonsForAnimation(const LayoutObject&);
static CompositingReasons CompositingReasonsForWillChange(
const ComputedStyle&);
static bool RequiresCompositingFor3DTransform(const LayoutObject&);
static CompositingReasons CompositingReasonsFor3DTransform(
const LayoutObject&);
static bool RequiresCompositingForRootScroller(const PaintLayer&);
static bool RequiresCompositingForScrollDependentPosition(const PaintLayer&);
......
......@@ -129,7 +129,8 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ToLayoutBox(transform_3d)->Layer()->GetCompositingReasons());
const auto* transform_2d = GetLayoutObjectByElementId("2d-transform");
EXPECT_FALSE(transform_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_TRUE(ToLayoutBox(transform_2d)->Layer()->GetCompositingReasons());
EXPECT_TRUE(CompositingReason::kTrivial3DTransform &
ToLayoutBox(transform_2d)->Layer()->GetCompositingReasons());
const auto* transform_3d_translate_z =
GetLayoutObjectByElementId("3d-transform-translate-z");
......@@ -143,6 +144,7 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
EXPECT_FALSE(
transform_2d_translate_z->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_TRUE(
CompositingReason::kTrivial3DTransform &
ToLayoutBox(transform_2d_translate_z)->Layer()->GetCompositingReasons());
const auto* transform_2d_translate_x =
GetLayoutObjectByElementId("2d-transform-translate-x");
......@@ -157,7 +159,8 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ToLayoutBox(xform_rot_x_3d)->Layer()->GetCompositingReasons());
const auto* xform_rot_x_2d = GetLayoutObjectByElementId("2d-transform-rot-x");
EXPECT_FALSE(xform_rot_x_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_TRUE(ToLayoutBox(xform_rot_x_2d)->Layer()->GetCompositingReasons());
EXPECT_TRUE(CompositingReason::kTrivial3DTransform &
ToLayoutBox(xform_rot_x_2d)->Layer()->GetCompositingReasons());
const auto* xform_rot_z_2d = GetLayoutObjectByElementId("2d-transform-rot-z");
EXPECT_FALSE(xform_rot_z_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_FALSE(ToLayoutBox(xform_rot_z_2d)->Layer()->GetCompositingReasons());
......@@ -168,7 +171,8 @@ TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ToLayoutBox(rotation_y_3d)->Layer()->GetCompositingReasons());
const auto* rotation_y_2d = GetLayoutObjectByElementId("2d-rotation-y");
EXPECT_FALSE(rotation_y_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_TRUE(ToLayoutBox(rotation_y_2d)->Layer()->GetCompositingReasons());
EXPECT_TRUE(CompositingReason::kTrivial3DTransform &
ToLayoutBox(rotation_y_2d)->Layer()->GetCompositingReasons());
const auto* rotation_z_2d = GetLayoutObjectByElementId("2d-rotation-z");
EXPECT_FALSE(rotation_z_2d->StyleRef().HasNonTrivial3DTransformOperation());
EXPECT_FALSE(ToLayoutBox(rotation_z_2d)->Layer()->GetCompositingReasons());
......
......@@ -19,6 +19,8 @@ struct CompositingReasonStringMap {
constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
{CompositingReason::k3DTransform, "transform3D", "Has a 3d transform"},
{CompositingReason::kTrivial3DTransform, "trivialTransform3D",
"Has a trivial 3d transform"},
{CompositingReason::kVideo, "video", "Is an accelerated video"},
{CompositingReason::kCanvas, "canvas",
"Is an accelerated canvas, or is a display list backed canvas that was "
......
......@@ -18,6 +18,7 @@ using CompositingReasons = uint64_t;
#define FOR_EACH_COMPOSITING_REASON(V) \
/* Intrinsic reasons that can be known right away by the layer. */ \
V(3DTransform) \
V(Trivial3DTransform) \
V(Video) \
V(Canvas) \
V(Plugin) \
......@@ -118,9 +119,10 @@ class PLATFORM_EXPORT CompositingReason {
kActiveFilterAnimation | kActiveBackdropFilterAnimation,
kComboAllDirectStyleDeterminedReasons =
k3DTransform | kBackfaceVisibilityHidden | kComboActiveAnimation |
kWillChangeTransform | kWillChangeOpacity | kWillChangeFilter |
kWillChangeOther | kBackdropFilter | kWillChangeBackdropFilter,
k3DTransform | kTrivial3DTransform | kBackfaceVisibilityHidden |
kComboActiveAnimation | kWillChangeTransform | kWillChangeOpacity |
kWillChangeFilter | kWillChangeOther | kBackdropFilter |
kWillChangeBackdropFilter,
kComboAllDirectNonStyleDeterminedReasons =
kVideo | kCanvas | kPlugin | kIFrame | kOverflowScrollingParent |
......@@ -132,7 +134,8 @@ class PLATFORM_EXPORT CompositingReason {
kComboAllDirectNonStyleDeterminedReasons,
kComboTransformedRasterizationDisallowedReasons =
kComboAllDirectReasons & ~kScrollDependentPosition,
kComboAllDirectReasons & ~kScrollDependentPosition &
~kTrivial3DTransform,
kComboAllCompositedScrollingDeterminedReasons =
kScrollDependentPosition | kOverflowScrolling,
......@@ -157,9 +160,9 @@ class PLATFORM_EXPORT CompositingReason {
kScrollDependentPosition | kVideo | kCanvas | kPlugin | kIFrame,
kDirectReasonsForTransformProperty =
k3DTransform | kWillChangeTransform | kWillChangeOther |
kPerspectiveWith3DDescendants | kPreserve3DWith3DDescendants |
kActiveTransformAnimation,
k3DTransform | kTrivial3DTransform | kWillChangeTransform |
kWillChangeOther | kPerspectiveWith3DDescendants |
kPreserve3DWith3DDescendants | kActiveTransformAnimation,
kDirectReasonsForScrollTranslationProperty =
kRootScroller | kOverflowScrolling,
kDirectReasonsForEffectProperty =
......
......@@ -351,7 +351,8 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
}
bool HasDirectCompositingReasonsOtherThan3dTransform() const {
return DirectCompositingReasons() & ~CompositingReason::k3DTransform;
return DirectCompositingReasons() & ~CompositingReason::k3DTransform &
~CompositingReason::kTrivial3DTransform;
}
// TODO(crbug.com/900241): Use HaveActiveTransformAnimation() instead of this
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Transforms Reference Test: Subpixel transform changes trivial 3D</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<div id="translateX1" style="transform: translate3d(0.48px, 0px, 0px);">transform: translate3d(0.48px, 0px, 0px);</div>
<div id="translateX2" style="transform: translate3d(3.17px, 0px, 0px);">transform: translate3d(3.17px, 0px, 0px);</div>
<div id="translateX3" style="transform: translate3d(0.34px, 0px, 0px);">transform: translate3d(0.34px, 0px, 0px);</div>
<div id="translateY1" style="transform: translate3d(0px, 0.48px, 0px);">transform: translate3d(0px, 0.48px, 0px);</div>
<div id="translateY2" style="transform: translate3d(0px, 3.17px, 0px);">transform: translate3d(0px, 3.17px, 0px);</div>
<div id="translateY3" style="transform: translate3d(0px, 0.34px, 0px);">transform: translate3d(0px, 0.34px, 0px);</div>
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="utf-8">
<title>CSS Transforms Test: Subpixel transform changes trivial 3D</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-transforms/#transform-property">
<link rel="match" href="reference/subpixel-transform-changes-004-ref.html">
<meta name="assert" content="Test checks that subpixel transform changes work as expected regardless of trivial 3D transforms.">
<div id="translateX1" style="transform: translate3d(0.12px, 0px, 0px);">transform: translate3d(0.48px, 0px, 0px);</div>
<div id="translateX2" style="transform: translate3d(0.56px, 0px, 0px);">transform: translate3d(3.17px, 0px, 0px);</div>
<div id="translateX3" style="transform: translate3d(1.87px, 0px, 0px);">transform: translate3d(0.34px, 0px, 0px);</div>
<div id="translateY1" style="transform: translate3d(0px, 0.12px, 0px);">transform: translate3d(0px, 0.48px, 0px);</div>
<div id="translateY2" style="transform: translate3d(0px, 0.56px, 0px);">transform: translate3d(0px, 3.17px, 0px);</div>
<div id="translateY3" style="transform: translate3d(0px, 1.87px, 0px);">transform: translate3d(0px, 0.34px, 0px);</div>
<script>
requestAnimationFrame(() => requestAnimationFrame(() => {
translateX1.style.transform = "translate3d(0.48px, 0px, 0px)";
translateX2.style.transform = "translate3d(3.17px, 0px, 0px)";
translateX3.style.transform = "translate3d(0.34px, 0px, 0px)";
translateY1.style.transform = "translate3d(0px, 0.48px, 0px)";
translateY2.style.transform = "translate3d(0px, 3.17px, 0px)";
translateY3.style.transform = "translate3d(0px, 0.34px, 0px)";
document.documentElement.classList.remove("reftest-wait");
}));
</script>
</html>
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