From ffca400ef6f96a280c3e2c09210f950af64a1f24 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Tue, 22 Feb 2011 20:34:01 +0000 Subject: Make a separate path renderer object. Move enum types to GrTypes.h Review URL http://codereview.appspot.com/4167067/ git-svn-id: http://skia.googlecode.com/svn/trunk@829 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gpu/include/GrContext.h | 27 +-- gpu/include/GrContext_impl.h | 8 +- gpu/include/GrDrawTarget.h | 50 ++--- gpu/include/GrGpu.h | 12 +- gpu/include/GrInOrderDrawBuffer.h | 6 +- gpu/include/GrPaint.h | 10 +- gpu/include/GrTextContext.h | 1 + gpu/include/GrTypes.h | 41 ++++ gpu/src/GrContext.cpp | 354 ++------------------------------ gpu/src/GrDrawTarget.cpp | 14 +- gpu/src/GrGpu.cpp | 6 +- gpu/src/GrGpuGL.cpp | 10 +- gpu/src/GrGpuGL.h | 6 +- gpu/src/GrGpuGLFixed.cpp | 2 +- gpu/src/GrGpuGLFixed.h | 2 +- gpu/src/GrGpuGLShaders2.cpp | 6 +- gpu/src/GrGpuGLShaders2.h | 6 +- gpu/src/GrInOrderDrawBuffer.cpp | 11 +- gpu/src/GrPathRenderer.cpp | 352 +++++++++++++++++++++++++++++++ gpu/src/GrPathRenderer.h | 64 ++++++ gpu/src/GrTextContext.cpp | 5 +- gpu/src/gr_files.mk | 3 +- include/gpu/SkGr.h | 24 +-- src/gpu/SkGpuDevice.cpp | 26 +-- xcode/gpu/gpu.xcodeproj/project.pbxproj | 8 + 25 files changed, 584 insertions(+), 470 deletions(-) create mode 100644 gpu/src/GrPathRenderer.cpp create mode 100644 gpu/src/GrPathRenderer.h diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h index 93c012c33b..9df7105451 100644 --- a/gpu/include/GrContext.h +++ b/gpu/include/GrContext.h @@ -27,6 +27,7 @@ class GrPathIter; class GrVertexBufferAllocPool; class GrIndexBufferAllocPool; class GrInOrderDrawBuffer; +class GrPathRenderer; class GrContext : public GrRefCnt { public: @@ -276,19 +277,6 @@ public: const GrMatrix* dstMatrix = NULL, const GrMatrix* srcMatrix = NULL); - /** - * Path filling rules - */ - enum PathFills { - kWinding_PathFill, - kEvenOdd_PathFill, - kInverseWinding_PathFill, - kInverseEvenOdd_PathFill, - kHairLine_PathFill, - - kPathFillCount - }; - /** * Tessellates and draws a path. * @@ -300,7 +288,7 @@ public: */ void drawPath(const GrPaint& paint, GrPathIter* path, - PathFills fill, + GrPathFill fill, const GrPoint* translate = NULL); /** * Draws vertices with a paint. @@ -319,7 +307,7 @@ public: * number of indices. */ void drawVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, int vertexCount, const GrPoint positions[], const GrPoint texs[], @@ -358,7 +346,7 @@ public: typename COL_SRC, typename IDX_SRC> void drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc, const TEX_SRC* texCoordSrc, const COL_SRC* colorSrc, @@ -369,16 +357,16 @@ public: */ template void drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc); template void drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc, const TEX_SRC* texCoordSrc); template void drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc, const TEX_SRC* texCoordSrc, const COL_SRC* colorSrc); @@ -466,6 +454,7 @@ private: GrGpu* fGpu; GrTextureCache* fTextureCache; GrFontCache* fFontCache; + GrPathRenderer* fPathRenderer; GrVertexBufferAllocPool* fDrawBufferVBAllocPool; GrIndexBufferAllocPool* fDrawBufferIBAllocPool; diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h index 8af38e667a..c0a2107a87 100644 --- a/gpu/include/GrContext_impl.h +++ b/gpu/include/GrContext_impl.h @@ -20,7 +20,7 @@ template inline void GrContext::drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc, const TEX_SRC* texCoordSrc, const COL_SRC* colorSrc, @@ -101,7 +101,7 @@ public: template inline void GrContext::drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc) { this->drawCustomVertices inline void GrContext::drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc, const TEX_SRC* texCoordSrc) { this->drawCustomVertices inline void GrContext::drawCustomVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, const POS_SRC& posSrc, const TEX_SRC* texCoordSrc, const COL_SRC* colorSrc) { diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h index 9c78902f79..929b9ff39b 100644 --- a/gpu/include/GrDrawTarget.h +++ b/gpu/include/GrDrawTarget.h @@ -52,16 +52,10 @@ public: }; /** - * Geometric primitives used for drawing. + * Bitfield used to indicate which stages are in use. */ - enum PrimitiveType { - kTriangles_PrimitiveType, - kTriangleStrip_PrimitiveType, - kTriangleFan_PrimitiveType, - kPoints_PrimitiveType, - kLines_PrimitiveType, - kLineStrip_PrimitiveType - }; + typedef int StageBitfield; + GR_STATIC_ASSERT(sizeof(StageBitfield)*8 >= kNumStages); /** * Flags that affect rendering. Controlled using enable/disableState(). All @@ -80,22 +74,6 @@ public: // setClip. }; - /** - * Coeffecients for alpha-blending. - */ - enum BlendCoeff { - kZero_BlendCoeff, // Dst GrTCast(Src src) { */ typedef uint16_t GrVertexLayout; +/** + * Path filling rules + */ +enum GrPathFill { + kWinding_PathFill, + kEvenOdd_PathFill, + kInverseWinding_PathFill, + kInverseEvenOdd_PathFill, + kHairLine_PathFill, + + kPathFillCount +}; + +/** +* Geometric primitives used for drawing. +*/ +enum GrPrimitiveType { + kTriangles_PrimitiveType, + kTriangleStrip_PrimitiveType, + kTriangleFan_PrimitiveType, + kPoints_PrimitiveType, + kLines_PrimitiveType, + kLineStrip_PrimitiveType +}; + +/** + * Coeffecients for alpha-blending. + */ +enum GrBlendCoeff { + kZero_BlendCoeff, //setStencilPass(GrDrawTarget::kNone_StencilPass); fGpu->setViewMatrix(GrMatrix::I()); fGpu->setAlpha(0xff); - fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff, GrDrawTarget::kZero_BlendCoeff); + fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff); fGpu->disableState(GrDrawTarget::kDither_StateBit | GrDrawTarget::kClip_StateBit | GrDrawTarget::kAntialias_StateBit); @@ -166,7 +168,7 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key, texture->height(), 2*sizeof(GrPoint)); verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); - fGpu->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, + fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); entry = fTextureCache->createAndLock(*key, texture); } @@ -349,18 +351,18 @@ void GrContext::drawRect(const GrPaint& paint, return; } - GrDrawTarget::PrimitiveType primType; + GrPrimitiveType primType; int vertCount; GrPoint* vertex = geo.positions(); if (width > 0) { vertCount = 10; - primType = GrDrawTarget::kTriangleStrip_PrimitiveType; + primType = kTriangleStrip_PrimitiveType; setStrokeRectStrip(vertex, rect, width); } else { // hairline vertCount = 5; - primType = GrDrawTarget::kLineStrip_PrimitiveType; + primType = kLineStrip_PrimitiveType; vertex[0].set(rect.fLeft, rect.fTop); vertex[1].set(rect.fRight, rect.fTop); vertex[2].set(rect.fRight, rect.fBottom); @@ -398,7 +400,7 @@ void GrContext::drawRect(const GrPaint& paint, if (textured) { target->preConcatSamplerMatrix(0, m); } - target->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, 4); + target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); #else target->drawSimpleRect(rect, matrix, textured ? 1 : 0); #endif @@ -443,7 +445,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, target->preConcatSamplerMatrix(0, m); target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer()); - target->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, 4); + target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); #else GrDrawTarget* target; @@ -463,7 +465,7 @@ void GrContext::drawRectToRect(const GrPaint& paint, } void GrContext::drawVertices(const GrPaint& paint, - GrDrawTarget::PrimitiveType primitiveType, + GrPrimitiveType primitiveType, int vertexCount, const GrPoint positions[], const GrPoint texCoords[], @@ -529,339 +531,19 @@ void GrContext::drawVertices(const GrPaint& paint, //////////////////////////////////////////////////////////////////////////////// -#define STENCIL_OFF 0 // Always disable stencil (even when needed) -#define EVAL_TOL GR_Scalar1 - -static const uint32_t MAX_POINTS_PER_CURVE = 1 << 10; - -static uint32_t quadratic_point_count(const GrPoint points[], GrScalar tol) { - GrScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]); - // TODO: fixed points sqrt - if (d < tol) { - return 1; - } else { - // Each time we subdivide, d should be cut in 4. So we need to - // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x) - // points. - // 2^(log4(x)) = sqrt(x); - d = ceilf(sqrtf(d/tol)); - return GrMin(GrNextPow2((uint32_t)d), MAX_POINTS_PER_CURVE); - } -} - -static uint32_t generate_quadratic_points(const GrPoint& p0, - const GrPoint& p1, - const GrPoint& p2, - GrScalar tolSqd, - GrPoint** points, - uint32_t pointsLeft) { - if (pointsLeft < 2 || - (p1.distanceToLineSegmentBetweenSqd(p0, p2)) < tolSqd) { - (*points)[0] = p2; - *points += 1; - return 1; - } - - GrPoint q[] = { - GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)), - GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)), - }; - GrPoint r(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY)); - - pointsLeft >>= 1; - uint32_t a = generate_quadratic_points(p0, q[0], r, tolSqd, points, pointsLeft); - uint32_t b = generate_quadratic_points(r, q[1], p2, tolSqd, points, pointsLeft); - return a + b; -} - -static uint32_t cubic_point_count(const GrPoint points[], GrScalar tol) { - GrScalar d = GrMax(points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]), - points[2].distanceToLineSegmentBetweenSqd(points[0], points[3])); - d = sqrtf(d); - if (d < tol) { - return 1; - } else { - d = ceilf(sqrtf(d/tol)); - return GrMin(GrNextPow2((uint32_t)d), MAX_POINTS_PER_CURVE); - } -} - -static uint32_t generate_cubic_points(const GrPoint& p0, - const GrPoint& p1, - const GrPoint& p2, - const GrPoint& p3, - GrScalar tolSqd, - GrPoint** points, - uint32_t pointsLeft) { - if (pointsLeft < 2 || - (p1.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd && - p2.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd)) { - (*points)[0] = p3; - *points += 1; - return 1; - } - GrPoint q[] = { - GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)), - GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)), - GrPoint(GrScalarAve(p2.fX, p3.fX), GrScalarAve(p2.fY, p3.fY)) - }; - GrPoint r[] = { - GrPoint(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY)), - GrPoint(GrScalarAve(q[1].fX, q[2].fX), GrScalarAve(q[1].fY, q[2].fY)) - }; - GrPoint s(GrScalarAve(r[0].fX, r[1].fX), GrScalarAve(r[0].fY, r[1].fY)); - pointsLeft >>= 1; - uint32_t a = generate_cubic_points(p0, q[0], r[0], s, tolSqd, points, pointsLeft); - uint32_t b = generate_cubic_points(s, r[1], q[2], p3, tolSqd, points, pointsLeft); - return a + b; -} - -static int worst_case_point_count(GrPathIter* path, - int* subpaths, - GrScalar tol) { - int pointCount = 0; - *subpaths = 1; - - bool first = true; - - GrPathIter::Command cmd; - - GrPoint pts[4]; - while ((cmd = path->next(pts)) != GrPathIter::kEnd_Command) { - - switch (cmd) { - case GrPathIter::kLine_Command: - pointCount += 1; - break; - case GrPathIter::kQuadratic_Command: - pointCount += quadratic_point_count(pts, tol); - break; - case GrPathIter::kCubic_Command: - pointCount += cubic_point_count(pts, tol); - break; - case GrPathIter::kMove_Command: - pointCount += 1; - if (!first) { - ++(*subpaths); - } - break; - default: - break; - } - first = false; - } - return pointCount; -} - -static inline bool single_pass_path(const GrPathIter& path, - GrContext::PathFills fill, - const GrDrawTarget& target) { -#if STENCIL_OFF - return true; -#else - if (GrContext::kEvenOdd_PathFill == fill) { - GrPathIter::ConvexHint hint = path.hint(); - return hint == GrPathIter::kConvex_ConvexHint || - hint == GrPathIter::kNonOverlappingConvexPieces_ConvexHint; - } else if (GrContext::kWinding_PathFill == fill) { - GrPathIter::ConvexHint hint = path.hint(); - return hint == GrPathIter::kConvex_ConvexHint || - hint == GrPathIter::kNonOverlappingConvexPieces_ConvexHint || - (hint == GrPathIter::kSameWindingConvexPieces_ConvexHint && - target.canDisableBlend() && !target.isDitherState()); - - } - return false; -#endif -} - void GrContext::drawPath(const GrPaint& paint, GrPathIter* path, - PathFills fill, + GrPathFill fill, const GrPoint* translate) { GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - GrDrawTarget::AutoStateRestore asr(target); - - GrMatrix viewM = target->getViewMatrix(); - // In order to tesselate the path we get a bound on how much the matrix can - // stretch when mapping to screen coordinates. - GrScalar stretch = viewM.getMaxStretch(); - bool useStretch = stretch > 0; - GrScalar tol = EVAL_TOL; - if (!useStretch) { - // TODO: deal with perspective in some better way. - tol /= 10; - } else { - // TODO: fixed point divide - GrScalar sinv = 1 / stretch; - tol = GrMul(tol, sinv); - } - GrScalar tolSqd = GrMul(tol, tol); - - int subpathCnt; - int maxPts = worst_case_point_count(path, - &subpathCnt, - tol); - GrVertexLayout layout = 0; - + GrDrawTarget::StageBitfield enabledStages = 0; if (NULL != paint.getTexture()) { - layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); - } - // add 4 to hold the bounding rect - GrDrawTarget::AutoReleaseGeometry arg(target, layout, maxPts + 4, 0); - - GrPoint* base = (GrPoint*) arg.vertices(); - GrPoint* vert = base; - GrPoint* subpathBase = base; - - GrAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt); - - path->rewind(); - - // TODO: use primitve restart if available rather than multiple draws - GrDrawTarget::PrimitiveType type; - int passCount = 0; - GrDrawTarget::StencilPass passes[3]; - bool reverse = false; - - if (kHairLine_PathFill == fill) { - type = GrDrawTarget::kLineStrip_PrimitiveType; - passCount = 1; - passes[0] = GrDrawTarget::kNone_StencilPass; - } else { - type = GrDrawTarget::kTriangleFan_PrimitiveType; - if (single_pass_path(*path, fill, *target)) { - passCount = 1; - passes[0] = GrDrawTarget::kNone_StencilPass; - } else { - switch (fill) { - case kInverseEvenOdd_PathFill: - reverse = true; - // fallthrough - case kEvenOdd_PathFill: - passCount = 2; - passes[0] = GrDrawTarget::kEvenOddStencil_StencilPass; - passes[1] = GrDrawTarget::kEvenOddColor_StencilPass; - break; - - case kInverseWinding_PathFill: - reverse = true; - // fallthrough - case kWinding_PathFill: - passes[0] = GrDrawTarget::kWindingStencil1_StencilPass; - if (fGpu->supportsSingleStencilPassWinding()) { - passes[1] = GrDrawTarget::kWindingColor_StencilPass; - passCount = 2; - } else { - passes[1] = GrDrawTarget::kWindingStencil2_StencilPass; - passes[2] = GrDrawTarget::kWindingColor_StencilPass; - passCount = 3; - } - break; - default: - GrAssert(!"Unknown path fill!"); - return; - } - } - } - target->setReverseFill(reverse); - - GrPoint pts[4]; - - bool first = true; - int subpath = 0; - - for (;;) { - GrPathIter::Command cmd = path->next(pts); - switch (cmd) { - case GrPathIter::kMove_Command: - if (!first) { - subpathVertCount[subpath] = vert-subpathBase; - subpathBase = vert; - ++subpath; - } - *vert = pts[0]; - vert++; - break; - case GrPathIter::kLine_Command: - *vert = pts[1]; - vert++; - break; - case GrPathIter::kQuadratic_Command: { - generate_quadratic_points(pts[0], pts[1], pts[2], - tolSqd, &vert, - quadratic_point_count(pts, tol)); - break; - } - case GrPathIter::kCubic_Command: { - generate_cubic_points(pts[0], pts[1], pts[2], pts[3], - tolSqd, &vert, - cubic_point_count(pts, tol)); - break; - } - case GrPathIter::kClose_Command: - break; - case GrPathIter::kEnd_Command: - subpathVertCount[subpath] = vert-subpathBase; - ++subpath; // this could be only in debug - goto FINISHED; - } - first = false; - } -FINISHED: - GrAssert(subpath == subpathCnt); - GrAssert((vert - base) <= maxPts); - - if (translate) { - int count = vert - base; - for (int i = 0; i < count; i++) { - base[i].offset(translate->fX, translate->fY); - } - } - - // arbitrary path complexity cutoff - bool useBounds = fill != kHairLine_PathFill && - (reverse || (vert - base) > 8); - GrPoint* boundsVerts = base + maxPts; - if (useBounds) { - GrRect bounds; - if (reverse) { - GrAssert(NULL != target->getRenderTarget()); - // draw over the whole world. - bounds.setLTRB(0, 0, - GrIntToScalar(target->getRenderTarget()->width()), - GrIntToScalar(target->getRenderTarget()->height())); - GrMatrix vmi; - if (target->getViewInverse(&vmi)) { - vmi.mapRect(&bounds); - } - } else { - bounds.setBounds((GrPoint*)base, vert - base); - } - boundsVerts[0].setRectFan(bounds.fLeft, bounds.fTop, bounds.fRight, - bounds.fBottom); - } - - for (int p = 0; p < passCount; ++p) { - target->setStencilPass(passes[p]); - if (useBounds && (GrDrawTarget::kEvenOddColor_StencilPass == passes[p] || - GrDrawTarget::kWindingColor_StencilPass == passes[p])) { - target->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, - maxPts, 4); - - } else { - int baseVertex = 0; - for (int sp = 0; sp < subpathCnt; ++sp) { - target->drawNonIndexed(type, - baseVertex, - subpathVertCount[sp]); - baseVertex += subpathVertCount[sp]; - } - } + enabledStages |= 1; } + fPathRenderer->drawPath(target, enabledStages, path, fill, translate); } //////////////////////////////////////////////////////////////////////////////// @@ -918,8 +600,8 @@ void GrContext::writePixels(int left, int top, int width, int height, fGpu->disableState(GrDrawTarget::kClip_StateBit); fGpu->setAlpha(0xFF); - fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff, - GrDrawTarget::kZero_BlendCoeff); + fGpu->setBlendFunc(kOne_BlendCoeff, + kZero_BlendCoeff); fGpu->setTexture(0, texture); GrSamplerState sampler; @@ -936,7 +618,7 @@ void GrContext::writePixels(int left, int top, int width, int height, return; } ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); - fGpu->drawNonIndexed(GrDrawTarget::kTriangleFan_PrimitiveType, 0, VCOUNT); + fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); } //////////////////////////////////////////////////////////////////////////////// @@ -1069,7 +751,7 @@ GrContext::GrContext(GrGpu* gpu) { #if BATCH_RECT_TO_RECT fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); #endif - + fPathRenderer = new GrDefaultPathRenderer(fGpu->supportsSingleStencilPassWinding()); } bool GrContext::finalizeTextureKey(GrTextureKey* key, diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp index 63e59c4831..ca525b3b02 100644 --- a/gpu/src/GrDrawTarget.cpp +++ b/gpu/src/GrDrawTarget.cpp @@ -374,8 +374,8 @@ void GrDrawTarget::disableState(uint32_t bits) { fCurrDrawState.fFlagBits &= ~(bits); } -void GrDrawTarget::setBlendFunc(BlendCoeff srcCoef, - BlendCoeff dstCoef) { +void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoef, + GrBlendCoeff dstCoef) { fCurrDrawState.fSrcBlend = srcCoef; fCurrDrawState.fDstBlend = dstCoef; } @@ -515,12 +515,10 @@ bool GrDrawTarget::canDisableBlend() const { /////////////////////////////////////////////////////////////////////////////// void GrDrawTarget::drawRect(const GrRect& rect, const GrMatrix* matrix, - int stageEnableMask, + StageBitfield stageEnableBitfield, const GrRect* srcRects[], const GrMatrix* srcMatrices[]) { - GR_STATIC_ASSERT(8*sizeof(int) >= kNumStages); - - GrVertexLayout layout = GetRectVertexLayout(stageEnableMask, srcRects); + GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects); AutoReleaseGeometry geo(this, layout, 4, 0); @@ -530,13 +528,13 @@ void GrDrawTarget::drawRect(const GrRect& rect, drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); } -GrVertexLayout GrDrawTarget::GetRectVertexLayout(int stageEnableMask, +GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield, const GrRect* srcRects[]) { GrVertexLayout layout = 0; for (int i = 0; i < kNumStages; ++i) { int numTC = 0; - if (stageEnableMask & (1 << i)) { + if (stageEnableBitfield & (1 << i)) { if (NULL != srcRects && NULL != srcRects[i]) { layout |= StageTexCoordVertexLayoutBit(i, numTC); ++numTC; diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp index 9e9c1859c7..019c99ff6d 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -167,7 +167,7 @@ void GrGpu::clipWillBeSet(const GrClip& newClip) { } } -bool GrGpu::setupClipAndFlushState(PrimitiveType type) { +bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { const GrIRect* r = NULL; // we check this early because we need a valid @@ -254,7 +254,7 @@ bool GrGpu::setupClipAndFlushState(PrimitiveType type) { /////////////////////////////////////////////////////////////////////////////// -void GrGpu::drawIndexed(PrimitiveType type, +void GrGpu::drawIndexed(GrPrimitiveType type, int startVertex, int startIndex, int vertexCount, @@ -282,7 +282,7 @@ void GrGpu::drawIndexed(PrimitiveType type, vertexCount, indexCount); } -void GrGpu::drawNonIndexed(PrimitiveType type, +void GrGpu::drawNonIndexed(GrPrimitiveType type, int startVertex, int vertexCount) { GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc || diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp index 8cfc4a07ba..edcadb4be6 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -443,8 +443,8 @@ void GrGpuGL::resetContextHelper() { fHWDrawState.fFlagBits = 0; // illegal values - fHWDrawState.fSrcBlend = (BlendCoeff)-1; - fHWDrawState.fDstBlend = (BlendCoeff)-1; + fHWDrawState.fSrcBlend = (GrBlendCoeff)-1; + fHWDrawState.fDstBlend = (GrBlendCoeff)-1; fHWDrawState.fColor = GrColor_ILLEGAL; fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); @@ -1183,7 +1183,7 @@ GLenum gPrimitiveType2GLMode[] = { GL_LINE_STRIP }; -void GrGpuGL::drawIndexedHelper(PrimitiveType type, +void GrGpuGL::drawIndexedHelper(GrPrimitiveType type, uint32_t startVertex, uint32_t startIndex, uint32_t vertexCount, @@ -1203,7 +1203,7 @@ void GrGpuGL::drawIndexedHelper(PrimitiveType type, GL_UNSIGNED_SHORT, indices)); } -void GrGpuGL::drawNonIndexedHelper(PrimitiveType type, +void GrGpuGL::drawNonIndexedHelper(GrPrimitiveType type, uint32_t startVertex, uint32_t vertexCount) { GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode)); @@ -1458,7 +1458,7 @@ void GrGpuGL::flushStencil() { } } -bool GrGpuGL::flushGLStateCommon(PrimitiveType type) { +bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { // GrGpu::setupClipAndFlushState should have already checked this // and bailed if not true. diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index 017d9ea403..f6216c5c6e 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -98,12 +98,12 @@ protected: GrGLExts fExts; // GrGpu overrides - virtual void drawIndexedHelper(PrimitiveType type, + virtual void drawIndexedHelper(GrPrimitiveType type, uint32_t startVertex, uint32_t startIndex, uint32_t vertexCount, uint32_t indexCount); - virtual void drawNonIndexedHelper(PrimitiveType type, + virtual void drawNonIndexedHelper(GrPrimitiveType type, uint32_t vertexCount, uint32_t numVertices); virtual void flushScissor(const GrIRect* rect); @@ -127,7 +127,7 @@ protected: // sampler state (filtering, tiling) // FBO binding // line width - bool flushGLStateCommon(PrimitiveType type); + bool flushGLStateCommon(GrPrimitiveType type); // adjusts texture matrix to account for orientation, size, and npotness static void AdjustTextureMatrix(const GrGLTexture* texture, diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp index efb09908a0..516381e308 100644 --- a/gpu/src/GrGpuGLFixed.cpp +++ b/gpu/src/GrGpuGLFixed.cpp @@ -128,7 +128,7 @@ void GrGpuGLFixed::flushProjectionMatrix() { GR_GL(LoadMatrixf(mat)); } -bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) { +bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) { bool usingTextures[kNumStages]; diff --git a/gpu/src/GrGpuGLFixed.h b/gpu/src/GrGpuGLFixed.h index e5d472dd2e..5b81ea616d 100644 --- a/gpu/src/GrGpuGLFixed.h +++ b/gpu/src/GrGpuGLFixed.h @@ -30,7 +30,7 @@ public: protected: // overrides from GrGpu - virtual bool flushGraphicsState(PrimitiveType type); + virtual bool flushGraphicsState(GrPrimitiveType type); virtual void setupGeometry(int* startVertex, int* startIndex, int vertexCount, diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp index 34e7c87e50..14134e7b6c 100644 --- a/gpu/src/GrGpuGLShaders2.cpp +++ b/gpu/src/GrGpuGLShaders2.cpp @@ -979,7 +979,7 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc, program->fViewMatrix = GrMatrix::InvalidMatrix(); } -void GrGpuGLShaders2::getProgramDesc(PrimitiveType primType, ProgramDesc* desc) { +void GrGpuGLShaders2::getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc) { // Must initialize all fields or cache will have false negatives! desc->fVertexLayout = fGeometrySrc.fVertexLayout; @@ -1220,7 +1220,7 @@ void GrGpuGLShaders2::flushRadial2(int stage) { unis)); } -void GrGpuGLShaders2::flushProgram(PrimitiveType type) { +void GrGpuGLShaders2::flushProgram(GrPrimitiveType type) { ProgramDesc desc; getProgramDesc(type, &desc); fProgram = fProgramCache->getProgram(desc); @@ -1234,7 +1234,7 @@ void GrGpuGLShaders2::flushProgram(PrimitiveType type) { } } -bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) { +bool GrGpuGLShaders2::flushGraphicsState(GrPrimitiveType type) { if (!flushGLStateCommon(type)) { return false; diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h index 2647e23a15..e8785c9677 100644 --- a/gpu/src/GrGpuGLShaders2.h +++ b/gpu/src/GrGpuGLShaders2.h @@ -30,7 +30,7 @@ public: protected: // overrides from GrGpu - virtual bool flushGraphicsState(PrimitiveType type); + virtual bool flushGraphicsState(GrPrimitiveType type); virtual void setupGeometry(int* startVertex, int* startIndex, int vertexCount, @@ -54,7 +54,7 @@ private: void flushRadial2(int stage); // called at flush time to setup the appropriate program - void flushProgram(PrimitiveType type); + void flushProgram(GrPrimitiveType type); struct Program; @@ -69,7 +69,7 @@ private: class ProgramCache; // gets a description of needed shader - void getProgramDesc(PrimitiveType primType, ProgramDesc* desc); + void getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc); // generates and compiles a program from a description and vertex layout // will change GL's bound program diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp index 25e74e37e4..68590fc8ab 100644 --- a/gpu/src/GrInOrderDrawBuffer.cpp +++ b/gpu/src/GrInOrderDrawBuffer.cpp @@ -74,7 +74,7 @@ void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) { void GrInOrderDrawBuffer::drawRect(const GrRect& rect, const GrMatrix* matrix, - int stageEnableMask, + StageBitfield stageEnableBitfield, const GrRect* srcRects[], const GrMatrix* srcMatrices[]) { @@ -87,7 +87,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, if (fMaxQuads) { bool appendToPreviousDraw = false; - GrVertexLayout layout = GetRectVertexLayout(stageEnableMask, srcRects); + GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects); AutoReleaseGeometry geo(this, layout, 4, 0); AutoViewMatrixRestore avmr(this); GrMatrix combinedMatrix = this->getViewMatrix(); @@ -167,13 +167,12 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect, if (disabledClip) { this->enableState(kClip_StateBit); } -this->enableState(kClip_StateBit); } else { - INHERITED::drawRect(rect, matrix, stageEnableMask, srcRects, srcMatrices); + INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices); } } -void GrInOrderDrawBuffer::drawIndexed(PrimitiveType primitiveType, +void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType, int startVertex, int startIndex, int vertexCount, @@ -239,7 +238,7 @@ void GrInOrderDrawBuffer::drawIndexed(PrimitiveType primitiveType, draw.fIndexBuffer->ref(); } -void GrInOrderDrawBuffer::drawNonIndexed(PrimitiveType primitiveType, +void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType, int startVertex, int vertexCount) { if (!vertexCount) { diff --git a/gpu/src/GrPathRenderer.cpp b/gpu/src/GrPathRenderer.cpp new file mode 100644 index 0000000000..c47b6e522c --- /dev/null +++ b/gpu/src/GrPathRenderer.cpp @@ -0,0 +1,352 @@ +#include "GrPathRenderer.h" + +#include "GrPoint.h" +#include "GrDrawTarget.h" +#include "GrPathIter.h" +#include "GrMemory.h" +#include "GrTexture.h" + + + +GrDefaultPathRenderer::GrDefaultPathRenderer(bool singlePassWindingStencil) + : fSinglePassWindingStencil(singlePassWindingStencil) { + +} + +//////////////////////////////////////////////////////////////////////////////// +// Helpers for draw Path + +#define STENCIL_OFF 0 // Always disable stencil (even when needed) +static const GrScalar gTolerance = GR_Scalar1; + +static const uint32_t MAX_POINTS_PER_CURVE = 1 << 10; + +static uint32_t quadratic_point_count(const GrPoint points[], GrScalar tol) { + GrScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]); + if (d < tol) { + return 1; + } else { + // Each time we subdivide, d should be cut in 4. So we need to + // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x) + // points. + // 2^(log4(x)) = sqrt(x); + d = ceilf(sqrtf(d/tol)); + return GrMin(GrNextPow2((uint32_t)d), MAX_POINTS_PER_CURVE); + } +} + +static uint32_t generate_quadratic_points(const GrPoint& p0, + const GrPoint& p1, + const GrPoint& p2, + GrScalar tolSqd, + GrPoint** points, + uint32_t pointsLeft) { + if (pointsLeft < 2 || + (p1.distanceToLineSegmentBetweenSqd(p0, p2)) < tolSqd) { + (*points)[0] = p2; + *points += 1; + return 1; + } + + GrPoint q[] = { + GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)), + GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)), + }; + GrPoint r(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY)); + + pointsLeft >>= 1; + uint32_t a = generate_quadratic_points(p0, q[0], r, tolSqd, points, pointsLeft); + uint32_t b = generate_quadratic_points(r, q[1], p2, tolSqd, points, pointsLeft); + return a + b; +} + +static uint32_t cubic_point_count(const GrPoint points[], GrScalar tol) { + GrScalar d = GrMax(points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]), + points[2].distanceToLineSegmentBetweenSqd(points[0], points[3])); + d = sqrtf(d); + if (d < tol) { + return 1; + } else { + d = ceilf(sqrtf(d/tol)); + return GrMin(GrNextPow2((uint32_t)d), MAX_POINTS_PER_CURVE); + } +} + +static uint32_t generate_cubic_points(const GrPoint& p0, + const GrPoint& p1, + const GrPoint& p2, + const GrPoint& p3, + GrScalar tolSqd, + GrPoint** points, + uint32_t pointsLeft) { + if (pointsLeft < 2 || + (p1.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd && + p2.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd)) { + (*points)[0] = p3; + *points += 1; + return 1; + } + GrPoint q[] = { + GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)), + GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)), + GrPoint(GrScalarAve(p2.fX, p3.fX), GrScalarAve(p2.fY, p3.fY)) + }; + GrPoint r[] = { + GrPoint(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY)), + GrPoint(GrScalarAve(q[1].fX, q[2].fX), GrScalarAve(q[1].fY, q[2].fY)) + }; + GrPoint s(GrScalarAve(r[0].fX, r[1].fX), GrScalarAve(r[0].fY, r[1].fY)); + pointsLeft >>= 1; + uint32_t a = generate_cubic_points(p0, q[0], r[0], s, tolSqd, points, pointsLeft); + uint32_t b = generate_cubic_points(s, r[1], q[2], p3, tolSqd, points, pointsLeft); + return a + b; +} + +static int worst_case_point_count(GrPathIter* path, + int* subpaths, + GrScalar tol) { + int pointCount = 0; + *subpaths = 1; + + bool first = true; + + GrPathIter::Command cmd; + + GrPoint pts[4]; + while ((cmd = path->next(pts)) != GrPathIter::kEnd_Command) { + + switch (cmd) { + case GrPathIter::kLine_Command: + pointCount += 1; + break; + case GrPathIter::kQuadratic_Command: + pointCount += quadratic_point_count(pts, tol); + break; + case GrPathIter::kCubic_Command: + pointCount += cubic_point_count(pts, tol); + break; + case GrPathIter::kMove_Command: + pointCount += 1; + if (!first) { + ++(*subpaths); + } + break; + default: + break; + } + first = false; + } + return pointCount; +} + +static inline bool single_pass_path(const GrPathIter& path, + GrPathFill fill, + const GrDrawTarget& target) { +#if STENCIL_OFF + return true; +#else + if (kEvenOdd_PathFill == fill) { + GrPathIter::ConvexHint hint = path.hint(); + return hint == GrPathIter::kConvex_ConvexHint || + hint == GrPathIter::kNonOverlappingConvexPieces_ConvexHint; + } else if (kWinding_PathFill == fill) { + GrPathIter::ConvexHint hint = path.hint(); + return hint == GrPathIter::kConvex_ConvexHint || + hint == GrPathIter::kNonOverlappingConvexPieces_ConvexHint || + (hint == GrPathIter::kSameWindingConvexPieces_ConvexHint && + target.canDisableBlend() && !target.isDitherState()); + + } + return false; +#endif +} + +void GrDefaultPathRenderer::drawPath(GrDrawTarget* target, + GrDrawTarget::StageBitfield stages, + GrPathIter* path, + GrPathFill fill, + const GrPoint* translate) { + + GrDrawTarget::AutoStateRestore asr(target); + + GrMatrix viewM = target->getViewMatrix(); + // In order to tesselate the path we get a bound on how much the matrix can + // stretch when mapping to screen coordinates. + GrScalar stretch = viewM.getMaxStretch(); + bool useStretch = stretch > 0; + GrScalar tol = gTolerance; + + if (!useStretch) { + // TODO: deal with perspective in some better way. + tol /= 10; + } else { + GrScalar sinv = GR_Scalar1 / stretch; + tol = GrMul(tol, sinv); + } + GrScalar tolSqd = GrMul(tol, tol); + + int subpathCnt; + int maxPts = worst_case_point_count(path, + &subpathCnt, + tol); + + GrVertexLayout layout = 0; + for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { + if ((1 << s) & stages) { + layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); + } + } + + // add 4 to hold the bounding rect + GrDrawTarget::AutoReleaseGeometry arg(target, layout, maxPts + 4, 0); + + GrPoint* base = (GrPoint*) arg.vertices(); + GrPoint* vert = base; + GrPoint* subpathBase = base; + + GrAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt); + + path->rewind(); + + // TODO: use primitve restart if available rather than multiple draws + GrPrimitiveType type; + int passCount = 0; + GrDrawTarget::StencilPass passes[3]; + bool reverse = false; + + if (kHairLine_PathFill == fill) { + type = kLineStrip_PrimitiveType; + passCount = 1; + passes[0] = GrDrawTarget::kNone_StencilPass; + } else { + type = kTriangleFan_PrimitiveType; + if (single_pass_path(*path, fill, *target)) { + passCount = 1; + passes[0] = GrDrawTarget::kNone_StencilPass; + } else { + switch (fill) { + case kInverseEvenOdd_PathFill: + reverse = true; + // fallthrough + case kEvenOdd_PathFill: + passCount = 2; + passes[0] = GrDrawTarget::kEvenOddStencil_StencilPass; + passes[1] = GrDrawTarget::kEvenOddColor_StencilPass; + break; + + case kInverseWinding_PathFill: + reverse = true; + // fallthrough + case kWinding_PathFill: + passes[0] = GrDrawTarget::kWindingStencil1_StencilPass; + if (fSinglePassWindingStencil) { + passes[1] = GrDrawTarget::kWindingColor_StencilPass; + passCount = 2; + } else { + passes[1] = GrDrawTarget::kWindingStencil2_StencilPass; + passes[2] = GrDrawTarget::kWindingColor_StencilPass; + passCount = 3; + } + break; + default: + GrAssert(!"Unknown path fill!"); + return; + } + } + } + target->setReverseFill(reverse); + + GrPoint pts[4]; + + bool first = true; + int subpath = 0; + + for (;;) { + GrPathIter::Command cmd = path->next(pts); + switch (cmd) { + case GrPathIter::kMove_Command: + if (!first) { + subpathVertCount[subpath] = vert-subpathBase; + subpathBase = vert; + ++subpath; + } + *vert = pts[0]; + vert++; + break; + case GrPathIter::kLine_Command: + *vert = pts[1]; + vert++; + break; + case GrPathIter::kQuadratic_Command: { + generate_quadratic_points(pts[0], pts[1], pts[2], + tolSqd, &vert, + quadratic_point_count(pts, tol)); + break; + } + case GrPathIter::kCubic_Command: { + generate_cubic_points(pts[0], pts[1], pts[2], pts[3], + tolSqd, &vert, + cubic_point_count(pts, tol)); + break; + } + case GrPathIter::kClose_Command: + break; + case GrPathIter::kEnd_Command: + subpathVertCount[subpath] = vert-subpathBase; + ++subpath; // this could be only in debug + goto FINISHED; + } + first = false; + } +FINISHED: + GrAssert(subpath == subpathCnt); + GrAssert((vert - base) <= maxPts); + + if (translate) { + int count = vert - base; + for (int i = 0; i < count; i++) { + base[i].offset(translate->fX, translate->fY); + } + } + + // arbitrary path complexity cutoff + bool useBounds = fill != kHairLine_PathFill && + (reverse || (vert - base) > 8); + GrPoint* boundsVerts = base + maxPts; + if (useBounds) { + GrRect bounds; + if (reverse) { + GrAssert(NULL != target->getRenderTarget()); + // draw over the whole world. + bounds.setLTRB(0, 0, + GrIntToScalar(target->getRenderTarget()->width()), + GrIntToScalar(target->getRenderTarget()->height())); + GrMatrix vmi; + if (target->getViewInverse(&vmi)) { + vmi.mapRect(&bounds); + } + } else { + bounds.setBounds((GrPoint*)base, vert - base); + } + boundsVerts[0].setRectFan(bounds.fLeft, bounds.fTop, bounds.fRight, + bounds.fBottom); + } + + for (int p = 0; p < passCount; ++p) { + target->setStencilPass(passes[p]); + if (useBounds && (GrDrawTarget::kEvenOddColor_StencilPass == passes[p] || + GrDrawTarget::kWindingColor_StencilPass == passes[p])) { + target->drawNonIndexed(kTriangleFan_PrimitiveType, + maxPts, 4); + + } else { + int baseVertex = 0; + for (int sp = 0; sp < subpathCnt; ++sp) { + target->drawNonIndexed(type, + baseVertex, + subpathVertCount[sp]); + baseVertex += subpathVertCount[sp]; + } + } + } +} diff --git a/gpu/src/GrPathRenderer.h b/gpu/src/GrPathRenderer.h new file mode 100644 index 0000000000..e3fd71507a --- /dev/null +++ b/gpu/src/GrPathRenderer.h @@ -0,0 +1,64 @@ +/* + Copyright 2011 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#ifndef GrPathRenderer_DEFINED +#define GrPathRenderer_DEFINED + +#include "GrDrawTarget.h" + +class GrPathIter; +struct GrPoint; + +/** + * A path renderer. + */ +class GrPathRenderer { +public: + /** + * Draws a path into the draw target. The target will already have its draw + * state configured for the draw. + * @param target the target to draw into. + * @param stages indicates which stages the are already + * in use. All enabled stages expect positions + * as texture coordinates. The path renderer + * use the remaining stages for its path + * filling algorithm. + * @param path the path to draw. + * @param fill the fill rule to apply. + * @param translate optional additional translation to apply to + * the path NULL means (0,0). + */ + virtual void drawPath(GrDrawTarget* target, + GrDrawTarget::StageBitfield stages, + GrPathIter* path, + GrPathFill fill, + const GrPoint* translate) = 0; +}; + +class GrDefaultPathRenderer : public GrPathRenderer { +public: + GrDefaultPathRenderer(bool singlePassWindingStencil); + + virtual void drawPath(GrDrawTarget* target, + GrDrawTarget::StageBitfield stages, + GrPathIter* path, + GrPathFill fill, + const GrPoint* translate); +private: + bool fSinglePassWindingStencil; +}; + +#endif \ No newline at end of file diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp index 0f244a2e81..8ce45e40eb 100644 --- a/gpu/src/GrTextContext.cpp +++ b/gpu/src/GrTextContext.cpp @@ -23,6 +23,7 @@ #include "GrFontScaler.h" #include "GrIndexBuffer.h" #include "GrGpuVertex.h" +#include "GrDrawTarget.h" static const int TEXT_STAGE = 1; @@ -47,7 +48,7 @@ void GrTextContext::flushGlyphs() { fDrawTarget->setTexture(TEXT_STAGE, fCurrTexture); fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); - fDrawTarget->drawIndexed(GrDrawTarget::kTriangles_PrimitiveType, + fDrawTarget->drawIndexed(kTriangles_PrimitiveType, 0, 0, fCurrVertex, nIndices); fDrawTarget->releaseReservedGeometry(); fVertices = NULL; @@ -178,7 +179,7 @@ void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, GrPoint translate; translate.set(GrFixedToScalar(vx - GrIntToFixed(glyph->fBounds.fLeft)), GrFixedToScalar(vy - GrIntToFixed(glyph->fBounds.fTop))); - fContext->drawPath(fPaint, &iter, GrContext::kWinding_PathFill, + fContext->drawPath(fPaint, &iter, kWinding_PathFill, &translate); return; } diff --git a/gpu/src/gr_files.mk b/gpu/src/gr_files.mk index e6d69972cb..88aa84b222 100644 --- a/gpu/src/gr_files.mk +++ b/gpu/src/gr_files.mk @@ -21,4 +21,5 @@ SOURCE := \ GrTextureCache.cpp \ GrTextContext.cpp \ GrTextStrike.cpp \ - GrBufferAllocPool.cpp + GrBufferAllocPool.cpp\ + GrPathRenderer.cpp diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h index 298763906d..ccdd400933 100644 --- a/include/gpu/SkGr.h +++ b/include/gpu/SkGr.h @@ -77,18 +77,18 @@ GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode == #define sk_tile_mode_to_grwrap(X) ((GrSamplerState::WrapMode)(X)) -GR_STATIC_ASSERT((int)GrGpu::kZero_BlendCoeff == (int)SkXfermode::kZero_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kOne_BlendCoeff == (int)SkXfermode::kOne_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kSC_BlendCoeff == (int)SkXfermode::kSC_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kISC_BlendCoeff == (int)SkXfermode::kISC_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kDC_BlendCoeff == (int)SkXfermode::kDC_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kIDC_BlendCoeff == (int)SkXfermode::kIDC_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kSA_BlendCoeff == (int)SkXfermode::kSA_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kISA_BlendCoeff == (int)SkXfermode::kISA_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kDA_BlendCoeff == (int)SkXfermode::kDA_Coeff); -GR_STATIC_ASSERT((int)GrGpu::kIDA_BlendCoeff == (int)SkXfermode::kIDA_Coeff); - -#define sk_blend_to_grblend(X) ((GrGpu::BlendCoeff)(X)) +GR_STATIC_ASSERT((int)kZero_BlendCoeff == (int)SkXfermode::kZero_Coeff); +GR_STATIC_ASSERT((int)kOne_BlendCoeff == (int)SkXfermode::kOne_Coeff); +GR_STATIC_ASSERT((int)kSC_BlendCoeff == (int)SkXfermode::kSC_Coeff); +GR_STATIC_ASSERT((int)kISC_BlendCoeff == (int)SkXfermode::kISC_Coeff); +GR_STATIC_ASSERT((int)kDC_BlendCoeff == (int)SkXfermode::kDC_Coeff); +GR_STATIC_ASSERT((int)kIDC_BlendCoeff == (int)SkXfermode::kIDC_Coeff); +GR_STATIC_ASSERT((int)kSA_BlendCoeff == (int)SkXfermode::kSA_Coeff); +GR_STATIC_ASSERT((int)kISA_BlendCoeff == (int)SkXfermode::kISA_Coeff); +GR_STATIC_ASSERT((int)kDA_BlendCoeff == (int)SkXfermode::kDA_Coeff); +GR_STATIC_ASSERT((int)kIDA_BlendCoeff == (int)SkXfermode::kIDA_Coeff); + +#define sk_blend_to_grblend(X) ((GrBlendCoeff)(X)) GR_STATIC_ASSERT((int)SkPath::kMove_Verb == (int)GrPathIter::kMove_Command); GR_STATIC_ASSERT((int)SkPath::kLine_Verb == (int)GrPathIter::kLine_Command); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index faa31f6532..3bf157bfa9 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -584,10 +584,10 @@ void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { } // must be in SkCanvas::PointMode order -static const GrDrawTarget::PrimitiveType gPointMode2PrimtiveType[] = { - GrDrawTarget::kPoints_PrimitiveType, - GrDrawTarget::kLines_PrimitiveType, - GrDrawTarget::kLineStrip_PrimitiveType +static const GrPrimitiveType gPointMode2PrimtiveType[] = { + kPoints_PrimitiveType, + kLines_PrimitiveType, + kLineStrip_PrimitiveType }; void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, @@ -774,21 +774,21 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, return; } - GrContext::PathFills fill = GrContext::kHairLine_PathFill; + GrPathFill fill = kHairLine_PathFill; if (doFill) { switch (pathPtr->getFillType()) { case SkPath::kWinding_FillType: - fill = GrContext::kWinding_PathFill; + fill = kWinding_PathFill; break; case SkPath::kEvenOdd_FillType: - fill = GrContext::kEvenOdd_PathFill; + fill = kEvenOdd_PathFill; break; case SkPath::kInverseWinding_FillType: - fill = GrContext::kInverseWinding_PathFill; + fill = kInverseWinding_PathFill; break; case SkPath::kInverseEvenOdd_FillType: - fill = GrContext::kInverseEvenOdd_PathFill; + fill = kInverseEvenOdd_PathFill; break; default: SkDebugf("Unsupported path fill type\n"); @@ -986,10 +986,10 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev, /////////////////////////////////////////////////////////////////////////////// // must be in SkCanvas::VertexMode order -static const GrDrawTarget::PrimitiveType gVertexMode2PrimitiveType[] = { - GrDrawTarget::kTriangles_PrimitiveType, - GrDrawTarget::kTriangleStrip_PrimitiveType, - GrDrawTarget::kTriangleFan_PrimitiveType, +static const GrPrimitiveType gVertexMode2PrimitiveType[] = { + kTriangles_PrimitiveType, + kTriangleStrip_PrimitiveType, + kTriangleFan_PrimitiveType, }; void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, diff --git a/xcode/gpu/gpu.xcodeproj/project.pbxproj b/xcode/gpu/gpu.xcodeproj/project.pbxproj index 22541557e1..58a6358394 100644 --- a/xcode/gpu/gpu.xcodeproj/project.pbxproj +++ b/xcode/gpu/gpu.xcodeproj/project.pbxproj @@ -92,6 +92,8 @@ D53904A112EA026E0025F3D6 /* GrPaint.h in Headers */ = {isa = PBXBuildFile; fileRef = D53904A012EA026E0025F3D6 /* GrPaint.h */; }; D58CAF9A12E7212100CB9277 /* GrGLUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D58CAF9812E7212100CB9277 /* GrGLUtil.cpp */; }; D5ED886F1313F92C00B98D64 /* GrRedBlackTree.h in Headers */ = {isa = PBXBuildFile; fileRef = D5ED886E1313F92C00B98D64 /* GrRedBlackTree.h */; }; + D5ED88EB13144FD600B98D64 /* GrPathRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D5ED88E913144FD600B98D64 /* GrPathRenderer.cpp */; }; + D5ED88EC13144FD600B98D64 /* GrPathRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = D5ED88EA13144FD600B98D64 /* GrPathRenderer.h */; }; D5FAF20C130726C6001550A4 /* GrGeometryBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = D5FAF20B130726C6001550A4 /* GrGeometryBuffer.h */; }; D5FAF22313072C27001550A4 /* GrBufferAllocPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D5FAF22113072C27001550A4 /* GrBufferAllocPool.cpp */; }; D5FAF22413072C27001550A4 /* GrBufferAllocPool.h in Headers */ = {isa = PBXBuildFile; fileRef = D5FAF22213072C27001550A4 /* GrBufferAllocPool.h */; }; @@ -184,6 +186,8 @@ D53904A012EA026E0025F3D6 /* GrPaint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrPaint.h; path = ../../gpu/include/GrPaint.h; sourceTree = SOURCE_ROOT; }; D58CAF9812E7212100CB9277 /* GrGLUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrGLUtil.cpp; path = ../../gpu/src/GrGLUtil.cpp; sourceTree = SOURCE_ROOT; }; D5ED886E1313F92C00B98D64 /* GrRedBlackTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrRedBlackTree.h; path = ../../gpu/src/GrRedBlackTree.h; sourceTree = SOURCE_ROOT; }; + D5ED88E913144FD600B98D64 /* GrPathRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrPathRenderer.cpp; path = ../../gpu/src/GrPathRenderer.cpp; sourceTree = SOURCE_ROOT; }; + D5ED88EA13144FD600B98D64 /* GrPathRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrPathRenderer.h; path = ../../gpu/src/GrPathRenderer.h; sourceTree = SOURCE_ROOT; }; D5FAF20B130726C6001550A4 /* GrGeometryBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrGeometryBuffer.h; path = ../../gpu/include/GrGeometryBuffer.h; sourceTree = SOURCE_ROOT; }; D5FAF22113072C27001550A4 /* GrBufferAllocPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GrBufferAllocPool.cpp; path = ../../gpu/src/GrBufferAllocPool.cpp; sourceTree = SOURCE_ROOT; }; D5FAF22213072C27001550A4 /* GrBufferAllocPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrBufferAllocPool.h; path = ../../gpu/src/GrBufferAllocPool.h; sourceTree = SOURCE_ROOT; }; @@ -277,6 +281,8 @@ 08FB7795FE84155DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( + D5ED88E913144FD600B98D64 /* GrPathRenderer.cpp */, + D5ED88EA13144FD600B98D64 /* GrPathRenderer.h */, D5ED886E1313F92C00B98D64 /* GrRedBlackTree.h */, D539049A12EA01E30025F3D6 /* GrContext_impl.h */, 00115DD812C1167A008296FE /* gr_unittests.cpp */, @@ -398,6 +404,7 @@ D5FAF22413072C27001550A4 /* GrBufferAllocPool.h in Headers */, 00216E5E130F0B03009A2160 /* GrGLIRect.h in Headers */, D5ED886F1313F92C00B98D64 /* GrRedBlackTree.h in Headers */, + D5ED88EC13144FD600B98D64 /* GrPathRenderer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -475,6 +482,7 @@ 00115E2912C1167A008296FE /* GrTextureCache.cpp in Sources */, D58CAF9A12E7212100CB9277 /* GrGLUtil.cpp in Sources */, D5FAF22313072C27001550A4 /* GrBufferAllocPool.cpp in Sources */, + D5ED88EB13144FD600B98D64 /* GrPathRenderer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- cgit v1.2.3