Towards NV path rendering
Review URL: http://codereview.appspot.com/6302049/
git-svn-id: http://skia.googlecode.com/svn/trunk@4219 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index e56b98f..55bd04c 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -14,6 +14,7 @@
#include "GrRefCnt.h"
#include "GrSamplerState.h"
#include "GrStencil.h"
+#include "GrTexture.h"
#include "SkXfermode.h"
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index bc373ba..148dd19 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -830,6 +830,14 @@
}
}
+void GrDrawTarget::stencilPath(const GrPath& path, GrPathFill fill) {
+ // TODO: extract portions of checkDraw that are relevant to path stenciling.
+ GrAssert(fCaps.fPathStencilingSupport);
+ GrAssert(kHairLine_GrPathFill != fill);
+ GrAssert(!GrIsFillInverted(fill));
+ this->onStencilPath(path, fill);
+}
+
////////////////////////////////////////////////////////////////////////////////
// Some blend modes allow folding a partial coverage value into the color's
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index a6ab675..6e5bc67 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -12,22 +12,17 @@
#define GrDrawTarget_DEFINED
#include "GrClip.h"
-#include "GrColor.h"
#include "GrDrawState.h"
#include "GrIndexBuffer.h"
#include "GrMatrix.h"
#include "GrRefCnt.h"
-#include "GrSamplerState.h"
-#include "GrStencil.h"
-#include "GrTexture.h"
#include "SkXfermode.h"
#include "SkTLazy.h"
-class GrTexture;
class GrClipIterator;
+class GrPath;
class GrVertexBuffer;
-class GrIndexBuffer;
class GrDrawTarget : public GrRefCnt {
public:
@@ -52,6 +47,7 @@
bool fFSAASupport : 1;
bool fDualSourceBlendingSupport : 1;
bool fBufferLockSupport : 1;
+ bool fPathStencilingSupport : 1;
int fMaxRenderTargetSize;
int fMaxTextureSize;
};
@@ -436,7 +432,7 @@
* Pops the vertex / index sources from the matching push.
*/
void popGeometrySource();
-
+
/**
* Draws indexed geometry using the current state and current vertex / index
* sources.
@@ -470,6 +466,13 @@
int vertexCount);
/**
+ * Draws path into the stencil buffer. The fill must be either even/odd or
+ * 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& path, GrPathFill fill);
+
+ /**
* Helper function for drawing rects. This does not use the current index
* and vertex sources. After returning, the vertex and index sources may
* have changed. They should be reestablished before the next drawIndexed
@@ -1042,6 +1045,8 @@
virtual void onDrawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount) = 0;
+ virtual void onStencilPath(const GrPath& path, GrPathFill fill) = 0;
+
// subclass overrides to be notified when clip is set. Must call
// INHERITED::clipwillBeSet
virtual void clipWillBeSet(const GrClip& clip) {}
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 9e26135..7765d24 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -226,6 +226,12 @@
return this->onCreateIndexBuffer(size, dynamic);
}
+GrPath* GrGpu::createPath(const SkPath& path) {
+ GrAssert(fCaps.fPathStencilingSupport);
+ this->handleDirtyContext();
+ return this->onCreatePath(path);
+}
+
void GrGpu::clear(const GrIRect* rect, GrColor color) {
if (NULL == this->getDrawState().getRenderTarget()) {
return;
@@ -358,7 +364,7 @@
////////////////////////////////////////////////////////////////////////////////
-bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
+bool GrGpu::setupClipAndFlushState(DrawType type) {
ScissoringSettings scissoringSettings;
@@ -410,7 +416,7 @@
this->handleDirtyContext();
- if (!this->setupClipAndFlushState(type)) {
+ if (!this->setupClipAndFlushState(PrimTypeToDrawType(type))) {
return;
}
@@ -423,11 +429,11 @@
}
void GrGpu::onDrawNonIndexed(GrPrimitiveType type,
- int startVertex,
- int vertexCount) {
+ int startVertex,
+ int vertexCount) {
this->handleDirtyContext();
- if (!this->setupClipAndFlushState(type)) {
+ if (!this->setupClipAndFlushState(PrimTypeToDrawType(type))) {
return;
}
@@ -437,6 +443,16 @@
this->onGpuDrawNonIndexed(type, sVertex, vertexCount);
}
+void GrGpu::onStencilPath(const GrPath& path, GrPathFill fill) {
+ this->handleDirtyContext();
+
+ if (!this->setupClipAndFlushState(kStencilPath_DrawType)) {
+ return;
+ }
+
+ this->onGpuStencilPath(path, fill);
+}
+
void GrGpu::finalizeReservedVertices() {
GrAssert(NULL != fVertexPool);
fVertexPool->unlock();
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index d39ace0..9302393 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -13,11 +13,11 @@
#include "GrDrawTarget.h"
#include "GrRect.h"
#include "GrRefCnt.h"
-#include "GrTexture.h"
#include "GrClipMaskManager.h"
class GrContext;
class GrIndexBufferAllocPool;
+class GrPath;
class GrPathRenderer;
class GrPathRendererChain;
class GrResource;
@@ -130,6 +130,12 @@
GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
/**
+ * 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);
+
+ /**
* Returns an index buffer that can be used to render quads.
* Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
* The max number of quads can be queried using GrIndexBuffer::maxQuads().
@@ -341,8 +347,32 @@
}
protected:
+ enum DrawType {
+ kDrawPoints_DrawType,
+ kDrawLines_DrawType,
+ kDrawTriangles_DrawType,
+ kStencilPath_DrawType,
+ };
+
+ DrawType PrimTypeToDrawType(GrPrimitiveType type) {
+ switch (type) {
+ case kTriangles_GrPrimitiveType:
+ case kTriangleStrip_GrPrimitiveType:
+ case kTriangleFan_GrPrimitiveType:
+ return kDrawTriangles_DrawType;
+ case kPoints_GrPrimitiveType:
+ return kDrawPoints_DrawType;
+ case kLines_GrPrimitiveType:
+ case kLineStrip_GrPrimitiveType:
+ return kDrawLines_DrawType;
+ default:
+ GrCrash("Unexpected primitive type");
+ return kDrawTriangles_DrawType;
+ }
+ }
+
// prepares clip flushes gpu state before a draw
- bool setupClipAndFlushState(GrPrimitiveType type);
+ bool setupClipAndFlushState(DrawType);
// Functions used to map clip-respecting stencil tests into normal
// stencil funcs supported by GPUs.
@@ -413,6 +443,7 @@
bool dynamic) = 0;
virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
bool dynamic) = 0;
+ virtual GrPath* onCreatePath(const SkPath& path) = 0;
// overridden by API-specific derivated class to perform the clear and
// clearRect. NULL rect means clear whole target.
@@ -428,6 +459,8 @@
virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
uint32_t vertexCount,
uint32_t numVertices) = 0;
+ // overridden by API-specific derived class to perform the path stenciling.
+ virtual void onGpuStencilPath(const GrPath& path, GrPathFill fill) = 0;
// overridden by API-specific derived class to perform flush
virtual void onForceRenderTargetFlush() = 0;
@@ -472,7 +505,7 @@
// deltas from previous state at draw time. This function does the
// API-specific flush of the state
// returns false if current state is unsupported.
- virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
+ virtual bool flushGraphicsState(DrawType) = 0;
// clears the entire stencil buffer to 0
virtual void clearStencil() = 0;
@@ -518,6 +551,7 @@
virtual void onDrawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount) SK_OVERRIDE;
+ virtual void onStencilPath(const GrPath& path, GrPathFill fill) SK_OVERRIDE;
// readies the pools to provide vertex/index data.
void prepareVertexPool();
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 7abe941..907b4f1 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -439,6 +439,10 @@
draw.fIndexBuffer = NULL;
}
+void GrInOrderDrawBuffer::onStencilPath(const GrPath&, GrPathFill) {
+ GrCrash("Not implemented yet. Should not get here.");
+}
+
void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
GrIRect r;
if (NULL == rect) {
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index a467f6c..ed7d97d 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -147,6 +147,7 @@
virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
int startVertex,
int vertexCount) SK_OVERRIDE;
+ virtual void onStencilPath(const GrPath&, GrPathFill) SK_OVERRIDE;
virtual bool onReserveVertexSpace(GrVertexLayout layout,
int vertexCount,
void** vertices) SK_OVERRIDE;
diff --git a/src/gpu/GrPath.h b/src/gpu/GrPath.h
new file mode 100644
index 0000000..872859d
--- /dev/null
+++ b/src/gpu/GrPath.h
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrPath_DEFINED
+#define GrPath_DEFINED
+
+#include "GrResource.h"
+#include "GrRect.h"
+
+class GrPath : public GrResource {
+public:
+ GrPath(GrGpu* gpu) : INHERITED(gpu) {}
+
+ const GrIRect& getBounds() const { return fBounds; }
+
+protected:
+ GrIRect fBounds;
+
+private:
+ typedef GrResource INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp
new file mode 100644
index 0000000..2fceaa3
--- /dev/null
+++ b/src/gpu/gl/GrGLPath.cpp
@@ -0,0 +1,101 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLPath.h"
+#include "GrGpuGL.h"
+
+#define GPUGL static_cast<GrGpuGL*>(this->getGpu())
+
+#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
+#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) {
+ static const GrGLubyte gTable[] = {
+ GR_GL_MOVE_TO,
+ GR_GL_LINE_TO,
+ GR_GL_QUADRATIC_CURVE_TO,
+ GR_GL_CUBIC_CURVE_TO,
+ GR_GL_CLOSE_PATH,
+ };
+ GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
+ GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
+ GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
+ GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb);
+ GR_STATIC_ASSERT(4 == SkPath::kClose_Verb);
+
+ GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable));
+ return gTable[verb];
+}
+
+inline int num_pts(const SkPath::Verb verb) {
+ static const int gTable[] = {
+ 1, // move
+ 1, // line
+ 2, // quad
+ 3, // cubic
+ 0, // close
+ };
+ GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
+ GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
+ GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
+ GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb);
+ GR_STATIC_ASSERT(4 == SkPath::kClose_Verb);
+
+ GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable));
+ return gTable[verb];
+}
+}
+
+GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu) {
+ GL_CALL_RET(fPathID, GenPaths(1));
+ SkPath::Iter iter(path, true);
+
+ SkSTArray<16, GrGLubyte, true> pathCommands;
+ GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); // assuming SkPoint is floats
+ SkSTArray<16, SkPoint, true> pathPoints;
+
+ int verbCnt = path.countVerbs();
+ int pointCnt = path.countPoints();
+ pathCommands.resize_back(verbCnt);
+ pathPoints.resize_back(pointCnt);
+
+ // TODO: Direct access to path points since we could pass them on directly.
+ path.getPoints(&pathPoints[0], pointCnt);
+ path.getVerbs(&pathCommands[0], verbCnt);
+
+ GR_DEBUGCODE(int numPts = 0);
+ for (int i = 0; i < verbCnt; ++i) {
+ SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
+ pathCommands[i] = verb_to_gl_path_cmd(v);
+ GR_DEBUGCODE(numPts += num_pts(v));
+ }
+ GrAssert(pathPoints.count() == numPts);
+
+ GL_CALL(PathCommands(fPathID,
+ verbCnt, &pathCommands[0],
+ 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
+ GrRect bounds = path.getBounds();
+ bounds.roundOut(&fBounds);
+}
+
+GrGLPath::~GrGLPath() {
+ this->release();
+}
+
+void GrGLPath::onRelease() {
+ if (0 != fPathID) {
+ GL_CALL(DeletePaths(1, fPathID));
+ fPathID = 0;
+ }
+}
+
+void GrGLPath::onAbandon() {
+ fPathID = 0;
+}
+
diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h
new file mode 100644
index 0000000..f9febb4
--- /dev/null
+++ b/src/gpu/gl/GrGLPath.h
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLPath_DEFINED
+#define GrGLPath_DEFINED
+
+#include "../GrPath.h"
+#include "gl/GrGLFunctions.h"
+
+class GrGpuGL;
+class SkPath;
+
+/**
+ * Currently this represents a path built using GL_NV_path_rendering. If we
+ * support other GL path extensions then this would have to have a type enum
+ * and/or be subclassed.
+ */
+
+class GrGLPath : public GrPath {
+public:
+ GrGLPath(GrGpuGL* gpu, const SkPath& path);
+ virtual ~GrGLPath();
+ GrGLuint pathID() const { return fPathID; }
+ // TODO: Figure out how to get an approximate size of the path in Gpu
+ // memory.
+ virtual size_t sizeInBytes() const SK_OVERRIDE { return 100; }
+
+protected:
+ virtual void onRelease() SK_OVERRIDE;
+ virtual void onAbandon() SK_OVERRIDE;
+
+private:
+ GrGLuint fPathID;
+
+ typedef GrPath INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index da168cd..77d8758 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -8,6 +8,7 @@
#include "GrGpuGL.h"
#include "GrGLStencilBuffer.h"
+#include "GrGLPath.h"
#include "GrTypes.h"
#include "SkTemplates.h"
@@ -1325,6 +1326,14 @@
return NULL;
}
+GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) {
+ GrPath* path = NULL;
+ if (fCaps.fPathStencilingSupport) {
+ path = new GrGLPath(this, inPath);
+ }
+ return path;
+}
+
void GrGpuGL::enableScissoring(const GrIRect& rect) {
const GrDrawState& drawState = this->getDrawState();
const GrGLRenderTarget* rt =
@@ -1718,6 +1727,10 @@
#endif
}
+void GrGpuGL::onGpuStencilPath(const GrPath&, GrPathFill) {
+ GrCrash("Not implemented yet. Should not get here.");
+}
+
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
@@ -1955,7 +1968,7 @@
}
}
-void GrGpuGL::flushAAState(GrPrimitiveType type) {
+void GrGpuGL::flushAAState(bool isLines) {
const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
if (kDesktop_GrGLBinding == this->glBinding()) {
// ES doesn't support toggling GL_MULTISAMPLE and doesn't have
@@ -1963,7 +1976,7 @@
// we prefer smooth lines over multisampled lines
bool smoothLines = false;
- if (GrIsPrimTypeLines(type)) {
+ if (isLines) {
smoothLines = this->willUseHWAALines();
if (smoothLines) {
if (kYes_TriState != fHWAAState.fSmoothLineEnabled) {
@@ -1999,10 +2012,10 @@
}
}
-void GrGpuGL::flushBlend(GrPrimitiveType type,
+void GrGpuGL::flushBlend(bool isLines,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff) {
- if (GrIsPrimTypeLines(type) && this->willUseHWAALines()) {
+ if (isLines && this->willUseHWAALines()) {
if (kYes_TriState != fHWBlendState.fEnabled) {
GL_CALL(Enable(GR_GL_BLEND));
fHWBlendState.fEnabled = kYes_TriState;
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 2906170..51e49ec 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -67,6 +67,7 @@
bool dynamic) SK_OVERRIDE;
virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
bool dynamic) SK_OVERRIDE;
+ virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE;
virtual GrTexture* onCreatePlatformTexture(
const GrPlatformTextureDesc& desc) SK_OVERRIDE;
virtual GrRenderTarget* onCreatePlatformRenderTarget(
@@ -106,13 +107,14 @@
virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
uint32_t vertexCount,
uint32_t numVertices) SK_OVERRIDE;
+ virtual void onGpuStencilPath(const GrPath&, GrPathFill) SK_OVERRIDE;
virtual void enableScissoring(const GrIRect& rect) SK_OVERRIDE;
virtual void disableScissor() SK_OVERRIDE;
virtual void clearStencil() SK_OVERRIDE;
virtual void clearStencilClip(const GrIRect& rect,
bool insideClip) SK_OVERRIDE;
- virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE;
+ virtual bool flushGraphicsState(DrawType) SK_OVERRIDE;
virtual void setupGeometry(int* startVertex,
int* startIndex,
int vertexCount,
@@ -135,7 +137,7 @@
// The params should be the final coeffecients to apply
// (after any blending optimizations or dual source blending considerations
// have been accounted for).
- void flushBlend(GrPrimitiveType type,
+ void flushBlend(bool isLines,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff);
@@ -233,7 +235,7 @@
static void DeleteProgram(const GrGLInterface* gl,
CachedData* programData);
- void buildProgram(GrPrimitiveType typeBlend,
+ void buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
GrCustomStage** customStages);
@@ -261,7 +263,7 @@
// NULL means whole target. Can be an empty rect.
void flushRenderTarget(const GrIRect* bound);
void flushStencil();
- void flushAAState(GrPrimitiveType type);
+ void flushAAState(bool isLines);
bool configToGLFormats(GrPixelConfig config,
bool getSizedInternal,
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index a38ae2d..97f9b6d 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -370,7 +370,7 @@
}
}
-bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
+bool GrGpuGL::flushGraphicsState(DrawType type) {
const GrDrawState& drawState = this->getDrawState();
// GrGpu::setupClipAndFlushState should have already checked this
@@ -379,7 +379,7 @@
this->flushMiscFixedFunctionState();
this->flushStencil();
- this->flushAAState(type);
+ this->flushAAState(kDrawLines_DrawType == type);
GrBlendCoeff srcCoeff;
GrBlendCoeff dstCoeff;
@@ -389,7 +389,8 @@
}
GrCustomStage* customStages [GrDrawState::kNumStages];
- this->buildProgram(type, blendOpts, dstCoeff, customStages);
+ this->buildProgram(kDrawPoints_DrawType == type,
+ blendOpts, dstCoeff, customStages);
fProgramData = fProgramCache->getProgramData(fCurrentProgram,
customStages);
if (NULL == fProgramData) {
@@ -402,7 +403,7 @@
fHWProgramID = fProgramData->fProgramID;
}
fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
- this->flushBlend(type, srcCoeff, dstCoeff);
+ this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
GrColor color;
GrColor coverage;
@@ -635,7 +636,7 @@
}
-void GrGpuGL::buildProgram(GrPrimitiveType type,
+void GrGpuGL::buildProgram(bool isPoints,
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff,
GrCustomStage** customStages) {
@@ -658,7 +659,7 @@
// Must initialize all fields or cache will have false negatives!
desc.fVertexLayout = this->getVertexLayout();
- desc.fEmitsPointSize = kPoints_GrPrimitiveType == type;
+ desc.fEmitsPointSize = isPoints;
bool requiresAttributeColors =
!skipColor && SkToBool(desc.fVertexLayout & kColor_VertexLayoutBit);