From 7ffe6810c6787f7a353ef3fe8fab3fc6440aae19 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Fri, 11 May 2012 17:32:43 +0000 Subject: Remove tesselated path renderer and supporting code, glu, and libtess target Review URL: http://codereview.appspot.com/6197075/ git-svn-id: http://skia.googlecode.com/svn/trunk@3912 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/GrAddPathRenderers_tesselated.cpp | 17 - src/gpu/GrDrawState.h | 69 +--- src/gpu/GrDrawTarget.cpp | 1 - src/gpu/GrDrawTarget.h | 9 - src/gpu/GrTesselatedPathRenderer.cpp | 613 ------------------------------ src/gpu/GrTesselatedPathRenderer.h | 32 -- src/gpu/gl/GrGLProgram.cpp | 52 +-- src/gpu/gl/GrGLProgram.h | 4 +- src/gpu/gl/GrGpuGL.cpp | 7 - src/gpu/gl/GrGpuGL.h | 1 - src/gpu/gl/GrGpuGLShaders.cpp | 40 +- src/gpu/gl/GrGpuGLShaders.h | 3 - 12 files changed, 9 insertions(+), 839 deletions(-) delete mode 100644 src/gpu/GrAddPathRenderers_tesselated.cpp delete mode 100644 src/gpu/GrTesselatedPathRenderer.cpp delete mode 100644 src/gpu/GrTesselatedPathRenderer.h (limited to 'src') diff --git a/src/gpu/GrAddPathRenderers_tesselated.cpp b/src/gpu/GrAddPathRenderers_tesselated.cpp deleted file mode 100644 index a1cde13155..0000000000 --- a/src/gpu/GrAddPathRenderers_tesselated.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#include "GrTesselatedPathRenderer.h" - - -void GrPathRenderer::AddPathRenderers(GrContext*, - GrPathRendererChain::UsageFlags flags, - GrPathRendererChain* chain) { - chain->addPathRenderer(new GrTesselatedPathRenderer())->unref(); -} diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 357f864c15..77e2139e6b 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -93,8 +93,6 @@ public: sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) + sizeof(fSrcBlend) + sizeof(fDstBlend) == this->podSize()); - - fEdgeAANumEdges = 0; } /////////////////////////////////////////////////////////////////////////// @@ -545,12 +543,10 @@ public: /////////////////////////////////////////////////////////////////////////// // @name Edge AA - // There are two ways to perform antialiasing using edge equations. One - // is to specify an (linear or quadratic) edge eq per-vertex. This requires - // splitting vertices shared by primitives. + // Edge equations can be specified to perform antialiasing. Because the + // edges are specified as per-vertex data, vertices that are shared by + // multiple edges must be split. // - // The other is via setEdgeAAData which sets a set of edges and each - // is tested against all the edges. //// /** @@ -592,48 +588,6 @@ public: VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; } - /** - * The absolute maximum number of edges that may be specified for - * a single draw call when performing edge antialiasing. This is used for - * the size of several static buffers, so implementations of getMaxEdges() - * (below) should clamp to this value. - */ - enum { - // TODO: this should be 32 when GrTesselatedPathRenderer is used - // Visual Studio 2010 does not permit a member array of size 0. - kMaxEdges = 1 - }; - - class Edge { - public: - Edge() {} - Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {} - GrPoint intersect(const Edge& other) { - return GrPoint::Make( - SkFloatToScalar((fY * other.fZ - other.fY * fZ) / - (fX * other.fY - other.fX * fY)), - SkFloatToScalar((fX * other.fZ - other.fX * fZ) / - (other.fX * fY - fX * other.fY))); - } - float fX, fY, fZ; - }; - - /** - * Sets the edge data required for edge antialiasing. - * - * @param edges 3 * numEdges float values, representing the edge - * equations in Ax + By + C form - */ - void setEdgeAAData(const Edge* edges, int numEdges) { - GrAssert(numEdges <= GrDrawState::kMaxEdges); - memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge)); - fEdgeAANumEdges = numEdges; - } - - int getNumAAEdges() const { return fEdgeAANumEdges; } - - const Edge* getAAEdges() const { return fEdgeAAEdges; } - /// @} /////////////////////////////////////////////////////////////////////////// @@ -719,10 +673,6 @@ public: return 0 != (fFlagBits & kNoColorWrites_StateBit); } - bool isConcaveEdgeAAState() const { - return 0 != (fFlagBits & kEdgeAAConcave_StateBit); - } - bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); } @@ -829,9 +779,6 @@ public: fViewMatrix = s.fViewMatrix; fBehaviorBits = s.fBehaviorBits; - GrAssert(0 == s.fEdgeAANumEdges); - fEdgeAANumEdges = 0; - for (int i = 0; i < kNumStages; i++) { if (s.fTextures[i]) { this->fSamplerStates[i] = s.fSamplerStates[i]; @@ -859,9 +806,6 @@ private: } size_t podSize() const { // Can't use offsetof() with non-POD types, so stuck with pointer math. - // TODO: ignores GrTesselatedPathRenderer data structures. We don't - // have a compile-time flag that lets us know if it's being used, and - // checking at runtime seems to cost 5% performance. return reinterpret_cast(&fPodEndMarker) - reinterpret_cast(&fPodStartMarker) + sizeof(fPodEndMarker); @@ -901,13 +845,6 @@ private: uint32_t fBehaviorBits; GrMatrix fViewMatrix; - // @{ Data for GrTesselatedPathRenderer - // TODO: currently ignored in copying & comparison for performance. - // Must be considered if GrTesselatedPathRenderer is being used. - int fEdgeAANumEdges; - Edge fEdgeAAEdges[kMaxEdges]; - // @} - // This field must be last; it will not be copied or compared // if the corresponding fTexture[] is NULL. GrSamplerState fSamplerStates[kNumStages]; diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 037f0f8530..715799c95f 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -956,7 +956,6 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, // edge aa or coverage texture stage bool hasCoverage = forceCoverage || 0xffffffff != drawState.getCoverage() || - drawState.getNumAAEdges() > 0 || (layout & kCoverage_VertexLayoutBit) || (layout & kEdge_VertexLayoutBit); for (int s = drawState.getFirstCoverageStage(); diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 273ef3c043..c0e70dd0cf 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -545,15 +545,6 @@ public: */ virtual void clear(const GrIRect* rect, GrColor color) = 0; - /** - * Returns the maximum number of edges that may be specified in a single - * draw call when performing edge antialiasing. This is usually limited - * by the number of fragment uniforms which may be uploaded. Must be a - * minimum of six, since a triangle's vertices each belong to two boundary - * edges which may be distinct. - */ - virtual int getMaxEdges() const { return 6; } - //////////////////////////////////////////////////////////////////////////// /** diff --git a/src/gpu/GrTesselatedPathRenderer.cpp b/src/gpu/GrTesselatedPathRenderer.cpp deleted file mode 100644 index 5920ae143b..0000000000 --- a/src/gpu/GrTesselatedPathRenderer.cpp +++ /dev/null @@ -1,613 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#include "GrTesselatedPathRenderer.h" - -#include "GrDrawState.h" -#include "GrPathUtils.h" -#include "GrPoint.h" -#include "GrRenderTarget.h" -#include "GrTDArray.h" - -#include "SkTemplates.h" - -#include -#include - -typedef GrTDArray GrEdgeArray; -typedef GrTDArray GrPointArray; -typedef GrTDArray GrIndexArray; -typedef void (*TESSCB)(); - -// limit the allowable vertex range to approximately half of the representable -// IEEE exponent in order to avoid overflow when doing multiplies between -// vertex components, -const float kMaxVertexValue = 1e18f; - -static inline GrDrawState::Edge computeEdge(const GrPoint& p, - const GrPoint& q, - float sign) { - GrVec tangent = GrVec::Make(p.fY - q.fY, q.fX - p.fX); - float scale = sign / tangent.length(); - float cross2 = p.fX * q.fY - q.fX * p.fY; - return GrDrawState::Edge(tangent.fX * scale, - tangent.fY * scale, - cross2 * scale); -} - -static inline GrPoint sanitizePoint(const GrPoint& pt) { - GrPoint r; - r.fX = SkScalarPin(pt.fX, - SkFloatToScalar(-kMaxVertexValue), - SkFloatToScalar(kMaxVertexValue)); - r.fY = SkScalarPin(pt.fY, - SkFloatToScalar(-kMaxVertexValue), - SkFloatToScalar(kMaxVertexValue)); - return r; -} - -class GrTess { -public: - GrTess(int count, unsigned winding_rule) { - fTess = Sk_gluNewTess(); - Sk_gluTessProperty(fTess, GLU_TESS_WINDING_RULE, winding_rule); - Sk_gluTessNormal(fTess, 0.0f, 0.0f, 1.0f); - Sk_gluTessCallback(fTess, GLU_TESS_BEGIN_DATA, (TESSCB) &beginCB); - Sk_gluTessCallback(fTess, GLU_TESS_VERTEX_DATA, (TESSCB) &vertexCB); - Sk_gluTessCallback(fTess, GLU_TESS_END_DATA, (TESSCB) &endCB); - Sk_gluTessCallback(fTess, GLU_TESS_EDGE_FLAG_DATA, (TESSCB) &edgeFlagCB); - Sk_gluTessCallback(fTess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineCB); - fInVertices = new double[count * 3]; - } - virtual ~GrTess() { - Sk_gluDeleteTess(fTess); - delete[] fInVertices; - } - void addVertex(const GrPoint& pt, int index) { - if (index > USHRT_MAX) return; - double* inVertex = &fInVertices[index * 3]; - inVertex[0] = pt.fX; - inVertex[1] = pt.fY; - inVertex[2] = 0.0; - *fVertices.append() = pt; - Sk_gluTessVertex(fTess, inVertex, reinterpret_cast(index)); - } - void addVertices(const GrPoint* points, const uint16_t* contours, int numContours) { - Sk_gluTessBeginPolygon(fTess, this); - size_t i = 0; - for (int j = 0; j < numContours; ++j) { - Sk_gluTessBeginContour(fTess); - size_t end = i + contours[j]; - for (; i < end; ++i) { - addVertex(points[i], i); - } - Sk_gluTessEndContour(fTess); - } - Sk_gluTessEndPolygon(fTess); - } - GLUtesselator* tess() { return fTess; } - const GrPointArray& vertices() const { return fVertices; } -protected: - virtual void begin(GLenum type) = 0; - virtual void vertex(int index) = 0; - virtual void edgeFlag(bool flag) = 0; - virtual void end() = 0; - virtual int combine(GLdouble coords[3], int vertexIndices[4], - GLfloat weight[4]) = 0; - static void beginCB(GLenum type, void* data) { - static_cast(data)->begin(type); - } - static void vertexCB(void* vertexData, void* data) { - static_cast(data)->vertex(reinterpret_cast(vertexData)); - } - static void edgeFlagCB(GLboolean flag, void* data) { - static_cast(data)->edgeFlag(flag != 0); - } - static void endCB(void* data) { - static_cast(data)->end(); - } - static void combineCB(GLdouble coords[3], void* vertexData[4], - GLfloat weight[4], void **outData, void* data) { - int vertexIndex[4]; - vertexIndex[0] = reinterpret_cast(vertexData[0]); - vertexIndex[1] = reinterpret_cast(vertexData[1]); - vertexIndex[2] = reinterpret_cast(vertexData[2]); - vertexIndex[3] = reinterpret_cast(vertexData[3]); - GrTess* tess = static_cast(data); - int outIndex = tess->combine(coords, vertexIndex, weight); - *reinterpret_cast(outData) = outIndex; - } -protected: - GLUtesselator* fTess; - GrPointArray fVertices; - double* fInVertices; -}; - -class GrPolygonTess : public GrTess { -public: - GrPolygonTess(int count, unsigned winding_rule) - : GrTess(count, winding_rule) { - } - ~GrPolygonTess() { - } - const GrIndexArray& indices() const { return fIndices; } -protected: - virtual void begin(GLenum type) { - GR_DEBUGASSERT(type == GL_TRIANGLES); - } - virtual void vertex(int index) { - *fIndices.append() = index; - } - virtual void edgeFlag(bool flag) {} - virtual void end() {} - virtual int combine(GLdouble coords[3], int vertexIndices[4], - GLfloat weight[4]) { - int index = fVertices.count(); - GrPoint p = GrPoint::Make(static_cast(coords[0]), - static_cast(coords[1])); - *fVertices.append() = p; - return index; - } -protected: - GrIndexArray fIndices; -}; - -class GrEdgePolygonTess : public GrPolygonTess { -public: - GrEdgePolygonTess(int count, unsigned winding_rule, const SkMatrix& matrix) - : GrPolygonTess(count, winding_rule), - fMatrix(matrix), - fEdgeFlag(false), - fEdgeVertex(-1), - fTriStartVertex(-1), - fEdges(NULL) { - } - ~GrEdgePolygonTess() { - delete[] fEdges; - } - const GrDrawState::Edge* edges() const { return fEdges; } -private: - void addEdge(int index0, int index1) { - GrPoint p = fVertices[index0]; - GrPoint q = fVertices[index1]; - fMatrix.mapPoints(&p, 1); - fMatrix.mapPoints(&q, 1); - p = sanitizePoint(p); - q = sanitizePoint(q); - if (p == q) return; - GrDrawState::Edge edge = computeEdge(p, q, 1.0f); - fEdges[index0 * 2 + 1] = edge; - fEdges[index1 * 2] = edge; - } - virtual void begin(GLenum type) { - GR_DEBUGASSERT(type == GL_TRIANGLES); - int count = fVertices.count() * 2; - fEdges = new GrDrawState::Edge[count]; - memset(fEdges, 0, count * sizeof(GrDrawState::Edge)); - } - virtual void edgeFlag(bool flag) { - fEdgeFlag = flag; - } - virtual void vertex(int index) { - bool triStart = fIndices.count() % 3 == 0; - GrPolygonTess::vertex(index); - if (fEdgeVertex != -1) { - if (triStart) { - addEdge(fEdgeVertex, fTriStartVertex); - } else { - addEdge(fEdgeVertex, index); - } - } - if (triStart) { - fTriStartVertex = index; - } - if (fEdgeFlag) { - fEdgeVertex = index; - } else { - fEdgeVertex = -1; - } - } - virtual void end() { - if (fEdgeVertex != -1) { - addEdge(fEdgeVertex, fTriStartVertex); - } - } - GrMatrix fMatrix; - bool fEdgeFlag; - int fEdgeVertex, fTriStartVertex; - GrDrawState::Edge* fEdges; -}; - -class GrBoundaryTess : public GrTess { -public: - GrBoundaryTess(int count, unsigned winding_rule) - : GrTess(count, winding_rule), - fContourStart(0) { - Sk_gluTessProperty(fTess, GLU_TESS_BOUNDARY_ONLY, 1); - } - ~GrBoundaryTess() { - } - GrPointArray& contourPoints() { return fContourPoints; } - const GrIndexArray& contours() const { return fContours; } -private: - virtual void begin(GLenum type) { - fContourStart = fContourPoints.count(); - } - virtual void vertex(int index) { - *fContourPoints.append() = fVertices.at(index); - } - virtual void edgeFlag(bool flag) {} - virtual void end() { - *fContours.append() = fContourPoints.count() - fContourStart; - } - virtual int combine(GLdouble coords[3], int vertexIndices[4], - GLfloat weight[4]) { - int index = fVertices.count(); - *fVertices.append() = GrPoint::Make(static_cast(coords[0]), - static_cast(coords[1])); - return index; - } - GrPointArray fContourPoints; - GrIndexArray fContours; - size_t fContourStart; -}; - -static bool nearlyEqual(float a, float b) { - return fabsf(a - b) < 0.0001f; -} - -static bool nearlyEqual(const GrPoint& a, const GrPoint& b) { - return nearlyEqual(a.fX, b.fX) && nearlyEqual(a.fY, b.fY); -} - -static bool parallel(const GrDrawState::Edge& a, const GrDrawState::Edge& b) { - return (nearlyEqual(a.fX, b.fX) && nearlyEqual(a.fY, b.fY)) || - (nearlyEqual(a.fX, -b.fX) && nearlyEqual(a.fY, -b.fY)); -} - -static unsigned fill_type_to_glu_winding_rule(GrPathFill fill) { - switch (fill) { - case kWinding_PathFill: - return GLU_TESS_WINDING_NONZERO; - case kEvenOdd_PathFill: - return GLU_TESS_WINDING_ODD; - case kInverseWinding_PathFill: - return GLU_TESS_WINDING_POSITIVE; - case kInverseEvenOdd_PathFill: - return GLU_TESS_WINDING_ODD; - case kHairLine_PathFill: - return GLU_TESS_WINDING_NONZERO; // FIXME: handle this - default: - GrAssert(!"Unknown path fill!"); - return 0; - } -} - -GrTesselatedPathRenderer::GrTesselatedPathRenderer() { -} - -static bool isCCW(const GrPoint* pts, int count) { - GrVec v1, v2; - do { - v1 = pts[1] - pts[0]; - v2 = pts[2] - pts[1]; - pts++; - count--; - } while (nearlyEqual(v1, v2) && count > 3); - return v1.cross(v2) < 0; -} - -static bool validEdge(const GrDrawState::Edge& edge) { - return !(edge.fX == 0.0f && edge.fY == 0.0f && edge.fZ == 0.0f); -} - -static size_t computeEdgesAndIntersect(const GrMatrix& matrix, - const GrMatrix& inverse, - GrPoint* vertices, - size_t numVertices, - GrEdgeArray* edges, - float sign) { - if (numVertices < 3) { - return 0; - } - matrix.mapPoints(vertices, numVertices); - if (sign == 0.0f) { - sign = isCCW(vertices, numVertices) ? -1.0f : 1.0f; - } - GrPoint p = sanitizePoint(vertices[numVertices - 1]); - for (size_t i = 0; i < numVertices; ++i) { - GrPoint q = sanitizePoint(vertices[i]); - if (p == q) { - continue; - } - GrDrawState::Edge edge = computeEdge(p, q, sign); - edge.fZ += 0.5f; // Offset by half a pixel along the tangent. - *edges->append() = edge; - p = q; - } - int count = edges->count(); - if (count == 0) { - return 0; - } - GrDrawState::Edge prev_edge = edges->at(0); - for (int i = 0; i < count; ++i) { - GrDrawState::Edge edge = edges->at(i < count - 1 ? i + 1 : 0); - if (parallel(edge, prev_edge)) { - // 3 points are collinear; offset by half the tangent instead - vertices[i].fX -= edge.fX * 0.5f; - vertices[i].fY -= edge.fY * 0.5f; - } else { - vertices[i] = prev_edge.intersect(edge); - } - inverse.mapPoints(&vertices[i], 1); - prev_edge = edge; - } - return edges->count(); -} - -bool GrTesselatedPathRenderer::onDrawPath(const SkPath& path, - GrPathFill fill, - const GrVec* translate, - GrDrawTarget* target, - GrDrawState::StageMask stageMask, - bool antiAlias) { - - GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); - GrDrawState* drawState = target->drawState(); - // face culling doesn't make sense here - GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace()); - - GrMatrix viewM = drawState->getViewMatrix(); - - GrScalar tol = GR_Scalar1; - tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds()); - GrScalar tolSqd = GrMul(tol, tol); - - int subpathCnt; - int maxPts = GrPathUtils::worstCasePointCount(path, &subpathCnt, tol); - - GrVertexLayout layout = 0; - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - if ((1 << s) & stageMask) { - layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); - } - } - - bool inverted = GrIsFillInverted(fill); - if (inverted) { - maxPts += 4; - subpathCnt++; - } - if (maxPts > USHRT_MAX) { - return false; - } - SkAutoSTMalloc<8, GrPoint> baseMem(maxPts); - GrPoint* base = baseMem; - GrPoint* vert = base; - GrPoint* subpathBase = base; - - SkAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt); - - GrPoint pts[4]; - SkPath::Iter iter(path, false); - - bool first = true; - int subpath = 0; - - for (;;) { - switch (iter.next(pts)) { - case kMove_PathCmd: - if (!first) { - subpathVertCount[subpath] = vert-subpathBase; - subpathBase = vert; - ++subpath; - } - *vert = pts[0]; - vert++; - break; - case kLine_PathCmd: - *vert = pts[1]; - vert++; - break; - case kQuadratic_PathCmd: { - GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], - tolSqd, &vert, - GrPathUtils::quadraticPointCount(pts, tol)); - break; - } - case kCubic_PathCmd: { - GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], - tolSqd, &vert, - GrPathUtils::cubicPointCount(pts, tol)); - break; - } - case kClose_PathCmd: - break; - case kEnd_PathCmd: - subpathVertCount[subpath] = vert-subpathBase; - ++subpath; // this could be only in debug - goto FINISHED; - } - first = false; - } -FINISHED: - if (NULL != translate && 0 != translate->fX && 0 != translate->fY) { - for (int i = 0; i < vert - base; i++) { - base[i].offset(translate->fX, translate->fY); - } - } - - if (inverted) { - GrRect bounds; - GrAssert(NULL != drawState->getRenderTarget()); - bounds.setLTRB(0, 0, - GrIntToScalar(drawState->getRenderTarget()->width()), - GrIntToScalar(drawState->getRenderTarget()->height())); - GrMatrix vmi; - if (drawState->getViewInverse(&vmi)) { - vmi.mapRect(&bounds); - } - *vert++ = GrPoint::Make(bounds.fLeft, bounds.fTop); - *vert++ = GrPoint::Make(bounds.fLeft, bounds.fBottom); - *vert++ = GrPoint::Make(bounds.fRight, bounds.fBottom); - *vert++ = GrPoint::Make(bounds.fRight, bounds.fTop); - subpathVertCount[subpath++] = 4; - } - - GrAssert(subpath == subpathCnt); - GrAssert((vert - base) <= maxPts); - - size_t count = vert - base; - - if (count < 3) { - return true; - } - - if (subpathCnt == 1 && !inverted && path.isConvex()) { - if (antiAlias) { - GrEdgeArray edges; - GrMatrix inverse, matrix = drawState->getViewMatrix(); - drawState->getViewInverse(&inverse); - - count = computeEdgesAndIntersect(matrix, inverse, base, count, &edges, 0.0f); - size_t maxEdges = target->getMaxEdges(); - if (count == 0) { - return true; - } - if (count <= maxEdges) { - // All edges fit; upload all edges and draw all verts as a fan - target->setVertexSourceToArray(layout, base, count); - drawState->setEdgeAAData(&edges[0], count); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); - } else { - // Upload "maxEdges" edges and verts at a time, and draw as - // separate fans - for (size_t i = 0; i < count - 2; i += maxEdges - 2) { - edges[i] = edges[0]; - base[i] = base[0]; - int size = GR_CT_MIN(count - i, maxEdges); - target->setVertexSourceToArray(layout, &base[i], size); - drawState->setEdgeAAData(&edges[i], size); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size); - } - } - drawState->setEdgeAAData(NULL, 0); - } else { - target->setVertexSourceToArray(layout, base, count); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); - } - return true; - } - - if (antiAlias) { - // Run the tesselator once to get the boundaries. - GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fill)); - btess.addVertices(base, subpathVertCount, subpathCnt); - - GrMatrix inverse, matrix = drawState->getViewMatrix(); - if (!drawState->getViewInverse(&inverse)) { - return false; - } - - if (btess.vertices().count() > USHRT_MAX) { - return false; - } - - // Inflate the boundary, and run the tesselator again to generate - // interior polys. - const GrPointArray& contourPoints = btess.contourPoints(); - const GrIndexArray& contours = btess.contours(); - GrEdgePolygonTess ptess(contourPoints.count(), GLU_TESS_WINDING_NONZERO, matrix); - - size_t i = 0; - Sk_gluTessBeginPolygon(ptess.tess(), &ptess); - for (int contour = 0; contour < contours.count(); ++contour) { - int count = contours[contour]; - GrEdgeArray edges; - int newCount = computeEdgesAndIntersect(matrix, inverse, &btess.contourPoints()[i], count, &edges, 1.0f); - Sk_gluTessBeginContour(ptess.tess()); - for (int j = 0; j < newCount; j++) { - ptess.addVertex(contourPoints[i + j], ptess.vertices().count()); - } - i += count; - Sk_gluTessEndContour(ptess.tess()); - } - - Sk_gluTessEndPolygon(ptess.tess()); - - if (ptess.vertices().count() > USHRT_MAX) { - return false; - } - - // Draw the resulting polys and upload their edge data. - drawState->enableState(GrDrawState::kEdgeAAConcave_StateBit); - const GrPointArray& vertices = ptess.vertices(); - const GrIndexArray& indices = ptess.indices(); - const GrDrawState::Edge* edges = ptess.edges(); - GR_DEBUGASSERT(indices.count() % 3 == 0); - for (int i = 0; i < indices.count(); i += 3) { - GrPoint tri_verts[3]; - int index0 = indices[i]; - int index1 = indices[i + 1]; - int index2 = indices[i + 2]; - tri_verts[0] = vertices[index0]; - tri_verts[1] = vertices[index1]; - tri_verts[2] = vertices[index2]; - GrDrawState::Edge tri_edges[6]; - int t = 0; - const GrDrawState::Edge& edge0 = edges[index0 * 2]; - const GrDrawState::Edge& edge1 = edges[index0 * 2 + 1]; - const GrDrawState::Edge& edge2 = edges[index1 * 2]; - const GrDrawState::Edge& edge3 = edges[index1 * 2 + 1]; - const GrDrawState::Edge& edge4 = edges[index2 * 2]; - const GrDrawState::Edge& edge5 = edges[index2 * 2 + 1]; - if (validEdge(edge0) && validEdge(edge1)) { - tri_edges[t++] = edge0; - tri_edges[t++] = edge1; - } - if (validEdge(edge2) && validEdge(edge3)) { - tri_edges[t++] = edge2; - tri_edges[t++] = edge3; - } - if (validEdge(edge4) && validEdge(edge5)) { - tri_edges[t++] = edge4; - tri_edges[t++] = edge5; - } - drawState->setEdgeAAData(&tri_edges[0], t); - target->setVertexSourceToArray(layout, &tri_verts[0], 3); - target->drawNonIndexed(kTriangles_PrimitiveType, 0, 3); - } - drawState->setEdgeAAData(NULL, 0); - drawState->disableState(GrDrawState::kEdgeAAConcave_StateBit); - return true; - } - - GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fill)); - ptess.addVertices(base, subpathVertCount, subpathCnt); - const GrPointArray& vertices = ptess.vertices(); - const GrIndexArray& indices = ptess.indices(); - if (indices.count() > 0) { - target->setVertexSourceToArray(layout, vertices.begin(), vertices.count()); - target->setIndexSourceToArray(indices.begin(), indices.count()); - target->drawIndexed(kTriangles_PrimitiveType, - 0, - 0, - vertices.count(), - indices.count()); - } - return true; -} - -bool GrTesselatedPathRenderer::canDrawPath(const SkPath& path, - GrPathFill fill, - const GrDrawTarget* target, - bool antiAlias) const { - return kHairLine_PathFill != fill; -} - diff --git a/src/gpu/GrTesselatedPathRenderer.h b/src/gpu/GrTesselatedPathRenderer.h deleted file mode 100644 index 3d12ae970c..0000000000 --- a/src/gpu/GrTesselatedPathRenderer.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef GrTesselatedPathRenderer_DEFINED -#define GrTesselatedPathRenderer_DEFINED - -#include "GrPathRenderer.h" - -class GrTesselatedPathRenderer : public GrPathRenderer { -public: - GrTesselatedPathRenderer(); - - virtual bool canDrawPath(const SkPath& path, - GrPathFill fill, - const GrDrawTarget* target, - bool antiAlias) const SK_OVERRIDE; - - virtual bool onDrawPath(const SkPath& path, - GrPathFill fill, - const GrVec* translate, - GrDrawTarget* target, - GrDrawState::StageMask stageMask, - bool antiAlias) SK_OVERRIDE; -}; - -#endif diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 88b1456dcf..27a0b12d3b 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -413,57 +413,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl, CachedData* programData, GrStringBuilder* coverageVar, ShaderCodeSegments* segments) const { - if (fProgramDesc.fEdgeAANumEdges > 0) { - segments->fFSUnis.push_back().set(kVec3f_GrSLType, - GrGLShaderVar::kUniform_TypeModifier, - EDGES_UNI_NAME, - fProgramDesc.fEdgeAANumEdges); - programData->fUniLocations.fEdgesUni = kUseUniform; - int count = fProgramDesc.fEdgeAANumEdges; - segments->fFSCode.append( - "\tvec3 pos = vec3(gl_FragCoord.xy, 1);\n"); - for (int i = 0; i < count; i++) { - segments->fFSCode.append("\tfloat a"); - segments->fFSCode.appendS32(i); - segments->fFSCode.append(" = clamp(dot(" EDGES_UNI_NAME "["); - segments->fFSCode.appendS32(i); - segments->fFSCode.append("], pos), 0.0, 1.0);\n"); - } - if (fProgramDesc.fEdgeAAConcave && (count & 0x01) == 0) { - // For concave polys, we consider the edges in pairs. - segments->fFSFunctions.append("float cross2(vec2 a, vec2 b) {\n"); - segments->fFSFunctions.append("\treturn dot(a, vec2(b.y, -b.x));\n"); - segments->fFSFunctions.append("}\n"); - for (int i = 0; i < count; i += 2) { - segments->fFSCode.appendf("\tfloat eb%d;\n", i / 2); - segments->fFSCode.appendf("\tif (cross2(" EDGES_UNI_NAME "[%d].xy, " EDGES_UNI_NAME "[%d].xy) < 0.0) {\n", i, i + 1); - segments->fFSCode.appendf("\t\teb%d = a%d * a%d;\n", i / 2, i, i + 1); - segments->fFSCode.append("\t} else {\n"); - segments->fFSCode.appendf("\t\teb%d = a%d + a%d - a%d * a%d;\n", i / 2, i, i + 1, i, i + 1); - segments->fFSCode.append("\t}\n"); - } - segments->fFSCode.append("\tfloat edgeAlpha = "); - for (int i = 0; i < count / 2 - 1; i++) { - segments->fFSCode.appendf("min(eb%d, ", i); - } - segments->fFSCode.appendf("eb%d", count / 2 - 1); - for (int i = 0; i < count / 2 - 1; i++) { - segments->fFSCode.append(")"); - } - segments->fFSCode.append(";\n"); - } else { - segments->fFSCode.append("\tfloat edgeAlpha = "); - for (int i = 0; i < count - 1; i++) { - segments->fFSCode.appendf("min(a%d * a%d, ", i, i + 1); - } - segments->fFSCode.appendf("a%d * a0", count - 1); - for (int i = 0; i < count - 1; i++) { - segments->fFSCode.append(")"); - } - segments->fFSCode.append(";\n"); - } - *coverageVar = "edgeAlpha"; - } else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) { + if (layout & GrDrawTarget::kEdge_VertexLayoutBit) { const char *vsName, *fsName; append_varying(kVec4f_GrSLType, "Edge", segments, &vsName, &fsName); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 9e2ee7e3f5..eecdee7575 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -242,12 +242,10 @@ public: uint8_t fDualSrcOutput; // casts to enum DualSrcOutput int8_t fFirstCoverageStage; SkBool8 fEmitsPointSize; - SkBool8 fEdgeAAConcave; SkBool8 fColorMatrixEnabled; - int8_t fEdgeAANumEdges; uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode - int8_t fPadding[3]; + int8_t fPadding[1]; } fProgramDesc; GR_STATIC_ASSERT(!(sizeof(ProgramDesc) % 4)); diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 69e494afdb..2966f59633 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -2489,10 +2489,3 @@ void GrGpuGL::setBuffers(bool indexed, } } -int GrGpuGL::getMaxEdges() const { - // FIXME: This is a pessimistic estimate based on how many other things - // want to add uniforms. This should be centralized somewhere. - return GR_CT_MIN(this->glCaps().maxFragmentUniformVectors() - 8, - GrDrawState::kMaxEdges); -} - diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 0f16feb8ce..b3453a02ae 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -144,7 +144,6 @@ protected: virtual void clearStencil(); virtual void clearStencilClip(const GrIRect& rect, bool insideClip); - virtual int getMaxEdges() const; // binds texture unit in GL void setTextureUnit(int unitIdx); diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGLShaders.cpp index 48ec623f42..49aa87c3e6 100644 --- a/src/gpu/gl/GrGpuGLShaders.cpp +++ b/src/gpu/gl/GrGpuGLShaders.cpp @@ -221,21 +221,13 @@ bool GrGpuGLShaders::programUnitTest() { bool edgeAA = random_bool(&random); if (edgeAA) { - bool vertexEdgeAA = random_bool(&random); - if (vertexEdgeAA) { - pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit; - if (this->getCaps().fShaderDerivativeSupport) { - pdesc.fVertexEdgeType = (GrDrawState::VertexEdgeType) random_int(&random, GrDrawState::kVertexEdgeTypeCnt); - } else { - pdesc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType; - } - pdesc.fEdgeAANumEdges = 0; + pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit; + if (this->getCaps().fShaderDerivativeSupport) { + pdesc.fVertexEdgeType = (GrDrawState::VertexEdgeType) random_int(&random, GrDrawState::kVertexEdgeTypeCnt); } else { - pdesc.fEdgeAANumEdges = random_int(&random, 1, this->getMaxEdges()); - pdesc.fEdgeAAConcave = random_bool(&random); + pdesc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType; } } else { - pdesc.fEdgeAANumEdges = 0; } pdesc.fColorMatrixEnabled = random_bool(&random); @@ -635,24 +627,6 @@ void GrGpuGLShaders::flushTexelSize(int s) { } } -void GrGpuGLShaders::flushEdgeAAData() { - const int& uni = fProgramData->fUniLocations.fEdgesUni; - if (GrGLProgram::kUnusedUniform != uni) { - int count = this->getDrawState().getNumAAEdges(); - GrDrawState::Edge edges[GrDrawState::kMaxEdges]; - // Flip the edges in Y - float height = - static_cast(this->getDrawState().getRenderTarget()->height()); - for (int i = 0; i < count; ++i) { - edges[i] = this->getDrawState().getAAEdges()[i]; - float b = edges[i].fY; - edges[i].fY = -b; - edges[i].fZ += b * height; - } - GL_CALL(Uniform3fv(uni, count, &edges[0].fX)); - } -} - void GrGpuGLShaders::flushColorMatrix() { const ProgramDesc& desc = fCurrentProgram.getDesc(); int matrixUni = fProgramData->fUniLocations.fColorMatrixUni; @@ -853,7 +827,6 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { } } } - this->flushEdgeAAData(); this->flushColorMatrix(); resetDirtyFlags(); return true; @@ -1108,10 +1081,6 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, desc.fCoverageInput = ProgramDesc::kAttribute_ColorInput; } - desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges(); - desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 && - drawState.isConcaveEdgeAAState(); - int lastEnabledStage = -1; if (!skipCoverage && (desc.fVertexLayout & @@ -1294,7 +1263,6 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, // other coverage inputs if (!hasCoverage) { hasCoverage = - desc.fEdgeAANumEdges || requiresAttributeCoverage || (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit); } diff --git a/src/gpu/gl/GrGpuGLShaders.h b/src/gpu/gl/GrGpuGLShaders.h index 55fd952bf1..b983389aa7 100644 --- a/src/gpu/gl/GrGpuGLShaders.h +++ b/src/gpu/gl/GrGpuGLShaders.h @@ -75,9 +75,6 @@ private: // flushes the normalized texel size void flushTexelSize(int stage); - // flushes the edges for edge AA - void flushEdgeAAData(); - // flushes the color matrix void flushColorMatrix(); -- cgit v1.2.3