Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Transform_graphite.h
Go to the documentation of this file.
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
13namespace skgpu::graphite {
14
15class Rect;
16
17// Transform encapsulates an SkM44 matrix, its inverse, and other properties dependent on the
18// original matrix value that are useful when rendering.
19class Transform {
20public:
21 // Type classifies the transform into coarse categories so that certain optimizations or
22 // properties can be queried efficiently
23 enum class Type : unsigned {
24 // Applying the matrix to a vector or point is a no-op, so could be skipped entirely.
26 // The matrix transforms a rect to another rect, without mirrors or rotations, so both
27 // pre-and-post transform coordinates can be exactly represented as rects.
29 // The matrix transforms a rect to another rect, but may mirror or rotate the corners
30 // relative to each other. This means that the post-transformed rect completely fills
31 // that space.
33 // The matrix transform may have skew or rotation, so a mapped rect does not fill space,
34 // but there is no need to perform perspective division or w-plane clipping. This also
35 // includes orthographic projections.
36 kAffine,
37 // The matrix includes perspective and requires further projection to 2D, so care must be
38 // taken when w is less than or near 0, and homogeneous division and perspective-correct
39 // interpolation are needed when rendering.
41 // The matrix is not invertible or not finite, so should not be used to draw.
43 };
44
45 explicit Transform(const SkM44& m);
46 Transform(const Transform& t) = default;
47
48 static constexpr Transform Identity() {
49 return Transform(SkM44(), SkM44(), Type::kIdentity, 1.f, 1.f);
50 }
55
56 static inline Transform Translate(float x, float y) {
57 if (x == 0.f && y == 0.f) {
58 return Identity();
59 } else if (SkIsFinite(x, y)) {
62 } else {
63 return Invalid();
64 }
65 }
66
67 static inline Transform Inverse(const Transform& t) {
68 return Transform(t.fInvM, t.fM, t.fType, 1.f / t.fMaxScaleFactor, 1.f / t.fMinScaleFactor);
69 }
70
71 Transform& operator=(const Transform& t) = default;
72
73 operator const SkM44&() const { return fM; }
74 operator SkMatrix() const { return fM.asM33(); }
75
76 bool operator!=(const Transform& t) const { return !(*this == t); }
77 bool operator==(const Transform& t) const {
78 return this->valid() == t.valid() && (!this->valid() || fM == t.fM);
79 }
80
81 const SkM44& matrix() const { return fM; }
82 const SkM44& inverse() const { return fInvM; }
83
84 Type type() const { return fType; }
85 bool valid() const { return fType != Type::kInvalid; }
86
87 // Return the {min,max} scale factor at the pre-transformed location 'p'. A unit circle about
88 // 'p' transformed by this Transform will be contained in an ellipse with radii equal to 'min'
89 // and 'max', e.g. moving 1 local unit will move at least 'min' pixels and at most 'max' pixels
90 std::pair<float, float> scaleFactors(const SkV2& p) const;
91
92 // This is valid for non-projection types and 1.0 for projection matrices.
93 float maxScaleFactor() const {
94 SkASSERT(this->valid());
95 return fMaxScaleFactor;
96 }
97
98 // Return the minimum distance needed to move in local (pre-transform) space to ensure that the
99 // transformed coordinates are at least 1px away from the original mapped point. This minimum
100 // distance is specific to the given local 'bounds' since the scale factors change with
101 // perspective.
102 //
103 // If the bounds would be clipped by the w=0 plane or otherwise is ill-conditioned, this will
104 // return positive infinity.
105 float localAARadius(const Rect& bounds) const;
106
107 Rect mapRect(const Rect& rect) const;
108 Rect inverseMapRect(const Rect& rect) const;
109
110 void mapPoints(const Rect& localRect, SkV4 deviceOut[4]) const;
111 void mapPoints(const SkV2* localIn, SkV4* deviceOut, int count) const;
112
113 void mapPoints(const SkV4* localIn, SkV4* deviceOut, int count) const;
114 void inverseMapPoints(const SkV4* deviceIn, SkV4* localOut, int count) const;
115
116 // Returns a transform equal to the pre- or post-translation of this matrix
117 Transform preTranslate(float x, float y) const {
118 return this->concat(SkM44::Translate(x, y));
119 }
120 Transform postTranslate(float x, float y) const {
121 return Translate(x, y).concat(*this);
122 }
123
124 // Returns a transform equal to (this * t)
125 Transform concat(const Transform& t) const {
126 SkASSERT(this->valid());
127 return Transform(fM * t.fM);
128 }
129 Transform concat(const SkM44& t) const {
130 SkASSERT(this->valid());
131 return Transform(fM * t);
132 }
133
134 // Returns a transform equal to (this * t^-1)
136 SkASSERT(this->valid());
137 return Transform(fM * t.fInvM);
138 }
139 Transform concatInverse(const SkM44& t) const {
140 SkASSERT(this->valid());
141 // Saves a multiply compared to inverting just 't' and calculating both fM*t^-1 and t*fInvM
142 // (t * this^-1)^-1 = this * t^-1
143 return Inverse(Transform(t * fInvM));
144 }
145
146private:
147 // Used for static factories that have known properties
148 constexpr Transform(const SkM44& m, const SkM44& invM, Type type,
149 float minScale, float maxScale)
150 : fM(m)
151 , fInvM(invM)
152 , fType(type)
153 , fMinScaleFactor(minScale)
154 , fMaxScaleFactor(maxScale) {}
155
156 SkM44 fM;
157 SkM44 fInvM; // M^-1
158 Type fType;
159
160 // These are cached for non-projection transforms since they are constant; projection matrices
161 // must be computed per point, and these values are ignored.
162 float fMinScaleFactor = 1.f;
163 float fMaxScaleFactor = 1.f;
164};
165
166} // namespace skgpu::graphite
167
168#endif // skgpu_graphite_geom_Transform_DEFINED
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
static bool SkIsFinite(T x, Pack... values)
Definition SkM44.h:150
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z=0)
Definition SkM44.h:225
SkMatrix asM33() const
Definition SkM44.h:409
@ kNaN_Constructor
Definition SkM44.h:172
void mapPoints(const Rect &localRect, SkV4 deviceOut[4]) const
bool operator!=(const Transform &t) const
std::pair< float, float > scaleFactors(const SkV2 &p) const
Transform concat(const SkM44 &t) const
bool operator==(const Transform &t) const
static constexpr Transform Invalid()
Transform postTranslate(float x, float y) const
void inverseMapPoints(const SkV4 *deviceIn, SkV4 *localOut, int count) const
static Transform Translate(float x, float y)
Transform(const Transform &t)=default
const SkM44 & inverse() const
Transform preTranslate(float x, float y) const
static Transform Inverse(const Transform &t)
Transform concatInverse(const Transform &t) const
float localAARadius(const Rect &bounds) const
const SkM44 & matrix() const
Transform & operator=(const Transform &t)=default
Rect mapRect(const Rect &rect) const
Transform concatInverse(const SkM44 &t) const
static constexpr Transform Identity()
Transform concat(const Transform &t) const
Rect inverseMapRect(const Rect &rect) const
double y
double x
TRect< Scalar > Rect
Definition rect.h:746
Definition SkM44.h:19
Definition SkM44.h:98