OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 } | 28 } |
29 | 29 |
30 struct Segment { | 30 struct Segment { |
31 enum { | 31 enum { |
32 // These enum values are assumed in member functions below. | 32 // These enum values are assumed in member functions below. |
33 kLine = 0, | 33 kLine = 0, |
34 kQuad = 1, | 34 kQuad = 1, |
35 } fType; | 35 } fType; |
36 | 36 |
37 // line uses one pt, quad uses 2 pts | 37 // line uses one pt, quad uses 2 pts |
38 GrPoint fPts[2]; | 38 SkPoint fPts[2]; |
39 // normal to edge ending at each pt | 39 // normal to edge ending at each pt |
40 GrVec fNorms[2]; | 40 SkVector fNorms[2]; |
41 // is the corner where the previous segment meets this segment | 41 // is the corner where the previous segment meets this segment |
42 // sharp. If so, fMid is a normalized bisector facing outward. | 42 // sharp. If so, fMid is a normalized bisector facing outward. |
43 GrVec fMid; | 43 SkVector fMid; |
44 | 44 |
45 int countPoints() { | 45 int countPoints() { |
46 GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); | 46 GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); |
47 return fType + 1; | 47 return fType + 1; |
48 } | 48 } |
49 const SkPoint& endPt() const { | 49 const SkPoint& endPt() const { |
50 GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); | 50 GR_STATIC_ASSERT(0 == kLine && 1 == kQuad); |
51 return fPts[fType]; | 51 return fPts[fType]; |
52 }; | 52 }; |
53 const SkPoint& endNorm() const { | 53 const SkPoint& endNorm() const { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 static void compute_vectors(SegmentArray* segments, | 112 static void compute_vectors(SegmentArray* segments, |
113 SkPoint* fanPt, | 113 SkPoint* fanPt, |
114 SkPath::Direction dir, | 114 SkPath::Direction dir, |
115 int* vCount, | 115 int* vCount, |
116 int* iCount) { | 116 int* iCount) { |
117 center_of_mass(*segments, fanPt); | 117 center_of_mass(*segments, fanPt); |
118 int count = segments->count(); | 118 int count = segments->count(); |
119 | 119 |
120 // Make the normals point towards the outside | 120 // Make the normals point towards the outside |
121 GrPoint::Side normSide; | 121 SkPoint::Side normSide; |
122 if (dir == SkPath::kCCW_Direction) { | 122 if (dir == SkPath::kCCW_Direction) { |
123 normSide = GrPoint::kRight_Side; | 123 normSide = SkPoint::kRight_Side; |
124 } else { | 124 } else { |
125 normSide = GrPoint::kLeft_Side; | 125 normSide = SkPoint::kLeft_Side; |
126 } | 126 } |
127 | 127 |
128 *vCount = 0; | 128 *vCount = 0; |
129 *iCount = 0; | 129 *iCount = 0; |
130 // compute normals at all points | 130 // compute normals at all points |
131 for (int a = 0; a < count; ++a) { | 131 for (int a = 0; a < count; ++a) { |
132 Segment& sega = (*segments)[a]; | 132 Segment& sega = (*segments)[a]; |
133 int b = (a + 1) % count; | 133 int b = (a + 1) % count; |
134 Segment& segb = (*segments)[b]; | 134 Segment& segb = (*segments)[b]; |
135 | 135 |
136 const GrPoint* prevPt = &sega.endPt(); | 136 const SkPoint* prevPt = &sega.endPt(); |
137 int n = segb.countPoints(); | 137 int n = segb.countPoints(); |
138 for (int p = 0; p < n; ++p) { | 138 for (int p = 0; p < n; ++p) { |
139 segb.fNorms[p] = segb.fPts[p] - *prevPt; | 139 segb.fNorms[p] = segb.fPts[p] - *prevPt; |
140 segb.fNorms[p].normalize(); | 140 segb.fNorms[p].normalize(); |
141 segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); | 141 segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); |
142 prevPt = &segb.fPts[p]; | 142 prevPt = &segb.fPts[p]; |
143 } | 143 } |
144 if (Segment::kLine == segb.fType) { | 144 if (Segment::kLine == segb.fType) { |
145 *vCount += 5; | 145 *vCount += 5; |
146 *iCount += 9; | 146 *iCount += 9; |
(...skipping 19 matching lines...) Expand all Loading... |
166 | 166 |
167 struct DegenerateTestData { | 167 struct DegenerateTestData { |
168 DegenerateTestData() { fStage = kInitial; } | 168 DegenerateTestData() { fStage = kInitial; } |
169 bool isDegenerate() const { return kNonDegenerate != fStage; } | 169 bool isDegenerate() const { return kNonDegenerate != fStage; } |
170 enum { | 170 enum { |
171 kInitial, | 171 kInitial, |
172 kPoint, | 172 kPoint, |
173 kLine, | 173 kLine, |
174 kNonDegenerate | 174 kNonDegenerate |
175 } fStage; | 175 } fStage; |
176 GrPoint fFirstPoint; | 176 SkPoint fFirstPoint; |
177 GrVec fLineNormal; | 177 SkVector fLineNormal; |
178 SkScalar fLineC; | 178 SkScalar fLineC; |
179 }; | 179 }; |
180 | 180 |
181 static const SkScalar kClose = (SK_Scalar1 / 16); | 181 static const SkScalar kClose = (SK_Scalar1 / 16); |
182 static const SkScalar kCloseSqd = SkScalarMul(kClose, kClose); | 182 static const SkScalar kCloseSqd = SkScalarMul(kClose, kClose); |
183 | 183 |
184 static void update_degenerate_test(DegenerateTestData* data, const GrPoint& pt)
{ | 184 static void update_degenerate_test(DegenerateTestData* data, const SkPoint& pt)
{ |
185 switch (data->fStage) { | 185 switch (data->fStage) { |
186 case DegenerateTestData::kInitial: | 186 case DegenerateTestData::kInitial: |
187 data->fFirstPoint = pt; | 187 data->fFirstPoint = pt; |
188 data->fStage = DegenerateTestData::kPoint; | 188 data->fStage = DegenerateTestData::kPoint; |
189 break; | 189 break; |
190 case DegenerateTestData::kPoint: | 190 case DegenerateTestData::kPoint: |
191 if (pt.distanceToSqd(data->fFirstPoint) > kCloseSqd) { | 191 if (pt.distanceToSqd(data->fFirstPoint) > kCloseSqd) { |
192 data->fLineNormal = pt - data->fFirstPoint; | 192 data->fLineNormal = pt - data->fFirstPoint; |
193 data->fLineNormal.normalize(); | 193 data->fLineNormal.normalize(); |
194 data->fLineNormal.setOrthog(data->fLineNormal); | 194 data->fLineNormal.setOrthog(data->fLineNormal); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 // line paths. We detect paths that are very close to a line (zero area) and | 281 // line paths. We detect paths that are very close to a line (zero area) and |
282 // draw nothing. | 282 // draw nothing. |
283 DegenerateTestData degenerateData; | 283 DegenerateTestData degenerateData; |
284 SkPath::Direction dir; | 284 SkPath::Direction dir; |
285 // get_direction can fail for some degenerate paths. | 285 // get_direction can fail for some degenerate paths. |
286 if (!get_direction(path, m, &dir)) { | 286 if (!get_direction(path, m, &dir)) { |
287 return false; | 287 return false; |
288 } | 288 } |
289 | 289 |
290 for (;;) { | 290 for (;;) { |
291 GrPoint pts[4]; | 291 SkPoint pts[4]; |
292 SkPath::Verb verb = iter.next(pts); | 292 SkPath::Verb verb = iter.next(pts); |
293 switch (verb) { | 293 switch (verb) { |
294 case SkPath::kMove_Verb: | 294 case SkPath::kMove_Verb: |
295 m.mapPoints(pts, 1); | 295 m.mapPoints(pts, 1); |
296 update_degenerate_test(°enerateData, pts[0]); | 296 update_degenerate_test(°enerateData, pts[0]); |
297 devBounds->set(pts->fX, pts->fY, pts->fX, pts->fY); | 297 devBounds->set(pts->fX, pts->fY, pts->fX, pts->fY); |
298 break; | 298 break; |
299 case SkPath::kLine_Verb: { | 299 case SkPath::kLine_Verb: { |
300 m.mapPoints(&pts[1], 1); | 300 m.mapPoints(&pts[1], 1); |
301 update_degenerate_test(°enerateData, pts[1]); | 301 update_degenerate_test(°enerateData, pts[1]); |
(...skipping 21 matching lines...) Expand all Loading... |
323 compute_vectors(segments, fanPt, dir, vCount, iCount); | 323 compute_vectors(segments, fanPt, dir, vCount, iCount); |
324 return true; | 324 return true; |
325 } | 325 } |
326 default: | 326 default: |
327 break; | 327 break; |
328 } | 328 } |
329 } | 329 } |
330 } | 330 } |
331 | 331 |
332 struct QuadVertex { | 332 struct QuadVertex { |
333 GrPoint fPos; | 333 SkPoint fPos; |
334 GrPoint fUV; | 334 SkPoint fUV; |
335 SkScalar fD0; | 335 SkScalar fD0; |
336 SkScalar fD1; | 336 SkScalar fD1; |
337 }; | 337 }; |
338 | 338 |
339 struct Draw { | 339 struct Draw { |
340 Draw() : fVertexCnt(0), fIndexCnt(0) {} | 340 Draw() : fVertexCnt(0), fIndexCnt(0) {} |
341 int fVertexCnt; | 341 int fVertexCnt; |
342 int fIndexCnt; | 342 int fIndexCnt; |
343 }; | 343 }; |
344 | 344 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 idxs[*i + 4] = *v + 1; | 432 idxs[*i + 4] = *v + 1; |
433 idxs[*i + 5] = *v + 2; | 433 idxs[*i + 5] = *v + 2; |
434 | 434 |
435 idxs[*i + 6] = *v + 4; | 435 idxs[*i + 6] = *v + 4; |
436 idxs[*i + 7] = *v + 3; | 436 idxs[*i + 7] = *v + 3; |
437 idxs[*i + 8] = *v + 2; | 437 idxs[*i + 8] = *v + 2; |
438 | 438 |
439 *v += 5; | 439 *v += 5; |
440 *i += 9; | 440 *i += 9; |
441 } else { | 441 } else { |
442 GrPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]}; | 442 SkPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]}; |
443 | 443 |
444 GrVec midVec = segb.fNorms[0] + segb.fNorms[1]; | 444 SkVector midVec = segb.fNorms[0] + segb.fNorms[1]; |
445 midVec.normalize(); | 445 midVec.normalize(); |
446 | 446 |
447 verts[*v + 0].fPos = fanPt; | 447 verts[*v + 0].fPos = fanPt; |
448 verts[*v + 1].fPos = qpts[0]; | 448 verts[*v + 1].fPos = qpts[0]; |
449 verts[*v + 2].fPos = qpts[2]; | 449 verts[*v + 2].fPos = qpts[2]; |
450 verts[*v + 3].fPos = qpts[0] + segb.fNorms[0]; | 450 verts[*v + 3].fPos = qpts[0] + segb.fNorms[0]; |
451 verts[*v + 4].fPos = qpts[2] + segb.fNorms[1]; | 451 verts[*v + 4].fPos = qpts[2] + segb.fNorms[1]; |
452 verts[*v + 5].fPos = qpts[1] + midVec; | 452 verts[*v + 5].fPos = qpts[1] + midVec; |
453 | 453 |
454 SkScalar c = segb.fNorms[0].dot(qpts[0]); | 454 SkScalar c = segb.fNorms[0].dot(qpts[0]); |
455 verts[*v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c; | 455 verts[*v + 0].fD0 = -segb.fNorms[0].dot(fanPt) + c; |
456 verts[*v + 1].fD0 = 0.f; | 456 verts[*v + 1].fD0 = 0.f; |
457 verts[*v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c; | 457 verts[*v + 2].fD0 = -segb.fNorms[0].dot(qpts[2]) + c; |
458 verts[*v + 3].fD0 = -SK_ScalarMax/100; | 458 verts[*v + 3].fD0 = -SK_ScalarMax/100; |
459 verts[*v + 4].fD0 = -SK_ScalarMax/100; | 459 verts[*v + 4].fD0 = -SK_ScalarMax/100; |
460 verts[*v + 5].fD0 = -SK_ScalarMax/100; | 460 verts[*v + 5].fD0 = -SK_ScalarMax/100; |
461 | 461 |
462 c = segb.fNorms[1].dot(qpts[2]); | 462 c = segb.fNorms[1].dot(qpts[2]); |
463 verts[*v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c; | 463 verts[*v + 0].fD1 = -segb.fNorms[1].dot(fanPt) + c; |
464 verts[*v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c; | 464 verts[*v + 1].fD1 = -segb.fNorms[1].dot(qpts[0]) + c; |
465 verts[*v + 2].fD1 = 0.f; | 465 verts[*v + 2].fD1 = 0.f; |
466 verts[*v + 3].fD1 = -SK_ScalarMax/100; | 466 verts[*v + 3].fD1 = -SK_ScalarMax/100; |
467 verts[*v + 4].fD1 = -SK_ScalarMax/100; | 467 verts[*v + 4].fD1 = -SK_ScalarMax/100; |
468 verts[*v + 5].fD1 = -SK_ScalarMax/100; | 468 verts[*v + 5].fD1 = -SK_ScalarMax/100; |
469 | 469 |
470 GrPathUtils::QuadUVMatrix toUV(qpts); | 470 GrPathUtils::QuadUVMatrix toUV(qpts); |
471 toUV.apply<6, sizeof(QuadVertex), sizeof(GrPoint)>(verts + *v); | 471 toUV.apply<6, sizeof(QuadVertex), sizeof(SkPoint)>(verts + *v); |
472 | 472 |
473 idxs[*i + 0] = *v + 3; | 473 idxs[*i + 0] = *v + 3; |
474 idxs[*i + 1] = *v + 1; | 474 idxs[*i + 1] = *v + 1; |
475 idxs[*i + 2] = *v + 2; | 475 idxs[*i + 2] = *v + 2; |
476 idxs[*i + 3] = *v + 4; | 476 idxs[*i + 3] = *v + 4; |
477 idxs[*i + 4] = *v + 3; | 477 idxs[*i + 4] = *v + 3; |
478 idxs[*i + 5] = *v + 2; | 478 idxs[*i + 5] = *v + 2; |
479 | 479 |
480 idxs[*i + 6] = *v + 5; | 480 idxs[*i + 6] = *v + 5; |
481 idxs[*i + 7] = *v + 3; | 481 idxs[*i + 7] = *v + 3; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 bool antiAlias) const { | 611 bool antiAlias) const { |
612 return (target->caps()->shaderDerivativeSupport() && antiAlias && | 612 return (target->caps()->shaderDerivativeSupport() && antiAlias && |
613 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()
); | 613 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()
); |
614 } | 614 } |
615 | 615 |
616 namespace { | 616 namespace { |
617 | 617 |
618 // position + edge | 618 // position + edge |
619 extern const GrVertexAttrib gPathAttribs[] = { | 619 extern const GrVertexAttrib gPathAttribs[] = { |
620 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, | 620 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding
}, |
621 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} | 621 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding} |
622 }; | 622 }; |
623 | 623 |
624 }; | 624 }; |
625 | 625 |
626 bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, | 626 bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, |
627 const SkStrokeRec&, | 627 const SkStrokeRec&, |
628 GrDrawTarget* target, | 628 GrDrawTarget* target, |
629 bool antiAlias) { | 629 bool antiAlias) { |
630 | 630 |
631 const SkPath* path = &origPath; | 631 const SkPath* path = &origPath; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 vOffset, // start vertex | 708 vOffset, // start vertex |
709 0, // start index | 709 0, // start index |
710 draw.fVertexCnt, | 710 draw.fVertexCnt, |
711 draw.fIndexCnt, | 711 draw.fIndexCnt, |
712 &devBounds); | 712 &devBounds); |
713 vOffset += draw.fVertexCnt; | 713 vOffset += draw.fVertexCnt; |
714 } | 714 } |
715 | 715 |
716 return true; | 716 return true; |
717 } | 717 } |
OLD | NEW |