Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Typedefs | Enumerations | Functions | Variables
SkMatrix.cpp File Reference
#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkFloatBits.h"
#include "src/base/SkVx.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkMatrixUtils.h"
#include "src/core/SkSamplingPriv.h"
#include <algorithm>
#include <cmath>

Go to the source code of this file.

Typedefs

typedef bool(* PolyMapProc) (const SkPoint[], SkMatrix *)
 

Enumerations

enum  {
  kTranslate_Shift , kScale_Shift , kAffine_Shift , kPerspective_Shift ,
  kRectStaysRect_Shift
}
 
enum  MinMaxOrBoth { kMin_MinMaxOrBoth , kMax_MinMaxOrBoth , kBoth_MinMaxOrBoth }
 

Functions

bool operator== (const SkMatrix &a, const SkMatrix &b)
 
static bool is_degenerate_2x2 (SkScalar scaleX, SkScalar skewX, SkScalar skewY, SkScalar scaleY)
 
static SkScalar sdot (SkScalar a, SkScalar b, SkScalar c, SkScalar d)
 
static SkScalar sdot (SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar e, SkScalar f)
 
static SkScalar scross (SkScalar a, SkScalar b, SkScalar c, SkScalar d)
 
static float muladdmul (float a, float b, float c, float d)
 
static float rowcol3 (const float row[], const float col[])
 
static bool only_scale_and_translate (unsigned mask)
 
static SkScalar scross_dscale (SkScalar a, SkScalar b, SkScalar c, SkScalar d, double scale)
 
static double dcross (double a, double b, double c, double d)
 
static SkScalar dcross_dscale (double a, double b, double c, double d, double scale)
 
static double sk_determinant (const float mat[9], int isPerspective)
 
static double sk_inv_determinant (const float mat[9], int isPerspective)
 
static skvx::float4 sort_as_rect (const skvx::float4 &ltrb)
 
static bool checkForZero (float x)
 
template<MinMaxOrBoth MIN_MAX_OR_BOTH>
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)
 
bool SkDecomposeUpper2x2 (const SkMatrix &matrix, SkPoint *rotation1, SkPoint *scale, SkPoint *rotation2)
 

Variables

static const int32_t kScalar1Int = 0x3f800000
 

Typedef Documentation

◆ PolyMapProc

typedef bool(* PolyMapProc) (const SkPoint[], SkMatrix *)

Definition at line 1381 of file SkMatrix.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
kTranslate_Shift 
kScale_Shift 
kAffine_Shift 
kPerspective_Shift 
kRectStaysRect_Shift 

Definition at line 72 of file SkMatrix.cpp.

72 {
78};
@ kScale_Shift
Definition SkMatrix.cpp:74
@ kRectStaysRect_Shift
Definition SkMatrix.cpp:77
@ kAffine_Shift
Definition SkMatrix.cpp:75
@ kTranslate_Shift
Definition SkMatrix.cpp:73
@ kPerspective_Shift
Definition SkMatrix.cpp:76

◆ MinMaxOrBoth

Enumerator
kMin_MinMaxOrBoth 
kMax_MinMaxOrBoth 
kBoth_MinMaxOrBoth 

Definition at line 1422 of file SkMatrix.cpp.

1422 {
1426};
@ kBoth_MinMaxOrBoth
@ kMin_MinMaxOrBoth
@ kMax_MinMaxOrBoth

Function Documentation

◆ checkForZero()

static bool checkForZero ( float  x)
inlinestatic

Definition at line 1289 of file SkMatrix.cpp.

1289 {
1290 return x*x == 0;
1291}
double x

◆ dcross()

static double dcross ( double  a,
double  b,
double  c,
double  d 
)
inlinestatic

Definition at line 705 of file SkMatrix.cpp.

705 {
706 return a * b - c * d;
707}
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
static bool b
struct MyStruct a[10]

◆ dcross_dscale()

static SkScalar dcross_dscale ( double  a,
double  b,
double  c,
double  d,
double  scale 
)
inlinestatic

Definition at line 709 of file SkMatrix.cpp.

710 {
711 return SkDoubleToScalar(dcross(a, b, c, d) * scale);
712}
static double dcross(double a, double b, double c, double d)
Definition SkMatrix.cpp:705
#define SkDoubleToScalar(x)
Definition SkScalar.h:64
const Scalar scale

◆ get_scale_factor()

