11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrTesselatedPathRenderer.h"
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrDrawState.h"
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrPathUtils.h"
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrPoint.h"
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrRenderTarget.h"
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrTDArray.h"
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTemplates.h"
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <limits.h>
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <sk_glu.h>
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef GrTDArray<GrDrawState::Edge> GrEdgeArray;
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef GrTDArray<GrPoint> GrPointArray;
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef GrTDArray<uint16_t> GrIndexArray;
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef void (*TESSCB)();
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// limit the allowable vertex range to approximately half of the representable
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// IEEE exponent in order to avoid overflow when doing multiplies between
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// vertex components,
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst float kMaxVertexValue = 1e18f;
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline GrDrawState::Edge computeEdge(const GrPoint& p,
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             const GrPoint& q,
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                             float sign) {
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVec tangent = GrVec::Make(p.fY - q.fY, q.fX - p.fX);
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float scale = sign / tangent.length();
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float cross2 = p.fX * q.fY - q.fX * p.fY;
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return GrDrawState::Edge(tangent.fX * scale,
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              tangent.fY * scale,
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              cross2 * scale);
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline GrPoint sanitizePoint(const GrPoint& pt) {
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint r;
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    r.fX = SkScalarPin(pt.fX, -kMaxVertexValue, kMaxVertexValue);
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    r.fY = SkScalarPin(pt.fY, -kMaxVertexValue, kMaxVertexValue);
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return r;
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass GrTess {
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTess(int count, unsigned winding_rule) {
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTess = Sk_gluNewTess();
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessProperty(fTess, GLU_TESS_WINDING_RULE, winding_rule);
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessNormal(fTess, 0.0f, 0.0f, 1.0f);
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessCallback(fTess, GLU_TESS_BEGIN_DATA, (TESSCB) &beginCB);
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessCallback(fTess, GLU_TESS_VERTEX_DATA, (TESSCB) &vertexCB);
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessCallback(fTess, GLU_TESS_END_DATA, (TESSCB) &endCB);
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessCallback(fTess, GLU_TESS_EDGE_FLAG_DATA, (TESSCB) &edgeFlagCB);
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessCallback(fTess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineCB);
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fInVertices = new double[count * 3];
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual ~GrTess() {
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluDeleteTess(fTess);
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        delete[] fInVertices;
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    void addVertex(const GrPoint& pt, int index) {
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (index > USHRT_MAX) return;
701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        double* inVertex = &fInVertices[index * 3];
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        inVertex[0] = pt.fX;
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        inVertex[1] = pt.fY;
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        inVertex[2] = 0.0;
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fVertices.append() = pt;
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessVertex(fTess, inVertex, reinterpret_cast<void*>(index));
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    void addVertices(const GrPoint* points, const uint16_t* contours, int numContours) {
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessBeginPolygon(fTess, this);
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t i = 0;
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int j = 0; j < numContours; ++j) {
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            Sk_gluTessBeginContour(fTess);
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            size_t end = i + contours[j];
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (; i < end; ++i) {
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                addVertex(points[i], i);
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            Sk_gluTessEndContour(fTess);
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessEndPolygon(fTess);
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GLUtesselator* tess() { return fTess; }
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrPointArray& vertices() const { return fVertices; }
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void begin(GLenum type) = 0;
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void vertex(int index) = 0;
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void edgeFlag(bool flag) = 0;
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void end() = 0;
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual int combine(GLdouble coords[3], int vertexIndices[4],
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         GLfloat weight[4]) = 0;
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static void beginCB(GLenum type, void* data) {
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static_cast<GrTess*>(data)->begin(type);
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static void vertexCB(void* vertexData, void* data) {
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static_cast<GrTess*>(data)->vertex(reinterpret_cast<long>(vertexData));
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static void edgeFlagCB(GLboolean flag, void* data) {
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static_cast<GrTess*>(data)->edgeFlag(flag != 0);
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static void endCB(void* data) {
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static_cast<GrTess*>(data)->end();
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static void combineCB(GLdouble coords[3], void* vertexData[4],
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                          GLfloat weight[4], void **outData, void* data) {
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int vertexIndex[4];
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        vertexIndex[0] = reinterpret_cast<long>(vertexData[0]);
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        vertexIndex[1] = reinterpret_cast<long>(vertexData[1]);
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        vertexIndex[2] = reinterpret_cast<long>(vertexData[2]);
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        vertexIndex[3] = reinterpret_cast<long>(vertexData[3]);
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTess* tess = static_cast<GrTess*>(data);
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int outIndex = tess->combine(coords, vertexIndex, weight);
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *reinterpret_cast<long*>(outData) = outIndex;
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GLUtesselator* fTess;
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPointArray fVertices;
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    double* fInVertices;
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass GrPolygonTess : public GrTess {
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPolygonTess(int count, unsigned winding_rule)
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger      : GrTess(count, winding_rule) {
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ~GrPolygonTess() {
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrIndexArray& indices() const { return fIndices; }
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void begin(GLenum type) {
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GR_DEBUGASSERT(type == GL_TRIANGLES);
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void vertex(int index) {
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fIndices.append() = index;
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void edgeFlag(bool flag) {}
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void end() {}
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual int combine(GLdouble coords[3], int vertexIndices[4],
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         GLfloat weight[4]) {
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int index = fVertices.count();
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPoint p = GrPoint::Make(static_cast<float>(coords[0]),
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  static_cast<float>(coords[1]));
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fVertices.append() = p;
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return index;
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIndexArray fIndices;
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass GrEdgePolygonTess : public GrPolygonTess {
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrEdgePolygonTess(int count, unsigned winding_rule, const SkMatrix& matrix)
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger      : GrPolygonTess(count, winding_rule),
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fMatrix(matrix),
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdgeFlag(false),
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdgeVertex(-1),
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTriStartVertex(-1),
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdges(NULL) {
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ~GrEdgePolygonTess() {
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        delete[] fEdges;
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState::Edge* edges() const { return fEdges; }
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    void addEdge(int index0, int index1) {
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPoint p = fVertices[index0];
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPoint q = fVertices[index1];
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fMatrix.mapPoints(&p, 1);
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fMatrix.mapPoints(&q, 1);
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        p = sanitizePoint(p);
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        q = sanitizePoint(q);
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (p == q) return;
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawState::Edge edge = computeEdge(p, q, 1.0f);
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdges[index0 * 2 + 1] = edge;
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdges[index1 * 2] = edge;
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void begin(GLenum type) {
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GR_DEBUGASSERT(type == GL_TRIANGLES);
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int count = fVertices.count() * 2;
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdges = new GrDrawState::Edge[count];
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        memset(fEdges, 0, count * sizeof(GrDrawState::Edge));
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void edgeFlag(bool flag) {
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fEdgeFlag = flag;
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void vertex(int index) {
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool triStart = fIndices.count() % 3 == 0;
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPolygonTess::vertex(index);
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (fEdgeVertex != -1) {
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (triStart) {
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                addEdge(fEdgeVertex, fTriStartVertex);
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                addEdge(fEdgeVertex, index);
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (triStart) {
2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fTriStartVertex = index;
2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (fEdgeFlag) {
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fEdgeVertex = index;
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fEdgeVertex = -1;
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void end() {
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (fEdgeVertex != -1) {
2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            addEdge(fEdgeVertex, fTriStartVertex);
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix fMatrix;
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool fEdgeFlag;
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int fEdgeVertex, fTriStartVertex;
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState::Edge* fEdges;
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass GrBoundaryTess : public GrTess {
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrBoundaryTess(int count, unsigned winding_rule)
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger      : GrTess(count, winding_rule),
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fContourStart(0) {
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessProperty(fTess, GLU_TESS_BOUNDARY_ONLY, 1);
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ~GrBoundaryTess() {
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPointArray& contourPoints() { return fContourPoints; }
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrIndexArray& contours() const { return fContours; }
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void begin(GLenum type) {
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fContourStart = fContourPoints.count();
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void vertex(int index) {
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fContourPoints.append() = fVertices.at(index);
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void edgeFlag(bool flag) {}
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void end() {
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fContours.append() = fContourPoints.count() - fContourStart;
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual int combine(GLdouble coords[3], int vertexIndices[4],
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        GLfloat weight[4]) {
2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int index = fVertices.count();
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fVertices.append() = GrPoint::Make(static_cast<float>(coords[0]),
2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            static_cast<float>(coords[1]));
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return index;
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPointArray fContourPoints;
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIndexArray fContours;
2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t fContourStart;
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool nearlyEqual(float a, float b) {
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fabsf(a - b) < 0.0001f;
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool nearlyEqual(const GrPoint& a, const GrPoint& b) {
2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return nearlyEqual(a.fX, b.fX) && nearlyEqual(a.fY, b.fY);
2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool parallel(const GrDrawState::Edge& a, const GrDrawState::Edge& b) {
2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return (nearlyEqual(a.fX, b.fX) && nearlyEqual(a.fY, b.fY)) ||
2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger           (nearlyEqual(a.fX, -b.fX) && nearlyEqual(a.fY, -b.fY));
2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic unsigned fill_type_to_glu_winding_rule(GrPathFill fill) {
2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    switch (fill) {
2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kWinding_PathFill:
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return GLU_TESS_WINDING_NONZERO;
2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kEvenOdd_PathFill:
2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return GLU_TESS_WINDING_ODD;
2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kInverseWinding_PathFill:
2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return GLU_TESS_WINDING_POSITIVE;
2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kInverseEvenOdd_PathFill:
2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return GLU_TESS_WINDING_ODD;
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case kHairLine_PathFill:
2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return GLU_TESS_WINDING_NONZERO;  // FIXME:  handle this
2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        default:
2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrAssert(!"Unknown path fill!");
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return 0;
2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2881cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTesselatedPathRenderer::GrTesselatedPathRenderer() {
2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isCCW(const GrPoint* pts, int count) {
2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVec v1, v2;
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    do {
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        v1 = pts[1] - pts[0];
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        v2 = pts[2] - pts[1];
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pts++;
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        count--;
2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } while (nearlyEqual(v1, v2) && count > 3);
2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return v1.cross(v2) < 0;
3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool validEdge(const GrDrawState::Edge& edge) {
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return !(edge.fX == 0.0f && edge.fY == 0.0f && edge.fZ == 0.0f);
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic size_t computeEdgesAndIntersect(const GrMatrix& matrix,
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       const GrMatrix& inverse,
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       GrPoint* vertices,
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       size_t numVertices,
3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       GrEdgeArray* edges,
3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       float sign) {
3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (numVertices < 3) {
3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return 0;
3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    matrix.mapPoints(vertices, numVertices);
3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (sign == 0.0f) {
3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sign = isCCW(vertices, numVertices) ? -1.0f : 1.0f;
3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint p = sanitizePoint(vertices[numVertices - 1]);
3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (size_t i = 0; i < numVertices; ++i) {
3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPoint q = sanitizePoint(vertices[i]);
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (p == q) {
3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            continue;
3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawState::Edge edge = computeEdge(p, q, sign);
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        edge.fZ += 0.5f;    // Offset by half a pixel along the tangent.
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *edges->append() = edge;
3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        p = q;
3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int count = edges->count();
3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (count == 0) {
3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return 0;
3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState::Edge prev_edge = edges->at(0);
3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < count; ++i) {
3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawState::Edge edge = edges->at(i < count - 1 ? i + 1 : 0);
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (parallel(edge, prev_edge)) {
3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // 3 points are collinear; offset by half the tangent instead
3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertices[i].fX -= edge.fX * 0.5f;
3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertices[i].fY -= edge.fY * 0.5f;
3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertices[i] = prev_edge.intersect(edge);
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        inverse.mapPoints(&vertices[i], 1);
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        prev_edge = edge;
3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return edges->count();
3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool GrTesselatedPathRenderer::onDrawPath(const SkPath& path,
3514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                          GrPathFill fill,
3524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                          const GrVec* translate,
3534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                          GrDrawTarget* target,
3544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                          GrDrawState::StageMask stageMask,
3554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                          bool antiAlias) {
3564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
3574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrDrawTarget::AutoStateRestore asr(target);
3584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrDrawState* drawState = target->drawState();
3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // face culling doesn't make sense here
3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix viewM = drawState->getViewMatrix();
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrScalar tol = GR_Scalar1;
3654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrScalar tolSqd = GrMul(tol, tol);
3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int subpathCnt;
3694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int maxPts = GrPathUtils::worstCasePointCount(path, &subpathCnt, tol);
3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = 0;
3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if ((1 << s) & stageMask) {
3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    bool inverted = GrIsFillInverted(fill);
3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (inverted) {
3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        maxPts += 4;
3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        subpathCnt++;
3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (maxPts > USHRT_MAX) {
3844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoSTMalloc<8, GrPoint> baseMem(maxPts);
3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* base = baseMem;
3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* vert = base;
3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* subpathBase = base;
3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt);
3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint pts[4];
3944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkPath::Iter iter(path, false);
3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool first = true;
3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int subpath = 0;
3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (;;) {
4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        switch (iter.next(pts)) {
4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case kMove_PathCmd:
4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (!first) {
4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    subpathVertCount[subpath] = vert-subpathBase;
4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    subpathBase = vert;
4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    ++subpath;
4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                *vert = pts[0];
4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                vert++;
4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case kLine_PathCmd:
4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                *vert = pts[1];
4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                vert++;
4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case kQuadratic_PathCmd: {
4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2],
4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                     tolSqd, &vert,
4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                     GrPathUtils::quadraticPointCount(pts, tol));
4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
4191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
4201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case kCubic_PathCmd: {
4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3],
4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 tolSqd, &vert,
4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 GrPathUtils::cubicPointCount(pts, tol));
4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
4251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case kClose_PathCmd:
4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case kEnd_PathCmd:
4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                subpathVertCount[subpath] = vert-subpathBase;
4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                ++subpath; // this could be only in debug
4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                goto FINISHED;
4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        first = false;
4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4351cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerFINISHED:
4364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (NULL != translate && 0 != translate->fX && 0 != translate->fY) {
4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < vert - base; i++) {
4384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            base[i].offset(translate->fX, translate->fY);
4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (inverted) {
4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrRect bounds;
4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(NULL != drawState->getRenderTarget());
4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bounds.setLTRB(0, 0,
4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                       GrIntToScalar(drawState->getRenderTarget()->width()),
4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                       GrIntToScalar(drawState->getRenderTarget()->height()));
4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrMatrix vmi;
4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (drawState->getViewInverse(&vmi)) {
4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vmi.mapRect(&bounds);
4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *vert++ = GrPoint::Make(bounds.fLeft, bounds.fTop);
4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *vert++ = GrPoint::Make(bounds.fLeft, bounds.fBottom);
4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *vert++ = GrPoint::Make(bounds.fRight, bounds.fBottom);
4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *vert++ = GrPoint::Make(bounds.fRight, bounds.fTop);
4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        subpathVertCount[subpath++] = 4;
4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(subpath == subpathCnt);
4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert((vert - base) <= maxPts);
4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t count = vert - base;
4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (count < 3) {
4654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return true;
4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (subpathCnt == 1 && !inverted && path.isConvex()) {
4694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (antiAlias) {
4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrEdgeArray edges;
4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrMatrix inverse, matrix = drawState->getViewMatrix();
4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->getViewInverse(&inverse);
4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            count = computeEdgesAndIntersect(matrix, inverse, base, count, &edges, 0.0f);
4754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            size_t maxEdges = target->getMaxEdges();
4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (count == 0) {
4774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                return true;
4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (count <= maxEdges) {
4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // All edges fit; upload all edges and draw all verts as a fan
4814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                target->setVertexSourceToArray(layout, base, count);
4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                drawState->setEdgeAAData(&edges[0], count);
4834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // Upload "maxEdges" edges and verts at a time, and draw as
4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // separate fans
4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                for (size_t i = 0; i < count - 2; i += maxEdges - 2) {
4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    edges[i] = edges[0];
4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    base[i] = base[0];
4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    int size = GR_CT_MIN(count - i, maxEdges);
4914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    target->setVertexSourceToArray(layout, &base[i], size);
4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    drawState->setEdgeAAData(&edges[i], size);
4934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size);
4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->setEdgeAAData(NULL, 0);
4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
4984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            target->setVertexSourceToArray(layout, base, count);
4994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return true;
5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (antiAlias) {
5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Run the tesselator once to get the boundaries.
5064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fill));
5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        btess.addVertices(base, subpathVertCount, subpathCnt);
5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrMatrix inverse, matrix = drawState->getViewMatrix();
5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!drawState->getViewInverse(&inverse)) {
5114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            return false;
5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (btess.vertices().count() > USHRT_MAX) {
5154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            return false;
5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Inflate the boundary, and run the tesselator again to generate
5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // interior polys.
5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrPointArray& contourPoints = btess.contourPoints();
5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrIndexArray& contours = btess.contours();
5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrEdgePolygonTess ptess(contourPoints.count(), GLU_TESS_WINDING_NONZERO, matrix);
5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t i = 0;
5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessBeginPolygon(ptess.tess(), &ptess);
5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int contour = 0; contour < contours.count(); ++contour) {
5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int count = contours[contour];
5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrEdgeArray edges;
5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int newCount = computeEdgesAndIntersect(matrix, inverse, &btess.contourPoints()[i], count, &edges, 1.0f);
5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            Sk_gluTessBeginContour(ptess.tess());
5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (int j = 0; j < newCount; j++) {
5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                ptess.addVertex(contourPoints[i + j], ptess.vertices().count());
5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            i += count;
5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            Sk_gluTessEndContour(ptess.tess());
5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Sk_gluTessEndPolygon(ptess.tess());
5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (ptess.vertices().count() > USHRT_MAX) {
5414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            return false;
5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Draw the resulting polys and upload their edge data.
5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->enableState(GrDrawState::kEdgeAAConcave_StateBit);
5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrPointArray& vertices = ptess.vertices();
5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrIndexArray& indices = ptess.indices();
5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrDrawState::Edge* edges = ptess.edges();
5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GR_DEBUGASSERT(indices.count() % 3 == 0);
5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < indices.count(); i += 3) {
5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrPoint tri_verts[3];
5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int index0 = indices[i];
5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int index1 = indices[i + 1];
5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int index2 = indices[i + 2];
5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tri_verts[0] = vertices[index0];
5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tri_verts[1] = vertices[index1];
5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tri_verts[2] = vertices[index2];
5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawState::Edge tri_edges[6];
5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int t = 0;
5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrDrawState::Edge& edge0 = edges[index0 * 2];
5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrDrawState::Edge& edge1 = edges[index0 * 2 + 1];
5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrDrawState::Edge& edge2 = edges[index1 * 2];
5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrDrawState::Edge& edge3 = edges[index1 * 2 + 1];
5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrDrawState::Edge& edge4 = edges[index2 * 2];
5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrDrawState::Edge& edge5 = edges[index2 * 2 + 1];
5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (validEdge(edge0) && validEdge(edge1)) {
5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                tri_edges[t++] = edge0;
5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                tri_edges[t++] = edge1;
5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (validEdge(edge2) && validEdge(edge3)) {
5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                tri_edges[t++] = edge2;
5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                tri_edges[t++] = edge3;
5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (validEdge(edge4) && validEdge(edge5)) {
5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                tri_edges[t++] = edge4;
5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                tri_edges[t++] = edge5;
5771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
5781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->setEdgeAAData(&tri_edges[0], t);
5794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            target->setVertexSourceToArray(layout, &tri_verts[0], 3);
5804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            target->drawNonIndexed(kTriangles_PrimitiveType, 0, 3);
5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setEdgeAAData(NULL, 0);
5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->disableState(GrDrawState::kEdgeAAConcave_StateBit);
5844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return true;
5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fill));
5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ptess.addVertices(base, subpathVertCount, subpathCnt);
5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrPointArray& vertices = ptess.vertices();
5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrIndexArray& indices = ptess.indices();
5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (indices.count() > 0) {
5924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        target->setVertexSourceToArray(layout, vertices.begin(), vertices.count());
5934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        target->setIndexSourceToArray(indices.begin(), indices.count());
5944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        target->drawIndexed(kTriangles_PrimitiveType,
5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            0,
5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            0,
5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            vertices.count(),
5981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            indices.count());
5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return true;
6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool GrTesselatedPathRenderer::canDrawPath(const SkPath& path,
6041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           GrPathFill fill,
6054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                           const GrDrawTarget* target,
6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           bool antiAlias) const {
6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return kHairLine_PathFill != fill;
6081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
610