diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-15 18:16:27 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-15 18:16:27 +0000 |
commit | fdfbb9d5f0d29cb4a956a693c499653f87f04ac4 (patch) | |
tree | 1a53e74b9354114f2b0ac799a632d9aac1fd0e8b /src/gpu/GrAAConvexPathRenderer.cpp | |
parent | 96583db7990ec524b6410c539518ebbc9844c5ec (diff) |
Fix repeated point quads/cubics in convex pr and update convexpaths GM
R=robertphillips@google.com, jvanverth@google.com
Author: bsalomon@google.com
Review URL: https://chromiumcodereview.appspot.com/23034003
git-svn-id: http://skia.googlecode.com/svn/trunk@10744 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/GrAAConvexPathRenderer.cpp')
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 105 |
1 files changed, 58 insertions, 47 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 408fcb541f..47315a453b 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -24,8 +24,6 @@ GrAAConvexPathRenderer::GrAAConvexPathRenderer() { } -namespace { - struct Segment { enum { // These enum values are assumed in member functions below. @@ -57,7 +55,7 @@ struct Segment { typedef SkTArray<Segment, true> SegmentArray; -void center_of_mass(const SegmentArray& segments, SkPoint* c) { +static void center_of_mass(const SegmentArray& segments, SkPoint* c) { SkScalar area = 0; SkPoint center = {0, 0}; int count = segments.count(); @@ -108,11 +106,11 @@ void center_of_mass(const SegmentArray& segments, SkPoint* c) { GrAssert(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY)); } -void compute_vectors(SegmentArray* segments, - SkPoint* fanPt, - SkPath::Direction dir, - int* vCount, - int* iCount) { +static void compute_vectors(SegmentArray* segments, + SkPoint* fanPt, + SkPath::Direction dir, + int* vCount, + int* iCount) { center_of_mass(*segments, fanPt); int count = segments->count(); @@ -177,17 +175,17 @@ struct DegenerateTestData { SkScalar fLineC; }; -void update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) { - static const SkScalar TOL = (SK_Scalar1 / 16); - static const SkScalar TOL_SQD = SkScalarMul(TOL, TOL); +static const SkScalar kClose = (SK_Scalar1 / 16); +static const SkScalar kCloseSqd = SkScalarMul(kClose, kClose); +static void update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) { switch (data->fStage) { case DegenerateTestData::kInitial: data->fFirstPoint = pt; data->fStage = DegenerateTestData::kPoint; break; case DegenerateTestData::kPoint: - if (pt.distanceToSqd(data->fFirstPoint) > TOL_SQD) { + if (pt.distanceToSqd(data->fFirstPoint) > kCloseSqd) { data->fLineNormal = pt - data->fFirstPoint; data->fLineNormal.normalize(); data->fLineNormal.setOrthog(data->fLineNormal); @@ -196,7 +194,7 @@ void update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) { } break; case DegenerateTestData::kLine: - if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > TOL) { + if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > kClose) { data->fStage = DegenerateTestData::kNonDegenerate; } case DegenerateTestData::kNonDegenerate: @@ -206,7 +204,7 @@ void update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) { } } -inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPath::Direction* dir) { +static inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPath::Direction* dir) { if (!path.cheapComputeDirection(dir)) { return false; } @@ -220,12 +218,42 @@ inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPath::Directi return true; } -bool get_segments(const SkPath& path, - const SkMatrix& m, - SegmentArray* segments, - SkPoint* fanPt, - int* vCount, - int* iCount) { +static inline void add_line_to_segment(const SkPoint& pt, SegmentArray* segments) { + segments->push_back(); + segments->back().fType = Segment::kLine; + segments->back().fPts[0] = pt; +} + +static inline void add_quad_segment(const SkPoint pts[3], SegmentArray* segments) { + if (pts[0].distanceToSqd(pts[1]) < kCloseSqd || pts[1].distanceToSqd(pts[2]) < kCloseSqd) { + if (pts[0] != pts[2]) { + add_line_to_segment(pts[2], segments); + } + } else { + segments->push_back(); + segments->back().fType = Segment::kQuad; + segments->back().fPts[0] = pts[1]; + segments->back().fPts[1] = pts[2]; + } +} + +static inline void add_cubic_segments(const SkPoint pts[4], + SkPath::Direction dir, + SegmentArray* segments) { + SkSTArray<15, SkPoint, true> quads; + GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads); + int count = quads.count(); + for (int q = 0; q < count; q += 3) { + add_quad_segment(&quads[q], segments); + } +} + +static bool get_segments(const SkPath& path, + const SkMatrix& m, + SegmentArray* segments, + SkPoint* fanPt, + int* vCount, + int* iCount) { SkPath::Iter iter(path, true); // This renderer over-emphasizes very thin path regions. We use the distance // to the path from the sample to compute coverage. Every pixel intersected @@ -250,38 +278,23 @@ bool get_segments(const SkPath& path, update_degenerate_test(°enerateData, pts[0]); break; case SkPath::kLine_Verb: { - m.mapPoints(pts + 1, 1); + m.mapPoints(&pts[1], 1); update_degenerate_test(°enerateData, pts[1]); - segments->push_back(); - segments->back().fType = Segment::kLine; - segments->back().fPts[0] = pts[1]; + add_line_to_segment(pts[1], segments); break; } case SkPath::kQuad_Verb: - m.mapPoints(pts + 1, 2); + m.mapPoints(pts, 3); update_degenerate_test(°enerateData, pts[1]); update_degenerate_test(°enerateData, pts[2]); - segments->push_back(); - segments->back().fType = Segment::kQuad; - segments->back().fPts[0] = pts[1]; - segments->back().fPts[1] = pts[2]; + add_quad_segment(pts, segments); break; case SkPath::kCubic_Verb: { m.mapPoints(pts, 4); update_degenerate_test(°enerateData, pts[1]); update_degenerate_test(°enerateData, pts[2]); update_degenerate_test(°enerateData, pts[3]); - // unlike quads and lines, the pts[0] will also be read (in - // convertCubicToQuads). - SkSTArray<15, SkPoint, true> quads; - GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads); - int count = quads.count(); - for (int q = 0; q < count; q += 3) { - segments->push_back(); - segments->back().fType = Segment::kQuad; - segments->back().fPts[0] = quads[q + 1]; - segments->back().fPts[1] = quads[q + 2]; - } + add_cubic_segments(pts, dir, segments); break; }; case SkPath::kDone_Verb: @@ -312,11 +325,11 @@ struct Draw { typedef SkTArray<Draw, true> DrawArray; -void create_vertices(const SegmentArray& segments, - const SkPoint& fanPt, - DrawArray* draws, - QuadVertex* verts, - uint16_t* idxs) { +static void create_vertices(const SegmentArray& segments, + const SkPoint& fanPt, + DrawArray* draws, + QuadVertex* verts, + uint16_t* idxs) { Draw* draw = &draws->push_back(); // alias just to make vert/index assignments easier to read. int* v = &draw->fVertexCnt; @@ -459,8 +472,6 @@ void create_vertices(const SegmentArray& segments, } } -} - /////////////////////////////////////////////////////////////////////////////// /* |