Commit 059ec54f authored by George Steel's avatar George Steel Committed by Commit Bot

Composite relative transform animations (behind a flag)

Begin development on compositing transform animations with relative
keyframes (with translate operations using percents), eliminating the
restriction that keyframes nust be absolute. This takes the approach of
converting keyframes for the compositor by evaluating lengths on the
current box size of the element under animation. Invalidation to deal
with changes in box size will be added in future patches before the
CompositeRelativeKeyframes flag is enabled.

Add a virtual test suite to run transform animation tests with using
this code path.

Design doc: https://docs.google.com/document/d/1zgr5CHRMpvlqodn1e0eM9J3MjL2eEMfAHrHsZUK7gMM/

Bug: 389359
Change-Id: I9ad764e1206acf7a599e32b28f35626df186747d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2477673
Commit-Queue: George Steel <gtsteel@chromium.org>
Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#819022}
parent 913d85d5
......@@ -42,8 +42,10 @@
#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/paint/filter_effect_builder.h"
......@@ -59,6 +61,7 @@
#include "third_party/blink/renderer/platform/animation/compositor_transform_animation_curve.h"
#include "third_party/blink/renderer/platform/animation/compositor_transform_keyframe.h"
#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
......@@ -235,12 +238,14 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
case CSSPropertyID::kScale:
case CSSPropertyID::kTranslate:
case CSSPropertyID::kTransform:
if (keyframe->GetCompositorKeyframeValue() &&
To<CompositorKeyframeTransform>(
keyframe->GetCompositorKeyframeValue())
->GetTransformOperations()
.BoxSizeDependencies()) {
reasons |= kTransformRelatedPropertyDependsOnBoxSize;
if (!RuntimeEnabledFeatures::CompositeRelativeKeyframesEnabled()) {
if (keyframe->GetCompositorKeyframeValue() &&
To<CompositorKeyframeTransform>(
keyframe->GetCompositorKeyframeValue())
->GetTransformOperations()
.BoxSizeDependencies()) {
reasons |= kTransformRelatedPropertyDependsOnBoxSize;
}
}
break;
case CSSPropertyID::kFilter:
......@@ -624,19 +629,22 @@ void AddKeyframeToCurve(CompositorColorAnimationCurve& curve,
void AddKeyframeToCurve(CompositorTransformAnimationCurve& curve,
Keyframe::PropertySpecificKeyframe* keyframe,
const CompositorKeyframeValue* value,
const TimingFunction& keyframe_timing_function) {
const TimingFunction& keyframe_timing_function,
const FloatSize& box_size) {
CompositorTransformOperations ops;
ToCompositorTransformOperations(
To<CompositorKeyframeTransform>(value)->GetTransformOperations(), &ops);
To<CompositorKeyframeTransform>(value)->GetTransformOperations(), &ops,
box_size);
CompositorTransformKeyframe transform_keyframe(
keyframe->Offset(), std::move(ops), keyframe_timing_function);
curve.AddKeyframe(transform_keyframe);
}
template <typename PlatformAnimationCurveType>
template <typename PlatformAnimationCurveType, typename... Args>
void AddKeyframesToCurve(PlatformAnimationCurveType& curve,
const PropertySpecificKeyframeVector& keyframes) {
const PropertySpecificKeyframeVector& keyframes,
Args... parameters) {
Keyframe::PropertySpecificKeyframe* last_keyframe = keyframes.back();
for (const auto& keyframe : keyframes) {
const TimingFunction* keyframe_timing_function = nullptr;
......@@ -648,7 +656,8 @@ void AddKeyframesToCurve(PlatformAnimationCurveType& curve,
const CompositorKeyframeValue* value =
keyframe->GetCompositorKeyframeValue();
AddKeyframeToCurve(curve, keyframe, value, *keyframe_timing_function);
AddKeyframeToCurve(curve, keyframe, value, *keyframe_timing_function,
parameters...);
}
}
......@@ -714,10 +723,16 @@ void CompositorAnimations::GetAnimationOnCompositor(
case CSSPropertyID::kScale:
case CSSPropertyID::kTranslate:
case CSSPropertyID::kTransform: {
FloatSize box_size;
if (RuntimeEnabledFeatures::CompositeRelativeKeyframesEnabled()) {
box_size = ComputedStyleUtils::ReferenceBoxForTransform(
*target_element.GetLayoutObject())
.Size();
}
target_property = compositor_target_property::TRANSFORM;
auto transform_curve =
std::make_unique<CompositorTransformAnimationCurve>();
AddKeyframesToCurve(*transform_curve, values);
AddKeyframesToCurve(*transform_curve, values, box_size);
transform_curve->SetTimingFunction(*timing.timing_function);
transform_curve->SetScaledDuration(scale);
curve = std::move(transform_curve);
......
......@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/platform/animation/animation_translation_util.h"
#include "third_party/blink/renderer/platform/animation/compositor_transform_operations.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/transforms/interpolated_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/matrix_transform_operation.h"
......@@ -40,7 +41,8 @@ namespace blink {
void ToCompositorTransformOperations(
const TransformOperations& transform_operations,
CompositorTransformOperations* out_transform_operations) {
CompositorTransformOperations* out_transform_operations,
const FloatSize& box_size) {
// We need to do a deep copy the transformOperations may contain ref pointers
// to TransformOperation objects.
for (const auto& operation : transform_operations.Operations()) {
......@@ -63,9 +65,10 @@ void ToCompositorTransformOperations(
case TransformOperation::kTranslate: {
auto* transform =
static_cast<const TranslateTransformOperation*>(operation.get());
DCHECK(transform->X().IsFixed() && transform->Y().IsFixed());
if (!RuntimeEnabledFeatures::CompositeRelativeKeyframesEnabled())
DCHECK(transform->X().IsFixed() && transform->Y().IsFixed());
out_transform_operations->AppendTranslate(
transform->X().Value(), transform->Y().Value(), transform->Z());
transform->X(box_size), transform->Y(box_size), transform->Z());
break;
}
case TransformOperation::kRotateX:
......@@ -112,7 +115,7 @@ void ToCompositorTransformOperations(
case TransformOperation::kRotateAroundOrigin:
case TransformOperation::kInterpolated: {
TransformationMatrix m;
operation->Apply(m, FloatSize());
operation->Apply(m, box_size);
out_transform_operations->AppendMatrix(
TransformationMatrix::ToSkMatrix44(m));
break;
......
......@@ -37,10 +37,12 @@ namespace blink {
class CompositorTransformOperations;
class TransformOperations;
class FloatSize;
PLATFORM_EXPORT void ToCompositorTransformOperations(
const TransformOperations& in_operations,
CompositorTransformOperations* out_operations);
CompositorTransformOperations* out_operations,
const FloatSize& box_size);
} // namespace blink
......
......@@ -25,8 +25,10 @@
#include "third_party/blink/renderer/platform/animation/animation_translation_util.h"
#include <memory>
#include "cc/test/geometry_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/animation/compositor_transform_operations.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/rotate_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/scale_transform_operation.h"
......@@ -45,7 +47,7 @@ TEST(AnimationTranslationUtilTest, transformsWork) {
0.1, 0.2, 0.3, 200000.4, TransformOperation::kRotate3D));
ops.Operations().push_back(ScaleTransformOperation::Create(
50.2, 100, -4, TransformOperation::kScale3D));
ToCompositorTransformOperations(ops, &out_ops);
ToCompositorTransformOperations(ops, &out_ops, FloatSize());
EXPECT_EQ(3UL, out_ops.AsCcTransformOperations().size());
const float kErr = 0.0001;
......@@ -70,4 +72,46 @@ TEST(AnimationTranslationUtilTest, transformsWork) {
EXPECT_NEAR(op2.scale.z, -4.0f, kErr);
}
TEST(AnimationTranslationUtilTest, RelativeTranslate) {
ScopedCompositeRelativeKeyframesForTest relative_keyframes(true);
TransformOperations ops;
ops.Operations().push_back(TranslateTransformOperation::Create(
Length::Percent(50), Length::Percent(50),
TransformOperation::kTranslate));
CompositorTransformOperations out_ops;
ToCompositorTransformOperations(ops, &out_ops, FloatSize(200, 100));
ASSERT_EQ(out_ops.AsCcTransformOperations().size(), 1u);
auto& op0 = out_ops.AsCcTransformOperations().at(0);
EXPECT_EQ(cc::TransformOperation::TRANSFORM_OPERATION_TRANSLATE, op0.type);
EXPECT_EQ(op0.translate.x, 100.0f);
EXPECT_EQ(op0.translate.y, 50.0f);
EXPECT_EQ(op0.translate.z, 0.0f);
}
TEST(AnimationTranslationUtilTest, RelativeInterpolated) {
ScopedCompositeRelativeKeyframesForTest relative_keyframes(true);
TransformOperations ops_a, ops_b;
ops_a.Operations().push_back(TranslateTransformOperation::Create(
Length::Percent(50), Length::Fixed(0), TransformOperation::kTranslate));
ops_b.Operations().push_back(
RotateTransformOperation::Create(3600, TransformOperation::kRotate));
TransformOperations ops_c = ops_b.Blend(ops_a, 0.5);
CompositorTransformOperations out_ops;
ToCompositorTransformOperations(ops_c, &out_ops, FloatSize(100, 100));
ASSERT_EQ(out_ops.AsCcTransformOperations().size(), 1u);
auto& op0 = out_ops.AsCcTransformOperations().at(0);
cc::TransformOperations ops_expected;
ops_expected.AppendTranslate(25, 0, 0);
EXPECT_EQ(cc::TransformOperation::TRANSFORM_OPERATION_MATRIX, op0.type);
cc::ExpectTransformationMatrixNear(op0.matrix, ops_expected.at(0).matrix,
1e-6f);
}
} // namespace blink
......@@ -344,6 +344,9 @@
name: "CompositedSelectionUpdate",
status: {"Android": "stable"},
},
{
name: "CompositeRelativeKeyframes",
},
{
name: "CompositeSVG",
status: "experimental",
......
......@@ -6410,6 +6410,13 @@ crbug.com/1083605 media/controls-styling-strict.html [ Pass Failure ]
crbug.com/1133901 virtual/threaded/external/wpt/css/css-transforms/animation/transform-interpolation-translate-em.html [ Failure ]
crbug.com/1131252 virtual/threaded/external/wpt/css/css-transforms/animation/transform-interpolation-skew.html [ Failure ]
# Composited Transform animations WIP:
# Existing failures
crbug.com/1131252 virtual/composite-relative-keyframes/external/wpt/css/css-transforms/animation/transform-interpolation-skew.html [ Failure ]
crbug.com/1133901 virtual/composite-relative-keyframes/external/wpt/css/css-transforms/animation/transform-interpolation-translate-em.html [ Failure ]
# Failures from incomplete implementation
crbug.com/389359 virtual/composite-relative-keyframes/external/wpt/css/css-transforms/animation/transform-interpolation-translate.html [ Failure ]
crbug.com/1136163 [ Linux ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy_with_pointerlock.html [ Failure ]
# Mixed content autoupgrades make these tests not applicable, since they check for mixed content images, the tests can be removed when cleaning up pre autoupgrades mixed content code.
......
......@@ -60,6 +60,12 @@
"transitions"],
"args": ["--enable-threaded-compositing"]
},
{
"prefix": "composite-relative-keyframes",
"bases": ["external/wpt/css/css-transforms/animation"],
"args": ["--enable-threaded-compositing",
"--enable-blink-features=CompositeRelativeKeyframes"]
},
{
"prefix": "off-main-thread-css-paint",
"bases": ["external/wpt/css/css-paint-api",
......
Tests for compositing transform animations with relative keyframes
(containing percentages), currently in-devellopment behind a flag.
Failures are currently expected due to incomplete invalidation checks.
See design doc at
https://docs.google.com/document/d/1zgr5CHRMpvlqodn1e0eM9J3MjL2eEMfAHrHsZUK7gMM/
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