Skip to content

Commit

Permalink
Make gfx::Matrix44 API similar to SkM44: Remove Matrix44::set3x3()
Browse files Browse the repository at this point in the history
Matrix44::set3x3() (which set top-left 3x3 of the matrix) was
confusing with Matrix44(SkMatrix) which sets the matrix from a 3x3
matrix by setting the 3rd row and the 3rd column to identity. The
col-major order of parameters is also different form the row-major
order used in the constructors of SkM44 and gfx::Transform.

It was used mostly to create rotation matrices. These usages are
replaced with gfx::Matrix44::setRotate*().

gfx::Matrix44::setRotateUnitSinCos() is added following
SkM44::setRotateUnitSinCos(). setRotateAbout(X|Y|Z)AxisSinCos() are
added for right angle rotations.

This makes it easy to switch between different gfx::Transform backends
for performance evaluation and migration.

Bug: 1167153
Change-Id: If31d7f9bf6fb86c779f853ed41c67d0b3c533e78
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3532620
Reviewed-by: danakj <danakj@chromium.org>
Owners-Override: danakj <danakj@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#985625}
  • Loading branch information
wangxianzhu authored and Chromium LUCI CQ committed Mar 26, 2022
1 parent 40b87fb commit 22ebcff
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 200 deletions.
193 changes: 90 additions & 103 deletions ui/gfx/geometry/matrix44.cc
Expand Up @@ -165,74 +165,6 @@ void Matrix44::setIdentity() {
this->setTypeMask(kIdentity_Mask);
}

void Matrix44::set3x3(SkScalar m_00,
SkScalar m_10,
SkScalar m_20,
SkScalar m_01,
SkScalar m_11,
SkScalar m_21,
SkScalar m_02,
SkScalar m_12,
SkScalar m_22) {
fMat[0][0] = m_00;
fMat[0][1] = m_10;
fMat[0][2] = m_20;
fMat[0][3] = 0;
fMat[1][0] = m_01;
fMat[1][1] = m_11;
fMat[1][2] = m_21;
fMat[1][3] = 0;
fMat[2][0] = m_02;
fMat[2][1] = m_12;
fMat[2][2] = m_22;
fMat[2][3] = 0;
fMat[3][0] = 0;
fMat[3][1] = 0;
fMat[3][2] = 0;
fMat[3][3] = 1;
this->recomputeTypeMask();
}

void Matrix44::set3x3RowMajorf(const float src[]) {
fMat[0][0] = src[0];
fMat[0][1] = src[3];
fMat[0][2] = src[6];
fMat[0][3] = 0;
fMat[1][0] = src[1];
fMat[1][1] = src[4];
fMat[1][2] = src[7];
fMat[1][3] = 0;
fMat[2][0] = src[2];
fMat[2][1] = src[5];
fMat[2][2] = src[8];
fMat[2][3] = 0;
fMat[3][0] = 0;
fMat[3][1] = 0;
fMat[3][2] = 0;
fMat[3][3] = 1;
this->recomputeTypeMask();
}

void Matrix44::set3x4RowMajorf(const float src[]) {
fMat[0][0] = src[0];
fMat[1][0] = src[1];
fMat[2][0] = src[2];
fMat[3][0] = src[3];
fMat[0][1] = src[4];
fMat[1][1] = src[5];
fMat[2][1] = src[6];
fMat[3][1] = src[7];
fMat[0][2] = src[8];
fMat[1][2] = src[9];
fMat[2][2] = src[10];
fMat[3][2] = src[11];
fMat[0][3] = 0;
fMat[1][3] = 0;
fMat[2][3] = 0;
fMat[3][3] = 1;
this->recomputeTypeMask();
}

///////////////////////////////////////////////////////////////////////////////