template<MinMaxOrBoth MIN_MAX_OR_BOTH>
bool get_scale_factor ( SkMatrix::TypeMask  typeMask,
const SkScalar  m[9],
SkScalar  results[] 
)

Definition at line 1428 of file SkMatrix.cpp.

1430 {
1431 if (typeMask & SkMatrix::kPerspective_Mask) {
1432 return false;
1433 }
1434 if (SkMatrix::kIdentity_Mask == typeMask) {
1435 results[0] = SK_Scalar1;
1436 if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1437 results[1] = SK_Scalar1;
1438 }
1439 return true;
1440 }
1441 if (!(typeMask & SkMatrix::kAffine_Mask)) {
1442 if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1443 results[0] = std::min(SkScalarAbs(m[SkMatrix::kMScaleX]),
1445 } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1446 results[0] = std::max(SkScalarAbs(m[SkMatrix::kMScaleX]),
1448 } else {
1449 results[0] = SkScalarAbs(m[SkMatrix::kMScaleX]);
1450 results[1] = SkScalarAbs(m[SkMatrix::kMScaleY]);
1451 if (results[0] > results[1]) {
1452 using std::swap;
1453 swap(results[0], results[1]);
1454 }
1455 }
1456 return true;
1457 }
1458 // ignore the translation part of the matrix, just look at 2x2 portion.
1459 // compute singular values, take largest or smallest abs value.
1460 // [a b; b c] = A^T*A
1467 // eigenvalues of A^T*A are the squared singular values of A.
1468 // characteristic equation is det((A^T*A) - l*I) = 0
1469 // l^2 - (a + c)l + (ac-b^2)
1470 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
1471 // and roots are guaranteed to be pos and real).
1472 SkScalar bSqd = b * b;
1473 // if upper left 2x2 is orthogonal save some math
1475 if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1476 results[0] = std::min(a, c);
1477 } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1478 results[0] = std::max(a, c);
1479 } else {
1480 results[0] = a;
1481 results[1] = c;
1482 if (results[0] > results[1]) {
1483 using std::swap;
1484 swap(results[0], results[1]);
1485 }
1486 }
1487 } else {
1488 SkScalar aminusc = a - c;
1489 SkScalar apluscdiv2 = SkScalarHalf(a + c);
1490 SkScalar x = SkScalarHalf(SkScalarSqrt(aminusc * aminusc + 4 * bSqd));
1491 if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1492 results[0] = apluscdiv2 - x;
1493 } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1494 results[0] = apluscdiv2 + x;
1495 } else {
1496 results[0] = apluscdiv2 - x;
1497 results[1] = apluscdiv2 + x;
1498 }
1499 }
1500 if (!SkIsFinite(results[0])) {
1501 return false;
1502 }
1503 // Due to the floating point inaccuracy, there might be an error in a, b, c
1504 // calculated by sdot, further deepened by subsequent arithmetic operations
1505 // on them. Therefore, we allow and cap the nearly-zero negative values.
1506 if (results[0] < 0) {
1507 results[0] = 0;
1508 }
1509 results[0] = SkScalarSqrt(results[0]);
1510 if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
1511 if (!SkIsFinite(results[1])) {
1512 return false;
1513 }
1514 if (results[1] < 0) {
1515 results[1] = 0;
1516 }
1517 results[1] = SkScalarSqrt(results[1]);
1518 }
1519 return true;
1520}
static bool SkIsFinite(T x, Pack... values)
static SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
Definition SkMatrix.cpp:241
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition SkRefCnt.h:341
#define SK_Scalar1
Definition SkScalar.h:18
#define SkScalarHalf(a)
Definition SkScalar.h:75
#define SK_ScalarNearlyZero
Definition SkScalar.h:99
#define SkScalarSqrt(x)
Definition SkScalar.h:42
#define SkScalarAbs(x)
Definition SkScalar.h:39
static constexpr int kMScaleX
horizontal scale factor
Definition SkMatrix.h:353
static constexpr int kMSkewY
vertical skew factor
Definition SkMatrix.h:356
static constexpr int kMScaleY
vertical scale factor
Definition SkMatrix.h:357
static constexpr int kMSkewX
horizontal skew factor
Definition SkMatrix.h:354
@ kPerspective_Mask
perspective SkMatrix
Definition SkMatrix.h:196
@ kIdentity_Mask
identity SkMatrix; all bits clear
Definition SkMatrix.h:192
@ kAffine_Mask
skew or rotate SkMatrix
Definition SkMatrix.h:195
float SkScalar
Definition extension.cpp:12

