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

Side by Side Diff: src/gpu/GrPathUtils.cpp

Issue 102683002: Simplify matrix generation for convex path renderer (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Rebase to latest Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « expectations/gm/ignored-tests.txt ('k') | no next file » | 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 2011 Google Inc. 2 * Copyright 2011 Google Inc.
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 "GrPathUtils.h" 8 #include "GrPathUtils.h"
9 9
10 #include "GrPoint.h" 10 #include "GrPoint.h"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 break; 180 break;
181 default: 181 default:
182 break; 182 break;
183 } 183 }
184 first = false; 184 first = false;
185 } 185 }
186 return pointCount; 186 return pointCount;
187 } 187 }
188 188
189 void GrPathUtils::QuadUVMatrix::set(const GrPoint qPts[3]) { 189 void GrPathUtils::QuadUVMatrix::set(const GrPoint qPts[3]) {
190 // can't make this static, no cons :(
191 SkMatrix UVpts;
192 #ifndef SK_SCALAR_IS_FLOAT 190 #ifndef SK_SCALAR_IS_FLOAT
193 GrCrash("Expected scalar is float."); 191 GrCrash("Expected scalar is float.");
194 #endif 192 #endif
195 SkMatrix m; 193 SkMatrix m;
196 // We want M such that M * xy_pt = uv_pt 194 // We want M such that M * xy_pt = uv_pt
197 // We know M * control_pts = [0 1/2 1] 195 // We know M * control_pts = [0 1/2 1]
198 // [0 0 1] 196 // [0 0 1]
199 // [1 1 1] 197 // [1 1 1]
198 // And control_pts = [x0 x1 x2]
199 // [y0 y1 y2]
200 // [1 1 1 ]
200 // We invert the control pt matrix and post concat to both sides to get M. 201 // We invert the control pt matrix and post concat to both sides to get M.
201 UVpts.setAll(0, SK_ScalarHalf, SK_Scalar1, 202 // Using the known form of the control point matrix and the result, we can
202 0, 0, SK_Scalar1, 203 // optimize and improve precision.
203 SkScalarToPersp(SK_Scalar1), 204
204 SkScalarToPersp(SK_Scalar1), 205 double x0 = qPts[0].fX;
205 SkScalarToPersp(SK_Scalar1)); 206 double y0 = qPts[0].fY;
206 m.setAll(qPts[0].fX, qPts[1].fX, qPts[2].fX, 207 double x1 = qPts[1].fX;
207 qPts[0].fY, qPts[1].fY, qPts[2].fY, 208 double y1 = qPts[1].fY;
208 SkScalarToPersp(SK_Scalar1), 209 double x2 = qPts[2].fX;
209 SkScalarToPersp(SK_Scalar1), 210 double y2 = qPts[2].fY;
210 SkScalarToPersp(SK_Scalar1)); 211 double det = x0*y1 - y0*x1 + x2*y0 - y2*x0 + x1*y2 - y1*x2;
211 if (!m.invert(&m)) { 212
213 if (!sk_float_isfinite(det)
214 || SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZ ero)) {
212 // The quad is degenerate. Hopefully this is rare. Find the pts that are 215 // The quad is degenerate. Hopefully this is rare. Find the pts that are
213 // farthest apart to compute a line (unless it is really a pt). 216 // farthest apart to compute a line (unless it is really a pt).
214 SkScalar maxD = qPts[0].distanceToSqd(qPts[1]); 217 SkScalar maxD = qPts[0].distanceToSqd(qPts[1]);
215 int maxEdge = 0; 218 int maxEdge = 0;
216 SkScalar d = qPts[1].distanceToSqd(qPts[2]); 219 SkScalar d = qPts[1].distanceToSqd(qPts[2]);
217 if (d > maxD) { 220 if (d > maxD) {
218 maxD = d; 221 maxD = d;
219 maxEdge = 1; 222 maxEdge = 1;
220 } 223 }
221 d = qPts[2].distanceToSqd(qPts[0]); 224 d = qPts[2].distanceToSqd(qPts[0]);
(...skipping 18 matching lines...) Expand all
240 fM[3] = lineVec.fX; 243 fM[3] = lineVec.fX;
241 fM[4] = lineVec.fY; 244 fM[4] = lineVec.fY;
242 fM[5] = -lineVec.dot(qPts[maxEdge]); 245 fM[5] = -lineVec.dot(qPts[maxEdge]);
243 } else { 246 } else {
244 // It's a point. It should cover zero area. Just set the matrix such 247 // It's a point. It should cover zero area. Just set the matrix such
245 // that (u, v) will always be far away from the quad. 248 // that (u, v) will always be far away from the quad.
246 fM[0] = 0; fM[1] = 0; fM[2] = 100.f; 249 fM[0] = 0; fM[1] = 0; fM[2] = 100.f;
247 fM[3] = 0; fM[4] = 0; fM[5] = 100.f; 250 fM[3] = 0; fM[4] = 0; fM[5] = 100.f;
248 } 251 }
249 } else { 252 } else {
250 m.postConcat(UVpts); 253 double scale = 1.0/det;
254
255 // compute adjugate matrix
256 double a0, a1, a2, a3, a4, a5, a6, a7, a8;
257 a0 = y1-y2;
258 a1 = x2-x1;
259 a2 = x1*y2-x2*y1;
260
261 a3 = y2-y0;
262 a4 = x0-x2;
263 a5 = x2*y0-x0*y2;
264
265 a6 = y0-y1;
266 a7 = x1-x0;
267 a8 = x0*y1-x1*y0;
268
269 // this performs the uv_pts*adjugate(control_pts) multiply,
270 // then does the scale by 1/det afterwards to improve precision
271 m[SkMatrix::kMScaleX] = (float)((0.5*a3 + a6)*scale);
272 m[SkMatrix::kMSkewX] = (float)((0.5*a4 + a7)*scale);
273 m[SkMatrix::kMTransX] = (float)((0.5*a5 + a8)*scale);
274
275 m[SkMatrix::kMSkewY] = (float)(a6*scale);
276 m[SkMatrix::kMScaleY] = (float)(a7*scale);
277 m[SkMatrix::kMTransY] = (float)(a8*scale);
278
279 m[SkMatrix::kMPersp0] = (float)((a0 + a3 + a6)*scale);
280 m[SkMatrix::kMPersp1] = (float)((a1 + a4 + a7)*scale);
281 m[SkMatrix::kMPersp2] = (float)((a2 + a5 + a8)*scale);
251 282
252 // The matrix should not have perspective. 283 // The matrix should not have perspective.
253 SkDEBUGCODE(static const SkScalar gTOL = 1.f / 100.f); 284 SkDEBUGCODE(static const SkScalar gTOL = 1.f / 100.f);
254 SkASSERT(SkScalarAbs(m.get(SkMatrix::kMPersp0)) < gTOL); 285 SkASSERT(SkScalarAbs(m.get(SkMatrix::kMPersp0)) < gTOL);
255 SkASSERT(SkScalarAbs(m.get(SkMatrix::kMPersp1)) < gTOL); 286 SkASSERT(SkScalarAbs(m.get(SkMatrix::kMPersp1)) < gTOL);
256 287
257 // It may not be normalized to have 1.0 in the bottom right 288 // It may not be normalized to have 1.0 in the bottom right
258 float m33 = m.get(SkMatrix::kMPersp2); 289 float m33 = m.get(SkMatrix::kMPersp2);
259 if (1.f != m33) { 290 if (1.f != m33) {
260 m33 = 1.f / m33; 291 m33 = 1.f / m33;
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 set_loop_klm(d, controlK, controlL, controlM); 862 set_loop_klm(d, controlK, controlL, controlM);
832 } else if (kCusp_CubicType == cType) { 863 } else if (kCusp_CubicType == cType) {
833 SkASSERT(0.f == d[0]); 864 SkASSERT(0.f == d[0]);
834 set_cusp_klm(d, controlK, controlL, controlM); 865 set_cusp_klm(d, controlK, controlL, controlM);
835 } else if (kQuadratic_CubicType == cType) { 866 } else if (kQuadratic_CubicType == cType) {
836 set_quadratic_klm(d, controlK, controlL, controlM); 867 set_quadratic_klm(d, controlK, controlL, controlM);
837 } 868 }
838 869
839 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]); 870 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]);
840 } 871 }
OLDNEW
« no previous file with comments | « expectations/gm/ignored-tests.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698