Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: src/core/SkMatrix.cpp

Issue 1045493002: use Sk4f for matrix math (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkMatrix.h ('k') | tests/MatrixTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkMatrix.h" 8 #include "SkMatrix.h"
9 #include "SkFloatBits.h" 9 #include "SkFloatBits.h"
10 #include "SkString.h" 10 #include "SkString.h"
11 #include "Sk4x.h"
11 12
12 #include <stddef.h> 13 #include <stddef.h>
13 14
14 static void normalize_perspective(SkScalar mat[9]) { 15 static void normalize_perspective(SkScalar mat[9]) {
15 // If it was interesting to never store the last element, we could divide al l 8 other 16 // If it was interesting to never store the last element, we could divide al l 8 other
16 // elements here by the 9th, making it 1.0... 17 // elements here by the 9th, making it 1.0...
17 // 18 //
18 // When SkScalar was SkFixed, we would sometimes rescale the entire matrix t o keep its 19 // When SkScalar was SkFixed, we would sometimes rescale the entire matrix t o keep its
19 // component values from getting too large. This is not a concern when using floats/doubles, 20 // component values from getting too large. This is not a concern when using floats/doubles,
20 // so we do nothing now. 21 // so we do nothing now.
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 861
861 if (inv == &tmp) { 862 if (inv == &tmp) {
862 *(SkMatrix*)this = tmp; 863 *(SkMatrix*)this = tmp;
863 } 864 }
864 } 865 }
865 return true; 866 return true;
866 } 867 }
867 868
868 /////////////////////////////////////////////////////////////////////////////// 869 ///////////////////////////////////////////////////////////////////////////////
869 870
870 void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], 871 void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[ ], int count) {
871 const SkPoint src[], int count) {
872 SkASSERT(m.getType() == 0); 872 SkASSERT(m.getType() == 0);
873 873
874 if (dst != src && count > 0) 874 if (dst != src && count > 0) {
875 memcpy(dst, src, count * sizeof(SkPoint)); 875 memcpy(dst, src, count * sizeof(SkPoint));
876 }
877
878 void SkMatrix::Trans_pts(const SkMatrix& m, SkPoint dst[],
879 const SkPoint src[], int count) {
880 SkASSERT(m.getType() == kTranslate_Mask);
881
882 if (count > 0) {
883 SkScalar tx = m.fMat[kMTransX];
884 SkScalar ty = m.fMat[kMTransY];
885 do {
886 dst->fY = src->fY + ty;
887 dst->fX = src->fX + tx;
888 src += 1;
889 dst += 1;
890 } while (--count);
891 } 876 }
892 } 877 }
893 878
894 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], 879 void SkMatrix::Trans_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
895 const SkPoint src[], int count) { 880 SkASSERT(m.getType() <= kTranslate_Mask);
896 SkASSERT(m.getType() == kScale_Mask); 881
897
898 if (count > 0) { 882 if (count > 0) {
899 SkScalar mx = m.fMat[kMScaleX]; 883 SkScalar tx = m.getTranslateX();
900 SkScalar my = m.fMat[kMScaleY]; 884 SkScalar ty = m.getTranslateY();
901 do { 885 if (count & 1) {
902 dst->fY = src->fY * my; 886 dst->fX = src->fX + tx;
903 dst->fX = src->fX * mx; 887 dst->fY = src->fY + ty;
904 src += 1; 888 src += 1;
905 dst += 1; 889 dst += 1;
906 } while (--count); 890 }
891 Sk4f trans4(tx, ty, tx, ty);
892 count >>= 1;
893 if (count & 1) {
894 (Sk4f::Load(&src->fX) + trans4).store(&dst->fX);
895 src += 2;
896 dst += 2;
897 }
898 count >>= 1;
899 for (int i = 0; i < count; ++i) {
900 (Sk4f::Load(&src[0].fX) + trans4).store(&dst[0].fX);
901 (Sk4f::Load(&src[2].fX) + trans4).store(&dst[2].fX);
902 src += 4;
903 dst += 4;
904 }
907 } 905 }
908 } 906 }
909 907
910 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], 908 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
911 const SkPoint src[], int count) { 909 SkASSERT(m.getType() <= (kScale_Mask | kTranslate_Mask));
912 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); 910
913
914 if (count > 0) { 911 if (count > 0) {
915 SkScalar mx = m.fMat[kMScaleX]; 912 SkScalar tx = m.getTranslateX();
916 SkScalar my = m.fMat[kMScaleY]; 913 SkScalar ty = m.getTranslateY();
917 SkScalar tx = m.fMat[kMTransX]; 914 SkScalar sx = m.getScaleX();
918 SkScalar ty = m.fMat[kMTransY]; 915 SkScalar sy = m.getScaleY();
919 do { 916 if (count & 1) {
920 dst->fY = src->fY * my + ty; 917 dst->fX = src->fX * sx + tx;
921 dst->fX = src->fX * mx + tx; 918 dst->fY = src->fY * sy + ty;
922 src += 1; 919 src += 1;
923 dst += 1; 920 dst += 1;
924 } while (--count); 921 }
922 Sk4f trans4(tx, ty, tx, ty);
923 Sk4f scale4(sx, sy, sx, sy);
924 count >>= 1;
925 if (count & 1) {
926 (Sk4f::Load(&src->fX) * scale4 + trans4).store(&dst->fX);
927 src += 2;
928 dst += 2;
929 }
930 count >>= 1;
931 for (int i = 0; i < count; ++i) {
932 (Sk4f::Load(&src[0].fX) * scale4 + trans4).store(&dst[0].fX);
933 (Sk4f::Load(&src[2].fX) * scale4 + trans4).store(&dst[2].fX);
934 src += 4;
935 dst += 4;
936 }
925 } 937 }
926 } 938 }
927 939
928 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], 940 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[],
929 const SkPoint src[], int count) { 941 const SkPoint src[], int count) {
930 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); 942 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0);
931 943
932 if (count > 0) { 944 if (count > 0) {
933 SkScalar mx = m.fMat[kMScaleX]; 945 SkScalar mx = m.fMat[kMScaleX];
934 SkScalar my = m.fMat[kMScaleY]; 946 SkScalar my = m.fMat[kMScaleY];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 z = SkScalarFastInvert(z); 1005 z = SkScalarFastInvert(z);
994 } 1006 }
995 1007
996 dst->fY = y * z; 1008 dst->fY = y * z;
997 dst->fX = x * z; 1009 dst->fX = x * z;
998 dst += 1; 1010 dst += 1;
999 } while (--count); 1011 } while (--count);
1000 } 1012 }
1001 } 1013 }
1002 1014
1003 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = {
1004 SkMatrix::Identity_pts, SkMatrix::Trans_pts,
1005 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts,
1006 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts,
1007 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts,
1008 // repeat the persp proc 8 times
1009 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1010 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1011 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1012 SkMatrix::Persp_pts, SkMatrix::Persp_pts
1013 };
1014
1015 void SkMatrix::mapPoints(SkPoint dst[], const SkPoint src[], int count) const {
1016 SkASSERT((dst && src && count > 0) || 0 == count);
1017 // no partial overlap
1018 SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
1019
1020 this->getMapPtsProc()(*this, dst, src, count);
1021 }
1022
1023 #include "Sk4x.h"
1024
1025 void SkMatrix::Trans_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
1026 SkASSERT(m.getType() <= kTranslate_Mask);
1027
1028 if (count > 0) {
1029 SkScalar tx = m.getTranslateX();
1030 SkScalar ty = m.getTranslateY();
1031 if (count & 1) {
1032 dst->fX = src->fX + tx;
1033 dst->fY = src->fY + ty;
1034 src += 1;
1035 dst += 1;
1036 }
1037 Sk4f trans4(tx, ty, tx, ty);
1038 count >>= 1;
1039 if (count & 1) {
1040 (Sk4f::Load(&src->fX) + trans4).store(&dst->fX);
1041 src += 2;
1042 dst += 2;
1043 }
1044 count >>= 1;
1045 for (int i = 0; i < count; ++i) {
1046 (Sk4f::Load(&src[0].fX) + trans4).store(&dst[0].fX);
1047 (Sk4f::Load(&src[2].fX) + trans4).store(&dst[2].fX);
1048 src += 4;
1049 dst += 4;
1050 }
1051 }
1052 }
1053
1054 void SkMatrix::Scale_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[], int count) {
1055 SkASSERT(m.getType() <= (kScale_Mask | kTranslate_Mask));
1056
1057 if (count > 0) {
1058 SkScalar tx = m.getTranslateX();
1059 SkScalar ty = m.getTranslateY();
1060 SkScalar sx = m.getScaleX();
1061 SkScalar sy = m.getScaleY();
1062 if (count & 1) {
1063 dst->fX = src->fX * sx + tx;
1064 dst->fY = src->fY * sy + ty;
1065 src += 1;
1066 dst += 1;
1067 }
1068 Sk4f trans4(tx, ty, tx, ty);
1069 Sk4f scale4(sx, sy, sx, sy);
1070 count >>= 1;
1071 if (count & 1) {
1072 (Sk4f::Load(&src->fX) * scale4 + trans4).store(&dst->fX);
1073 src += 2;
1074 dst += 2;
1075 }
1076 count >>= 1;
1077 for (int i = 0; i < count; ++i) {
1078 (Sk4f::Load(&src[0].fX) * scale4 + trans4).store(&dst[0].fX);
1079 (Sk4f::Load(&src[2].fX) * scale4 + trans4).store(&dst[2].fX);
1080 src += 4;
1081 dst += 4;
1082 }
1083 }
1084 }
1085
1086 void SkMatrix::Affine_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[] , int count) { 1015 void SkMatrix::Affine_vpts(const SkMatrix& m, SkPoint dst[], const SkPoint src[] , int count) {
1087 SkASSERT(m.getType() != kPerspective_Mask); 1016 SkASSERT(m.getType() != kPerspective_Mask);
1088 1017
1089 if (count > 0) { 1018 if (count > 0) {
1090 SkScalar tx = m.getTranslateX(); 1019 SkScalar tx = m.getTranslateX();
1091 SkScalar ty = m.getTranslateY(); 1020 SkScalar ty = m.getTranslateY();
1092 SkScalar sx = m.getScaleX(); 1021 SkScalar sx = m.getScaleX();
1093 SkScalar sy = m.getScaleY(); 1022 SkScalar sy = m.getScaleY();
1094 SkScalar kx = m.getSkewX(); 1023 SkScalar kx = m.getSkewX();
1095 SkScalar ky = m.getSkewY(); 1024 SkScalar ky = m.getSkewY();
(...skipping 10 matching lines...) Expand all
1106 for (int i = 0; i < count; ++i) { 1035 for (int i = 0; i < count; ++i) {
1107 Sk4f src4 = Sk4f::Load(&src->fX); 1036 Sk4f src4 = Sk4f::Load(&src->fX);
1108 Sk4f swz4(src[0].fY, src[0].fX, src[1].fY, src[1].fX); // need ABCD -> BADC 1037 Sk4f swz4(src[0].fY, src[0].fX, src[1].fY, src[1].fX); // need ABCD -> BADC
1109 (src4 * scale4 + swz4 * skew4 + trans4).store(&dst->fX); 1038 (src4 * scale4 + swz4 * skew4 + trans4).store(&dst->fX);
1110 src += 2; 1039 src += 2;
1111 dst += 2; 1040 dst += 2;
1112 } 1041 }
1113 } 1042 }
1114 } 1043 }
1115 1044
1116 const SkMatrix::MapPtsProc SkMatrix::gMapVPtsProcs[] = { 1045 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = {
1117 SkMatrix::Identity_pts, SkMatrix::Trans_vpts, 1046 SkMatrix::Identity_pts, SkMatrix::Trans_pts,
1118 SkMatrix::Scale_vpts, SkMatrix::Scale_vpts, 1047 SkMatrix::Scale_pts, SkMatrix::Scale_pts,
1048 #ifdef SK_SUPPORT_LEGACY_SCALAR_MAPPOINTS
1049 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts,
1050 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts,
1051 #else
1119 SkMatrix::Affine_vpts, SkMatrix::Affine_vpts, 1052 SkMatrix::Affine_vpts, SkMatrix::Affine_vpts,
1120 SkMatrix::Affine_vpts, SkMatrix::Affine_vpts, 1053 SkMatrix::Affine_vpts, SkMatrix::Affine_vpts,
1054 #endif
1121 // repeat the persp proc 8 times 1055 // repeat the persp proc 8 times
1122 SkMatrix::Persp_pts, SkMatrix::Persp_pts, 1056 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1123 SkMatrix::Persp_pts, SkMatrix::Persp_pts, 1057 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1124 SkMatrix::Persp_pts, SkMatrix::Persp_pts, 1058 SkMatrix::Persp_pts, SkMatrix::Persp_pts,
1125 SkMatrix::Persp_pts, SkMatrix::Persp_pts 1059 SkMatrix::Persp_pts, SkMatrix::Persp_pts
1126 }; 1060 };
1127 1061
1128 /////////////////////////////////////////////////////////////////////////////// 1062 ///////////////////////////////////////////////////////////////////////////////
1129 1063
1130 void SkMatrix::mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int co unt) const { 1064 void SkMatrix::mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int co unt) const {
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 rotation1->fX = cos1; 1845 rotation1->fX = cos1;
1912 rotation1->fY = sin1; 1846 rotation1->fY = sin1;
1913 } 1847 }
1914 if (rotation2) { 1848 if (rotation2) {
1915 rotation2->fX = cos2; 1849 rotation2->fX = cos2;
1916 rotation2->fY = sin2; 1850 rotation2->fY = sin2;
1917 } 1851 }
1918 1852
1919 return true; 1853 return true;
1920 } 1854 }
OLDNEW
« no previous file with comments | « include/core/SkMatrix.h ('k') | tests/MatrixTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698