◆ is_degenerate_2x2()

static bool is_degenerate_2x2 ( SkScalar  scaleX,
SkScalar  skewX,
SkScalar  skewY,
SkScalar  scaleY 
)
inlinestatic

Definition at line 172 of file SkMatrix.cpp.

173 {
174 SkScalar perp_dot = scaleX*scaleY - skewX*skewY;
176}
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:101
static SkScalar perp_dot(const SkPoint &p0, const SkPoint &p1, const SkPoint &p2)

◆ muladdmul()

static float muladdmul ( float  a,
float  b,
float  c,
float  d 
)
inlinestatic

Definition at line 591 of file SkMatrix.cpp.

591 {
592 return sk_double_to_float((double)a * b + (double)c * d);
593}
static constexpr float sk_double_to_float(double x)

◆ only_scale_and_translate()

static bool only_scale_and_translate ( unsigned  mask)
static

Definition at line 599 of file SkMatrix.cpp.

599 {
601}

◆ operator==()

bool operator== ( const SkMatrix a,
const SkMatrix b 
)

Compares a and b; returns true if a and b are numerically equal. Returns true even if sign of zero values are different. Returns false if either SkMatrix contains NaN, even if the other SkMatrix also contains NaN.

Parameters
aSkMatrix to compare
bSkMatrix to compare
Returns
true if SkMatrix a and SkMatrix b are numerically equal

Definition at line 160 of file SkMatrix.cpp.

160 {
161 const SkScalar* SK_RESTRICT ma = a.fMat;
162 const SkScalar* SK_RESTRICT mb = b.fMat;
163
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];
167}
#define SK_RESTRICT
Definition SkFeatures.h:42

◆ rowcol3()

static float rowcol3 ( const float  row[],
const float  col[] 
)
inlinestatic

Definition at line 595 of file SkMatrix.cpp.

595 {
596 return row[0] * col[0] + row[1] * col[3] + row[2] * col[6];
597}

◆ scross()

static SkScalar scross ( SkScalar  a,
SkScalar  b,
SkScalar  c,
SkScalar  d 
)
inlinestatic

Definition at line 250 of file SkMatrix.cpp.

250 {
251 return a * b - c * d;
252}

◆ scross_dscale()

static SkScalar scross_dscale ( SkScalar  a,
SkScalar  b,
SkScalar  c,
SkScalar  d,
double  scale 
)
inlinestatic

Definition at line 700 of file SkMatrix.cpp.

701 {
702 return SkDoubleToScalar(scross(a, b, c, d) * scale);
703}
static SkScalar scross(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
Definition SkMatrix.cpp:250

◆ sdot() [1/2]

static SkScalar sdot ( SkScalar  a,
SkScalar  b,
SkScalar  c,
SkScalar  d 
)
inlinestatic

Definition at line 241 of file SkMatrix.cpp.

241 {
242 return a * b + c * d;
243}

◆ sdot() [2/2]

static SkScalar sdot ( SkScalar  a,
SkScalar  b,
SkScalar  c,
SkScalar  d,
SkScalar  e,
SkScalar  f 
)
inlinestatic

Definition at line 245 of file SkMatrix.cpp.

246 {
247 return a * b + c * d + e * f;
248}

◆ sk_determinant()

static double sk_determinant ( const float  mat[9],
int  isPerspective 
)
static

Definition at line 714 of file SkMatrix.cpp.

714 {
715 if (isPerspective) {
716 return mat[SkMatrix::kMScaleX] *
719 +
720 mat[SkMatrix::kMSkewX] *
723 +
724 mat[SkMatrix::kMTransX] *
727 } else {
730 }
731}
static constexpr int kMTransY
vertical translation
Definition SkMatrix.h:358
static constexpr int kMPersp1
input y perspective factor
Definition SkMatrix.h:360
static constexpr int kMPersp0
input x perspective factor
Definition SkMatrix.h:359
static constexpr int kMPersp2
perspective bias
Definition SkMatrix.h:361
static constexpr int kMTransX
horizontal translation
Definition SkMatrix.h:355

◆ sk_inv_determinant()

static double sk_inv_determinant ( const float  mat[9],
int  isPerspective 
)
static

Definition at line 733 of file SkMatrix.cpp.

733 {
734 double det = sk_determinant(mat, isPerspective);
735
736 // Since the determinant is on the order of the cube of the matrix members,
737 // compare to the cube of the default nearly-zero constant (although an
738 // estimate of the condition number would be better if it wasn't so expensive).
741 return 0;
742 }
743 return 1.0 / det;
744}
static double sk_determinant(const float mat[9], int isPerspective)
Definition SkMatrix.cpp:714

