diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 19 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 13 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 14 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 33 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 21 | ||||
-rw-r--r-- | src/gpu/GrPath.h | 9 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverPathRenderer.cpp | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.cpp | 48 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 22 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 2 |
13 files changed, 132 insertions, 76 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 64eedfbef7..fa2223d4c4 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -517,20 +517,18 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, } } -void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) { +void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path stenciling. SkASSERT(NULL != path); SkASSERT(this->caps()->pathRenderingSupport()); - SkASSERT(!stroke.isHairlineStyle()); SkASSERT(!SkPath::IsInverseFillType(fill)); - this->onStencilPath(path, stroke, fill); + this->onStencilPath(path, fill); } -void GrDrawTarget::fillPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) { +void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path rendering. SkASSERT(NULL != path); SkASSERT(this->caps()->pathRenderingSupport()); - SkASSERT(!stroke.isHairlineStyle()); const GrDrawState* drawState = &getDrawState(); SkRect devBounds; @@ -548,7 +546,7 @@ void GrDrawTarget::fillPath(const GrPath* path, const SkStrokeRec& stroke, SkPat return; } - this->onFillPath(path, stroke, fill, dstCopy.texture() ? &dstCopy : NULL); + this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 49dd3880c8..feba55ea5b 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -326,13 +326,13 @@ public: * winding (not inverse or hairline). It will respect the HW antialias flag * on the draw state (if possible in the 3D API). */ - void stencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill); + void stencilPath(const GrPath*, SkPath::FillType fill); /** - * Fills a path. Fill must not be a hairline. It will respect the HW + * Draws a path. Fill must not be a hairline. It will respect the HW * antialias flag on the draw state (if possible in the 3D API). */ - void fillPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill); + void drawPath(const GrPath*, SkPath::FillType fill); /** * Helper function for drawing rects. It performs a geometry src push and pop @@ -455,11 +455,11 @@ public: void executeDraw(const DrawInfo& info) { this->onDraw(info); } /** - * For subclass internal use to invoke a call to onFillPath(). + * For subclass internal use to invoke a call to onDrawPath(). */ - void executeFillPath(const GrPath* path, const SkStrokeRec& stroke, - SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) { - this->onFillPath(path, stroke, fill, dstCopy); + void executeDrawPath(const GrPath* path, SkPath::FillType fill, + const GrDeviceCoordTexture* dstCopy) { + this->onDrawPath(path, fill, dstCopy); } //////////////////////////////////////////////////////////////////////////// @@ -838,8 +838,9 @@ private: const SkMatrix* matrix, const SkRect* localRect, const SkMatrix* localMatrix); - virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill) = 0; - virtual void onFillPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill, + + virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0; + virtual void onDrawPath(const GrPath*, SkPath::FillType, const GrDeviceCoordTexture* dstCopy) = 0; // helpers for reserving vertex and index space. diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 5b1c23afe4..7677b7c436 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -197,10 +197,10 @@ GrIndexBuffer* GrGpu::createIndexBuffer(uint32_t size, bool dynamic) { return this->onCreateIndexBuffer(size, dynamic); } -GrPath* GrGpu::createPath(const SkPath& path) { +GrPath* GrGpu::createPath(const SkPath& path, const SkStrokeRec& stroke) { SkASSERT(this->caps()->pathRenderingSupport()); this->handleDirtyContext(); - return this->onCreatePath(path); + return this->onCreatePath(path, stroke); } void GrGpu::clear(const SkIRect* rect, @@ -382,7 +382,7 @@ void GrGpu::onDraw(const DrawInfo& info) { this->onGpuDraw(info); } -void GrGpu::onStencilPath(const GrPath* path, const SkStrokeRec&, SkPath::FillType fill) { +void GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) { this->handleDirtyContext(); GrDrawState::AutoRestoreEffects are; @@ -393,18 +393,19 @@ void GrGpu::onStencilPath(const GrPath* path, const SkStrokeRec&, SkPath::FillTy this->onGpuStencilPath(path, fill); } -void GrGpu::onFillPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill, + +void GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) { this->handleDirtyContext(); drawState()->setDefaultVertexAttribs(); GrDrawState::AutoRestoreEffects are; - if (!this->setupClipAndFlushState(kFillPath_DrawType, dstCopy, &are)) { + if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are)) { return; } - this->onGpuFillPath(path, fill); + this->onGpuDrawPath(path, fill); } void GrGpu::finalizeReservedVertices() { diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 6a9dfa2b58..b449f9eb17 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -124,7 +124,7 @@ public: * Creates a path object that can be stenciled using stencilPath(). It is * only legal to call this if the caps report support for path stenciling. */ - GrPath* createPath(const SkPath& path); + GrPath* createPath(const SkPath& path, const SkStrokeRec& stroke); /** * Returns an index buffer that can be used to render quads. @@ -343,7 +343,7 @@ protected: kDrawLines_DrawType, kDrawTriangles_DrawType, kStencilPath_DrawType, - kFillPath_DrawType, + kDrawPath_DrawType, }; DrawType PrimTypeToDrawType(GrPrimitiveType type) { @@ -435,7 +435,7 @@ private: virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) = 0; virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size, bool dynamic) = 0; virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, bool dynamic) = 0; - virtual GrPath* onCreatePath(const SkPath& path) = 0; + virtual GrPath* onCreatePath(const SkPath& path, const SkStrokeRec&) = 0; // overridden by backend-specific derived class to perform the clear and // clearRect. NULL rect means clear whole target. @@ -446,7 +446,7 @@ private: // overridden by backend-specific derived class to perform the path stenciling. virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) = 0; - virtual void onGpuFillPath(const GrPath*, SkPath::FillType) = 0; + virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) = 0; // overridden by backend-specific derived class to perform flush virtual void onForceRenderTargetFlush() = 0; @@ -489,10 +489,8 @@ private: // GrDrawTarget overrides virtual void onDraw(const DrawInfo&) SK_OVERRIDE; - virtual void onStencilPath(const GrPath* path, const SkStrokeRec& stroke, - SkPath::FillType) SK_OVERRIDE; - - virtual void onFillPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType, + virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; + virtual void onDrawPath(const GrPath*, SkPath::FillType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; // readies the pools to provide vertex/index data. diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index dbbdf163e6..e426de358a 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -384,11 +384,10 @@ void GrInOrderDrawBuffer::onDraw(const DrawInfo& info) { } } -GrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {} -GrInOrderDrawBuffer::FillPath::FillPath() : fStroke(SkStrokeRec::kFill_InitStyle) {} +GrInOrderDrawBuffer::StencilPath::StencilPath() {} +GrInOrderDrawBuffer::DrawPath::DrawPath() {} -void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& stroke, - SkPath::FillType fill) { +void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fill) { if (this->needsNewClip()) { this->recordClip(); } @@ -400,10 +399,9 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& s sp->fPath.reset(path); path->ref(); sp->fFill = fill; - sp->fStroke = stroke; } -void GrInOrderDrawBuffer::onFillPath(const GrPath* path, const SkStrokeRec& stroke, +void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) { if (this->needsNewClip()) { this->recordClip(); @@ -412,11 +410,10 @@ void GrInOrderDrawBuffer::onFillPath(const GrPath* path, const SkStrokeRec& stro if (this->needsNewState()) { this->recordState(); } - FillPath* cp = this->recordFillPath(); + DrawPath* cp = this->recordDrawPath(); cp->fPath.reset(path); path->ref(); cp->fFill = fill; - cp->fStroke = stroke; if (NULL != dstCopy) { cp->fDstCopy = *dstCopy; } @@ -456,7 +453,7 @@ void GrInOrderDrawBuffer::reset() { fCmds.reset(); fDraws.reset(); fStencilPaths.reset(); - fFillPaths.reset(); + fDrawPaths.reset(); fStates.reset(); fClears.reset(); fVertexPool.reset(); @@ -501,7 +498,7 @@ void GrInOrderDrawBuffer::flush() { int currClear = 0; int currDraw = 0; int currStencilPath = 0; - int currFillPath = 0; + int currDrawPath = 0; int currCopySurface = 0; for (int c = 0; c < numCmds; ++c) { @@ -519,15 +516,15 @@ void GrInOrderDrawBuffer::flush() { } case kStencilPath_Cmd: { const StencilPath& sp = fStencilPaths[currStencilPath]; - fDstGpu->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill); + fDstGpu->stencilPath(sp.fPath.get(), sp.fFill); ++currStencilPath; break; } - case kFillPath_Cmd: { - const FillPath& cp = fFillPaths[currFillPath]; - fDstGpu->executeFillPath(cp.fPath.get(), cp.fStroke, cp.fFill, + case kDrawPath_Cmd: { + const DrawPath& cp = fDrawPaths[currDrawPath]; + fDstGpu->executeDrawPath(cp.fPath.get(), cp.fFill, NULL != cp.fDstCopy.texture() ? &cp.fDstCopy : NULL); - ++currFillPath; + ++currDrawPath; break; } case kSetState_Cmd: @@ -839,9 +836,9 @@ GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() { return &fStencilPaths.push_back(); } -GrInOrderDrawBuffer::FillPath* GrInOrderDrawBuffer::recordFillPath() { - fCmds.push_back(kFillPath_Cmd); - return &fFillPaths.push_back(); +GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath() { + fCmds.push_back(kDrawPath_Cmd); + return &fDrawPaths.push_back(); } GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() { diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index b9e5ca8718..275d7e06fa 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -14,7 +14,6 @@ #include "GrPath.h" #include "SkClipStack.h" -#include "SkStrokeRec.h" #include "SkTemplates.h" #include "SkTypes.h" @@ -87,7 +86,7 @@ private: kSetClip_Cmd = 4, kClear_Cmd = 5, kCopySurface_Cmd = 6, - kFillPath_Cmd = 7, + kDrawPath_Cmd = 7, }; class DrawRecord : public DrawInfo { @@ -101,15 +100,13 @@ private: StencilPath(); SkAutoTUnref<const GrPath> fPath; - SkStrokeRec fStroke; SkPath::FillType fFill; }; - struct FillPath : public ::SkNoncopyable { - FillPath(); + struct DrawPath : public ::SkNoncopyable { + DrawPath(); SkAutoTUnref<const GrPath> fPath; - SkStrokeRec fStroke; SkPath::FillType fFill; GrDeviceCoordTexture fDstCopy; }; @@ -136,9 +133,11 @@ private: const SkMatrix* matrix, const SkRect* localRect, const SkMatrix* localMatrix) SK_OVERRIDE; - virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; - virtual void onFillPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType, + + virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; + virtual void onDrawPath(const GrPath*, SkPath::FillType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; + virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE; @@ -181,7 +180,7 @@ private: void recordClip(); DrawRecord* recordDraw(const DrawInfo&); StencilPath* recordStencilPath(); - FillPath* recordFillPath(); + DrawPath* recordDrawPath(); Clear* recordClear(); CopySurface* recordCopySurface(); @@ -190,7 +189,7 @@ private: kCmdPreallocCnt = 32, kDrawPreallocCnt = 8, kStencilPathPreallocCnt = 8, - kFillPathPreallocCnt = 8, + kDrawPathPreallocCnt = 8, kStatePreallocCnt = 8, kClipPreallocCnt = 8, kClearPreallocCnt = 4, @@ -201,7 +200,7 @@ private: SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds; GrSTAllocator<kDrawPreallocCnt, DrawRecord> fDraws; GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths; - GrSTAllocator<kStatePreallocCnt, FillPath> fFillPaths; + GrSTAllocator<kStatePreallocCnt, DrawPath> fDrawPaths; GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState> fStates; GrSTAllocator<kClearPreallocCnt, Clear> fClears; GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces; diff --git a/src/gpu/GrPath.h b/src/gpu/GrPath.h index c7e7f92064..37dc9591a6 100644 --- a/src/gpu/GrPath.h +++ b/src/gpu/GrPath.h @@ -10,17 +10,24 @@ #include "GrResource.h" #include "SkRect.h" +#include "SkStrokeRec.h" class GrPath : public GrResource { public: SK_DECLARE_INST_COUNT(GrPath); - GrPath(GrGpu* gpu, bool isWrapped) : INHERITED(gpu, isWrapped) {} + GrPath(GrGpu* gpu, bool isWrapped, const SkStrokeRec& stroke) + : INHERITED(gpu, isWrapped), + fStroke(stroke) { + } const SkRect& getBounds() const { return fBounds; } + const SkStrokeRec& getStroke() const { return fStroke; } + protected: SkRect fBounds; + SkStrokeRec fStroke; private: typedef GrResource INHERITED; diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index ef3b953861..0271b22a9a 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -38,7 +38,7 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { - return stroke.isFillStyle() && + return !stroke.isHairlineStyle() && !antiAlias && // doesn't do per-path AA, relies on the target having MSAA NULL != target->getDrawState().getRenderTarget()->getStencilBuffer() && target->getDrawState().getStencil().isDisabled(); @@ -55,8 +55,8 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { SkASSERT(!path.isInverseFillType()); - SkAutoTUnref<GrPath> p(fGpu->createPath(path)); - target->stencilPath(p, stroke, path.getFillType()); + SkAutoTUnref<GrPath> p(fGpu->createPath(path, stroke)); + target->stencilPath(p, path.getFillType()); } bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, @@ -69,7 +69,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, GrDrawState* drawState = target->drawState(); SkASSERT(drawState->getStencil().isDisabled()); - SkAutoTUnref<GrPath> p(fGpu->createPath(path)); + SkAutoTUnref<GrPath> p(fGpu->createPath(path, stroke)); if (path.isInverseFillType()) { GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, @@ -96,7 +96,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, *drawState->stencil() = kStencilPass; } - target->fillPath(p, stroke, path.getFillType()); + target->drawPath(p, path.getFillType()); target->drawState()->stencil()->setDisabled(); return true; diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp index c5a4425dcd..c85644e311 100644 --- a/src/gpu/gl/GrGLPath.cpp +++ b/src/gpu/gl/GrGLPath.cpp @@ -8,6 +8,7 @@ #include "GrGLPath.h" #include "GrGpuGL.h" +#include "SkStrokeRec.h" #define GPUGL static_cast<GrGpuGL*>(this->getGpu()) @@ -15,7 +16,7 @@ #define GL_CALL_RET(R, X) GR_GL_CALL_RET(GPUGL->glInterface(), R, X) namespace { -inline GrGLubyte verb_to_gl_path_cmd(const SkPath::Verb verb) { +inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) { static const GrGLubyte gTable[] = { GR_GL_MOVE_TO, GR_GL_LINE_TO, @@ -35,7 +36,7 @@ inline GrGLubyte verb_to_gl_path_cmd(const SkPath::Verb verb) { } #ifdef SK_DEBUG -inline int num_pts(const SkPath::Verb verb) { +inline int num_pts(SkPath::Verb verb) { static const int gTable[] = { 1, // move 1, // line @@ -54,11 +55,39 @@ inline int num_pts(const SkPath::Verb verb) { return gTable[verb]; } #endif + +inline GrGLenum join_to_gl_join(SkPaint::Join join) { + static GrGLenum gSkJoinsToGrGLJoins[] = { + GR_GL_MITER_REVERT, + GR_GL_ROUND, + GR_GL_BEVEL + }; + return gSkJoinsToGrGLJoins[join]; + GR_STATIC_ASSERT(0 == SkPaint::kMiter_Join); + GR_STATIC_ASSERT(1 == SkPaint::kRound_Join); + GR_STATIC_ASSERT(2 == SkPaint::kBevel_Join); + GR_STATIC_ASSERT(GR_ARRAY_COUNT(gSkJoinsToGrGLJoins) == SkPaint::kJoinCount); +} + +inline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) { + static GrGLenum gSkCapsToGrGLCaps[] = { + GR_GL_FLAT, + GR_GL_ROUND, + GR_GL_SQUARE + }; + return gSkCapsToGrGLCaps[cap]; + GR_STATIC_ASSERT(0 == SkPaint::kButt_Cap); + GR_STATIC_ASSERT(1 == SkPaint::kRound_Cap); + GR_STATIC_ASSERT(2 == SkPaint::kSquare_Cap); + GR_STATIC_ASSERT(GR_ARRAY_COUNT(gSkCapsToGrGLCaps) == SkPaint::kCapCount); +} + } static const bool kIsWrapped = false; // The constructor creates the GL path object. -GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu, kIsWrapped) { +GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke) + : INHERITED(gpu, kIsWrapped, stroke) { #ifndef SK_SCALAR_IS_FLOAT GrCrash("Assumes scalar is float."); #endif @@ -90,6 +119,19 @@ GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu, kIsWrapped verbCnt, &pathCommands[0], 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); fBounds = path.getBounds(); + + if (stroke.needToApply()) { + GL_CALL(PathParameterf(fPathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth()))); + GL_CALL(PathParameterf(fPathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter()))); + GrGLenum join = join_to_gl_join(stroke.getJoin()); + GL_CALL(PathParameteri(fPathID, GR_GL_PATH_JOIN_STYLE, join)); + GrGLenum cap = cap_to_gl_cap(stroke.getCap()); + GL_CALL(PathParameteri(fPathID, GR_GL_PATH_INITIAL_END_CAP, cap)); + GL_CALL(PathParameteri(fPathID, GR_GL_PATH_TERMINAL_END_CAP, cap)); + + // FIXME: try to account for stroking, without rasterizing the stroke. + fBounds.outset(SkScalarToFloat(stroke.getWidth()), SkScalarToFloat(stroke.getWidth())); + } } GrGLPath::~GrGLPath() { diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h index dfe3405443..ef3aa567ad 100644 --- a/src/gpu/gl/GrGLPath.h +++ b/src/gpu/gl/GrGLPath.h @@ -14,6 +14,7 @@ class GrGpuGL; class SkPath; +class SkStrokeRec; /** * Currently this represents a path built using GL_NV_path_rendering. If we @@ -23,7 +24,7 @@ class SkPath; class GrGLPath : public GrPath { public: - GrGLPath(GrGpuGL* gpu, const SkPath& path); + GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke); virtual ~GrGLPath(); GrGLuint pathID() const { return fPathID; } // TODO: Figure out how to get an approximate size of the path in Gpu diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 113866759e..d313167a82 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -12,6 +12,7 @@ #include "GrGLShaderBuilder.h" #include "GrTemplates.h" #include "GrTypes.h" +#include "SkStrokeRec.h" #include "SkTemplates.h" static const GrGLuint GR_MAX_GLUINT = ~0U; @@ -1276,9 +1277,9 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) { } } -GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) { +GrPath* GrGpuGL::onCreatePath(const SkPath& inPath, const SkStrokeRec& stroke) { SkASSERT(this->caps()->pathRenderingSupport()); - return SkNEW_ARGS(GrGLPath, (this, inPath)); + return SkNEW_ARGS(GrGLPath, (this, inPath, stroke)); } void GrGpuGL::flushScissor() { @@ -1700,7 +1701,7 @@ void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { GL_CALL(StencilFillPath(id, fillMode, writeMask)); } -void GrGpuGL::onGpuFillPath(const GrPath* path, SkPath::FillType fill) { +void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) { SkASSERT(this->caps()->pathRenderingSupport()); GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); @@ -1709,16 +1710,27 @@ void GrGpuGL::onGpuFillPath(const GrPath* path, SkPath::FillType fill) { SkASSERT(!fCurrentProgram->hasVertexShader()); flushPathStencilSettings(fill); + const SkStrokeRec& stroke = path->getStroke(); SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill); SkASSERT(!fHWPathStencilSettings.isTwoSided()); GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); - GL_CALL(StencilFillPath(id, fillMode, writeMask)); + + if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { + GL_CALL(StencilFillPath(id, fillMode, writeMask)); + } + if (stroke.needToApply()) { + GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); + } if (nonInvertedFill == fill) { - GL_CALL(CoverFillPath(id, GR_GL_BOUNDING_BOX)); + if (stroke.needToApply()) { + GL_CALL(CoverStrokePath(id, GR_GL_BOUNDING_BOX)); + } else { + GL_CALL(CoverFillPath(id, GR_GL_BOUNDING_BOX)); + } } else { GrDrawState* drawState = this->drawState(); GrDrawState::AutoViewMatrixRestore avmr; diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index a945e54c99..17699efc7f 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -121,7 +121,7 @@ private: bool dynamic) SK_OVERRIDE; virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, bool dynamic) SK_OVERRIDE; - virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE; + virtual GrPath* onCreatePath(const SkPath&, const SkStrokeRec&) SK_OVERRIDE; virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE; virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE; virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt, @@ -152,7 +152,7 @@ private: virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE; virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; - virtual void onGpuFillPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; + virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; virtual void clearStencil() SK_OVERRIDE; virtual void clearStencilClip(const SkIRect& rect, diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index f3b566c209..4f9adb727d 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -253,7 +253,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC return false; } - SkASSERT(kFillPath_DrawType != type || !fCurrentProgram->hasVertexShader()); + SkASSERT(kDrawPath_DrawType != type || !fCurrentProgram->hasVertexShader()); fCurrentProgram.get()->ref(); |