aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrDrawTarget.cpp10
-rw-r--r--src/gpu/GrDrawTarget.h19
-rw-r--r--src/gpu/GrGpu.cpp13
-rw-r--r--src/gpu/GrGpu.h14
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp33
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h21
-rw-r--r--src/gpu/GrPath.h9
-rw-r--r--src/gpu/GrStencilAndCoverPathRenderer.cpp10
-rw-r--r--src/gpu/gl/GrGLPath.cpp48
-rw-r--r--src/gpu/gl/GrGLPath.h3
-rw-r--r--src/gpu/gl/GrGpuGL.cpp22
-rw-r--r--src/gpu/gl/GrGpuGL.h4
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp2
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();