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