Commit 04a0c98f authored by George Steel's avatar George Steel Committed by Commit Bot

Fix blend from InterpolatedTransformOperation to none

This particular case was reversing its progress.
Rewrite TransformOperationsTest::InterpolatedTransformBlendIdentityTest
to check interpolation in both directions.

Bug: 1132480
Change-Id: Ib81db414353961acb401b3805417417e1d8073f5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2432761Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Reviewed-by: default avatarIan Vollick <vollick@chromium.org>
Commit-Queue: George Steel <gtsteel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812969}
parent 6ff69d8a
......@@ -2062,6 +2062,7 @@ source_set("blink_platform_unittests_sources") {
"transforms/rotation_test.cc",
"transforms/transform_operations_test.cc",
"transforms/transformation_matrix_test.cc",
"transforms/transformation_matrix_test_helpers.h",
"video_capture/gpu_memory_buffer_test_support.cc",
"video_capture/gpu_memory_buffer_test_support.h",
"video_capture/video_capture_impl_test.cc",
......
......@@ -28,8 +28,6 @@
namespace blink {
class FloatBox;
bool ApproximatelyEqual(const float&, const float&);
namespace float_box_test {
bool ApproximatelyEqual(const float&, const float&);
bool ApproximatelyEqual(const FloatBox&, const FloatBox&);
......
......@@ -63,8 +63,8 @@ scoped_refptr<TransformOperation> InterpolatedTransformOperation::Blend(
to_operations.Operations().push_back(this);
TransformOperations from_operations;
if (blend_to_identity) {
return InterpolatedTransformOperation::Create(
to_operations, from_operations, 0, 1 - progress);
return InterpolatedTransformOperation::Create(to_operations,
from_operations, 0, progress);
}
if (from) {
......
......@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/transform_operations.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
......@@ -101,6 +102,13 @@ class PLATFORM_EXPORT InterpolatedTransformOperation final
double progress_;
};
template <>
struct DowncastTraits<InterpolatedTransformOperation> {
static bool AllowFrom(const TransformOperation& transform) {
return transform.GetType() == TransformOperation::kInterpolated;
}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_INTERPOLATED_TRANSFORM_OPERATION_H_
......@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/platform/transforms/rotate_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/scale_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/skew_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix_test_helpers.h"
#include "third_party/blink/renderer/platform/transforms/translate_transform_operation.h"
namespace blink {
......@@ -570,35 +571,44 @@ TEST(TransformOperationsTest, PerspectiveOpsTest) {
EXPECT_TRUE(ops.HasNonTrivial3DComponent());
}
TEST(TransformOperations, InterpolatedTransformBlendTest) {
// When interpolating transform lists of differing lengths,the length of the
// shorter list is padded with identity transforms. The Blend method accepts a
// null from operator when blending from an identity transform. This test
// verifies the correctness of an interpolated transform when the 'from
// transform' list is shorter than the 'to transform' list (crbug.com/998938).
TransformOperations empt_from, from_ops_padding;
TransformOperations to_ops, to_intrepolated;
double progress = 0.25, abs_difference = 1e-5;
to_ops.Operations().push_back(
ScaleTransformOperation::Create(5, 2, TransformOperation::kScale));
// to_interpolated is scale(2, 1.25)
to_intrepolated.Operations().push_back(
InterpolatedTransformOperation::Create(empt_from, to_ops, 0, progress));
// result is scale(1.25, 1.0625)
TransformOperations result = to_intrepolated.Blend(empt_from, progress);
from_ops_padding.Operations().push_back(TranslateTransformOperation::Create(
Length::Fixed(20), Length::Fixed(20), TransformOperation::kTranslate));
// Pad the from_ops_padding to have at least one operation, otherwise it would
// execute the matching prefix.
FloatPoint3D original_point(64, 64, 4);
FloatPoint3D expected_point(83, 80, 4);
TransformationMatrix blended_transform;
// result is scale(1.0625, 1.015625) and translate(15, 15)
result = result.Blend(from_ops_padding, progress);
result.Apply(FloatSize(), blended_transform);
FloatPoint3D final_point = blended_transform.MapPoint(original_point);
EXPECT_NEAR(expected_point.X(), final_point.X(), abs_difference);
EXPECT_NEAR(expected_point.Y(), final_point.Y(), abs_difference);
EXPECT_NEAR(expected_point.Z(), final_point.Z(), abs_difference);
TEST(TransformOperationsTest, InterpolatedTransformBlendIdentityTest) {
// When interpolating transform lists of differing lengths, the length of the
// shorter list behaves as if it is padded with identity transforms.
// The Blend method accepts a null from operation when blending to/from an
// identity transform, with the direction of interpolation controlled by.
// the blend_to_identity parameter.
// This test verifies the correctness of interpolating between a deferred,
// box-size-dependent matrix interpolation and an empty transform list in
// both directions.
TransformOperations ops_a, ops_b, ops_empty;
ops_a.Operations().push_back(TranslateTransformOperation::Create(
Length::Percent(100), Length::Fixed(0), TransformOperation::kTranslate));
ops_b.Operations().push_back(
RotateTransformOperation::Create(90, TransformOperation::kRotate));
// Equivalent to translateX(50%) rotate(45deg) but a deferred interpolation
TransformOperations ops_c = ops_a.Blend(ops_b, 0.5);
ASSERT_EQ(ops_c.Operations().size(), 1u);
ASSERT_TRUE(IsA<InterpolatedTransformOperation>(*ops_c.Operations()[0]));
// Both should be the same and equal to translateX(12.5%) rotate(11.25deg);
TransformOperations ops_d1 = ops_c.Blend(ops_empty, 0.25);
TransformOperations ops_d2 = ops_empty.Blend(ops_c, 0.75);
TransformOperations ops_d3;
ops_d3.Operations().push_back(TranslateTransformOperation::Create(
Length::Percent(12.5), Length::Fixed(0), TransformOperation::kTranslate));
ops_d3.Operations().push_back(
RotateTransformOperation::Create(11.25, TransformOperation::kRotate));
const FloatSize box_size(100, 100);
TransformationMatrix mat_d1, mat_d2, mat_d3;
ops_d1.Apply(box_size, mat_d1);
ops_d2.Apply(box_size, mat_d2);
ops_d3.Apply(box_size, mat_d3);
EXPECT_TRANSFORMATION_MATRIX(mat_d1, mat_d2);
EXPECT_TRANSFORMATION_MATRIX(mat_d1, mat_d3);
EXPECT_TRANSFORMATION_MATRIX(mat_d2, mat_d3);
}
} // namespace blink
......@@ -4,27 +4,11 @@
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "cc/test/geometry_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "ui/gfx/transform.h"
namespace blink {
// Allow non-zero tolerance when comparing floating point results to
// accommodate precision errors.
const double kFloatingPointErrorTolerance = 1e-6;
#define EXPECT_TRANSFORMATION_MATRIX(expected, actual) \
do { \
SCOPED_TRACE(""); \
cc::ExpectTransformationMatrixNear( \
TransformationMatrix::ToTransform(expected), \
TransformationMatrix::ToTransform(actual), \
kFloatingPointErrorTolerance); \
} while (false)
#define EXPECT_FLOAT(expected, actual) \
EXPECT_NEAR(expected, actual, kFloatingPointErrorTolerance)
TEST(TransformationMatrixTest, NonInvertableBlendTest) {
TransformationMatrix from;
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORMATION_MATRIX_TEST_HELPERS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORMATION_MATRIX_TEST_HELPERS_H_
#include "cc/test/geometry_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/transform.h"
namespace blink {
// Allow non-zero tolerance when comparing floating point results to
// accommodate precision errors.
constexpr double kFloatingPointErrorTolerance = 1e-6;
#define EXPECT_TRANSFORMATION_MATRIX(expected, actual) \
do { \
SCOPED_TRACE(""); \
cc::ExpectTransformationMatrixNear( \
TransformationMatrix::ToTransform(expected), \
TransformationMatrix::ToTransform(actual), \
kFloatingPointErrorTolerance); \
} while (false)
#define EXPECT_FLOAT(expected, actual) \
EXPECT_NEAR(expected, actual, kFloatingPointErrorTolerance)
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORMATION_MATRIX_TEST_HELPERS_H_
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