◆ SkDecomposeUpper2x2()

bool SkDecomposeUpper2x2 ( const SkMatrix matrix,
SkPoint rotation1,
SkPoint scale,
SkPoint rotation2 
)

Decomposes the upper-left 2x2 of the matrix into a rotation (represented by the cosine and sine of the rotation angle), followed by a non-uniform scale, followed by another rotation. If there is a reflection, one of the scale factors will be negative. Returns true if successful. Returns false if the matrix is degenerate.

Definition at line 1689 of file SkMatrix.cpp.

1692 {
1693
1698
1699 if (is_degenerate_2x2(A, B, C, D)) {
1700 return false;
1701 }
1702
1703 double w1, w2;
1704 SkScalar cos1, sin1;
1705 SkScalar cos2, sin2;
1706
1707 // do polar decomposition (M = Q*S)
1708 SkScalar cosQ, sinQ;
1709 double Sa, Sb, Sd;
1710 // if M is already symmetric (i.e., M = I*S)
1711 if (SkScalarNearlyEqual(B, C)) {
1712 cosQ = 1;
1713 sinQ = 0;
1714
1715 Sa = A;
1716 Sb = B;
1717 Sd = D;
1718 } else {
1719 cosQ = A + D;
1720 sinQ = C - B;
1721 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cosQ*cosQ + sinQ*sinQ));
1722 cosQ *= reciplen;
1723 sinQ *= reciplen;
1724
1725 // S = Q^-1*M
1726 // we don't calc Sc since it's symmetric
1727 Sa = A*cosQ + C*sinQ;
1728 Sb = B*cosQ + D*sinQ;
1729 Sd = -B*sinQ + D*cosQ;
1730 }
1731
1732 // Now we need to compute eigenvalues of S (our scale factors)
1733 // and eigenvectors (bases for our rotation)
1734 // From this, should be able to reconstruct S as U*W*U^T
1736 // already diagonalized
1737 cos1 = 1;
1738 sin1 = 0;
1739 w1 = Sa;
1740 w2 = Sd;
1741 cos2 = cosQ;
1742 sin2 = sinQ;
1743 } else {
1744 double diff = Sa - Sd;
1745 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb);
1746 double trace = Sa + Sd;
1747 if (diff > 0) {
1748 w1 = 0.5*(trace + discriminant);
1749 w2 = 0.5*(trace - discriminant);
1750 } else {
1751 w1 = 0.5*(trace - discriminant);
1752 w2 = 0.5*(trace + discriminant);
1753 }
1754
1755 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa);
1756 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cos1*cos1 + sin1*sin1));
1757 cos1 *= reciplen;
1758 sin1 *= reciplen;
1759
1760 // rotation 2 is composition of Q and U
1761 cos2 = cos1*cosQ - sin1*sinQ;
1762 sin2 = sin1*cosQ + cos1*sinQ;
1763
1764 // rotation 1 is U^T
1765 sin1 = -sin1;
1766 }
1767
1768 if (scale) {
1769 scale->fX = SkDoubleToScalar(w1);
1770 scale->fY = SkDoubleToScalar(w2);
1771 }
1772 if (rotation1) {
1773 rotation1->fX = cos1;
1774 rotation1->fY = sin1;
1775 }
1776 if (rotation2) {
1777 rotation2->fX = cos2;
1778 rotation2->fY = sin2;
1779 }
1780
1781 return true;
1782}
static bool is_degenerate_2x2(SkScalar scaleX, SkScalar skewX, SkScalar skewY, SkScalar scaleY)
Definition SkMatrix.cpp:172
#define SkScalarInvert(x)
Definition SkScalar.h:73
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define B
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition SkVx.h:706
float fX
x-axis value
float fY
y-axis value

◆ SkTreatAsSprite()

bool SkTreatAsSprite ( const SkMatrix mat,
const SkISize size,
const SkSamplingOptions sampling,
bool  isAntiAlias 
)

Given a matrix, size and an antialias setting, return true if the computed dst-rect would align such that there is a 1-to-1 coorspondence between src and dst pixels. This can be called by drawing code to see if drawBitmap can be turned into drawSprite (which is faster).

