Flutter Engine
The Flutter Engine
Functions
SkM44.cpp File Reference
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "src/base/SkVx.h"
#include "src/core/SkMatrixInvert.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkPathPriv.h"

Go to the source code of this file.

Functions

static void transpose_arrays (SkScalar dst[], const SkScalar src[])
 
static SkRect map_rect_affine (const SkRect &src, const float mat[16])
 
static SkRect map_rect_perspective (const SkRect &src, const float mat[16])
 
static SkV3 normalize (SkV3 v)
 
static SkV4 v4 (SkV3 v, SkScalar w)
 

Function Documentation

◆ map_rect_affine()

static SkRect map_rect_affine ( const SkRect src,
const float  mat[16] 
)
static

Definition at line 140 of file SkM44.cpp.

140 {
141 // When multiplied against vectors of the form <x,y,x,y>, 'flip' allows a single min()
142 // to compute both the min and "negated" max between the xy coordinates. Once finished, another
143 // multiplication produces the original max.
144 const skvx::float4 flip{1.f, 1.f, -1.f, -1.f};
145
146 // Since z = 0 and it's assumed ther's no perspective, only load the upper 2x2 and (tx,ty) in c3
147 auto c0 = skvx::shuffle<0,1,0,1>(skvx::float2::Load(mat + 0)) * flip;
148 auto c1 = skvx::shuffle<0,1,0,1>(skvx::float2::Load(mat + 4)) * flip;
149 auto c3 = skvx::shuffle<0,1,0,1>(skvx::float2::Load(mat + 12));
150
151 // Compute the min and max of the four transformed corners pre-translation; then translate once
152 // at the end.
153 auto minMax = c3 + flip * min(min(c0 * src.fLeft + c1 * src.fTop,
154 c0 * src.fRight + c1 * src.fTop),
155 min(c0 * src.fLeft + c1 * src.fBottom,
156 c0 * src.fRight + c1 * src.fBottom));
157
158 // minMax holds (min x, min y, max x, max y) so can be copied into an SkRect expecting l,t,r,b
159 SkRect r;
160 minMax.store(&r);
161 return r;
162}
static float min(float r, float g, float b)
Definition: hsl.cpp:48
Definition: SkVx.h:83
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
Definition: SkVx.h:109

◆ map_rect_perspective()

static SkRect map_rect_perspective ( const SkRect src,
const float  mat[16] 
)
static

Definition at line 164 of file SkM44.cpp.

164 {
165 // Like map_rect_affine, z = 0 so we can skip the 3rd column, but we do need to compute w's
166 // for each corner of the src rect.
167 auto c0 = skvx::float4::Load(mat + 0);
168 auto c1 = skvx::float4::Load(mat + 4);
169 auto c3 = skvx::float4::Load(mat + 12);
170
171 // Unlike map_rect_affine, we do not defer the 4th column since we may need to homogeneous
172 // coordinates to clip against the w=0 plane
173 auto tl = c0 * src.fLeft + c1 * src.fTop + c3;
174 auto tr = c0 * src.fRight + c1 * src.fTop + c3;
175 auto bl = c0 * src.fLeft + c1 * src.fBottom + c3;
176 auto br = c0 * src.fRight + c1 * src.fBottom + c3;
177
178 // After clipping to w>0 and projecting to 2d, 'project' employs the same negation trick to
179 // compute min and max at the same time.
180 const skvx::float4 flip{1.f, 1.f, -1.f, -1.f};
181 auto project = [&flip](const skvx::float4& p0, const skvx::float4& p1, const skvx::float4& p2) {
182 float w0 = p0[3];
184 // Unclipped, just divide by w
185 return flip * skvx::shuffle<0,1,0,1>(p0) / w0;
186 } else {
187 auto clip = [&](const skvx::float4& p) {
188 float w = p[3];
190 float t = (SkPathPriv::kW0PlaneDistance - w0) / (w - w0);
191 auto c = (t * skvx::shuffle<0,1>(p) + (1.f - t) * skvx::shuffle<0,1>(p0)) /
193
194 return flip * skvx::shuffle<0,1,0,1>(c);
195 } else {
197 }
198 };
199 // Clip both edges leaving p0, and return the min/max of the two clipped points
200 // (since clip returns infinity when both p0 and 2nd vertex have w<0, it'll
201 // automatically be ignored).
202 return min(clip(p1), clip(p2));
203 }
204 };
205
206 // Project all 4 corners, and pass in their adjacent vertices for clipping if it has w < 0,
207 // then accumulate the min and max xy's.
208 auto minMax = flip * min(min(project(tl, tr, bl), project(tr, br, tl)),
209 min(project(br, bl, tr), project(bl, tl, br)));
210
211 SkRect r;
212 minMax.store(&r);
213 return r;
214}
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
#define SK_ScalarInfinity
Definition: SkScalar.h:26
static constexpr SkScalar kW0PlaneDistance
Definition: SkPathPriv.h:41
Vec< 4, float > float4
Definition: SkVx.h:1146
SkScalar w

◆ normalize()

static SkV3 normalize ( SkV3  v)
static

Definition at line 323 of file SkM44.cpp.

323 {
324 const auto vlen = v.length();
325
326 return SkScalarNearlyZero(vlen) ? v : v * (1.0f / vlen);
327}
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:101
SkScalar length() const
Definition: SkM44.h:88

◆ transpose_arrays()

static void transpose_arrays ( SkScalar  dst[],
const SkScalar  src[] 
)
static

Definition at line 37 of file SkM44.cpp.

37 {
38 dst[0] = src[0]; dst[1] = src[4]; dst[2] = src[8]; dst[3] = src[12];
39 dst[4] = src[1]; dst[5] = src[5]; dst[6] = src[9]; dst[7] = src[13];
40 dst[8] = src[2]; dst[9] = src[6]; dst[10] = src[10]; dst[11] = src[14];
41 dst[12] = src[3]; dst[13] = src[7]; dst[14] = src[11]; dst[15] = src[15];
42}
dst
Definition: cp.py:12

◆ v4()

static SkV4 v4 ( SkV3  v,
SkScalar  w 
)
static

Definition at line 329 of file SkM44.cpp.

329{ return {v.x, v.y, v.z, w}; }
float y
Definition: SkM44.h:57
float z
Definition: SkM44.h:57
float x
Definition: SkM44.h:57