Matrix44& Matrix44::setTranslate(SkScalar dx, SkScalar dy, SkScalar dz) {
Expand Down Expand Up @@ -331,31 +263,14 @@ Matrix44& Matrix44::postScale(SkScalar sx, SkScalar sy, SkScalar sz) {

///////////////////////////////////////////////////////////////////////////////

void Matrix44::setRotateAbout(SkScalar x,
SkScalar y,
SkScalar z,
SkScalar radians) {
double len2 = static_cast<double>(x) * x + static_cast<double>(y) * y +
static_cast<double>(z) * z;
if (1 != len2) {
if (0 == len2) {
this->setIdentity();
return;
}
double scale = 1 / sqrt(len2);
x = SkScalar(x * scale);
y = SkScalar(y * scale);
z = SkScalar(z * scale);
}
this->setRotateAboutUnit(x, y, z, radians);
}

void Matrix44::setRotateAboutUnit(SkScalar x,
SkScalar y,
SkScalar z,
SkScalar radians) {
double c = cos(radians);
double s = sin(radians);
void Matrix44::setRotateUnitSinCos(SkScalar x,
SkScalar y,
SkScalar z,
SkScalar sin_angle,
SkScalar cos_angle) {
// Use double precision for intermediate results.
double c = cos_angle;
double s = sin_angle;
double C = 1 - c;
double xs = x * s;
double ys = y * s;
Expand All @@ -367,18 +282,90 @@ void Matrix44::setRotateAboutUnit(SkScalar x,
double yzC = y * zC;
double zxC = z * xC;

// if you're looking at wikipedia, remember that we're column major.
this->set3x3(SkScalar(x * xC + c), // scale x
SkScalar(xyC + zs), // skew x
SkScalar(zxC - ys), // trans x
fMat[0][0] = SkDoubleToScalar(x * xC + c);
fMat[0][1] = SkDoubleToScalar(xyC + zs);
fMat[0][2] = SkDoubleToScalar(zxC - ys);
fMat[0][3] = SkDoubleToScalar(0);
fMat[1][0] = SkDoubleToScalar(xyC - zs);
fMat[1][1] = SkDoubleToScalar(y * yC + c);
fMat[1][2] = SkDoubleToScalar(yzC + xs);
fMat[1][3] = SkDoubleToScalar(0);
fMat[2][0] = SkDoubleToScalar(zxC + ys);
fMat[2][1] = SkDoubleToScalar(yzC - xs);
fMat[2][2] = SkDoubleToScalar(z * zC + c);
fMat[2][3] = SkDoubleToScalar(0);
fMat[3][0] = SkDoubleToScalar(0);
fMat[3][1] = SkDoubleToScalar(0);
fMat[3][2] = SkDoubleToScalar(0);
fMat[3][3] = SkDoubleToScalar(1);

SkScalar(xyC - zs), // skew y
SkScalar(y * yC + c), // scale y
SkScalar(yzC + xs), // trans y
this->recomputeTypeMask();
}

SkScalar(zxC + ys), // persp x
SkScalar(yzC - xs), // persp y
SkScalar(z * zC + c)); // persp 2
void Matrix44::setRotateAboutXAxisSinCos(SkScalar sin_angle,
SkScalar cos_angle) {
fMat[0][0] = 1;
fMat[0][1] = 0;
fMat[0][2] = 0;
fMat[0][3] = 0;
fMat[1][0] = 0;
fMat[1][1] = cos_angle;
fMat[1][2] = sin_angle;
fMat[1][3] = 0;
fMat[2][0] = 0;
fMat[2][1] = -sin_angle;
fMat[2][2] = cos_angle;
fMat[2][3] = 0;
fMat[3][0] = 0;
fMat[3][1] = 0;
fMat[3][2] = 0;
fMat[3][3] = 1;

this->recomputeTypeMask();
}

void Matrix44::setRotateAboutYAxisSinCos(SkScalar sin_angle,
SkScalar cos_angle) {
fMat[0][0] = cos_angle;
fMat[0][1] = 0;
fMat[0][2] = -sin_angle;
fMat[0][3] = 0;
fMat[1][0] = 0;
fMat[1][1] = 1;
fMat[1][2] = 0;
fMat[1][3] = 0;
fMat[2][0] = sin_angle;
fMat[2][1] = 0;
fMat[2][2] = cos_angle;
fMat[2][3] = 0;
fMat[3][0] = 0;
fMat[3][1] = 0;
fMat[3][2] = 0;
fMat[3][3] = 1;

this->recomputeTypeMask();
}

void Matrix44::setRotateAboutZAxisSinCos(SkScalar sin_angle,
SkScalar cos_angle) {
fMat[0][0] = cos_angle;
fMat[0][1] = sin_angle;
fMat[0][2] = 0;
fMat[0][3] = 0;
fMat[1][0] = -sin_angle;
fMat[1][1] = cos_angle;
fMat[1][2] = 0;
fMat[1][3] = 0;
fMat[2][0] = 0;
fMat[2][1] = 0;
fMat[2][2] = 1;
fMat[2][3] = 0;
fMat[3][0] = 0;
fMat[3][1] = 0;
fMat[3][2] = 0;
fMat[3][3] = 1;

this->recomputeTypeMask();
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
55 changes: 15 additions & 40 deletions ui/gfx/geometry/matrix44.h
Expand Up @@ -54,13 +54,6 @@ struct Vector4 {

// This is the underlying data structure of Transform. Don't use this type
// directly. The public methods can be called through Transform::matrix().
//
// This class was originally SkMatrix44, then moved into Chromium as
// skia::Matrix44, then moved here. For now this class mostly follows the
// Skia coding style, especially the naming convention. This is to make the
// API of this class similar to SkM44 to ease experiment with different
// underlying matrix data structure of Transform.
//
class GEOMETRY_SKIA_EXPORT Matrix44 {
public:
enum Uninitialized_Constructor { kUninitialized_Constructor };
Expand Down Expand Up @@ -109,7 +102,7 @@ class GEOMETRY_SKIA_EXPORT Matrix44 {
* [ g h i ] [ 0 0 1 0 ]
* [ g h 0 i ]
*/
explicit Matrix44(const SkMatrix& sk_matrix);
explicit Matrix44(const SkMatrix&);

// Inverse conversion of the above.
SkMatrix asM33() const;
Expand Down Expand Up @@ -216,20 +209,6 @@ class GEOMETRY_SKIA_EXPORT Matrix44 {
CATransform3D ToCATransform3D() const;
#endif

/* This sets the top-left of the matrix and clears the translation and
* perspective components (with [3][3] set to 1). m_ij is interpreted
* as the matrix entry at row = i, col = j. */
void set3x3(SkScalar m_00,
SkScalar m_10,
SkScalar m_20,
SkScalar m_01,
SkScalar m_11,
SkScalar m_21,
SkScalar m_02,
SkScalar m_12,
SkScalar m_22);
void set3x3RowMajorf(const float[]);

Matrix44& setTranslate(SkScalar dx, SkScalar dy, SkScalar dz);
Matrix44& preTranslate(SkScalar dx, SkScalar dy, SkScalar dz);
Matrix44& postTranslate(SkScalar dx, SkScalar dy, SkScalar dz);
Expand All @@ -248,21 +227,20 @@ class GEOMETRY_SKIA_EXPORT Matrix44 {
return this->postScale(scale, scale, scale);
}

void setRotateDegreesAbout(SkScalar x,
SkScalar y,
SkScalar z,
SkScalar degrees) {
this->setRotateAbout(x, y, z, degrees * SK_ScalarPI / 180);
}

/** Rotate about the vector [x,y,z]. If that vector is not unit-length,
it will be automatically resized.
*/
void setRotateAbout(SkScalar x, SkScalar y, SkScalar z, SkScalar radians);
/** Rotate about the vector [x,y,z]. Does not check the length of the
vector, assuming it is unit-length.
*/
void setRotateAboutUnit(SkScalar x, SkScalar y, SkScalar z, SkScalar radians);
// Sets this matrix to rotate about the specified unit-length axis vector,
// by an angle specified by its sin() and cos(). This does not attempt to
// verify that axis(x, y, z).length() == 1 or that the sin, cos values are
// correct.
void setRotateUnitSinCos(SkScalar x,
SkScalar y,
SkScalar z,
SkScalar sin_angle,
SkScalar cos_angle);

// Special case for x, y or z axis of the above function.
void setRotateAboutXAxisSinCos(SkScalar sin_angle, SkScalar cos_angle);
void setRotateAboutYAxisSinCos(SkScalar sin_angle, SkScalar cos_angle);
void setRotateAboutZAxisSinCos(SkScalar sin_angle, SkScalar cos_angle);

void setConcat(const Matrix44& a, const Matrix44& b);
inline void preConcat(const Matrix44& m) { this->setConcat(*this, m); }
Expand Down Expand Up @@ -327,9 +305,6 @@ class GEOMETRY_SKIA_EXPORT Matrix44 {

static constexpr int kAllPublic_Masks = 0xF;

void as3x4RowMajorf(float[]) const;
void set3x4RowMajorf(const float[]);

SkScalar transX() const { return fMat[3][0]; }
SkScalar transY() const { return fMat[3][1]; }
SkScalar transZ() const { return fMat[3][2]; }
Expand Down

0 comments on commit 22ebcff

Please sign in to comment.