GrAAConvexPathRenderer.cpp revision 278dc6929b6481204874dcfcc055e2aaa30a95b2
1fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
2fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin/*
3fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * Copyright 2012 Google Inc.
4fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin *
5fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * Use of this source code is governed by a BSD-style license that can be
6fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin * found in the LICENSE file.
7fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin */
8fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
9fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrAAConvexPathRenderer.h"
10fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
11fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrContext.h"
12fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrDrawState.h"
13fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "GrPathUtils.h"
14fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "SkString.h"
15fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin#include "SkTrace.h"
16fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
17fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
18fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz ZavinGrAAConvexPathRenderer::GrAAConvexPathRenderer() {
19fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
20fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
21fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinbool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget::Caps& targetCaps,
22fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                         const SkPath& path,
23fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                         GrPathFill fill,
24fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                         bool antiAlias) const {
25b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    return targetCaps.fShaderDerivativeSupport && antiAlias &&
26fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin           kHairLine_PathFill != fill && !GrIsFillInverted(fill) &&
27fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin           path.isConvex();
28fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
29fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
30fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinnamespace {
31b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
32fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinstruct Segment {
33fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    enum {
34fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        kLine,
35fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        kQuad
36fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    } fType;
37fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // line uses one pt, quad uses 2 pts
38fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrPoint fPts[2];
39b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    // normal to edge ending at each pt
40b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    GrVec fNorms[2];
41b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    // is the corner where the previous segment meets this segment
42fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // sharp. If so, fMid is a normalized bisector facing outward.
43fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrVec fMid;
44b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
45b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    int countPoints() {
46fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        return (kLine == fType) ? 1 : 2;
47fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
48fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    const SkPoint& endPt() const {
49fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        return (kLine == fType) ? fPts[0] : fPts[1];
50b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    };
51fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    const SkPoint& endNorm() const {
52fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        return (kLine == fType) ? fNorms[0] : fNorms[1];
53b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    };
54fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin};
55fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
56fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavintypedef SkTArray<Segment, true> SegmentArray;
57fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
58fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid center_of_mass(const SegmentArray& segments, SkPoint* c) {
59fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrScalar area = 0;
60fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    SkPoint center;
61fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    center.set(0, 0);
62fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    int count = segments.count();
63fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    for (int i = 0; i < count; ++i) {
64fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        const SkPoint& pi = segments[i].endPt();
65fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        int j = (i + 1) % count;
66fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        const SkPoint& pj = segments[j].endPt();
67fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        GrScalar t = GrMul(pi.fX, pj.fY) - GrMul(pj.fX, pi.fY);
68fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        area += t;
69fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        center.fX += (pi.fX + pj.fX) * t;
70fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        center.fY += (pi.fY + pj.fY) * t;
71fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
72fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // If the poly has no area then we instead return the average of
73fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // its points.
74fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (SkScalarAbs(area) < SK_ScalarNearlyZero) {
75fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        SkPoint avg;
76fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        avg.set(0, 0);
77fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        for (int i = 0; i < count; ++i) {
78fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            const SkPoint& pt = segments[i].endPt();
79fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            avg.fX += pt.fX;
80fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            avg.fY += pt.fY;
81fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        }
82fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        SkScalar denom = SK_Scalar1 / count;
83fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        avg.scale(denom);
84b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        *c = avg;
85b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    } else {
86b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        area *= 3;
87b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        area = GrScalarDiv(GR_Scalar1, area);
88b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        center.fX = GrScalarMul(center.fX, area);
896bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong        center.fY = GrScalarMul(center.fY, area);
906bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong        *c = center;
916bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong    }
926bf5fadc2cc19bc298c4e998657e35cf03644d3dJames Dong    GrAssert(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY));
93fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
94fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
95fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid compute_vectors(SegmentArray* segments,
96fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     SkPoint* fanPt,
97fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     SkPath::Direction dir,
98fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     int* vCount,
99fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     int* iCount) {
100fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    center_of_mass(*segments, fanPt);
101fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    int count = segments->count();
102fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
103fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // Make the normals point towards the outside
104fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrPoint::Side normSide;
105fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (dir == SkPath::kCCW_Direction) {
106fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        normSide = GrPoint::kRight_Side;
107fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    } else {
108fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        normSide = GrPoint::kLeft_Side;
109fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
110fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
111fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    *vCount = 0;
112fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    *iCount = 0;
113fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // compute normals at all points
114fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    for (int a = 0; a < count; ++a) {
115fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        const Segment& sega = (*segments)[a];
116fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        int b = (a + 1) % count;
117fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        Segment& segb = (*segments)[b];
118fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
119fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        const GrPoint* prevPt = &sega.endPt();
120fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        int n = segb.countPoints();
121fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        for (int p = 0; p < n; ++p) {
122fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            segb.fNorms[p] = segb.fPts[p] - *prevPt;
123fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            segb.fNorms[p].normalize();
124fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            segb.fNorms[p].setOrthog(segb.fNorms[p], normSide);
125fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            prevPt = &segb.fPts[p];
126fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        }
127fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        if (Segment::kLine == segb.fType) {
128fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            *vCount += 5;
129fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            *iCount += 9;
130fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        } else {
131fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            *vCount += 6;
132fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            *iCount += 12;
133fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        }
134fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
135fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
136fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // compute mid-vectors where segments meet. TODO: Detect shallow corners
137b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    // and leave out the wedges and close gaps by stitching segments together.
138b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    for (int a = 0; a < count; ++a) {
139b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        const Segment& sega = (*segments)[a];
140b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        int b = (a + 1) % count;
141b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        Segment& segb = (*segments)[b];
142b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        segb.fMid = segb.fNorms[0] + sega.endNorm();
143b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        segb.fMid.normalize();
144b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        // corner wedges
145b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        *vCount += 4;
146b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        *iCount += 6;
147b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    }
148b65f253fdc60f6208a54911bee793d225f23cdf8James Dong}
149b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
150b65f253fdc60f6208a54911bee793d225f23cdf8James Dongstruct DegenerateTestData {
151b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    DegenerateTestData() { fStage = kInitial; }
152b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    bool isDegenerate() const { return kNonDegenerate != fStage; }
153b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    enum {
154b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        kInitial,
155b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        kPoint,
156b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        kLine,
157b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        kNonDegenerate
158b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    }           fStage;
159b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    GrPoint     fFirstPoint;
160b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    GrVec       fLineNormal;
161b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    GrScalar    fLineC;
162b65f253fdc60f6208a54911bee793d225f23cdf8James Dong};
163b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
164b65f253fdc60f6208a54911bee793d225f23cdf8James Dongvoid update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) {
165b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    static const SkScalar TOL = (SK_Scalar1 / 16);
166b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    static const SkScalar TOL_SQD = SkScalarMul(TOL, TOL);
167fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
168fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    switch (data->fStage) {
169b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        case DegenerateTestData::kInitial:
170b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            data->fFirstPoint = pt;
171b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            data->fStage = DegenerateTestData::kPoint;
172b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            break;
173b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        case DegenerateTestData::kPoint:
174b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            if (pt.distanceToSqd(data->fFirstPoint) > TOL_SQD) {
175b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                data->fLineNormal = pt - data->fFirstPoint;
176b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                data->fLineNormal.normalize();
177b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                data->fLineNormal.setOrthog(data->fLineNormal);
178fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                data->fLineC = -data->fLineNormal.dot(data->fFirstPoint);
179fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                data->fStage = DegenerateTestData::kLine;
180fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            }
181fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            break;
182fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        case DegenerateTestData::kLine:
183fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > TOL) {
184fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                data->fStage = DegenerateTestData::kNonDegenerate;
185fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            }
186b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        case DegenerateTestData::kNonDegenerate:
187b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            break;
188fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        default:
189b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            GrCrash("Unexpected degenerate test stage.");
190fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
191fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
192fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
193fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinbool get_segments(const GrPath& path,
194fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                 SegmentArray* segments,
195fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                 SkPoint* fanPt,
196fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                 int* vCount,
197b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                 int* iCount) {
198b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    SkPath::Iter iter(path, true);
199fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // This renderer overemphasises very thin path regions. We use the distance
200fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // to the path from the sample to compute coverage. Every pixel intersected
201fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // by the path will be hit and the maximum distance is sqrt(2)/2. We don't
202b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    // notice that the sample may be close to a very thin area of the path and
203fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // thus should be very light. This is particularly egregious for degenerate
204fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    // line paths. We detect paths that are very close to a line (zero area) and
205b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    // draw nothing.
206fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    DegenerateTestData degenerateData;
207fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
208fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    for (;;) {
209fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        GrPoint pts[4];
210fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        GrPathCmd cmd = (GrPathCmd)iter.next(pts);
211fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        switch (cmd) {
212fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            case kMove_PathCmd:
213fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[0]);
214fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                break;
215fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            case kLine_PathCmd: {
216fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[1]);
217fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                segments->push_back();
218b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                segments->back().fType = Segment::kLine;
219fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                segments->back().fPts[0] = pts[1];
220b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                break;
221fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            }
222fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            case kQuadratic_PathCmd:
223fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[1]);
224fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[2]);
225fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                segments->push_back();
226fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                segments->back().fType = Segment::kQuad;
227fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                segments->back().fPts[0] = pts[1];
228fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                segments->back().fPts[1] = pts[2];
229fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                break;
230b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            case kCubic_PathCmd: {
231fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[1]);
232fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[2]);
233fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                update_degenerate_test(&degenerateData, pts[3]);
234fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                SkSTArray<15, SkPoint, true> quads;
235b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, &quads);
236fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                int count = quads.count();
237fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                for (int q = 0; q < count; q += 3) {
238fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    segments->push_back();
239fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    segments->back().fType = Segment::kQuad;
240b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                    segments->back().fPts[0] = quads[q + 1];
241fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    segments->back().fPts[1] = quads[q + 2];
242fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                }
243fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                break;
244fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            };
245fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            case kEnd_PathCmd:
246b65f253fdc60f6208a54911bee793d225f23cdf8James Dong                if (degenerateData.isDegenerate()) {
247fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    return false;
248fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                } else {
249fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    SkPath::Direction dir;
250fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    GR_DEBUGCODE(bool succeeded = )
251fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    path.cheapComputeDirection(&dir);
252fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    GrAssert(succeeded);
253fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    compute_vectors(segments, fanPt, dir, vCount, iCount);
254fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                    return true;
255fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                }
256fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            default:
257fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                break;
258fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        }
259b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    }
260b65f253fdc60f6208a54911bee793d225f23cdf8James Dong}
261b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
262fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinstruct QuadVertex {
263fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrPoint  fPos;
264fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrPoint  fUV;
265b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    GrScalar fD0;
266fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrScalar fD1;
267fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin};
268fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
269fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid create_vertices(const SegmentArray&  segments,
270fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     const SkPoint& fanPt,
271fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     QuadVertex*    verts,
272fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                     uint16_t*      idxs) {
273fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    int v = 0;
274fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    int i = 0;
275fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
276fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    int count = segments.count();
277fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    for (int a = 0; a < count; ++a) {
278fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        const Segment& sega = segments[a];
279fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        int b = (a + 1) % count;
280fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        const Segment& segb = segments[b];
281fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
282fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        // FIXME: These tris are inset in the 1 unit arc around the corner
283fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 0].fPos = sega.endPt();
284fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 1].fPos = verts[v + 0].fPos + sega.endNorm();
285fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 2].fPos = verts[v + 0].fPos + segb.fMid;
286fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 3].fPos = verts[v + 0].fPos + segb.fNorms[0];
287fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 0].fUV.set(0,0);
288fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 1].fUV.set(0,-SK_Scalar1);
289fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 2].fUV.set(0,-SK_Scalar1);
290fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 3].fUV.set(0,-SK_Scalar1);
291fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1;
292fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1;
293fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1;
294fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1;
295fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
296fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        idxs[i + 0] = v + 0;
297fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        idxs[i + 1] = v + 2;
298fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        idxs[i + 2] = v + 1;
299b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        idxs[i + 3] = v + 0;
300b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        idxs[i + 4] = v + 3;
301b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        idxs[i + 5] = v + 2;
302b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
303fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        v += 4;
304fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        i += 6;
305fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
306fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        if (Segment::kLine == segb.fType) {
307fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 0].fPos = fanPt;
308fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 1].fPos = sega.endPt();
309fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 2].fPos = segb.fPts[0];
310fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
311fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 3].fPos = verts[v + 1].fPos + segb.fNorms[0];
312fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 4].fPos = verts[v + 2].fPos + segb.fNorms[0];
313fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
314fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            // we draw the line edge as a degenerate quad (u is 0, v is the
315fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            // signed distance to the edge)
316b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            GrScalar dist = fanPt.distanceToLineBetween(verts[v + 1].fPos,
317fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                                        verts[v + 2].fPos);
318fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 0].fUV.set(0, dist);
319fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 1].fUV.set(0, 0);
320b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            verts[v + 2].fUV.set(0, 0);
321b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            verts[v + 3].fUV.set(0, -SK_Scalar1);
322b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            verts[v + 4].fUV.set(0, -SK_Scalar1);
323b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
324b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            verts[v + 0].fD0 = verts[v + 0].fD1 = -SK_Scalar1;
325fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 1].fD0 = verts[v + 1].fD1 = -SK_Scalar1;
326b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            verts[v + 2].fD0 = verts[v + 2].fD1 = -SK_Scalar1;
327fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 3].fD0 = verts[v + 3].fD1 = -SK_Scalar1;
328fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 4].fD0 = verts[v + 4].fD1 = -SK_Scalar1;
329fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
330fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 0] = v + 0;
331fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 1] = v + 2;
332fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 2] = v + 1;
333fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
334fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 3] = v + 3;
335fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 4] = v + 1;
33624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            idxs[i + 5] = v + 2;
337fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
33824ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            idxs[i + 6] = v + 4;
33924ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            idxs[i + 7] = v + 3;
34024ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            idxs[i + 8] = v + 2;
341b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
342fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            v += 5;
343fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            i += 9;
34424ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong        } else {
345fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            GrPoint qpts[] = {sega.endPt(), segb.fPts[0], segb.fPts[1]};
34624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong
34724ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            GrVec midVec = segb.fNorms[0] + segb.fNorms[1];
34824ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            midVec.normalize();
34924ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong
350fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 0].fPos = fanPt;
35124ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 1].fPos = qpts[0];
35285e28eec8163c776f2f3a093f4053a96ed2d6f98Steve Block            verts[v + 2].fPos = qpts[2];
35324ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 3].fPos = qpts[0] + segb.fNorms[0];
354b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            verts[v + 4].fPos = qpts[2] + segb.fNorms[1];
35524ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 5].fPos = qpts[1] + midVec;
35624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong
35724ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            GrScalar c = segb.fNorms[0].dot(qpts[0]);
35824ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 0].fD0 =  -segb.fNorms[0].dot(fanPt) + c;
35924ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 1].fD0 =  0.f;
36024ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 2].fD0 =  -segb.fNorms[0].dot(qpts[2]) + c;
361fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 3].fD0 = -GR_ScalarMax/100;
36224ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 4].fD0 = -GR_ScalarMax/100;
36324ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 5].fD0 = -GR_ScalarMax/100;
36424ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong
36524ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            c = segb.fNorms[1].dot(qpts[2]);
36624ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 0].fD1 =  -segb.fNorms[1].dot(fanPt) + c;
36724ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 1].fD1 =  -segb.fNorms[1].dot(qpts[0]) + c;
36885e28eec8163c776f2f3a093f4053a96ed2d6f98Steve Block            verts[v + 2].fD1 =  0.f;
369fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 3].fD1 = -GR_ScalarMax/100;
37024ef98f0d3b5d00b1d30c8ebf0791ef708170a32James Dong            verts[v + 4].fD1 = -GR_ScalarMax/100;
371fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            verts[v + 5].fD1 = -GR_ScalarMax/100;
372fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
373fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            GrMatrix toUV;
374fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            GrPathUtils::quadDesignSpaceToUVCoordsMatrix(qpts, &toUV);
375fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            toUV.mapPointsWithStride(&verts[v].fUV,
376fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                     &verts[v].fPos,
377fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                     sizeof(QuadVertex),
378fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                     6);
379fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
380fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 0] = v + 3;
381fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 1] = v + 1;
382fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 2] = v + 2;
383b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            idxs[i + 3] = v + 4;
384fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 4] = v + 3;
385fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 5] = v + 2;
386fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
387fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 6] = v + 5;
388b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            idxs[i + 7] = v + 3;
389fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            idxs[i + 8] = v + 4;
390b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
391b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            idxs[i +  9] = v + 0;
392b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            idxs[i + 10] = v + 2;
393b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            idxs[i + 11] = v + 1;
394fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
395fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            v += 6;
396b65f253fdc60f6208a54911bee793d225f23cdf8James Dong            i += 12;
397fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        }
398fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
399fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
400fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
401fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
402fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
403fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavinvoid GrAAConvexPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
404fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrAssert(fPath->isConvex());
405fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (fPath->isEmpty()) {
406fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        return;
407b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    }
408fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrDrawState* drawState = fTarget->drawState();
409fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
410fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrDrawTarget::AutoStateRestore asr;
411fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrMatrix vm = drawState->getViewMatrix();
412fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    vm.postTranslate(fTranslate.fX, fTranslate.fY);
413fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    asr.set(fTarget);
414fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrMatrix ivm;
415fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (vm.invert(&ivm)) {
416fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        drawState->preConcatSamplerMatrices(stageMask, ivm);
417fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
418fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    drawState->setViewMatrix(GrMatrix::I());
419fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
420b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    SkPath path;
421b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    fPath->transform(vm, &path);
422fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
423fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    GrVertexLayout layout = 0;
424fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
425fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        if ((1 << s) & stageMask) {
426fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
427fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        }
428fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
429fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    layout |= GrDrawTarget::kEdge_VertexLayoutBit;
430fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
431fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    QuadVertex *verts;
432fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    uint16_t* idxs;
433fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
434fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    int vCount;
435b65f253fdc60f6208a54911bee793d225f23cdf8James Dong    int iCount;
436fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    SegmentArray segments;
437fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    SkPoint fanPt;
438fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (!get_segments(path, &segments, &fanPt, &vCount, &iCount)) {
439b65f253fdc60f6208a54911bee793d225f23cdf8James Dong        return;
440fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
441b65f253fdc60f6208a54911bee793d225f23cdf8James Dong
442fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (!fTarget->reserveVertexSpace(layout,
443fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                     vCount,
444fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                                     reinterpret_cast<void**>(&verts))) {
445fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        return;
446fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
447fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    if (!fTarget->reserveIndexSpace(iCount, reinterpret_cast<void**>(&idxs))) {
448fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        fTarget->resetVertexSource();
449fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin        return;
450fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    }
451fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
452fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    create_vertices(segments, fanPt, verts, idxs);
453fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
454fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    drawState->setVertexEdgeType(GrDrawState::kQuad_EdgeType);
455fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin    fTarget->drawIndexed(kTriangles_PrimitiveType,
456fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                         0,        // start vertex
457fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                         0,        // start index
458fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                         vCount,
459fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin                         iCount);
460fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin}
461fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin
462fb3766f18a2c18b6f4798a6a631fdb88fcacd1dcRebecca Schultz Zavin