• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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