30void SkMatrix::doNormalizePerspective() {
38 if (p2 != 0 && p2 != 1) {
39 double inv = 1.0 / p2;
40 for (
int i = 0;
i < 6; ++
i) {
45 this->setTypeMask(kUnknown_Mask);
53 this->setTypeMask(kUnknown_Mask);
67 this->setTypeMask(kUnknown_Mask);
82uint8_t SkMatrix::computePerspectiveTypeMask()
const {
91 return SkToU8(kORableMasks);
94 return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask);
97uint8_t SkMatrix::computeTypeMask()
const {
103 return SkToU8(kORableMasks);
132 int dp0 = 0 == (m00 | m11) ;
164 return ma[0] == mb[0] && ma[1] == mb[1] && ma[2] == mb[2] &&
165 ma[3] == mb[3] && ma[4] == mb[4] && ma[5] == mb[5] &&
166 ma[6] == mb[6] && ma[7] == mb[7] && ma[8] == mb[8];
242 return a *
b + c *
d;
247 return a *
b + c *
d +
e *
f;
251 return a *
b - c *
d;
264 const unsigned mask = this->
getType();
271 m.setTranslate(
dx, dy);
277 this->updateTranslateMask();
284 m.setTranslate(
dx, dy);
289 this->updateTranslateMask();
297 if (1 == sx && 1 == sy) {
306 auto rectMask = (sx == 0 || sy == 0) ? 0 : kRectStaysRect_Mask;
316 if (1 == sx && 1 == sy) {
321 m.setScale(sx, sy, px, py);
326 if (1 == sx && 1 == sy) {
354 this->clearTypeMask(kRectStaysRect_Mask);
361 if (1 == sx && 1 == sy) {
365 m.setScale(sx, sy, px, py);
370 if (1 == sx && 1 == sy) {
380bool SkMatrix::postIDiv(
int divx,
int divy) {
381 if (divx == 0 || divy == 0) {
385 const float invX = 1.f / divx;
386 const float invY = 1.f / divy;
396 this->setTypeMask(kUnknown_Mask);
403 const SkScalar oneMinusCosV = 1 - cosV;
416 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
432 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
448 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
464 m.setRotate(degrees, px, py);
470 m.setRotate(degrees);
476 m.setRotate(degrees, px, py);
482 m.setRotate(degrees);
492 kUnknown_Mask | kOnlyPerspectiveValid_Mask);
508 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
514 m.setSkew(sx, sy, px, py);
526 m.setSkew(sx, sy, px, py);
551 bool xLarger =
false;
562 tx =
dst.fLeft -
src.fLeft * sx;
563 ty =
dst.fTop -
src.fTop * sy;
568 diff =
dst.width() -
src.width() * sy;
570 diff =
dst.height() -
src.height() * sy;
595static inline float rowcol3(
const float row[],
const float col[]) {
596 return row[0] * col[0] + row[1] * col[3] + row[2] * col[6];
607 if (
a.isTriviallyIdentity()) {
609 }
else if (
b.isTriviallyIdentity()) {
630 tmp.setTypeMask(kUnknown_Mask);
667 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
705static inline double dcross(
double a,
double b,
double c,
double d) {
706 return a *
b - c *
d;
710 double c,
double d,
double scale) {
779 this->getMapXYProc()(*
this,
x,
y,
result);
813bool SkMatrix::invertNonIdentity(
SkMatrix*
inv)
const {
819 bool invertible =
true;
842 inv->setTypeMask(mask | kRectStaysRect_Mask);
862 bool applyingInPlace = (
inv ==
this);
867 if (applyingInPlace ||
nullptr == tmp) {
871 ComputeInv(tmp->fMat, fMat, invDet, isPersp);
876 tmp->setTypeMask(fTypeMask);
878 if (applyingInPlace) {
934 p =
p * scale4 + trans4;
992 bool trailingElement = (
count & 1);
998 (src4 * scale4 + swz4 * skew4 + trans4).
store(
dst);
1002 if (trailingElement) {
1007 (src4 * scale4 + swz4 * skew4 + trans4).lo.store(
dst);
1012const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = {
1013 SkMatrix::Identity_pts, SkMatrix::Trans_pts,
1014 SkMatrix::Scale_pts, SkMatrix::Scale_pts,
1015 SkMatrix::Affine_vpts, SkMatrix::Affine_vpts,
1016 SkMatrix::Affine_vpts, SkMatrix::Affine_vpts,
1018 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1019 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1020 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1021 SkMatrix::Persp_pts, SkMatrix::Persp_pts
1028 size_t srcStride,
int count) {
1041 dst =
reinterpret_cast<SkPoint3*
>(
reinterpret_cast<char*
>(
dst) + dstStride);
1042 src =
reinterpret_cast<const SkPoint3*
>(
reinterpret_cast<const char*
>(
src) +
1053 src =
reinterpret_cast<const SkPoint3*
>(
reinterpret_cast<const char*
>(
src) + srcStride);
1056 SkScalar x =
sdot(sx, mat[M::kMScaleX], sy, mat[M::kMSkewX], sw, mat[M::kMTransX]);
1057 SkScalar y =
sdot(sx, mat[M::kMSkewY], sy, mat[M::kMScaleY], sw, mat[M::kMTransY]);
1058 SkScalar w =
sdot(sx, mat[M::kMPersp0], sy, mat[M::kMPersp1], sw, mat[M::kMPersp2]);
1061 dst =
reinterpret_cast<SkPoint3*
>(
reinterpret_cast<char*
>(
dst) + dstStride);
1079 fMat[0] *
src[
i].fX + fMat[1] *
src[
i].fY + fMat[2],
1080 fMat[3] *
src[
i].fX + fMat[4] *
src[
i].fY + fMat[5],
1081 fMat[6] *
src[
i].fX + fMat[7] *
src[
i].fY + fMat[8],
1087 fMat[0] *
src[
i].fX + fMat[1] *
src[
i].fY + fMat[2],
1088 fMat[3] *
src[
i].fX + fMat[4] *
src[
i].fY + fMat[5],
1101 MapXYProc proc = this->getMapXYProc();
1102 proc(*
this, 0, 0, &origin);
1104 for (
int i =
count - 1;
i >= 0; --
i) {
1107 proc(*
this,
src[
i].fX,
src[
i].fY, &tmp);
1157 path.transform(*
this);
1165 dst->setBoundsNoCheck(quad, 4);
1173 vec[0].
set(radius, 0);
1174 vec[1].
set(0, radius);
1254const SkMatrix::MapXYProc SkMatrix::gMapXYProcs[] = {
1255 SkMatrix::Identity_xy, SkMatrix::Trans_xy,
1256 SkMatrix::Scale_xy, SkMatrix::ScaleTrans_xy,
1257 SkMatrix::Rot_xy, SkMatrix::RotTrans_xy,
1258 SkMatrix::Rot_xy, SkMatrix::RotTrans_xy,
1260 SkMatrix::Persp_xy, SkMatrix::Persp_xy,
1261 SkMatrix::Persp_xy, SkMatrix::Persp_xy,
1262 SkMatrix::Persp_xy, SkMatrix::Persp_xy,
1263 SkMatrix::Persp_xy, SkMatrix::Persp_xy
1269#define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26)))
1271bool SkMatrix::isFixedStepInX()
const {
1272 return PerspNearlyZero(fMat[
kMPersp0]);
1277 if (PerspNearlyZero(fMat[
kMPersp1]) &&
1278 PerspNearlyZero(fMat[
kMPersp2] - 1)) {
1305 dst->setTypeMask(kUnknown_Mask);
1321 dst->setTypeMask(kUnknown_Mask);
1327 float x0, y0, x1, y1, x2, y2;
1329 x0 = srcPt[2].
fX - srcPt[0].
fX;
1330 y0 = srcPt[2].
fY - srcPt[0].
fY;
1331 x1 = srcPt[2].
fX - srcPt[1].
fX;
1332 y1 = srcPt[2].
fY - srcPt[1].
fY;
1333 x2 = srcPt[2].
fX - srcPt[3].
fX;
1334 y2 = srcPt[2].
fY - srcPt[3].
fY;
1337 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) {
1342 a1 = (((x0 - x1) * y2 / x2) - y0 + y1) / denom;
1352 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) {
1377 dst->setTypeMask(kUnknown_Mask);
1386 if ((
unsigned)
count > 4) {
1387 SkDebugf(
"--- SkMatrix::setPolyToPoly count out of range %d\n",
count);
1401 SkMatrix::Poly2Proc, SkMatrix::Poly3Proc, SkMatrix::Poly4Proc
1407 if (!proc(
src, &tempMap)) {
1413 if (!proc(
dst, &tempMap)) {
1451 if (results[0] > results[1]) {
1453 swap(results[0], results[1]);
1482 if (results[0] > results[1]) {
1484 swap(results[0], results[1]);
1492 results[0] = apluscdiv2 -
x;
1494 results[0] = apluscdiv2 +
x;
1496 results[0] = apluscdiv2 -
x;
1497 results[1] = apluscdiv2 +
x;
1506 if (results[0] < 0) {
1514 if (results[1] < 0) {
1524 if (get_scale_factor<kMin_MinMaxOrBoth>(this->
getType(), fMat, &factor)) {
1533 if (get_scale_factor<kMax_MinMaxOrBoth>(this->
getType(), fMat, &factor)) {
1541 return get_scale_factor<kBoth_MinMaxOrBoth>(this->
getType(), fMat, scaleFactors);
1583size_t SkMatrix::writeToMemory(
void*
buffer)
const {
1585 static const size_t sizeInMemory = 9 *
sizeof(
SkScalar);
1587 memcpy(
buffer, fMat, sizeInMemory);
1589 return sizeInMemory;
1592size_t SkMatrix::readFromMemory(
const void*
buffer,
size_t length) {
1593 static const size_t sizeInMemory = 9 *
sizeof(
SkScalar);
1594 if (
length < sizeInMemory) {
1597 memcpy(fMat,
buffer, sizeInMemory);
1598 this->setTypeMask(kUnknown_Mask);
1601 return sizeInMemory;
1606 str.
appendf(
"[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]",
1607 fMat[0], fMat[1], fMat[2], fMat[3], fMat[4], fMat[5],
1608 fMat[6], fMat[7], fMat[8]);
1623 static const unsigned kAntiAliasSubpixelBits = 4;
1625 const unsigned subpixelBits = isAntiAlias ? kAntiAliasSubpixelBits : 0;
1670 const float scale = 1 << subpixelBits;
1679 return isrc == idst;
1727 Sa =
A*cosQ +
C*sinQ;
1728 Sb =
B*cosQ +
D*sinQ;
1729 Sd = -
B*sinQ +
D*cosQ;
1744 double diff = Sa - Sd;
1745 double discriminant =
sqrt(diff*diff + 4.0*Sb*Sb);
1746 double trace = Sa + Sd;
1748 w1 = 0.5*(trace + discriminant);
1749 w2 = 0.5*(trace - discriminant);
1751 w1 = 0.5*(trace - discriminant);
1752 w2 = 0.5*(trace + discriminant);
1761 cos2 = cos1*cosQ - sin1*sinQ;
1762 sin2 = sin1*cosQ + cos1*sinQ;
1773 rotation1->
fX = cos1;
1774 rotation1->
fY = sin1;
1777 rotation2->
fX = cos2;
1778 rotation2->
fY = sin2;
1805 m.mapHomogeneousPoints(&xyw, &
p, 1);
1812 m.getScaleX(),
m.getSkewY(),
m.getPerspX(),
1813 m.getSkewX(),
m.getScaleY(),
m.getPerspY());
1815 double denom = 1.0 / xyw.
fZ;
1816 denom = denom * denom * denom;
1823 if (!
m.hasPerspective()) {
1835 m.mapHomogeneousPoints(xyw, quad, 4);
1839 SkPoint3 v1{
m.getScaleX(),
m.getSkewY(),
m.getPerspX()};
1851 double det = detCrossProd.
dot(xyw[0]);
1853 double denom = 1.0 / xyw[0].
fZ;
1854 denom = denom * denom * denom;
1858 tolerance *= tolerance;
1859 for (
int i = 1;
i < 4; ++
i) {
1865 det = detCrossProd.
dot(xyw[
i]);
1866 denom = 1.0 / xyw[
i].
fZ;
1867 denom = denom * denom * denom;
static SkM44 inv(const SkM44 &m)
static bool invalid(const SkISize &size)
sk_bzero(glyphs, sizeof(glyphs))
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SkScalarAs2sCompliment(x)
static constexpr float sk_double_to_float(double x)
static bool SkIsFinite(T x, Pack... values)
static constexpr float sk_ieee_float_divide(float numer, float denom)
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
static SkScalar dcross_dscale(double a, double b, double c, double d, double scale)
bool get_scale_factor(SkMatrix::TypeMask typeMask, const SkScalar m[9], SkScalar results[])
bool SkTreatAsSprite(const SkMatrix &mat, const SkISize &size, const SkSamplingOptions &sampling, bool isAntiAlias)
static bool only_scale_and_translate(unsigned mask)
static bool checkForZero(float x)
static double sk_inv_determinant(const float mat[9], int isPerspective)
static skvx::float4 sort_as_rect(const skvx::float4 <rb)
bool(* PolyMapProc)(const SkPoint[], SkMatrix *)
static SkScalar scross(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
static float rowcol3(const float row[], const float col[])
static double sk_determinant(const float mat[9], int isPerspective)
static const int32_t kScalar1Int
static double dcross(double a, double b, double c, double d)
static SkScalar scross_dscale(SkScalar a, SkScalar b, SkScalar c, SkScalar d, double scale)
static SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
static float muladdmul(float a, float b, float c, float d)
bool operator==(const SkMatrix &a, const SkMatrix &b)
bool SkDecomposeUpper2x2(const SkMatrix &matrix, SkPoint *rotation1, SkPoint *scale, SkPoint *rotation2)
static bool is_degenerate_2x2(SkScalar scaleX, SkScalar skewX, SkScalar skewY, SkScalar scaleY)
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
void swap(sk_sp< T > &a, sk_sp< T > &b)
#define SkDegreesToRadians(degrees)
#define SkScalarInvert(x)
static float SkScalarSinSnapToZero(SkScalar radians)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkScalarRoundToInt(x)
#define SkDoubleToScalar(x)
#define SK_ScalarNearlyZero
#define SK_ScalarInfinity
static SkScalar SkScalarSquare(SkScalar x)
static float SkScalarCosSnapToZero(SkScalar radians)
static SkScalar perp_dot(const SkPoint &p0, const SkPoint &p1, const SkPoint &p2)
constexpr uint8_t SkToU8(S x)
SkM44 & setTranslate(SkScalar x, SkScalar y, SkScalar z=0)
static SkScalar DifferentialAreaScale(const SkMatrix &m, const SkPoint &p)
static void MapHomogeneousPointsWithStride(const SkMatrix &mx, SkPoint3 dst[], size_t dstStride, const SkPoint3 src[], size_t srcStride, int count)
static bool NearlyAffine(const SkMatrix &m, const SkRect &bounds, SkScalar tolerance=SK_ScalarNearlyZero)
static SkScalar ComputeResScaleForStroking(const SkMatrix &matrix)
SkScalar mapRadius(SkScalar radius) const
SkMatrix & setAffine(const SkScalar affine[6])
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
SkMatrix & postRotate(SkScalar degrees, SkScalar px, SkScalar py)
static constexpr int kATransY
vertical translation
SkMatrix & preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
static constexpr int kMScaleX
horizontal scale factor
static constexpr int kMTransY
vertical translation
SkMatrix & postConcat(const SkMatrix &other)
static constexpr int kAScaleY
vertical scale factor
bool getMinMaxScales(SkScalar scaleFactors[2]) const
SkScalar getSkewY() const
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
static constexpr int kASkewX
horizontal skew factor
void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
static constexpr int kMPersp1
input y perspective factor
void mapVectors(SkVector dst[], const SkVector src[], int count) const
static constexpr int kATransX
horizontal translation
SkScalar getTranslateY() const
@ kEnd_ScaleToFit
scales and aligns to right and bottom
@ kCenter_ScaleToFit
scales and aligns to center
@ kFill_ScaleToFit
scales in x and y to fill destination SkRect
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
bool preservesRightAngles(SkScalar tol=SK_ScalarNearlyZero) const
bool asAffine(SkScalar affine[6]) const
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
SkScalar getSkewX() const
SkMatrix & setSinCos(SkScalar sinValue, SkScalar cosValue, SkScalar px, SkScalar py)
SkMatrix & postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
bool invert(SkMatrix *inverse) const
static constexpr int kAScaleX
horizontal scale factor
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
static void SetAffineIdentity(SkScalar affine[6])
static constexpr int kASkewY
vertical skew factor
bool rectStaysRect() const
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
SkScalar getScaleX() const
SkMatrix & setRSXform(const SkRSXform &rsxForm)
SkScalar getMinScale() const
SkMatrix & set9(const SkScalar buffer[9])
static const SkMatrix & I()
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
bool decomposeScale(SkSize *scale, SkMatrix *remaining=nullptr) const
SkMatrix & preConcat(const SkMatrix &other)
static constexpr int kMPersp0
input x perspective factor
SkMatrix & preRotate(SkScalar degrees, SkScalar px, SkScalar py)
void mapRectScaleTranslate(SkRect *dst, const SkRect &src) const
SkScalar getScaleY() const
SkMatrix & setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
bool isScaleTranslate() const
SkScalar getMaxScale() const
static constexpr int kMPersp2
perspective bias
static constexpr int kMTransX
horizontal translation
bool hasPerspective() const
static constexpr int kMSkewY
vertical skew factor
static constexpr int kMScaleY
vertical scale factor
bool setRectToRect(const SkRect &src, const SkRect &dst, ScaleToFit stf)
bool isSimilarity(SkScalar tol=SK_ScalarNearlyZero) const
static constexpr int kMSkewX
horizontal skew factor
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkScalar getTranslateX() const
@ kPerspective_Mask
perspective SkMatrix
@ kTranslate_Mask
translation SkMatrix
@ kScale_Mask
scale SkMatrix
@ kIdentity_Mask
identity SkMatrix; all bits clear
@ kAffine_Mask
skew or rotate SkMatrix
SkMatrix & setConcat(const SkMatrix &a, const SkMatrix &b)
static const SkMatrix & InvalidMatrix()
static bool NoChangeWithIdentityMatrix(const SkSamplingOptions &sampling)
const char * c_str() const
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static float max(float r, float g, float b)
static float min(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
SkSamplingOptions sampling
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SINT T dot(const Vec< N, T > &a, const Vec< N, T > &b)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
SIT T max(const Vec< 1, T > &x)
SIT T min(const Vec< 1, T > &x)
int32_t fBottom
larger y-axis bounds
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeSize(const SkISize &size)
void offset(int32_t dx, int32_t dy)
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
SkPoint3 cross(const SkPoint3 &vec) const
SkScalar dot(const SkPoint3 &vec) const
static constexpr SkPoint Make(float x, float y)
void set(float x, float y)
static float Length(float x, float y)
const SkFilterMode filter
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
SKVX_ALWAYS_INLINE void store(void *ptr) const