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

Side by Side Diff: src/gpu/batches/GrAAConvexTessellator.cpp

Issue 2318183002: Revert of Make AALinearizingConvexPathRenderer able to handle stroke and fill (Closed)
Patch Set: Created 4 years, 3 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 "GrAAConvexTessellator.h" 8 #include "GrAAConvexTessellator.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkPath.h" 10 #include "SkPath.h"
(...skipping 14 matching lines...) Expand all
25 static const SkScalar kQuadTolerance = 0.2f; 25 static const SkScalar kQuadTolerance = 0.2f;
26 static const SkScalar kCubicTolerance = 0.2f; 26 static const SkScalar kCubicTolerance = 0.2f;
27 static const SkScalar kConicTolerance = 0.5f; 27 static const SkScalar kConicTolerance = 0.5f;
28 28
29 // dot product below which we use a round cap between curve segments 29 // dot product below which we use a round cap between curve segments
30 static const SkScalar kRoundCapThreshold = 0.8f; 30 static const SkScalar kRoundCapThreshold = 0.8f;
31 31
32 // dot product above which we consider two adjacent curves to be part of the "sa me" curve 32 // dot product above which we consider two adjacent curves to be part of the "sa me" curve
33 static const SkScalar kCurveConnectionThreshold = 0.8f; 33 static const SkScalar kCurveConnectionThreshold = 0.8f;
34 34
35 static bool intersect(const SkPoint& p0, const SkPoint& n0, 35 static SkScalar intersect(const SkPoint& p0, const SkPoint& n0,
36 const SkPoint& p1, const SkPoint& n1, 36 const SkPoint& p1, const SkPoint& n1) {
37 SkScalar* t) {
38 const SkPoint v = p1 - p0; 37 const SkPoint v = p1 - p0;
39 SkScalar perpDot = n0.fX * n1.fY - n0.fY * n1.fX; 38 SkScalar perpDot = n0.fX * n1.fY - n0.fY * n1.fX;
40 if (SkScalarNearlyZero(perpDot)) { 39 return (v.fX * n1.fY - v.fY * n1.fX) / perpDot;
41 return false;
42 }
43 *t = (v.fX * n1.fY - v.fY * n1.fX) / perpDot;
44 SkASSERT(SkScalarIsFinite(*t));
45 return true;
46 } 40 }
47 41
48 // This is a special case version of intersect where we have the vector 42 // This is a special case version of intersect where we have the vector
49 // perpendicular to the second line rather than the vector parallel to it. 43 // perpendicular to the second line rather than the vector parallel to it.
50 static SkScalar perp_intersect(const SkPoint& p0, const SkPoint& n0, 44 static SkScalar perp_intersect(const SkPoint& p0, const SkPoint& n0,
51 const SkPoint& p1, const SkPoint& perp) { 45 const SkPoint& p1, const SkPoint& perp) {
52 const SkPoint v = p1 - p0; 46 const SkPoint v = p1 - p0;
53 SkScalar perpDot = n0.dot(perp); 47 SkScalar perpDot = n0.dot(perp);
54 return v.dot(perp) / perpDot; 48 return v.dot(perp) / perpDot;
55 } 49 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // The polygon state is captured in the Ring class while the GrAAConvexTessellat or 211 // The polygon state is captured in the Ring class while the GrAAConvexTessellat or
218 // controls the iteration. The CandidateVerts holds the formative points for the 212 // controls the iteration. The CandidateVerts holds the formative points for the
219 // next ring. 213 // next ring.
220 bool GrAAConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) { 214 bool GrAAConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) {
221 if (!this->extractFromPath(m, path)) { 215 if (!this->extractFromPath(m, path)) {
222 return false; 216 return false;
223 } 217 }
224 218
225 SkScalar coverage = 1.0f; 219 SkScalar coverage = 1.0f;
226 SkScalar scaleFactor = 0.0f; 220 SkScalar scaleFactor = 0.0f;
227 221 if (fStrokeWidth >= 0.0f) {
228 if (SkStrokeRec::kStrokeAndFill_Style == fStyle) {
229 SkASSERT(m.isSimilarity()); 222 SkASSERT(m.isSimilarity());
230 scaleFactor = m.getMaxScale(); // x and y scale are the same 223 scaleFactor = m.getMaxScale(); // x and y scale are the same
231 SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth; 224 SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth;
232 Ring outerStrokeAndAARing;
233 this->createOuterRing(fInitialRing,
234 effectiveStrokeWidth / 2 + kAntialiasingRadius, 0. 0,
235 &outerStrokeAndAARing);
236
237 // discard all the triangles added between the originating ring and the new outer ring
238 fIndices.rewind();
239
240 outerStrokeAndAARing.init(*this);
241
242 outerStrokeAndAARing.makeOriginalRing();
243
244 // Add the outer stroke ring's normals to the originating ring's normals
245 // so it can also act as an originating ring
246 fNorms.setReserve(fNorms.count() + outerStrokeAndAARing.numPts());
247 for (int i = 0; i < outerStrokeAndAARing.numPts(); ++i) {
248 fNorms.push(outerStrokeAndAARing.norm(i));
249 }
250
251 // the bisectors are only needed for the computation of the outer ring
252 fBisectors.rewind();
253
254 Ring* insetAARing;
255 this->createInsetRings(outerStrokeAndAARing,
256 0.0f, 0.0f, 2*kAntialiasingRadius, 1.0f,
257 &insetAARing);
258
259 SkDEBUGCODE(this->validate();)
260 return true;
261 }
262
263 if (SkStrokeRec::kStroke_Style == fStyle) {
264 SkASSERT(fStrokeWidth >= 0.0f);
265 SkASSERT(m.isSimilarity());
266 scaleFactor = m.getMaxScale(); // x and y scale are the same
267 SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth;
268 Ring outerStrokeRing; 225 Ring outerStrokeRing;
269 this->createOuterRing(fInitialRing, effectiveStrokeWidth / 2 - kAntialia singRadius, 226 this->createOuterRing(fInitialRing, effectiveStrokeWidth / 2 - kAntialia singRadius,
270 coverage, &outerStrokeRing); 227 coverage, &outerStrokeRing);
271 outerStrokeRing.init(*this); 228 outerStrokeRing.init(*this);
272 Ring outerAARing; 229 Ring outerAARing;
273 this->createOuterRing(outerStrokeRing, kAntialiasingRadius * 2, 0.0f, &o uterAARing); 230 this->createOuterRing(outerStrokeRing, kAntialiasingRadius * 2, 0.0f, &o uterAARing);
274 } else { 231 } else {
275 Ring outerAARing; 232 Ring outerAARing;
276 this->createOuterRing(fInitialRing, kAntialiasingRadius, 0.0f, &outerAAR ing); 233 this->createOuterRing(fInitialRing, kAntialiasingRadius, 0.0f, &outerAAR ing);
277 } 234 }
278 235
279 // the bisectors are only needed for the computation of the outer ring 236 // the bisectors are only needed for the computation of the outer ring
280 fBisectors.rewind(); 237 fBisectors.rewind();
281 if (SkStrokeRec::kStroke_Style == fStyle && fInitialRing.numPts() > 2) { 238 if (fStrokeWidth >= 0.0f && fInitialRing.numPts() > 2) {
282 SkASSERT(fStrokeWidth >= 0.0f);
283 SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth; 239 SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth;
284 Ring* insetStrokeRing; 240 Ring* insetStrokeRing;
285 SkScalar strokeDepth = effectiveStrokeWidth / 2 - kAntialiasingRadius; 241 SkScalar strokeDepth = effectiveStrokeWidth / 2 - kAntialiasingRadius;
286 if (this->createInsetRings(fInitialRing, 0.0f, coverage, strokeDepth, co verage, 242 if (this->createInsetRings(fInitialRing, 0.0f, coverage, strokeDepth, co verage,
287 &insetStrokeRing)) { 243 &insetStrokeRing)) {
288 Ring* insetAARing; 244 Ring* insetAARing;
289 this->createInsetRings(*insetStrokeRing, strokeDepth, coverage, stro keDepth + 245 this->createInsetRings(*insetStrokeRing, strokeDepth, coverage, stro keDepth +
290 kAntialiasingRadius * 2, 0.0f, &insetAARing); 246 kAntialiasingRadius * 2, 0.0f, &insetAARing);
291 } 247 }
292 } else { 248 } else {
293 Ring* insetAARing; 249 Ring* insetAARing;
294 this->createInsetRings(fInitialRing, 0.0f, 0.5f, kAntialiasingRadius, 1. 0f, &insetAARing); 250 this->createInsetRings(fInitialRing, 0.0f, 0.5f, kAntialiasingRadius, 1. 0f, &insetAARing);
295 } 251 }
296 252
297 SkDEBUGCODE(this->validate();) 253 SkDEBUGCODE(this->validate();)
298 return true; 254 return true;
299 } 255 }
300 256
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 383
428 // Make all the normals face outwards rather than along the edge 384 // Make all the normals face outwards rather than along the edge
429 for (int cur = 0; cur < fNorms.count(); ++cur) { 385 for (int cur = 0; cur < fNorms.count(); ++cur) {
430 fNorms[cur].setOrthog(fNorms[cur], fSide); 386 fNorms[cur].setOrthog(fNorms[cur], fSide);
431 SkASSERT(SkScalarNearlyEqual(1.0f, fNorms[cur].length())); 387 SkASSERT(SkScalarNearlyEqual(1.0f, fNorms[cur].length()));
432 } 388 }
433 389
434 this->computeBisectors(); 390 this->computeBisectors();
435 } else if (this->numPts() == 2) { 391 } else if (this->numPts() == 2) {
436 // We've got two points, so we're degenerate. 392 // We've got two points, so we're degenerate.
437 if (fStyle == SkStrokeRec::kFill_Style) { 393 if (fStrokeWidth < 0.0f) {
438 // it's a fill, so we don't need to worry about degenerate paths 394 // it's a fill, so we don't need to worry about degenerate paths
439 return false; 395 return false;
440 } 396 }
441 // For stroking, we still need to process the degenerate path, so fix it up 397 // For stroking, we still need to process the degenerate path, so fix it up
442 fSide = SkPoint::kLeft_Side; 398 fSide = SkPoint::kLeft_Side;
443 399
444 // Make all the normals face outwards rather than along the edge 400 // Make all the normals face outwards rather than along the edge
445 for (int cur = 0; cur < fNorms.count(); ++cur) { 401 for (int cur = 0; cur < fNorms.count(); ++cur) {
446 fNorms[cur].setOrthog(fNorms[cur], fSide); 402 fNorms[cur].setOrthog(fNorms[cur], fSide);
447 SkASSERT(SkScalarNearlyEqual(1.0f, fNorms[cur].length())); 403 SkASSERT(SkScalarNearlyEqual(1.0f, fNorms[cur].length()));
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 int lastIdx = previousRing.index(numPts - 1); 579 int lastIdx = previousRing.index(numPts - 1);
624 this->addTri(lastIdx, firstPerpIdx, previousRing.index(0)); 580 this->addTri(lastIdx, firstPerpIdx, previousRing.index(0));
625 this->addTri(lastIdx, lastPerpIdx, firstPerpIdx); 581 this->addTri(lastIdx, lastPerpIdx, firstPerpIdx);
626 582
627 this->validate(); 583 this->validate();
628 } 584 }
629 585
630 // Something went wrong in the creation of the next ring. If we're filling the s hape, just go ahead 586 // Something went wrong in the creation of the next ring. If we're filling the s hape, just go ahead
631 // and fan it. 587 // and fan it.
632 void GrAAConvexTessellator::terminate(const Ring& ring) { 588 void GrAAConvexTessellator::terminate(const Ring& ring) {
633 if (fStyle != SkStrokeRec::kStroke_Style) { 589 if (fStrokeWidth < 0.0f) {
634 this->fanRing(ring); 590 this->fanRing(ring);
635 } 591 }
636 } 592 }
637 593
638 static SkScalar compute_coverage(SkScalar depth, SkScalar initialDepth, SkScalar initialCoverage, 594 static SkScalar compute_coverage(SkScalar depth, SkScalar initialDepth, SkScalar initialCoverage,
639 SkScalar targetDepth, SkScalar targetCoverage) { 595 SkScalar targetDepth, SkScalar targetCoverage) {
640 if (SkScalarNearlyEqual(initialDepth, targetDepth)) { 596 if (SkScalarNearlyEqual(initialDepth, targetDepth)) {
641 return targetCoverage; 597 return targetCoverage;
642 } 598 }
643 SkScalar result = (depth - initialDepth) / (targetDepth - initialDepth) * 599 SkScalar result = (depth - initialDepth) / (targetDepth - initialDepth) *
644 (targetCoverage - initialCoverage) + initialCoverage; 600 (targetCoverage - initialCoverage) + initialCoverage;
645 return SkScalarClampMax(result, 1.0f); 601 return SkScalarClampMax(result, 1.0f);
646 } 602 }
647 603
648 // return true when processing is complete 604 // return true when processing is complete
649 bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing , 605 bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing ,
650 SkScalar initialDepth, SkScalar init ialCoverage, 606 SkScalar initialDepth, SkScalar init ialCoverage,
651 SkScalar targetDepth, SkScalar targe tCoverage, 607 SkScalar targetDepth, SkScalar targe tCoverage,
652 bool forceNew) { 608 bool forceNew) {
653 bool done = false; 609 bool done = false;
654 610
655 fCandidateVerts.rewind(); 611 fCandidateVerts.rewind();
656 612
657 // Loop through all the points in the ring and find the intersection with th e smallest depth 613 // Loop through all the points in the ring and find the intersection with th e smallest depth
658 SkScalar minDist = SK_ScalarMax, minT = 0.0f; 614 SkScalar minDist = SK_ScalarMax, minT = 0.0f;
659 int minEdgeIdx = -1; 615 int minEdgeIdx = -1;
660 616
661 for (int cur = 0; cur < lastRing.numPts(); ++cur) { 617 for (int cur = 0; cur < lastRing.numPts(); ++cur) {
662 int next = (cur + 1) % lastRing.numPts(); 618 int next = (cur + 1) % lastRing.numPts();
663 619 SkScalar t = intersect(this->point(lastRing.index(cur)), lastRing.bisec tor(cur),
664 SkScalar t; 620 this->point(lastRing.index(next)), lastRing.bisec tor(next));
665 bool result = intersect(this->point(lastRing.index(cur)), lastRing.bise ctor(cur),
666 this->point(lastRing.index(next)), lastRing.bise ctor(next),
667 &t);
668 if (!result) {
669 continue;
670 }
671 SkScalar dist = -t * lastRing.norm(cur).dot(lastRing.bisector(cur)); 621 SkScalar dist = -t * lastRing.norm(cur).dot(lastRing.bisector(cur));
672 622
673 if (minDist > dist) { 623 if (minDist > dist) {
674 minDist = dist; 624 minDist = dist;
675 minT = t; 625 minT = t;
676 minEdgeIdx = cur; 626 minEdgeIdx = cur;
677 } 627 }
678 } 628 }
679 629
680 if (minEdgeIdx == -1) { 630 if (minEdgeIdx == -1) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 dst[i] = nextRing->index(dst[i]); 738 dst[i] = nextRing->index(dst[i]);
789 } 739 }
790 740
791 for (int i = 0; i < lastRing.numPts(); ++i) { 741 for (int i = 0; i < lastRing.numPts(); ++i) {
792 int next = (i + 1) % lastRing.numPts(); 742 int next = (i + 1) % lastRing.numPts();
793 743
794 this->addTri(lastRing.index(i), lastRing.index(next), dst[next]); 744 this->addTri(lastRing.index(i), lastRing.index(next), dst[next]);
795 this->addTri(lastRing.index(i), dst[next], dst[i]); 745 this->addTri(lastRing.index(i), dst[next], dst[i]);
796 } 746 }
797 747
798 if (done && fStyle != SkStrokeRec::kStroke_Style) { 748 if (done && fStrokeWidth < 0.0f) {
799 // fill or stroke-and-fill 749 // fill
800 this->fanRing(*nextRing); 750 this->fanRing(*nextRing);
801 } 751 }
802 752
803 if (nextRing->numPts() < 3) { 753 if (nextRing->numPts() < 3) {
804 done = true; 754 done = true;
805 } 755 }
806 return done; 756 return done;
807 } 757 }
808 758
809 void GrAAConvexTessellator::validate() const { 759 void GrAAConvexTessellator::validate() const {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 fNorms.pop(); 853 fNorms.pop();
904 fCurveState.pop(); 854 fCurveState.pop();
905 // double-check that the new last point is not a duplicate of the new po int. In an ideal 855 // double-check that the new last point is not a duplicate of the new po int. In an ideal
906 // world this wouldn't be necessary (since it's only possible for non-co nvex paths), but 856 // world this wouldn't be necessary (since it's only possible for non-co nvex paths), but
907 // floating point precision issues mean it can actually happen on paths that were determined 857 // floating point precision issues mean it can actually happen on paths that were determined
908 // to be convex. 858 // to be convex.
909 if (duplicate_pt(p, this->lastPoint())) { 859 if (duplicate_pt(p, this->lastPoint())) {
910 return; 860 return;
911 } 861 }
912 } 862 }
913 SkScalar initialRingCoverage = (SkStrokeRec::kFill_Style == fStyle) ? 0.5f : 1.0f; 863 SkScalar initialRingCoverage = fStrokeWidth < 0.0f ? 0.5f : 1.0f;
914 this->addPt(p, 0.0f, initialRingCoverage, false, curve); 864 this->addPt(p, 0.0f, initialRingCoverage, false, curve);
915 if (this->numPts() > 1) { 865 if (this->numPts() > 1) {
916 *fNorms.push() = fPts.top() - fPts[fPts.count()-2]; 866 *fNorms.push() = fPts.top() - fPts[fPts.count()-2];
917 SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fNorms.top()); 867 SkDEBUGCODE(SkScalar len =) SkPoint::Normalize(&fNorms.top());
918 SkASSERT(len > 0.0f); 868 SkASSERT(len > 0.0f);
919 SkASSERT(SkScalarNearlyEqual(1.0f, fNorms.top().length())); 869 SkASSERT(SkScalarNearlyEqual(1.0f, fNorms.top().length()));
920 } 870 }
921 } 871 }
922 872
923 void GrAAConvexTessellator::lineTo(const SkMatrix& m, SkPoint p, CurveState curv e) { 873 void GrAAConvexTessellator::lineTo(const SkMatrix& m, SkPoint p, CurveState curv e) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 1043
1094 SkString num; 1044 SkString num;
1095 num.printf("%d", i); 1045 num.printf("%d", i);
1096 canvas->drawText(num.c_str(), num.size(), 1046 canvas->drawText(num.c_str(), num.size(),
1097 this->point(i).fX, this->point(i).fY+(kPointRadius/2.0f ), 1047 this->point(i).fX, this->point(i).fY+(kPointRadius/2.0f ),
1098 paint); 1048 paint);
1099 } 1049 }
1100 } 1050 }
1101 1051
1102 #endif 1052 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrAAConvexTessellator.h ('k') | src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698