The src-rect is defined to be { 0, 0, size.width(), size.height() }

Definition at line 1614 of file SkMatrix.cpp.

1615 {
1617 return false;
1618 }
1619
1620 // Our path aa is 2-bits, and our rect aa is 8, so we could use 8,
1621 // but in practice 4 seems enough (still looks smooth) and allows
1622 // more slightly fractional cases to fall into the fast (sprite) case.
1623 static const unsigned kAntiAliasSubpixelBits = 4;
1624
1625 const unsigned subpixelBits = isAntiAlias ? kAntiAliasSubpixelBits : 0;
1626
1627 // quick reject on affine or perspective
1629 return false;
1630 }
1631
1632 // We don't want to snap to pixels if we're asking for linear filtering with
1633 // a subpixel translation. (b/41322892).
1634 // This mirrors `tweak_sampling` in SkImageShader.cpp
1636 (mat.getTranslateX() != (int)mat.getTranslateX() ||
1637 mat.getTranslateY() != (int)mat.getTranslateY())) {
1638 return false;
1639 }
1640
1641 // quick success check
1642 if (!subpixelBits && !(mat.getType() & ~SkMatrix::kTranslate_Mask)) {
1643 return true;
1644 }
1645
1646 // mapRect supports negative scales, so we eliminate those first
1647 if (mat.getScaleX() < 0 || mat.getScaleY() < 0) {
1648 return false;
1649 }
1650
1651 SkRect dst;
1652 SkIRect isrc = SkIRect::MakeSize(size);
1653
1654 {
1655 SkRect src;
1656 src.set(isrc);
1657 mat.mapRect(&dst, src);
1658 }
1659
1660 // just apply the translate to isrc
1663
1664 if (subpixelBits) {
1665 isrc.fLeft = SkLeftShift(isrc.fLeft, subpixelBits);
1666 isrc.fTop = SkLeftShift(isrc.fTop, subpixelBits);
1667 isrc.fRight = SkLeftShift(isrc.fRight, subpixelBits);
1668 isrc.fBottom = SkLeftShift(isrc.fBottom, subpixelBits);
1669
1670 const float scale = 1 << subpixelBits;
1671 dst.fLeft *= scale;
1672 dst.fTop *= scale;
1673 dst.fRight *= scale;
1674 dst.fBottom *= scale;
1675 }
1676
1677 SkIRect idst;
1678 dst.round(&idst);
1679 return isrc == idst;
1680}
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
Definition SkMath.h:37
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
SkScalar getTranslateY() const
Definition SkMatrix.h:452
SkScalar getScaleX() const
Definition SkMatrix.h:415
SkScalar getScaleY() const
Definition SkMatrix.h:422
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkScalar getTranslateX() const
Definition SkMatrix.h:445
@ kTranslate_Mask
translation SkMatrix
Definition SkMatrix.h:193
@ kScale_Mask
scale SkMatrix
Definition SkMatrix.h:194
TypeMask getType() const
Definition SkMatrix.h:207
static bool NoChangeWithIdentityMatrix(const SkSamplingOptions &sampling)
SkSamplingOptions sampling
Definition SkRecords.h:337
dst
Definition cp.py:12
int32_t fBottom
larger y-axis bounds
Definition SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66
void offset(int32_t dx, int32_t dy)
Definition SkRect.h:367
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition SkRect.h:35
const SkFilterMode filter

◆ sort_as_rect()

static skvx::float4 sort_as_rect ( const skvx::float4 ltrb)
static

Definition at line 1119 of file SkMatrix.cpp.

1119 {
1120 skvx::float4 rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]);
1121 auto min = skvx::min(ltrb, rblt);
1122 auto max = skvx::max(ltrb, rblt);
1123 // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on
1124 // ARM this sequence generates the fastest (a single instruction).
1125 return skvx::float4(min[2], min[3], max[0], max[1]);
1126}
static float max(float r, float g, float b)
Definition hsl.cpp:49
static float min(float r, float g, float b)
Definition hsl.cpp:48
Vec< 4, float > float4
Definition SkVx.h:1146
SIT T max(const Vec< 1, T > &x)
Definition SkVx.h:641
SIT T min(const Vec< 1, T > &x)
Definition SkVx.h:640

Variable Documentation

◆ kScalar1Int

const int32_t kScalar1Int = 0x3f800000
static

Definition at line 80 of file SkMatrix.cpp.