SkMatrix44.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. /*
  2. * Copyright 2011 Google Inc.
  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. #include "include/core/SkMatrix44.h"
  8. #include <type_traits>
  9. #include <utility>
  10. // Copying SkMatrix44 byte-wise is performance-critical to Blink. This class is
  11. // contained in several Transform classes, which are copied multiple times
  12. // during the rendering life cycle. See crbug.com/938563 for reference.
  13. #if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
  14. // std::is_trivially_copyable is not supported for some older clang versions,
  15. // which (at least as of this patch) are in use for Chromecast.
  16. static_assert(std::is_trivially_copyable<SkMatrix44>::value,
  17. "SkMatrix44 must be trivially copyable");
  18. #endif
  19. static inline bool eq4(const SkMScalar* SK_RESTRICT a,
  20. const SkMScalar* SK_RESTRICT b) {
  21. return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]) & (a[3] == b[3]);
  22. }
  23. bool SkMatrix44::operator==(const SkMatrix44& other) const {
  24. if (this == &other) {
  25. return true;
  26. }
  27. if (this->isIdentity() && other.isIdentity()) {
  28. return true;
  29. }
  30. const SkMScalar* SK_RESTRICT a = &fMat[0][0];
  31. const SkMScalar* SK_RESTRICT b = &other.fMat[0][0];
  32. #if 0
  33. for (int i = 0; i < 16; ++i) {
  34. if (a[i] != b[i]) {
  35. return false;
  36. }
  37. }
  38. return true;
  39. #else
  40. // to reduce branch instructions, we compare 4 at a time.
  41. // see bench/Matrix44Bench.cpp for test.
  42. if (!eq4(&a[0], &b[0])) {
  43. return false;
  44. }
  45. if (!eq4(&a[4], &b[4])) {
  46. return false;
  47. }
  48. if (!eq4(&a[8], &b[8])) {
  49. return false;
  50. }
  51. return eq4(&a[12], &b[12]);
  52. #endif
  53. }
  54. ///////////////////////////////////////////////////////////////////////////////
  55. void SkMatrix44::recomputeTypeMask() {
  56. if (0 != perspX() || 0 != perspY() || 0 != perspZ() || 1 != fMat[3][3]) {
  57. fTypeMask = kTranslate_Mask | kScale_Mask | kAffine_Mask | kPerspective_Mask;
  58. return;
  59. }
  60. TypeMask mask = kIdentity_Mask;
  61. if (0 != transX() || 0 != transY() || 0 != transZ()) {
  62. mask |= kTranslate_Mask;
  63. }
  64. if (1 != scaleX() || 1 != scaleY() || 1 != scaleZ()) {
  65. mask |= kScale_Mask;
  66. }
  67. if (0 != fMat[1][0] || 0 != fMat[0][1] || 0 != fMat[0][2] ||
  68. 0 != fMat[2][0] || 0 != fMat[1][2] || 0 != fMat[2][1]) {
  69. mask |= kAffine_Mask;
  70. }
  71. fTypeMask = mask;
  72. }
  73. ///////////////////////////////////////////////////////////////////////////////
  74. void SkMatrix44::asColMajorf(float dst[]) const {
  75. const SkMScalar* src = &fMat[0][0];
  76. #ifdef SK_MSCALAR_IS_DOUBLE
  77. for (int i = 0; i < 16; ++i) {
  78. dst[i] = SkMScalarToFloat(src[i]);
  79. }
  80. #elif defined SK_MSCALAR_IS_FLOAT
  81. memcpy(dst, src, 16 * sizeof(float));
  82. #endif
  83. }
  84. void SkMatrix44::as3x4RowMajorf(float dst[]) const {
  85. dst[0] = fMat[0][0]; dst[1] = fMat[1][0]; dst[2] = fMat[2][0]; dst[3] = fMat[3][0];
  86. dst[4] = fMat[0][1]; dst[5] = fMat[1][1]; dst[6] = fMat[2][1]; dst[7] = fMat[3][1];
  87. dst[8] = fMat[0][2]; dst[9] = fMat[1][2]; dst[10] = fMat[2][2]; dst[11] = fMat[3][2];
  88. }
  89. void SkMatrix44::asColMajord(double dst[]) const {
  90. const SkMScalar* src = &fMat[0][0];
  91. #ifdef SK_MSCALAR_IS_DOUBLE
  92. memcpy(dst, src, 16 * sizeof(double));
  93. #elif defined SK_MSCALAR_IS_FLOAT
  94. for (int i = 0; i < 16; ++i) {
  95. dst[i] = SkMScalarToDouble(src[i]);
  96. }
  97. #endif
  98. }
  99. void SkMatrix44::asRowMajorf(float dst[]) const {
  100. const SkMScalar* src = &fMat[0][0];
  101. for (int i = 0; i < 4; ++i) {
  102. dst[0] = SkMScalarToFloat(src[0]);
  103. dst[4] = SkMScalarToFloat(src[1]);
  104. dst[8] = SkMScalarToFloat(src[2]);
  105. dst[12] = SkMScalarToFloat(src[3]);
  106. src += 4;
  107. dst += 1;
  108. }
  109. }
  110. void SkMatrix44::asRowMajord(double dst[]) const {
  111. const SkMScalar* src = &fMat[0][0];
  112. for (int i = 0; i < 4; ++i) {
  113. dst[0] = SkMScalarToDouble(src[0]);
  114. dst[4] = SkMScalarToDouble(src[1]);
  115. dst[8] = SkMScalarToDouble(src[2]);
  116. dst[12] = SkMScalarToDouble(src[3]);
  117. src += 4;
  118. dst += 1;
  119. }
  120. }
  121. void SkMatrix44::setColMajorf(const float src[]) {
  122. SkMScalar* dst = &fMat[0][0];
  123. #ifdef SK_MSCALAR_IS_DOUBLE
  124. for (int i = 0; i < 16; ++i) {
  125. dst[i] = SkMScalarToFloat(src[i]);
  126. }
  127. #elif defined SK_MSCALAR_IS_FLOAT
  128. memcpy(dst, src, 16 * sizeof(float));
  129. #endif
  130. this->recomputeTypeMask();
  131. }
  132. void SkMatrix44::setColMajord(const double src[]) {
  133. SkMScalar* dst = &fMat[0][0];
  134. #ifdef SK_MSCALAR_IS_DOUBLE
  135. memcpy(dst, src, 16 * sizeof(double));
  136. #elif defined SK_MSCALAR_IS_FLOAT
  137. for (int i = 0; i < 16; ++i) {
  138. dst[i] = SkDoubleToMScalar(src[i]);
  139. }
  140. #endif
  141. this->recomputeTypeMask();
  142. }
  143. void SkMatrix44::setRowMajorf(const float src[]) {
  144. SkMScalar* dst = &fMat[0][0];
  145. for (int i = 0; i < 4; ++i) {
  146. dst[0] = SkMScalarToFloat(src[0]);
  147. dst[4] = SkMScalarToFloat(src[1]);
  148. dst[8] = SkMScalarToFloat(src[2]);
  149. dst[12] = SkMScalarToFloat(src[3]);
  150. src += 4;
  151. dst += 1;
  152. }
  153. this->recomputeTypeMask();
  154. }
  155. void SkMatrix44::setRowMajord(const double src[]) {
  156. SkMScalar* dst = &fMat[0][0];
  157. for (int i = 0; i < 4; ++i) {
  158. dst[0] = SkDoubleToMScalar(src[0]);
  159. dst[4] = SkDoubleToMScalar(src[1]);
  160. dst[8] = SkDoubleToMScalar(src[2]);
  161. dst[12] = SkDoubleToMScalar(src[3]);
  162. src += 4;
  163. dst += 1;
  164. }
  165. this->recomputeTypeMask();
  166. }
  167. ///////////////////////////////////////////////////////////////////////////////
  168. const SkMatrix44& SkMatrix44::I() {
  169. static constexpr SkMatrix44 gIdentity44(kIdentity_Constructor);
  170. return gIdentity44;
  171. }
  172. void SkMatrix44::setIdentity() {
  173. fMat[0][0] = 1;
  174. fMat[0][1] = 0;
  175. fMat[0][2] = 0;
  176. fMat[0][3] = 0;
  177. fMat[1][0] = 0;
  178. fMat[1][1] = 1;
  179. fMat[1][2] = 0;
  180. fMat[1][3] = 0;
  181. fMat[2][0] = 0;
  182. fMat[2][1] = 0;
  183. fMat[2][2] = 1;
  184. fMat[2][3] = 0;
  185. fMat[3][0] = 0;
  186. fMat[3][1] = 0;
  187. fMat[3][2] = 0;
  188. fMat[3][3] = 1;
  189. this->setTypeMask(kIdentity_Mask);
  190. }
  191. void SkMatrix44::set3x3(SkMScalar m_00, SkMScalar m_10, SkMScalar m_20,
  192. SkMScalar m_01, SkMScalar m_11, SkMScalar m_21,
  193. SkMScalar m_02, SkMScalar m_12, SkMScalar m_22) {
  194. fMat[0][0] = m_00; fMat[0][1] = m_10; fMat[0][2] = m_20; fMat[0][3] = 0;
  195. fMat[1][0] = m_01; fMat[1][1] = m_11; fMat[1][2] = m_21; fMat[1][3] = 0;
  196. fMat[2][0] = m_02; fMat[2][1] = m_12; fMat[2][2] = m_22; fMat[2][3] = 0;
  197. fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1;
  198. this->recomputeTypeMask();
  199. }
  200. void SkMatrix44::set3x3RowMajorf(const float src[]) {
  201. fMat[0][0] = src[0]; fMat[0][1] = src[3]; fMat[0][2] = src[6]; fMat[0][3] = 0;
  202. fMat[1][0] = src[1]; fMat[1][1] = src[4]; fMat[1][2] = src[7]; fMat[1][3] = 0;
  203. fMat[2][0] = src[2]; fMat[2][1] = src[5]; fMat[2][2] = src[8]; fMat[2][3] = 0;
  204. fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1;
  205. this->recomputeTypeMask();
  206. }
  207. void SkMatrix44::set3x4RowMajorf(const float src[]) {
  208. fMat[0][0] = src[0]; fMat[1][0] = src[1]; fMat[2][0] = src[2]; fMat[3][0] = src[3];
  209. fMat[0][1] = src[4]; fMat[1][1] = src[5]; fMat[2][1] = src[6]; fMat[3][1] = src[7];
  210. fMat[0][2] = src[8]; fMat[1][2] = src[9]; fMat[2][2] = src[10]; fMat[3][2] = src[11];
  211. fMat[0][3] = 0; fMat[1][3] = 0; fMat[2][3] = 0; fMat[3][3] = 1;
  212. this->recomputeTypeMask();
  213. }
  214. void SkMatrix44::set4x4(SkMScalar m_00, SkMScalar m_10, SkMScalar m_20, SkMScalar m_30,
  215. SkMScalar m_01, SkMScalar m_11, SkMScalar m_21, SkMScalar m_31,
  216. SkMScalar m_02, SkMScalar m_12, SkMScalar m_22, SkMScalar m_32,
  217. SkMScalar m_03, SkMScalar m_13, SkMScalar m_23, SkMScalar m_33) {
  218. fMat[0][0] = m_00; fMat[0][1] = m_10; fMat[0][2] = m_20; fMat[0][3] = m_30;
  219. fMat[1][0] = m_01; fMat[1][1] = m_11; fMat[1][2] = m_21; fMat[1][3] = m_31;
  220. fMat[2][0] = m_02; fMat[2][1] = m_12; fMat[2][2] = m_22; fMat[2][3] = m_32;
  221. fMat[3][0] = m_03; fMat[3][1] = m_13; fMat[3][2] = m_23; fMat[3][3] = m_33;
  222. this->recomputeTypeMask();
  223. }
  224. ///////////////////////////////////////////////////////////////////////////////
  225. void SkMatrix44::setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
  226. this->setIdentity();
  227. if (!dx && !dy && !dz) {
  228. return;
  229. }
  230. fMat[3][0] = dx;
  231. fMat[3][1] = dy;
  232. fMat[3][2] = dz;
  233. this->setTypeMask(kTranslate_Mask);
  234. }
  235. void SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
  236. if (!dx && !dy && !dz) {
  237. return;
  238. }
  239. for (int i = 0; i < 4; ++i) {
  240. fMat[3][i] = fMat[0][i] * dx + fMat[1][i] * dy + fMat[2][i] * dz + fMat[3][i];
  241. }
  242. this->recomputeTypeMask();
  243. }
  244. void SkMatrix44::postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
  245. if (!dx && !dy && !dz) {
  246. return;
  247. }
  248. if (this->getType() & kPerspective_Mask) {
  249. for (int i = 0; i < 4; ++i) {
  250. fMat[i][0] += fMat[i][3] * dx;
  251. fMat[i][1] += fMat[i][3] * dy;
  252. fMat[i][2] += fMat[i][3] * dz;
  253. }
  254. } else {
  255. fMat[3][0] += dx;
  256. fMat[3][1] += dy;
  257. fMat[3][2] += dz;
  258. this->recomputeTypeMask();
  259. }
  260. }
  261. ///////////////////////////////////////////////////////////////////////////////
  262. void SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
  263. this->setIdentity();
  264. if (1 == sx && 1 == sy && 1 == sz) {
  265. return;
  266. }
  267. fMat[0][0] = sx;
  268. fMat[1][1] = sy;
  269. fMat[2][2] = sz;
  270. this->setTypeMask(kScale_Mask);
  271. }
  272. void SkMatrix44::preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
  273. if (1 == sx && 1 == sy && 1 == sz) {
  274. return;
  275. }
  276. // The implementation matrix * pureScale can be shortcut
  277. // by knowing that pureScale components effectively scale
  278. // the columns of the original matrix.
  279. for (int i = 0; i < 4; i++) {
  280. fMat[0][i] *= sx;
  281. fMat[1][i] *= sy;
  282. fMat[2][i] *= sz;
  283. }
  284. this->recomputeTypeMask();
  285. }
  286. void SkMatrix44::postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
  287. if (1 == sx && 1 == sy && 1 == sz) {
  288. return;
  289. }
  290. for (int i = 0; i < 4; i++) {
  291. fMat[i][0] *= sx;
  292. fMat[i][1] *= sy;
  293. fMat[i][2] *= sz;
  294. }
  295. this->recomputeTypeMask();
  296. }
  297. ///////////////////////////////////////////////////////////////////////////////
  298. void SkMatrix44::setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
  299. SkMScalar radians) {
  300. double len2 = (double)x * x + (double)y * y + (double)z * z;
  301. if (1 != len2) {
  302. if (0 == len2) {
  303. this->setIdentity();
  304. return;
  305. }
  306. double scale = 1 / sqrt(len2);
  307. x = SkDoubleToMScalar(x * scale);
  308. y = SkDoubleToMScalar(y * scale);
  309. z = SkDoubleToMScalar(z * scale);
  310. }
  311. this->setRotateAboutUnit(x, y, z, radians);
  312. }
  313. void SkMatrix44::setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
  314. SkMScalar radians) {
  315. double c = cos(radians);
  316. double s = sin(radians);
  317. double C = 1 - c;
  318. double xs = x * s;
  319. double ys = y * s;
  320. double zs = z * s;
  321. double xC = x * C;
  322. double yC = y * C;
  323. double zC = z * C;
  324. double xyC = x * yC;
  325. double yzC = y * zC;
  326. double zxC = z * xC;
  327. // if you're looking at wikipedia, remember that we're column major.
  328. this->set3x3(SkDoubleToMScalar(x * xC + c), // scale x
  329. SkDoubleToMScalar(xyC + zs), // skew x
  330. SkDoubleToMScalar(zxC - ys), // trans x
  331. SkDoubleToMScalar(xyC - zs), // skew y
  332. SkDoubleToMScalar(y * yC + c), // scale y
  333. SkDoubleToMScalar(yzC + xs), // trans y
  334. SkDoubleToMScalar(zxC + ys), // persp x
  335. SkDoubleToMScalar(yzC - xs), // persp y
  336. SkDoubleToMScalar(z * zC + c)); // persp 2
  337. }
  338. ///////////////////////////////////////////////////////////////////////////////
  339. static bool bits_isonly(int value, int mask) {
  340. return 0 == (value & ~mask);
  341. }
  342. void SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) {
  343. const SkMatrix44::TypeMask a_mask = a.getType();
  344. const SkMatrix44::TypeMask b_mask = b.getType();
  345. if (kIdentity_Mask == a_mask) {
  346. *this = b;
  347. return;
  348. }
  349. if (kIdentity_Mask == b_mask) {
  350. *this = a;
  351. return;
  352. }
  353. bool useStorage = (this == &a || this == &b);
  354. SkMScalar storage[16];
  355. SkMScalar* result = useStorage ? storage : &fMat[0][0];
  356. // Both matrices are at most scale+translate
  357. if (bits_isonly(a_mask | b_mask, kScale_Mask | kTranslate_Mask)) {
  358. result[0] = a.fMat[0][0] * b.fMat[0][0];
  359. result[1] = result[2] = result[3] = result[4] = 0;
  360. result[5] = a.fMat[1][1] * b.fMat[1][1];
  361. result[6] = result[7] = result[8] = result[9] = 0;
  362. result[10] = a.fMat[2][2] * b.fMat[2][2];
  363. result[11] = 0;
  364. result[12] = a.fMat[0][0] * b.fMat[3][0] + a.fMat[3][0];
  365. result[13] = a.fMat[1][1] * b.fMat[3][1] + a.fMat[3][1];
  366. result[14] = a.fMat[2][2] * b.fMat[3][2] + a.fMat[3][2];
  367. result[15] = 1;
  368. } else {
  369. for (int j = 0; j < 4; j++) {
  370. for (int i = 0; i < 4; i++) {
  371. double value = 0;
  372. for (int k = 0; k < 4; k++) {
  373. value += SkMScalarToDouble(a.fMat[k][i]) * b.fMat[j][k];
  374. }
  375. *result++ = SkDoubleToMScalar(value);
  376. }
  377. }
  378. }
  379. if (useStorage) {
  380. memcpy(fMat, storage, sizeof(storage));
  381. }
  382. this->recomputeTypeMask();
  383. }
  384. ///////////////////////////////////////////////////////////////////////////////
  385. /** We always perform the calculation in doubles, to avoid prematurely losing
  386. precision along the way. This relies on the compiler automatically
  387. promoting our SkMScalar values to double (if needed).
  388. */
  389. double SkMatrix44::determinant() const {
  390. if (this->isIdentity()) {
  391. return 1;
  392. }
  393. if (this->isScaleTranslate()) {
  394. return fMat[0][0] * fMat[1][1] * fMat[2][2] * fMat[3][3];
  395. }
  396. double a00 = fMat[0][0];
  397. double a01 = fMat[0][1];
  398. double a02 = fMat[0][2];
  399. double a03 = fMat[0][3];
  400. double a10 = fMat[1][0];
  401. double a11 = fMat[1][1];
  402. double a12 = fMat[1][2];
  403. double a13 = fMat[1][3];
  404. double a20 = fMat[2][0];
  405. double a21 = fMat[2][1];
  406. double a22 = fMat[2][2];
  407. double a23 = fMat[2][3];
  408. double a30 = fMat[3][0];
  409. double a31 = fMat[3][1];
  410. double a32 = fMat[3][2];
  411. double a33 = fMat[3][3];
  412. double b00 = a00 * a11 - a01 * a10;
  413. double b01 = a00 * a12 - a02 * a10;
  414. double b02 = a00 * a13 - a03 * a10;
  415. double b03 = a01 * a12 - a02 * a11;
  416. double b04 = a01 * a13 - a03 * a11;
  417. double b05 = a02 * a13 - a03 * a12;
  418. double b06 = a20 * a31 - a21 * a30;
  419. double b07 = a20 * a32 - a22 * a30;
  420. double b08 = a20 * a33 - a23 * a30;
  421. double b09 = a21 * a32 - a22 * a31;
  422. double b10 = a21 * a33 - a23 * a31;
  423. double b11 = a22 * a33 - a23 * a32;
  424. // Calculate the determinant
  425. return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  426. }
  427. ///////////////////////////////////////////////////////////////////////////////
  428. static bool is_matrix_finite(const SkMatrix44& matrix) {
  429. SkMScalar accumulator = 0;
  430. for (int row = 0; row < 4; ++row) {
  431. for (int col = 0; col < 4; ++col) {
  432. accumulator *= matrix.get(row, col);
  433. }
  434. }
  435. return accumulator == 0;
  436. }
  437. bool SkMatrix44::invert(SkMatrix44* storage) const {
  438. if (this->isIdentity()) {
  439. if (storage) {
  440. storage->setIdentity();
  441. }
  442. return true;
  443. }
  444. if (this->isTranslate()) {
  445. if (storage) {
  446. storage->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]);
  447. }
  448. return true;
  449. }
  450. SkMatrix44 tmp;
  451. // Use storage if it's available and distinct from this matrix.
  452. SkMatrix44* inverse = (storage && storage != this) ? storage : &tmp;
  453. if (this->isScaleTranslate()) {
  454. if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) {
  455. return false;
  456. }
  457. double invXScale = 1 / fMat[0][0];
  458. double invYScale = 1 / fMat[1][1];
  459. double invZScale = 1 / fMat[2][2];
  460. inverse->fMat[0][0] = SkDoubleToMScalar(invXScale);
  461. inverse->fMat[0][1] = 0;
  462. inverse->fMat[0][2] = 0;
  463. inverse->fMat[0][3] = 0;
  464. inverse->fMat[1][0] = 0;
  465. inverse->fMat[1][1] = SkDoubleToMScalar(invYScale);
  466. inverse->fMat[1][2] = 0;
  467. inverse->fMat[1][3] = 0;
  468. inverse->fMat[2][0] = 0;
  469. inverse->fMat[2][1] = 0;
  470. inverse->fMat[2][2] = SkDoubleToMScalar(invZScale);
  471. inverse->fMat[2][3] = 0;
  472. inverse->fMat[3][0] = SkDoubleToMScalar(-fMat[3][0] * invXScale);
  473. inverse->fMat[3][1] = SkDoubleToMScalar(-fMat[3][1] * invYScale);
  474. inverse->fMat[3][2] = SkDoubleToMScalar(-fMat[3][2] * invZScale);
  475. inverse->fMat[3][3] = 1;
  476. inverse->setTypeMask(this->getType());
  477. if (!is_matrix_finite(*inverse)) {
  478. return false;
  479. }
  480. if (storage && inverse != storage) {
  481. *storage = *inverse;
  482. }
  483. return true;
  484. }
  485. double a00 = fMat[0][0];
  486. double a01 = fMat[0][1];
  487. double a02 = fMat[0][2];
  488. double a03 = fMat[0][3];
  489. double a10 = fMat[1][0];
  490. double a11 = fMat[1][1];
  491. double a12 = fMat[1][2];
  492. double a13 = fMat[1][3];
  493. double a20 = fMat[2][0];
  494. double a21 = fMat[2][1];
  495. double a22 = fMat[2][2];
  496. double a23 = fMat[2][3];
  497. double a30 = fMat[3][0];
  498. double a31 = fMat[3][1];
  499. double a32 = fMat[3][2];
  500. double a33 = fMat[3][3];
  501. if (!(this->getType() & kPerspective_Mask)) {
  502. // If we know the matrix has no perspective, then the perspective
  503. // component is (0, 0, 0, 1). We can use this information to save a lot
  504. // of arithmetic that would otherwise be spent to compute the inverse
  505. // of a general matrix.
  506. SkASSERT(a03 == 0);
  507. SkASSERT(a13 == 0);
  508. SkASSERT(a23 == 0);
  509. SkASSERT(a33 == 1);
  510. double b00 = a00 * a11 - a01 * a10;
  511. double b01 = a00 * a12 - a02 * a10;
  512. double b03 = a01 * a12 - a02 * a11;
  513. double b06 = a20 * a31 - a21 * a30;
  514. double b07 = a20 * a32 - a22 * a30;
  515. double b08 = a20;
  516. double b09 = a21 * a32 - a22 * a31;
  517. double b10 = a21;
  518. double b11 = a22;
  519. // Calculate the determinant
  520. double det = b00 * b11 - b01 * b10 + b03 * b08;
  521. double invdet = sk_ieee_double_divide(1.0, det);
  522. // If det is zero, we want to return false. However, we also want to return false
  523. // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are
  524. // handled by checking that 1/det is finite.
  525. if (!sk_float_isfinite(sk_double_to_float(invdet))) {
  526. return false;
  527. }
  528. b00 *= invdet;
  529. b01 *= invdet;
  530. b03 *= invdet;
  531. b06 *= invdet;
  532. b07 *= invdet;
  533. b08 *= invdet;
  534. b09 *= invdet;
  535. b10 *= invdet;
  536. b11 *= invdet;
  537. inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10);
  538. inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11);
  539. inverse->fMat[0][2] = SkDoubleToMScalar(b03);
  540. inverse->fMat[0][3] = 0;
  541. inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11);
  542. inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08);
  543. inverse->fMat[1][2] = SkDoubleToMScalar(-b01);
  544. inverse->fMat[1][3] = 0;
  545. inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08);
  546. inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10);
  547. inverse->fMat[2][2] = SkDoubleToMScalar(b00);
  548. inverse->fMat[2][3] = 0;
  549. inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06);
  550. inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
  551. inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
  552. inverse->fMat[3][3] = 1;
  553. inverse->setTypeMask(this->getType());
  554. if (!is_matrix_finite(*inverse)) {
  555. return false;
  556. }
  557. if (storage && inverse != storage) {
  558. *storage = *inverse;
  559. }
  560. return true;
  561. }
  562. double b00 = a00 * a11 - a01 * a10;
  563. double b01 = a00 * a12 - a02 * a10;
  564. double b02 = a00 * a13 - a03 * a10;
  565. double b03 = a01 * a12 - a02 * a11;
  566. double b04 = a01 * a13 - a03 * a11;
  567. double b05 = a02 * a13 - a03 * a12;
  568. double b06 = a20 * a31 - a21 * a30;
  569. double b07 = a20 * a32 - a22 * a30;
  570. double b08 = a20 * a33 - a23 * a30;
  571. double b09 = a21 * a32 - a22 * a31;
  572. double b10 = a21 * a33 - a23 * a31;
  573. double b11 = a22 * a33 - a23 * a32;
  574. // Calculate the determinant
  575. double det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  576. double invdet = sk_ieee_double_divide(1.0, det);
  577. // If det is zero, we want to return false. However, we also want to return false
  578. // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are
  579. // handled by checking that 1/det is finite.
  580. if (!sk_float_isfinite(sk_double_to_float(invdet))) {
  581. return false;
  582. }
  583. b00 *= invdet;
  584. b01 *= invdet;
  585. b02 *= invdet;
  586. b03 *= invdet;
  587. b04 *= invdet;
  588. b05 *= invdet;
  589. b06 *= invdet;
  590. b07 *= invdet;
  591. b08 *= invdet;
  592. b09 *= invdet;
  593. b10 *= invdet;
  594. b11 *= invdet;
  595. inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10 + a13 * b09);
  596. inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11 - a03 * b09);
  597. inverse->fMat[0][2] = SkDoubleToMScalar(a31 * b05 - a32 * b04 + a33 * b03);
  598. inverse->fMat[0][3] = SkDoubleToMScalar(a22 * b04 - a21 * b05 - a23 * b03);
  599. inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11 - a13 * b07);
  600. inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08 + a03 * b07);
  601. inverse->fMat[1][2] = SkDoubleToMScalar(a32 * b02 - a30 * b05 - a33 * b01);
  602. inverse->fMat[1][3] = SkDoubleToMScalar(a20 * b05 - a22 * b02 + a23 * b01);
  603. inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08 + a13 * b06);
  604. inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10 - a03 * b06);
  605. inverse->fMat[2][2] = SkDoubleToMScalar(a30 * b04 - a31 * b02 + a33 * b00);
  606. inverse->fMat[2][3] = SkDoubleToMScalar(a21 * b02 - a20 * b04 - a23 * b00);
  607. inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06);
  608. inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
  609. inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
  610. inverse->fMat[3][3] = SkDoubleToMScalar(a20 * b03 - a21 * b01 + a22 * b00);
  611. inverse->setTypeMask(this->getType());
  612. if (!is_matrix_finite(*inverse)) {
  613. return false;
  614. }
  615. if (storage && inverse != storage) {
  616. *storage = *inverse;
  617. }
  618. return true;
  619. }
  620. ///////////////////////////////////////////////////////////////////////////////
  621. void SkMatrix44::transpose() {
  622. if (!this->isIdentity()) {
  623. using std::swap;
  624. swap(fMat[0][1], fMat[1][0]);
  625. swap(fMat[0][2], fMat[2][0]);
  626. swap(fMat[0][3], fMat[3][0]);
  627. swap(fMat[1][2], fMat[2][1]);
  628. swap(fMat[1][3], fMat[3][1]);
  629. swap(fMat[2][3], fMat[3][2]);
  630. this->recomputeTypeMask();
  631. }
  632. }
  633. ///////////////////////////////////////////////////////////////////////////////
  634. void SkMatrix44::mapScalars(const SkScalar src[4], SkScalar dst[4]) const {
  635. SkScalar storage[4];
  636. SkScalar* result = (src == dst) ? storage : dst;
  637. for (int i = 0; i < 4; i++) {
  638. SkMScalar value = 0;
  639. for (int j = 0; j < 4; j++) {
  640. value += fMat[j][i] * src[j];
  641. }
  642. result[i] = SkMScalarToScalar(value);
  643. }
  644. if (storage == result) {
  645. memcpy(dst, storage, sizeof(storage));
  646. }
  647. }
  648. #ifdef SK_MSCALAR_IS_DOUBLE
  649. void SkMatrix44::mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const {
  650. SkMScalar storage[4];
  651. SkMScalar* result = (src == dst) ? storage : dst;
  652. for (int i = 0; i < 4; i++) {
  653. SkMScalar value = 0;
  654. for (int j = 0; j < 4; j++) {
  655. value += fMat[j][i] * src[j];
  656. }
  657. result[i] = value;
  658. }
  659. if (storage == result) {
  660. memcpy(dst, storage, sizeof(storage));
  661. }
  662. }
  663. #endif
  664. typedef void (*Map2Procf)(const SkMScalar mat[][4], const float src2[], int count, float dst4[]);
  665. typedef void (*Map2Procd)(const SkMScalar mat[][4], const double src2[], int count, double dst4[]);
  666. static void map2_if(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
  667. int count, float* SK_RESTRICT dst4) {
  668. for (int i = 0; i < count; ++i) {
  669. dst4[0] = src2[0];
  670. dst4[1] = src2[1];
  671. dst4[2] = 0;
  672. dst4[3] = 1;
  673. src2 += 2;
  674. dst4 += 4;
  675. }
  676. }
  677. static void map2_id(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
  678. int count, double* SK_RESTRICT dst4) {
  679. for (int i = 0; i < count; ++i) {
  680. dst4[0] = src2[0];
  681. dst4[1] = src2[1];
  682. dst4[2] = 0;
  683. dst4[3] = 1;
  684. src2 += 2;
  685. dst4 += 4;
  686. }
  687. }
  688. static void map2_tf(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
  689. int count, float* SK_RESTRICT dst4) {
  690. const float mat30 = SkMScalarToFloat(mat[3][0]);
  691. const float mat31 = SkMScalarToFloat(mat[3][1]);
  692. const float mat32 = SkMScalarToFloat(mat[3][2]);
  693. for (int n = 0; n < count; ++n) {
  694. dst4[0] = src2[0] + mat30;
  695. dst4[1] = src2[1] + mat31;
  696. dst4[2] = mat32;
  697. dst4[3] = 1;
  698. src2 += 2;
  699. dst4 += 4;
  700. }
  701. }
  702. static void map2_td(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
  703. int count, double* SK_RESTRICT dst4) {
  704. for (int n = 0; n < count; ++n) {
  705. dst4[0] = src2[0] + mat[3][0];
  706. dst4[1] = src2[1] + mat[3][1];
  707. dst4[2] = mat[3][2];
  708. dst4[3] = 1;
  709. src2 += 2;
  710. dst4 += 4;
  711. }
  712. }
  713. static void map2_sf(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
  714. int count, float* SK_RESTRICT dst4) {
  715. const float mat32 = SkMScalarToFloat(mat[3][2]);
  716. for (int n = 0; n < count; ++n) {
  717. dst4[0] = SkMScalarToFloat(mat[0][0] * src2[0] + mat[3][0]);
  718. dst4[1] = SkMScalarToFloat(mat[1][1] * src2[1] + mat[3][1]);
  719. dst4[2] = mat32;
  720. dst4[3] = 1;
  721. src2 += 2;
  722. dst4 += 4;
  723. }
  724. }
  725. static void map2_sd(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
  726. int count, double* SK_RESTRICT dst4) {
  727. for (int n = 0; n < count; ++n) {
  728. dst4[0] = mat[0][0] * src2[0] + mat[3][0];
  729. dst4[1] = mat[1][1] * src2[1] + mat[3][1];
  730. dst4[2] = mat[3][2];
  731. dst4[3] = 1;
  732. src2 += 2;
  733. dst4 += 4;
  734. }
  735. }
  736. static void map2_af(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
  737. int count, float* SK_RESTRICT dst4) {
  738. SkMScalar r;
  739. for (int n = 0; n < count; ++n) {
  740. SkMScalar sx = SkFloatToMScalar(src2[0]);
  741. SkMScalar sy = SkFloatToMScalar(src2[1]);
  742. r = mat[0][0] * sx + mat[1][0] * sy + mat[3][0];
  743. dst4[0] = SkMScalarToFloat(r);
  744. r = mat[0][1] * sx + mat[1][1] * sy + mat[3][1];
  745. dst4[1] = SkMScalarToFloat(r);
  746. r = mat[0][2] * sx + mat[1][2] * sy + mat[3][2];
  747. dst4[2] = SkMScalarToFloat(r);
  748. dst4[3] = 1;
  749. src2 += 2;
  750. dst4 += 4;
  751. }
  752. }
  753. static void map2_ad(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
  754. int count, double* SK_RESTRICT dst4) {
  755. for (int n = 0; n < count; ++n) {
  756. double sx = src2[0];
  757. double sy = src2[1];
  758. dst4[0] = mat[0][0] * sx + mat[1][0] * sy + mat[3][0];
  759. dst4[1] = mat[0][1] * sx + mat[1][1] * sy + mat[3][1];
  760. dst4[2] = mat[0][2] * sx + mat[1][2] * sy + mat[3][2];
  761. dst4[3] = 1;
  762. src2 += 2;
  763. dst4 += 4;
  764. }
  765. }
  766. static void map2_pf(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
  767. int count, float* SK_RESTRICT dst4) {
  768. SkMScalar r;
  769. for (int n = 0; n < count; ++n) {
  770. SkMScalar sx = SkFloatToMScalar(src2[0]);
  771. SkMScalar sy = SkFloatToMScalar(src2[1]);
  772. for (int i = 0; i < 4; i++) {
  773. r = mat[0][i] * sx + mat[1][i] * sy + mat[3][i];
  774. dst4[i] = SkMScalarToFloat(r);
  775. }
  776. src2 += 2;
  777. dst4 += 4;
  778. }
  779. }
  780. static void map2_pd(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
  781. int count, double* SK_RESTRICT dst4) {
  782. for (int n = 0; n < count; ++n) {
  783. double sx = src2[0];
  784. double sy = src2[1];
  785. for (int i = 0; i < 4; i++) {
  786. dst4[i] = mat[0][i] * sx + mat[1][i] * sy + mat[3][i];
  787. }
  788. src2 += 2;
  789. dst4 += 4;
  790. }
  791. }
  792. void SkMatrix44::map2(const float src2[], int count, float dst4[]) const {
  793. static const Map2Procf gProc[] = {
  794. map2_if, map2_tf, map2_sf, map2_sf, map2_af, map2_af, map2_af, map2_af
  795. };
  796. TypeMask mask = this->getType();
  797. Map2Procf proc = (mask & kPerspective_Mask) ? map2_pf : gProc[mask];
  798. proc(fMat, src2, count, dst4);
  799. }
  800. void SkMatrix44::map2(const double src2[], int count, double dst4[]) const {
  801. static const Map2Procd gProc[] = {
  802. map2_id, map2_td, map2_sd, map2_sd, map2_ad, map2_ad, map2_ad, map2_ad
  803. };
  804. TypeMask mask = this->getType();
  805. Map2Procd proc = (mask & kPerspective_Mask) ? map2_pd : gProc[mask];
  806. proc(fMat, src2, count, dst4);
  807. }
  808. bool SkMatrix44::preserves2dAxisAlignment (SkMScalar epsilon) const {
  809. // Can't check (mask & kPerspective_Mask) because Z isn't relevant here.
  810. if (0 != perspX() || 0 != perspY()) return false;
  811. // A matrix with two non-zeroish values in any of the upper right
  812. // rows or columns will skew. If only one value in each row or
  813. // column is non-zeroish, we get a scale plus perhaps a 90-degree
  814. // rotation.
  815. int col0 = 0;
  816. int col1 = 0;
  817. int row0 = 0;
  818. int row1 = 0;
  819. // Must test against epsilon, not 0, because we can get values
  820. // around 6e-17 in the matrix that "should" be 0.
  821. if (SkMScalarAbs(fMat[0][0]) > epsilon) {
  822. col0++;
  823. row0++;
  824. }
  825. if (SkMScalarAbs(fMat[0][1]) > epsilon) {
  826. col1++;
  827. row0++;
  828. }
  829. if (SkMScalarAbs(fMat[1][0]) > epsilon) {
  830. col0++;
  831. row1++;
  832. }
  833. if (SkMScalarAbs(fMat[1][1]) > epsilon) {
  834. col1++;
  835. row1++;
  836. }
  837. if (col0 > 1 || col1 > 1 || row0 > 1 || row1 > 1) {
  838. return false;
  839. }
  840. return true;
  841. }
  842. ///////////////////////////////////////////////////////////////////////////////
  843. void SkMatrix44::dump() const {
  844. static const char* format = "|%g %g %g %g|\n"
  845. "|%g %g %g %g|\n"
  846. "|%g %g %g %g|\n"
  847. "|%g %g %g %g|\n";
  848. SkDebugf(format,
  849. fMat[0][0], fMat[1][0], fMat[2][0], fMat[3][0],
  850. fMat[0][1], fMat[1][1], fMat[2][1], fMat[3][1],
  851. fMat[0][2], fMat[1][2], fMat[2][2], fMat[3][2],
  852. fMat[0][3], fMat[1][3], fMat[2][3], fMat[3][3]);
  853. }
  854. ///////////////////////////////////////////////////////////////////////////////
  855. static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) {
  856. dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]);
  857. dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]);
  858. dst[2][0] = 0;
  859. dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]);
  860. dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]);
  861. dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]);
  862. dst[2][1] = 0;
  863. dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]);
  864. dst[0][2] = 0;
  865. dst[1][2] = 0;
  866. dst[2][2] = 1;
  867. dst[3][2] = 0;
  868. dst[0][3] = SkScalarToMScalar(src[SkMatrix::kMPersp0]);
  869. dst[1][3] = SkScalarToMScalar(src[SkMatrix::kMPersp1]);
  870. dst[2][3] = 0;
  871. dst[3][3] = SkScalarToMScalar(src[SkMatrix::kMPersp2]);
  872. }
  873. SkMatrix44::SkMatrix44(const SkMatrix& src) {
  874. this->operator=(src);
  875. }
  876. SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) {
  877. initFromMatrix(fMat, src);
  878. if (src.isIdentity()) {
  879. this->setTypeMask(kIdentity_Mask);
  880. } else {
  881. this->recomputeTypeMask();
  882. }
  883. return *this;
  884. }
  885. SkMatrix44::operator SkMatrix() const {
  886. SkMatrix dst;
  887. dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]);
  888. dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]);
  889. dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]);
  890. dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]);
  891. dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]);
  892. dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]);
  893. dst[SkMatrix::kMPersp0] = SkMScalarToScalar(fMat[0][3]);
  894. dst[SkMatrix::kMPersp1] = SkMScalarToScalar(fMat[1][3]);
  895. dst[SkMatrix::kMPersp2] = SkMScalarToScalar(fMat[3][3]);
  896. return dst;
  897. }