[graphite] Add more utility and SkM44/SkMatrix interop to Transform class
Change-Id: I028bd133778d14edcb22ccef0c35c5a8e3d7d552 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/554516 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
987901fa3f
commit
9d82f9e4b8
@ -30,6 +30,7 @@ struct SK_API SkV2 {
|
||||
friend SkV2 operator*(SkV2 v, SkScalar s) { return {v.x*s, v.y*s}; }
|
||||
friend SkV2 operator*(SkScalar s, SkV2 v) { return {v.x*s, v.y*s}; }
|
||||
friend SkV2 operator/(SkV2 v, SkScalar s) { return {v.x/s, v.y/s}; }
|
||||
friend SkV2 operator/(SkScalar s, SkV2 v) { return {s/v.x, s/v.y}; }
|
||||
|
||||
void operator+=(SkV2 v) { *this = *this + v; }
|
||||
void operator-=(SkV2 v) { *this = *this - v; }
|
||||
|
@ -93,6 +93,15 @@ Transform::Transform(const SkM44& m) : fM(m) {
|
||||
fType = get_matrix_info(m, &fInvM, &fScale);
|
||||
}
|
||||
|
||||
const Transform& Transform::Identity() {
|
||||
static const Transform kIdentity{SkM44()};
|
||||
return kIdentity;
|
||||
}
|
||||
const Transform& Transform::Invalid() {
|
||||
static const Transform kInvalid{SkM44(SkM44::kNaN_Constructor)};
|
||||
return kInvalid;
|
||||
}
|
||||
|
||||
bool Transform::operator==(const Transform& t) const {
|
||||
// Checking fM should be sufficient as all other values are computed from it.
|
||||
SkASSERT(fM != t.fM || (fInvM == t.fInvM && fType == t.fType && fScale == t.fScale));
|
||||
@ -131,4 +140,50 @@ void Transform::inverseMapPoints(const SkV4* deviceIn, SkV4* localOut, int count
|
||||
return map_points(fInvM, deviceIn, localOut, count);
|
||||
}
|
||||
|
||||
Transform Transform::preTranslate(float x, float y) const {
|
||||
Transform t = *this;
|
||||
t.fM.preTranslate(x, y);
|
||||
t.fInvM.postTranslate(-x, -y);
|
||||
|
||||
// Under normal conditions, type and scale won't change, but if we've overflown the translation
|
||||
// components, mark the matrix as invalid.
|
||||
if (!t.fM.isFinite() || !t.fInvM.isFinite()) {
|
||||
t.fType = Type::kInvalid;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
Transform Transform::postTranslate(float x, float y) const {
|
||||
Transform t = *this;
|
||||
t.fM.postTranslate(x, y);
|
||||
t.fInvM.preTranslate(-x, -y);
|
||||
if (!t.fM.isFinite() || !t.fInvM.isFinite()) {
|
||||
t.fType = Type::kInvalid;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
Transform Transform::concat(const Transform& t) const {
|
||||
Transform c = {fM * t.fM, t.fInvM * fInvM, std::max(fType, t.fType), {fScale * t.fScale}};
|
||||
if (!c.fM.isFinite() || !c.fInvM.isFinite()) {
|
||||
c.fType = Type::kInvalid;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
Transform Transform::concatInverse(const Transform& t) const {
|
||||
Transform c = {fM * t.fInvM, t.fM * fInvM, std::max(fType, t.fType), {fScale * (1.f/t.fScale)}};
|
||||
if (!c.fM.isFinite() || !c.fInvM.isFinite()) {
|
||||
c.fType = Type::kInvalid;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
Transform Transform::concatInverse(const SkM44& t) const {
|
||||
// saves a multiply compared to inverting just t and then computing fM*t^-1 and t*fInvM, if we
|
||||
// instead start with (t*fInvM) and swap definition of computed fM and fInvM.
|
||||
Transform inverse{t * fInvM};
|
||||
return {inverse.fInvM, inverse.fM, inverse.fType, 1.f / inverse.fScale};
|
||||
}
|
||||
|
||||
} // namespace skgpu::graphite
|
||||
|
@ -44,6 +44,9 @@ public:
|
||||
explicit Transform(const SkM44& m);
|
||||
Transform(const Transform& t) = default;
|
||||
|
||||
static const Transform& Identity();
|
||||
static const Transform& Invalid();
|
||||
|
||||
Transform& operator=(const Transform& t) = default;
|
||||
|
||||
operator const SkM44&() const { return fM; }
|
||||
@ -70,7 +73,22 @@ public:
|
||||
void mapPoints(const SkV4* localIn, SkV4* deviceOut, int count) const;
|
||||
void inverseMapPoints(const SkV4* deviceIn, SkV4* localOut, int count) const;
|
||||
|
||||
// Returns a transform equal to the pre- or post-translating this matrix
|
||||
Transform preTranslate(float x, float y) const;
|
||||
Transform postTranslate(float x, float y) const;
|
||||
|
||||
// Returns a transform equal to (this * t)
|
||||
Transform concat(const Transform& t) const;
|
||||
Transform concat(const SkM44& t) const { return Transform(fM * t); }
|
||||
|
||||
// Returns a transform equal to (this * t^-1)
|
||||
Transform concatInverse(const Transform& t) const;
|
||||
Transform concatInverse(const SkM44& t) const;
|
||||
|
||||
private:
|
||||
Transform(const SkM44& m, const SkM44& invM, Type type, const SkV2 scale)
|
||||
: fM(m), fInvM(invM), fType(type), fScale(scale) {}
|
||||
|
||||
SkM44 fM;
|
||||
SkM44 fInvM; // M^-1
|
||||
Type fType;
|
||||
|
Loading…
Reference in New Issue
Block a user