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 tessellate_AffineMatrix_DEFINED 9 #define tessellate_AffineMatrix_DEFINED 10 11 #include "include/core/SkMatrix.h" 12 #include "src/gpu/tessellate/Tessellation.h" 13 14 namespace skgpu { 15 16 // Applies an affine 2d transformation to points. Uses SIMD, but takes care to map points 17 // identically, regardless of which method is called. 18 // 19 // This class stores redundant data, so it is best used only as a stack-allocated object at the 20 // point of use. 21 class AffineMatrix { 22 public: 23 AffineMatrix() = default; AffineMatrix(const SkMatrix & m)24 AffineMatrix(const SkMatrix& m) { *this = m; } 25 26 AffineMatrix& operator=(const SkMatrix& m) { 27 SkASSERT(!m.hasPerspective()); 28 // Duplicate the matrix in float4.lo and float4.hi so we can map two points at once. 29 fScale = float2(m.getScaleX(), m.getScaleY()).xyxy(); 30 fSkew = float2(m.getSkewX(), m.getSkewY()).xyxy(); 31 fTrans = float2(m.getTranslateX(), m.getTranslateY()).xyxy(); 32 return *this; 33 } 34 map2Points(float4 p0p1)35 SK_ALWAYS_INLINE float4 map2Points(float4 p0p1) const { 36 return fScale * p0p1 + (fSkew * p0p1.yxwz() + fTrans); 37 } 38 map2Points(const SkPoint pts[2])39 SK_ALWAYS_INLINE float4 map2Points(const SkPoint pts[2]) const { 40 return this->map2Points(float4::Load(pts)); 41 } 42 map2Points(SkPoint p0,SkPoint p1)43 SK_ALWAYS_INLINE float4 map2Points(SkPoint p0, SkPoint p1) const { 44 return this->map2Points(float4(skvx::bit_pun<float2>(p0), skvx::bit_pun<float2>(p1))); 45 } 46 mapPoint(float2 p)47 SK_ALWAYS_INLINE float2 mapPoint(float2 p) const { 48 return fScale.lo * p + (fSkew.lo * p.yx() + fTrans.lo); 49 } 50 map1Point(const SkPoint pt[1])51 SK_ALWAYS_INLINE float2 map1Point(const SkPoint pt[1]) const { 52 return this->mapPoint(float2::Load(pt)); 53 } 54 mapPoint(SkPoint p)55 SK_ALWAYS_INLINE SkPoint mapPoint(SkPoint p) const { 56 return skvx::bit_pun<SkPoint>(this->mapPoint(skvx::bit_pun<float2>(p))); 57 } 58 59 private: 60 float4 fScale; 61 float4 fSkew; 62 float4 fTrans; 63 }; 64 65 } // namespace skgpu 66 67 #endif // tessellate_AffineMatrix_DEFINED 68