1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_geom_Transform_DEFINED 9 #define skgpu_graphite_geom_Transform_DEFINED 10 11 #include "include/core/SkM44.h" 12 13 #include <algorithm> 14 15 namespace skgpu::graphite { 16 17 class Rect; 18 19 // Transform encapsulates an SkM44 matrix, its inverse, and other properties dependent on the 20 // original matrix value that are useful when rendering. 21 class Transform { 22 public: 23 // Type classifies the transform into coarse categories so that certain optimizations or 24 // properties can be queried efficiently 25 enum class Type : unsigned { 26 // Applying the matrix to a vector or point is a no-op, so could be skipped entirely. 27 kIdentity, 28 // The matrix transforms a rect to another rect, without mirrors or rotations, so both 29 // pre-and-post transform coordinates can be exactly represented as rects. 30 kSimpleRectStaysRect, 31 // The matrix transforms a rect to another rect, but may mirror or rotate the corners 32 // relative to each other. This means that the post-transformed rect completely fills 33 // that space. 34 kRectStaysRect, 35 // The matrix transform may have skew or rotation, so a mapped rect does not fill space, 36 // but there is no need to perform perspective division or w-plane clipping. 37 kAffine, 38 // The matrix includes perspective or modifies Z and requires further projection to 2D, 39 // so care must be taken when w is less than or near 0, and homogeneous division and 40 // perspective-correct interpolation are needed when rendering. 41 kProjection, 42 // The matrix is not invertible or not finite, so should not be used to draw. 43 kInvalid, 44 }; 45 46 explicit Transform(const SkM44& m); 47 Transform(const Transform& t) = default; 48 49 static const Transform& Identity(); 50 static const Transform& Invalid(); 51 52 Transform& operator=(const Transform& t) = default; 53 54 operator const SkM44&() const { return fM; } SkMatrix()55 operator SkMatrix() const { return fM.asM33(); } 56 57 bool operator==(const Transform& t) const; 58 bool operator!=(const Transform& t) const { return !(*this == t); } 59 matrix()60 const SkM44& matrix() const { return fM; } inverse()61 const SkM44& inverse() const { return fInvM; } 62 scaleFactors()63 const SkV2& scaleFactors() const { return fScale; } maxScaleFactor()64 float maxScaleFactor() const { return std::max(fScale.x, fScale.y); } 65 type()66 Type type() const { return fType; } valid()67 bool valid() const { return fType != Type::kInvalid; } 68 69 Rect mapRect(const Rect& rect) const; 70 Rect inverseMapRect(const Rect& rect) const; 71 72 void mapPoints(const Rect& localRect, SkV4 deviceOut[4]) const; 73 void mapPoints(const SkV2* localIn, SkV4* deviceOut, int count) const; 74 75 void mapPoints(const SkV4* localIn, SkV4* deviceOut, int count) const; 76 void inverseMapPoints(const SkV4* deviceIn, SkV4* localOut, int count) const; 77 78 // Returns a transform equal to the pre- or post-translating this matrix 79 Transform preTranslate(float x, float y) const; 80 Transform postTranslate(float x, float y) const; 81 82 // Returns a transform equal to (this * t) 83 Transform concat(const Transform& t) const; concat(const SkM44 & t)84 Transform concat(const SkM44& t) const { return Transform(fM * t); } 85 86 // Returns a transform equal to (this * t^-1) 87 Transform concatInverse(const Transform& t) const; 88 Transform concatInverse(const SkM44& t) const; 89 90 private: Transform(const SkM44 & m,const SkM44 & invM,Type type,const SkV2 scale)91 Transform(const SkM44& m, const SkM44& invM, Type type, const SkV2 scale) 92 : fM(m), fInvM(invM), fType(type), fScale(scale) {} 93 94 SkM44 fM; 95 SkM44 fInvM; // M^-1 96 Type fType; 97 // TODO: It would be nice to have a scale factor for perspective too, and there is 98 // SkMatrixPriv::DifferentialAreaScale but that requires a specific location. 99 SkV2 fScale; // always > 0 100 }; 101 102 } // namespace skgpu::graphite 103 104 #endif // skgpu_graphite_geom_Transform_DEFINED 105