From ef161fb5c19ea0af8fa9a39518c595a006f23648 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Thu, 16 Apr 2020 15:27:41 -0400 Subject: [PATCH] Convert MatrixDecomposition from SkMatrix44 to SkM44 (#17760) * Convert MatrixDecomposition from SkMatrix44 to SkM44 SkMatrix44 is deprecated and being removed. --- flow/matrix_decomposition.cc | 142 ++++++++++--------------- flow/matrix_decomposition.h | 25 +++-- flow/matrix_decomposition_unittests.cc | 120 ++++++++++----------- flow/scene_update_context.cc | 24 ++--- 4 files changed, 142 insertions(+), 169 deletions(-) diff --git a/flow/matrix_decomposition.cc b/flow/matrix_decomposition.cc index 1935393906513..c9bb1ff475da2 100644 --- a/flow/matrix_decomposition.cc +++ b/flow/matrix_decomposition.cc @@ -6,140 +6,114 @@ namespace flutter { -static inline SkVector3 SkVector3Combine(const SkVector3& a, - float a_scale, - const SkVector3& b, - float b_scale) { - return { - a_scale * a.fX + b_scale * b.fX, // - a_scale * a.fY + b_scale * b.fY, // - a_scale * a.fZ + b_scale * b.fZ, // - }; -} - -static inline SkVector3 SkVector3Cross(const SkVector3& a, const SkVector3& b) { - return { - (a.fY * b.fZ) - (a.fZ * b.fY), // - (a.fZ * b.fX) - (a.fX * b.fZ), // - (a.fX * b.fY) - (a.fY * b.fX) // - }; +static inline SkV3 SkV3Combine(const SkV3& a, + float a_scale, + const SkV3& b, + float b_scale) { + return (a * a_scale) + (b * b_scale); } MatrixDecomposition::MatrixDecomposition(const SkMatrix& matrix) - : MatrixDecomposition(SkMatrix44{matrix}) {} + : MatrixDecomposition(SkM44{matrix}) {} // Use custom normalize to avoid skia precision loss/normalize() privatization. -static inline void SkVector3Normalize(SkVector3& v) { - double mag = sqrt(v.fX * v.fX + v.fY * v.fY + v.fZ * v.fZ); +static inline void SkV3Normalize(SkV3& v) { + double mag = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); double scale = 1.0 / mag; - v.fX *= scale; - v.fY *= scale; - v.fZ *= scale; + v.x *= scale; + v.y *= scale; + v.z *= scale; } -MatrixDecomposition::MatrixDecomposition(SkMatrix44 matrix) : valid_(false) { - if (matrix.get(3, 3) == 0) { +MatrixDecomposition::MatrixDecomposition(SkM44 matrix) : valid_(false) { + if (matrix.rc(3, 3) == 0) { return; } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - matrix.set(j, i, matrix.get(j, i) / matrix.get(3, 3)); + matrix.setRC(j, i, matrix.rc(j, i) / matrix.rc(3, 3)); } } - SkMatrix44 perpective_matrix = matrix; + SkM44 perpective_matrix = matrix; for (int i = 0; i < 3; i++) { - perpective_matrix.set(3, i, 0.0); + perpective_matrix.setRC(3, i, 0.0); } - perpective_matrix.set(3, 3, 1.0); + perpective_matrix.setRC(3, 3, 1.0); - if (perpective_matrix.determinant() == 0.0) { + SkM44 inverted(SkM44::Uninitialized_Constructor::kUninitialized_Constructor); + if (!perpective_matrix.invert(&inverted)) { return; } - if (matrix.get(3, 0) != 0.0 || matrix.get(3, 1) != 0.0 || - matrix.get(3, 2) != 0.0) { - const SkVector4 right_hand_side(matrix.get(3, 0), matrix.get(3, 1), - matrix.get(3, 2), matrix.get(3, 3)); - - SkMatrix44 inverted_transposed( - SkMatrix44::Uninitialized_Constructor::kUninitialized_Constructor); - if (!perpective_matrix.invert(&inverted_transposed)) { - return; - } - inverted_transposed.transpose(); + if (matrix.rc(3, 0) != 0.0 || matrix.rc(3, 1) != 0.0 || + matrix.rc(3, 2) != 0.0) { + const SkV4 right_hand_side = matrix.row(3); - perspective_ = inverted_transposed * right_hand_side; + perspective_ = inverted.transpose() * right_hand_side; - matrix.set(3, 0, 0); - matrix.set(3, 1, 0); - matrix.set(3, 2, 0); - matrix.set(3, 3, 1); + matrix.setRow(3, {0, 0, 0, 1}); } - translation_ = {matrix.get(0, 3), matrix.get(1, 3), matrix.get(2, 3)}; + translation_ = {matrix.rc(0, 3), matrix.rc(1, 3), matrix.rc(2, 3)}; - matrix.set(0, 3, 0.0); - matrix.set(1, 3, 0.0); - matrix.set(2, 3, 0.0); + matrix.setRC(0, 3, 0.0); + matrix.setRC(1, 3, 0.0); + matrix.setRC(2, 3, 0.0); - SkVector3 row[3]; + SkV3 row[3]; for (int i = 0; i < 3; i++) { - row[i].set(matrix.get(0, i), matrix.get(1, i), matrix.get(2, i)); + row[i] = {matrix.rc(0, i), matrix.rc(1, i), matrix.rc(2, i)}; } - scale_.fX = row[0].length(); + scale_.x = row[0].length(); - SkVector3Normalize(row[0]); + SkV3Normalize(row[0]); - shear_.fX = row[0].dot(row[1]); - row[1] = SkVector3Combine(row[1], 1.0, row[0], -shear_.fX); + shear_.x = row[0].dot(row[1]); + row[1] = SkV3Combine(row[1], 1.0, row[0], -shear_.x); - scale_.fY = row[1].length(); + scale_.y = row[1].length(); - SkVector3Normalize(row[1]); + SkV3Normalize(row[1]); - shear_.fX /= scale_.fY; + shear_.x /= scale_.y; - shear_.fY = row[0].dot(row[2]); - row[2] = SkVector3Combine(row[2], 1.0, row[0], -shear_.fY); - shear_.fZ = row[1].dot(row[2]); - row[2] = SkVector3Combine(row[2], 1.0, row[1], -shear_.fZ); + shear_.y = row[0].dot(row[2]); + row[2] = SkV3Combine(row[2], 1.0, row[0], -shear_.y); + shear_.z = row[1].dot(row[2]); + row[2] = SkV3Combine(row[2], 1.0, row[1], -shear_.z); - scale_.fZ = row[2].length(); + scale_.z = row[2].length(); - SkVector3Normalize(row[2]); + SkV3Normalize(row[2]); - shear_.fY /= scale_.fZ; - shear_.fZ /= scale_.fZ; + shear_.y /= scale_.z; + shear_.z /= scale_.z; - if (row[0].dot(SkVector3Cross(row[1], row[2])) < 0) { - scale_.fX *= -1; - scale_.fY *= -1; - scale_.fZ *= -1; + if (row[0].dot(row[1].cross(row[2])) < 0) { + scale_ *= -1; for (int i = 0; i < 3; i++) { - row[i].fX *= -1; - row[i].fY *= -1; - row[i].fZ *= -1; + row[i] *= -1; } } - rotation_.set(0.5 * sqrt(fmax(1.0 + row[0].fX - row[1].fY - row[2].fZ, 0.0)), - 0.5 * sqrt(fmax(1.0 - row[0].fX + row[1].fY - row[2].fZ, 0.0)), - 0.5 * sqrt(fmax(1.0 - row[0].fX - row[1].fY + row[2].fZ, 0.0)), - 0.5 * sqrt(fmax(1.0 + row[0].fX + row[1].fY + row[2].fZ, 0.0))); + rotation_.x = 0.5 * sqrt(fmax(1.0 + row[0].x - row[1].y - row[2].z, 0.0)); + rotation_.y = 0.5 * sqrt(fmax(1.0 - row[0].x + row[1].y - row[2].z, 0.0)); + rotation_.z = 0.5 * sqrt(fmax(1.0 - row[0].x - row[1].y + row[2].z, 0.0)); + rotation_.w = 0.5 * sqrt(fmax(1.0 + row[0].x + row[1].y + row[2].z, 0.0)); - if (row[2].fY > row[1].fZ) { - rotation_.fData[0] = -rotation_.fData[0]; + if (row[2].y > row[1].z) { + rotation_.x = -rotation_.x; } - if (row[0].fZ > row[2].fX) { - rotation_.fData[1] = -rotation_.fData[1]; + if (row[0].z > row[2].x) { + rotation_.y = -rotation_.y; } - if (row[1].fX > row[0].fY) { - rotation_.fData[2] = -rotation_.fData[2]; + if (row[1].x > row[0].y) { + rotation_.z = -rotation_.z; } valid_ = true; diff --git a/flow/matrix_decomposition.h b/flow/matrix_decomposition.h index 81794c2fe589f..ea0af37ae9b50 100644 --- a/flow/matrix_decomposition.h +++ b/flow/matrix_decomposition.h @@ -6,9 +6,8 @@ #define FLUTTER_FLOW_MATRIX_DECOMPOSITION_H_ #include "flutter/fml/macros.h" +#include "third_party/skia/include/core/SkM44.h" #include "third_party/skia/include/core/SkMatrix.h" -#include "third_party/skia/include/core/SkMatrix44.h" -#include "third_party/skia/include/core/SkPoint3.h" namespace flutter { @@ -19,29 +18,29 @@ class MatrixDecomposition { public: MatrixDecomposition(const SkMatrix& matrix); - MatrixDecomposition(SkMatrix44 matrix); + MatrixDecomposition(SkM44 matrix); ~MatrixDecomposition(); bool IsValid() const; - const SkVector3& translation() const { return translation_; } + const SkV3& translation() const { return translation_; } - const SkVector3& scale() const { return scale_; } + const SkV3& scale() const { return scale_; } - const SkVector3& shear() const { return shear_; } + const SkV3& shear() const { return shear_; } - const SkVector4& perspective() const { return perspective_; } + const SkV4& perspective() const { return perspective_; } - const SkVector4& rotation() const { return rotation_; } + const SkV4& rotation() const { return rotation_; } private: bool valid_; - SkVector3 translation_; - SkVector3 scale_; - SkVector3 shear_; - SkVector4 perspective_; - SkVector4 rotation_; + SkV3 translation_; + SkV3 scale_; + SkV3 shear_; + SkV4 perspective_; + SkV4 rotation_; FML_DISALLOW_COPY_AND_ASSIGN(MatrixDecomposition); }; diff --git a/flow/matrix_decomposition_unittests.cc b/flow/matrix_decomposition_unittests.cc index 8aa511e4a0a97..fb39cf0f94c85 100644 --- a/flow/matrix_decomposition_unittests.cc +++ b/flow/matrix_decomposition_unittests.cc @@ -16,24 +16,24 @@ namespace flutter { namespace testing { TEST(MatrixDecomposition, Rotation) { - SkMatrix44 matrix = SkMatrix44::I(); + SkM44 matrix; const auto angle = M_PI_4; - matrix.setRotateAbout(0.0, 0.0, 1.0, angle); + matrix.setRotate({0.0, 0.0, 1.0}, angle); flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); const auto sine = sin(angle * 0.5); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[0]); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[1]); - ASSERT_FLOAT_EQ(sine, decomposition.rotation().fData[2]); - ASSERT_FLOAT_EQ(cos(angle * 0.5), decomposition.rotation().fData[3]); + ASSERT_FLOAT_EQ(0, decomposition.rotation().x); + ASSERT_FLOAT_EQ(0, decomposition.rotation().y); + ASSERT_FLOAT_EQ(sine, decomposition.rotation().z); + ASSERT_FLOAT_EQ(cos(angle * 0.5), decomposition.rotation().w); } TEST(MatrixDecomposition, Scale) { - SkMatrix44 matrix = SkMatrix44::I(); + SkM44 matrix; const auto scale = 5.0; matrix.setScale(scale + 0, scale + 1, scale + 2); @@ -41,13 +41,13 @@ TEST(MatrixDecomposition, Scale) { flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); - ASSERT_FLOAT_EQ(scale + 0, decomposition.scale().fX); - ASSERT_FLOAT_EQ(scale + 1, decomposition.scale().fY); - ASSERT_FLOAT_EQ(scale + 2, decomposition.scale().fZ); + ASSERT_FLOAT_EQ(scale + 0, decomposition.scale().x); + ASSERT_FLOAT_EQ(scale + 1, decomposition.scale().y); + ASSERT_FLOAT_EQ(scale + 2, decomposition.scale().z); } TEST(MatrixDecomposition, Translate) { - SkMatrix44 matrix = SkMatrix44::I(); + SkM44 matrix; const auto translate = 125.0; matrix.setTranslate(translate + 0, translate + 1, translate + 2); @@ -55,9 +55,9 @@ TEST(MatrixDecomposition, Translate) { flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); - ASSERT_FLOAT_EQ(translate + 0, decomposition.translation().fX); - ASSERT_FLOAT_EQ(translate + 1, decomposition.translation().fY); - ASSERT_FLOAT_EQ(translate + 2, decomposition.translation().fZ); + ASSERT_FLOAT_EQ(translate + 0, decomposition.translation().x); + ASSERT_FLOAT_EQ(translate + 1, decomposition.translation().y); + ASSERT_FLOAT_EQ(translate + 2, decomposition.translation().z); } TEST(MatrixDecomposition, Combination) { @@ -65,65 +65,65 @@ TEST(MatrixDecomposition, Combination) { const auto scale = 5; const auto translate = 125.0; - SkMatrix44 m1 = SkMatrix44::I(); - m1.setRotateAbout(0, 0, 1, rotation); + SkM44 m1; + m1.setRotate({0, 0, 1}, rotation); - SkMatrix44 m2 = SkMatrix44::I(); - m2.setScale(scale); + SkM44 m2; + m2.setScale(scale, scale, scale); - SkMatrix44 m3 = SkMatrix44::I(); + SkM44 m3; m3.setTranslate(translate, translate, translate); - SkMatrix44 combined = m3 * m2 * m1; + SkM44 combined = m3 * m2 * m1; flutter::MatrixDecomposition decomposition(combined); ASSERT_TRUE(decomposition.IsValid()); - ASSERT_FLOAT_EQ(translate, decomposition.translation().fX); - ASSERT_FLOAT_EQ(translate, decomposition.translation().fY); - ASSERT_FLOAT_EQ(translate, decomposition.translation().fZ); + ASSERT_FLOAT_EQ(translate, decomposition.translation().x); + ASSERT_FLOAT_EQ(translate, decomposition.translation().y); + ASSERT_FLOAT_EQ(translate, decomposition.translation().z); - ASSERT_FLOAT_EQ(scale, decomposition.scale().fX); - ASSERT_FLOAT_EQ(scale, decomposition.scale().fY); - ASSERT_FLOAT_EQ(scale, decomposition.scale().fZ); + ASSERT_FLOAT_EQ(scale, decomposition.scale().x); + ASSERT_FLOAT_EQ(scale, decomposition.scale().y); + ASSERT_FLOAT_EQ(scale, decomposition.scale().z); const auto sine = sin(rotation * 0.5); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[0]); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[1]); - ASSERT_FLOAT_EQ(sine, decomposition.rotation().fData[2]); - ASSERT_FLOAT_EQ(cos(rotation * 0.5), decomposition.rotation().fData[3]); + ASSERT_FLOAT_EQ(0, decomposition.rotation().x); + ASSERT_FLOAT_EQ(0, decomposition.rotation().y); + ASSERT_FLOAT_EQ(sine, decomposition.rotation().z); + ASSERT_FLOAT_EQ(cos(rotation * 0.5), decomposition.rotation().w); } TEST(MatrixDecomposition, ScaleFloatError) { constexpr float scale_increment = 0.00001f; for (float scale = 0.0001f; scale < 2.0f; scale += scale_increment) { - SkMatrix44 matrix = SkMatrix44::I(); + SkM44 matrix; matrix.setScale(scale, scale, 1.0f); flutter::MatrixDecomposition decomposition3(matrix); ASSERT_TRUE(decomposition3.IsValid()); - ASSERT_FLOAT_EQ(scale, decomposition3.scale().fX); - ASSERT_FLOAT_EQ(scale, decomposition3.scale().fY); - ASSERT_FLOAT_EQ(1.f, decomposition3.scale().fZ); - ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[0]); - ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[1]); - ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[2]); + ASSERT_FLOAT_EQ(scale, decomposition3.scale().x); + ASSERT_FLOAT_EQ(scale, decomposition3.scale().y); + ASSERT_FLOAT_EQ(1.f, decomposition3.scale().z); + ASSERT_FLOAT_EQ(0, decomposition3.rotation().x); + ASSERT_FLOAT_EQ(0, decomposition3.rotation().y); + ASSERT_FLOAT_EQ(0, decomposition3.rotation().z); } - SkMatrix44 matrix = SkMatrix44::I(); + SkM44 matrix; const auto scale = 1.7734375f; matrix.setScale(scale, scale, 1.f); // Bug upper bound (empirical) const auto scale2 = 1.773437559603f; - SkMatrix44 matrix2 = SkMatrix44::I(); + SkM44 matrix2; matrix2.setScale(scale2, scale2, 1.f); // Bug lower bound (empirical) const auto scale3 = 1.7734374403954f; - SkMatrix44 matrix3 = SkMatrix44::I(); + SkM44 matrix3; matrix3.setScale(scale3, scale3, 1.f); flutter::MatrixDecomposition decomposition(matrix); @@ -135,26 +135,26 @@ TEST(MatrixDecomposition, ScaleFloatError) { flutter::MatrixDecomposition decomposition3(matrix3); ASSERT_TRUE(decomposition3.IsValid()); - ASSERT_FLOAT_EQ(scale, decomposition.scale().fX); - ASSERT_FLOAT_EQ(scale, decomposition.scale().fY); - ASSERT_FLOAT_EQ(1.f, decomposition.scale().fZ); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[0]); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[1]); - ASSERT_FLOAT_EQ(0, decomposition.rotation().fData[2]); - - ASSERT_FLOAT_EQ(scale2, decomposition2.scale().fX); - ASSERT_FLOAT_EQ(scale2, decomposition2.scale().fY); - ASSERT_FLOAT_EQ(1.f, decomposition2.scale().fZ); - ASSERT_FLOAT_EQ(0, decomposition2.rotation().fData[0]); - ASSERT_FLOAT_EQ(0, decomposition2.rotation().fData[1]); - ASSERT_FLOAT_EQ(0, decomposition2.rotation().fData[2]); - - ASSERT_FLOAT_EQ(scale3, decomposition3.scale().fX); - ASSERT_FLOAT_EQ(scale3, decomposition3.scale().fY); - ASSERT_FLOAT_EQ(1.f, decomposition3.scale().fZ); - ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[0]); - ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[1]); - ASSERT_FLOAT_EQ(0, decomposition3.rotation().fData[2]); + ASSERT_FLOAT_EQ(scale, decomposition.scale().x); + ASSERT_FLOAT_EQ(scale, decomposition.scale().y); + ASSERT_FLOAT_EQ(1.f, decomposition.scale().z); + ASSERT_FLOAT_EQ(0, decomposition.rotation().x); + ASSERT_FLOAT_EQ(0, decomposition.rotation().y); + ASSERT_FLOAT_EQ(0, decomposition.rotation().z); + + ASSERT_FLOAT_EQ(scale2, decomposition2.scale().x); + ASSERT_FLOAT_EQ(scale2, decomposition2.scale().y); + ASSERT_FLOAT_EQ(1.f, decomposition2.scale().z); + ASSERT_FLOAT_EQ(0, decomposition2.rotation().x); + ASSERT_FLOAT_EQ(0, decomposition2.rotation().y); + ASSERT_FLOAT_EQ(0, decomposition2.rotation().z); + + ASSERT_FLOAT_EQ(scale3, decomposition3.scale().x); + ASSERT_FLOAT_EQ(scale3, decomposition3.scale().y); + ASSERT_FLOAT_EQ(1.f, decomposition3.scale().z); + ASSERT_FLOAT_EQ(0, decomposition3.rotation().x); + ASSERT_FLOAT_EQ(0, decomposition3.rotation().y); + ASSERT_FLOAT_EQ(0, decomposition3.rotation().z); } } // namespace testing diff --git a/flow/scene_update_context.cc b/flow/scene_update_context.cc index 1dadfd7327f23..bca3debe05e70 100644 --- a/flow/scene_update_context.cc +++ b/flow/scene_update_context.cc @@ -250,22 +250,22 @@ SceneUpdateContext::Transform::Transform(SceneUpdateContext& context, if (decomposition.IsValid()) { // Don't allow clients to control the z dimension; we control that // instead to make sure layers appear in proper order. - entity_node().SetTranslation(decomposition.translation().x(), // - decomposition.translation().y(), // - 0.f // + entity_node().SetTranslation(decomposition.translation().x, // + decomposition.translation().y, // + 0.f // ); - entity_node().SetScale(decomposition.scale().x(), // - decomposition.scale().y(), // - 1.f // + entity_node().SetScale(decomposition.scale().x, // + decomposition.scale().y, // + 1.f // ); - context.top_scale_x_ *= decomposition.scale().x(); - context.top_scale_y_ *= decomposition.scale().y(); + context.top_scale_x_ *= decomposition.scale().x; + context.top_scale_y_ *= decomposition.scale().y; - entity_node().SetRotation(decomposition.rotation().fData[0], // - decomposition.rotation().fData[1], // - decomposition.rotation().fData[2], // - decomposition.rotation().fData[3] // + entity_node().SetRotation(decomposition.rotation().x, // + decomposition.rotation().y, // + decomposition.rotation().z, // + decomposition.rotation().w // ); } }