aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/beziereffects.cpp17
-rw-r--r--gm/convexpolyeffect.cpp5
-rw-r--r--include/private/GrTypesPriv.h45
-rw-r--r--src/gpu/GrDefaultGeoProcFactory.cpp45
-rw-r--r--src/gpu/GrGeometryProcessor.h37
-rw-r--r--src/gpu/GrGpuCommandBuffer.cpp8
-rw-r--r--src/gpu/GrPathProcessor.h12
-rw-r--r--src/gpu/GrPrimitiveProcessor.cpp52
-rw-r--r--src/gpu/GrPrimitiveProcessor.h149
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor.h10
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp24
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp68
-rw-r--r--src/gpu/ccpr/GrCCPathProcessor.cpp36
-rw-r--r--src/gpu/ccpr/GrCCPathProcessor.h23
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp30
-rw-r--r--src/gpu/effects/GrBezierEffect.h44
-rw-r--r--src/gpu/effects/GrBitmapTextGeoProc.cpp23
-rw-r--r--src/gpu/effects/GrBitmapTextGeoProc.h16
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.cpp120
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.h52
-rw-r--r--src/gpu/effects/GrShadowGeoProc.cpp15
-rw-r--r--src/gpu/effects/GrShadowGeoProc.h17
-rw-r--r--src/gpu/gl/GrGLGpu.cpp40
-rw-r--r--src/gpu/gl/GrGLProgram.cpp6
-rw-r--r--src/gpu/gl/GrGLProgram.h27
-rw-r--r--src/gpu/gl/GrGLVaryingHandler.cpp3
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp38
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h7
-rw-r--r--src/gpu/glsl/GrGLSLVarying.cpp18
-rw-r--r--src/gpu/glsl/GrGLSLVarying.h2
-rw-r--r--src/gpu/ops/GrAAConvexPathRenderer.cpp42
-rw-r--r--src/gpu/ops/GrAAFillRectOp.cpp19
-rw-r--r--src/gpu/ops/GrAAHairLinePathRenderer.cpp15
-rw-r--r--src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp10
-rw-r--r--src/gpu/ops/GrAAStrokeRectOp.cpp8
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp4
-rw-r--r--src/gpu/ops/GrDashOp.cpp115
-rw-r--r--src/gpu/ops/GrDefaultPathRenderer.cpp2
-rw-r--r--src/gpu/ops/GrDrawAtlasOp.cpp6
-rw-r--r--src/gpu/ops/GrDrawVerticesOp.cpp6
-rw-r--r--src/gpu/ops/GrLatticeOp.cpp48
-rw-r--r--src/gpu/ops/GrNonAAFillRectOp.cpp23
-rw-r--r--src/gpu/ops/GrNonAAStrokeRectOp.cpp6
-rw-r--r--src/gpu/ops/GrOvalOpFactory.cpp236
-rw-r--r--src/gpu/ops/GrRegionOp.cpp13
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp7
-rw-r--r--src/gpu/ops/GrSmallPathRenderer.cpp17
-rw-r--r--src/gpu/ops/GrTessellatingPathRenderer.cpp18
-rw-r--r--src/gpu/ops/GrTextureOp.cpp112
-rw-r--r--src/gpu/vk/GrVkPipeline.cpp80
-rw-r--r--tests/GrMeshTest.cpp51
-rw-r--r--tests/GrPipelineDynamicStateTest.cpp22
-rw-r--r--tests/OnFlushCallbackTest.cpp9
-rw-r--r--tests/PrimitiveProcessorTest.cpp27
54 files changed, 1091 insertions, 794 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 1c26989df2..26da791746 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -93,14 +93,13 @@ private:
void onPrepareDraws(Target* target) override {
QuadHelper helper;
- size_t vertexStride = this->gp()->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint));
- SkPoint* pts = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
+ SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(SkPoint));
+ SkPoint* pts = reinterpret_cast<SkPoint*>(helper.init(target, sizeof(SkPoint), 1));
if (!pts) {
return;
}
SkRect rect = this->rect();
- SkPointPriv::SetRectTriStrip(pts, rect, vertexStride);
+ SkPointPriv::SetRectTriStrip(pts, rect, sizeof(SkPoint));
helper.recordDraw(target, this->gp(), this->makePipeline(target));
}
@@ -285,9 +284,8 @@ private:
void onPrepareDraws(Target* target) override {
QuadHelper helper;
- size_t vertexStride = this->gp()->getVertexStride();
- SkASSERT(vertexStride == sizeof(Vertex));
- Vertex* verts = reinterpret_cast<Vertex*>(helper.init(target, vertexStride, 1));
+ SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(Vertex));
+ Vertex* verts = reinterpret_cast<Vertex*>(helper.init(target, sizeof(Vertex), 1));
if (!verts) {
return;
}
@@ -507,9 +505,8 @@ private:
void onPrepareDraws(Target* target) override {
QuadHelper helper;
- size_t vertexStride = this->gp()->getVertexStride();
- SkASSERT(vertexStride == sizeof(Vertex));
- Vertex* verts = reinterpret_cast<Vertex*>(helper.init(target, vertexStride, 1));
+ SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(Vertex));
+ Vertex* verts = reinterpret_cast<Vertex*>(helper.init(target, sizeof(Vertex), 1));
if (!verts) {
return;
}
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 18c5ebdcdc..496b6b173f 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -83,10 +83,9 @@ private:
sk_sp<GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Make(
color, Coverage::kSolid_Type, LocalCoords::kUnused_Type, SkMatrix::I()));
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint));
+ SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint));
QuadHelper helper;
- SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
+ SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, sizeof(SkPoint), 1));
if (!verts) {
return;
}
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 5913a1e48c..e957f1f893 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -694,51 +694,6 @@ enum GrVertexAttribType {
static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
/**
- * Returns the size of the attrib type in bytes.
- */
-static inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
- switch (type) {
- case kFloat_GrVertexAttribType:
- return sizeof(float);
- case kFloat2_GrVertexAttribType:
- return 2 * sizeof(float);
- case kFloat3_GrVertexAttribType:
- return 3 * sizeof(float);
- case kFloat4_GrVertexAttribType:
- return 4 * sizeof(float);
- case kHalf_GrVertexAttribType:
- return sizeof(float);
- case kHalf2_GrVertexAttribType:
- return 2 * sizeof(float);
- case kHalf3_GrVertexAttribType:
- return 3 * sizeof(float);
- case kHalf4_GrVertexAttribType:
- return 4 * sizeof(float);
- case kInt2_GrVertexAttribType:
- return 2 * sizeof(int32_t);
- case kInt3_GrVertexAttribType:
- return 3 * sizeof(int32_t);
- case kInt4_GrVertexAttribType:
- return 4 * sizeof(int32_t);
- case kUByte_norm_GrVertexAttribType:
- return 1 * sizeof(char);
- case kUByte4_norm_GrVertexAttribType:
- return 4 * sizeof(char);
- case kShort2_GrVertexAttribType:
- return 2 * sizeof(int16_t);
- case kUShort2_GrVertexAttribType: // fall through
- case kUShort2_norm_GrVertexAttribType:
- return 2 * sizeof(uint16_t);
- case kInt_GrVertexAttribType:
- return sizeof(int32_t);
- case kUint_GrVertexAttribType:
- return sizeof(uint32_t);
- }
- SK_ABORT("Unexpected attribute type");
- return 0;
-}
-
-/**
* converts a GrVertexAttribType to a GrSLType
*/
static inline GrSLType GrVertexAttribTypeToSLType(GrVertexAttribType type) {
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index defb214eb0..e2bf87b277 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -45,17 +45,13 @@ public:
const char* name() const override { return "DefaultGeometryProcessor"; }
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inColor() const { return fInColor; }
- const Attribute* inLocalCoords() const { return fInLocalCoords; }
- const Attribute* inCoverage() const { return fInCoverage; }
GrColor color() const { return fColor; }
- bool hasVertexColor() const { return SkToBool(fInColor); }
+ bool hasVertexColor() const { return fInColor.isInitialized(); }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
bool localCoordsWillBeRead() const { return fLocalCoordsWillBeRead; }
uint8_t coverage() const { return fCoverage; }
- bool hasVertexCoverage() const { return SkToBool(fInCoverage); }
+ bool hasVertexCoverage() const { return fInCoverage.isInitialized(); }
class GLSLProcessor : public GrGLSLGeometryProcessor {
public:
@@ -78,7 +74,7 @@ public:
varyingHandler->addVarying("color", &varying);
// There are several optional steps to process the color. Start with the attribute:
- vertBuilder->codeAppendf("half4 color = %s;", gp.inColor()->name());
+ vertBuilder->codeAppendf("half4 color = %s;", gp.fInColor.name());
// For SkColor, do a red/blue swap, possible color space conversion, and premul
if (gp.fFlags & kColorAttributeIsSkColor_GPFlag) {
@@ -107,16 +103,16 @@ public:
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
- gp.inPosition()->name(),
+ gp.fInPosition.name(),
gp.viewMatrix(),
&fViewMatrixUniform);
- if (gp.inLocalCoords()) {
+ if (gp.fInLocalCoords.isInitialized()) {
// emit transforms with explicit local coords
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- gp.inLocalCoords()->asShaderVar(),
+ gp.fInLocalCoords.asShaderVar(),
gp.localMatrix(),
args.fFPCoordTransformHandler);
} else {
@@ -124,7 +120,7 @@ public:
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- gp.inPosition()->asShaderVar(),
+ gp.fInPosition.asShaderVar(),
gp.localMatrix(),
args.fFPCoordTransformHandler);
}
@@ -132,7 +128,7 @@ public:
// Setup coverage as pass through
if (gp.hasVertexCoverage()) {
fragBuilder->codeAppendf("half alpha = 1.0;");
- varyingHandler->addPassThroughAttribute(gp.inCoverage(), "alpha");
+ varyingHandler->addPassThroughAttribute(gp.fInCoverage, "alpha");
fragBuilder->codeAppendf("%s = half4(alpha);", args.fOutputCoverage);
} else if (gp.coverage() == 0xff) {
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
@@ -222,22 +218,31 @@ private:
, fFlags(gpTypeFlags)
, fLocalCoordsWillBeRead(localCoordsWillBeRead)
, fColorSpaceXform(std::move(colorSpaceXform)) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ int cnt = 1;
if (fFlags & kColorAttribute_GPFlag) {
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
+ fInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ ++cnt;
}
if (fFlags & kLocalCoordAttribute_GPFlag) {
- fInLocalCoords = &this->addVertexAttrib("inLocalCoord", kFloat2_GrVertexAttribType);
+ fInLocalCoords = {"inLocalCoord", kFloat2_GrVertexAttribType};
+ ++cnt;
}
if (fFlags & kCoverageAttribute_GPFlag) {
- fInCoverage = &this->addVertexAttrib("inCoverage", kHalf_GrVertexAttribType);
+ fInCoverage = {"inCoverage", kHalf_GrVertexAttribType};
+ ++cnt;
}
+ this->setVertexAttributeCnt(cnt);
}
- const Attribute* fInPosition = nullptr;
- const Attribute* fInColor = nullptr;
- const Attribute* fInLocalCoords = nullptr;
- const Attribute* fInCoverage = nullptr;
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthInitializedAttribute(i, fInPosition, fInColor, fInLocalCoords, fInCoverage);
+ }
+
+ Attribute fInPosition;
+ Attribute fInColor;
+ Attribute fInLocalCoords;
+ Attribute fInCoverage;
GrColor fColor;
SkMatrix fViewMatrix;
SkMatrix fLocalMatrix;
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index a12ab0058d..5035ad0f53 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -39,7 +39,44 @@ protected:
fSampleShading = sampleShading;
}
+ /**
+ * Recursive helpers for implementing onVertexAttribute or onInstanceAttribute.
+ */
+
+ template <typename... Args>
+ static const Attribute& IthAttribute(int i, const Attribute& attr0, const Args&... attrs) {
+ SkASSERT(attr0.isInitialized());
+ return (0 == i) ? attr0 : IthAttribute(i - 1, attrs...);
+ }
+
+ static const Attribute& IthAttribute(int i) {
+ SK_ABORT("Illegal attribute Index");
+ static constexpr Attribute kBogus;
+ return kBogus;
+ }
+
+ template <typename... Args>
+ static const Attribute& IthInitializedAttribute(int i, const Attribute& attr0,
+ const Args&... attrs) {
+ if (attr0.isInitialized()) {
+ if (0 == i) {
+ return attr0;
+ }
+ i -= 1;
+ }
+ return IthInitializedAttribute(i, attrs...);
+ }
+
+ static const Attribute& IthInitializedAttribute(int i) { return IthAttribute(i); }
+
private:
+ // Since most subclasses don't use instancing provide a default implementation for that case.
+ const Attribute& onInstanceAttribute(int i) const override {
+ SK_ABORT("No instanced attributes");
+ static constexpr Attribute kBogus;
+ return kBogus;
+ }
+
bool fWillUseGeoShader;
float fSampleShading;
diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp
index 13ae6c9844..fa2ce077b5 100644
--- a/src/gpu/GrGpuCommandBuffer.cpp
+++ b/src/gpu/GrGpuCommandBuffer.cpp
@@ -33,12 +33,12 @@ bool GrGpuRTCommandBuffer::draw(const GrPipeline& pipeline,
int meshCount,
const SkRect& bounds) {
#ifdef SK_DEBUG
- SkASSERT(!primProc.hasInstanceAttribs() || this->gpu()->caps()->instanceAttribSupport());
+ SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
for (int i = 0; i < meshCount; ++i) {
SkASSERT(!GrPrimTypeRequiresGeometryShaderSupport(meshes[i].primitiveType()) ||
this->gpu()->caps()->shaderCaps()->geometryShaderSupport());
- SkASSERT(primProc.hasVertexAttribs() == meshes[i].hasVertexData());
- SkASSERT(primProc.hasInstanceAttribs() == meshes[i].isInstanced());
+ SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
+ SkASSERT(primProc.hasInstanceAttributes() == meshes[i].isInstanced());
}
#endif
auto resourceProvider = this->gpu()->getContext()->contextPriv().resourceProvider();
@@ -47,7 +47,7 @@ bool GrGpuRTCommandBuffer::draw(const GrPipeline& pipeline,
return false;
}
- if (primProc.numAttribs() > this->gpu()->caps()->maxVertexAttributes()) {
+ if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
this->gpu()->stats()->incNumFailedDraws();
return false;
}
diff --git a/src/gpu/GrPathProcessor.h b/src/gpu/GrPathProcessor.h
index 72e5168a4f..6893e882dc 100644
--- a/src/gpu/GrPathProcessor.h
+++ b/src/gpu/GrPathProcessor.h
@@ -38,6 +38,18 @@ public:
virtual bool isPathRendering() const override { return true; }
private:
+ const Attribute& onVertexAttribute(int i) const final {
+ SK_ABORT("No vertex attributes");
+ static constexpr Attribute kBogus;
+ return kBogus;
+ }
+
+ const Attribute& onInstanceAttribute(int i) const final {
+ SK_ABORT("No instanced attributes");
+ static constexpr Attribute kBogus;
+ return kBogus;
+ }
+
GrPathProcessor(GrColor, const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
GrColor fColor;
diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp
index 7d1e1a644e..db79fb1052 100644
--- a/src/gpu/GrPrimitiveProcessor.cpp
+++ b/src/gpu/GrPrimitiveProcessor.cpp
@@ -17,6 +17,58 @@ enum MatrixType {
kGeneral_MatrixType = 1,
};
+GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrResourceIOProcessor(classID) {}
+
+const GrPrimitiveProcessor::Attribute& GrPrimitiveProcessor::vertexAttribute(int i) const {
+ SkASSERT(i >= 0 && i < this->numVertexAttributes());
+ const auto& result = this->onVertexAttribute(i);
+ SkASSERT(result.isInitialized());
+ return result;
+}
+
+const GrPrimitiveProcessor::Attribute& GrPrimitiveProcessor::instanceAttribute(int i) const {
+ SkASSERT(i >= 0 && i < this->numInstanceAttributes());
+ const auto& result = this->onInstanceAttribute(i);
+ SkASSERT(result.isInitialized());
+ return result;
+}
+
+#ifdef SK_DEBUG
+size_t GrPrimitiveProcessor::debugOnly_vertexStride() const {
+ size_t stride = 0;
+ for (int i = 0; i < fVertexAttributeCnt; ++i) {
+ stride += this->vertexAttribute(i).sizeAlign4();
+ }
+ return stride;
+}
+
+size_t GrPrimitiveProcessor::debugOnly_instanceStride() const {
+ size_t stride = 0;
+ for (int i = 0; i < fInstanceAttributeCnt; ++i) {
+ stride += this->instanceAttribute(i).sizeAlign4();
+ }
+ return stride;
+}
+
+size_t GrPrimitiveProcessor::debugOnly_vertexAttributeOffset(int i) const {
+ SkASSERT(i >= 0 && i < fVertexAttributeCnt);
+ size_t offset = 0;
+ for (int j = 0; j < i; ++j) {
+ offset += this->vertexAttribute(j).sizeAlign4();
+ }
+ return offset;
+}
+
+size_t GrPrimitiveProcessor::debugOnly_instanceAttributeOffset(int i) const {
+ SkASSERT(i >= 0 && i < fInstanceAttributeCnt);
+ size_t offset = 0;
+ for (int j = 0; j < i; ++j) {
+ offset += this->instanceAttribute(j).sizeAlign4();
+ }
+ return offset;
+}
+#endif
+
uint32_t
GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
int numCoords) const {
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index c75f13c496..6563ad9a7d 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -40,23 +40,22 @@ class GrGLSLPrimitiveProcessor;
*/
class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
public:
+ /** Describes a vertex or instance attribute. */
class Attribute {
public:
- enum class InputRate : bool {
- kPerVertex,
- kPerInstance
- };
-
constexpr Attribute() = default;
- constexpr Attribute(const char* name, GrVertexAttribType type, int offset, InputRate rate)
- : fName(name), fType(type), fOffsetInRecord(offset), fInputRate(rate) {}
+ constexpr Attribute(const char* name, GrVertexAttribType type) : fName(name), fType(type) {}
+ constexpr Attribute(const Attribute&) = default;
+
+ Attribute& operator=(const Attribute&) = default;
+
+ constexpr bool isInitialized() const { return SkToBool(fName); }
- bool isInitialized() const { return SkToBool(fName); }
+ constexpr const char* name() const { return fName; }
+ constexpr GrVertexAttribType type() const { return fType; }
- const char* name() const { return fName; }
- GrVertexAttribType type() const { return fType; }
- int offsetInRecord() const { return fOffsetInRecord; }
- InputRate inputRate() const { return fInputRate; }
+ inline constexpr size_t size() const;
+ constexpr size_t sizeAlign4() const { return SkAlign4(this->size()); }
GrShaderVar asShaderVar() const {
return {fName, GrVertexAttribTypeToSLType(fType), GrShaderVar::kIn_TypeModifier};
@@ -65,35 +64,34 @@ public:
private:
const char* fName = nullptr;
GrVertexAttribType fType = kFloat_GrVertexAttribType;
- int fOffsetInRecord = 0;
- InputRate fInputRate = InputRate::kPerVertex;
};
- GrPrimitiveProcessor(ClassID classID)
- : GrResourceIOProcessor(classID) {}
+ GrPrimitiveProcessor(ClassID);
- int numAttribs() const { return fAttribs.count(); }
- const Attribute& getAttrib(int index) const { return fAttribs[index]; }
+ int numVertexAttributes() const { return fVertexAttributeCnt; }
+ const Attribute& vertexAttribute(int i) const;
+ int numInstanceAttributes() const { return fInstanceAttributeCnt; }
+ const Attribute& instanceAttribute(int i) const;
- bool hasVertexAttribs() const { return SkToBool(fVertexStride); }
- bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); }
+ bool hasVertexAttributes() const { return SkToBool(fVertexAttributeCnt); }
+ bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributeCnt); }
+#ifdef SK_DEBUG
/**
- * These return the strides of the vertex and instance buffers. Attributes are expected to be
- * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord
- * indicates an attribute's location in bytes relative to the first attribute. (These are padded
- * to the nearest 4 bytes for performance reasons.)
- *
- * A common practice is to populate the buffer's memory using an implicit array of structs. In
- * this case, it is best to assert:
- *
- * stride == sizeof(struct) and
- * offsetof(struct, field[i]) == attrib[i].fOffsetInRecord
- *
- * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses.
+ * A common practice is to populate the the vertex/instance's memory using an implicit array of
+ * structs. In this case, it is best to assert that:
+ * debugOnly_stride == sizeof(struct) and
+ * offsetof(struct, field[i]) == debugOnly_AttributeOffset(i)
+ * In general having Op subclasses assert that attribute offsets and strides agree with their
+ * tessellation code's expectations is good practice.
+ * However, these functions walk the attributes to compute offsets and call virtual functions
+ * to access the attributes. Thus, they are only available in debug builds.
*/
- int getVertexStride() const { return fVertexStride; }
- int getInstanceStride() const { return fInstanceStride; }
+ size_t debugOnly_vertexStride() const;
+ size_t debugOnly_instanceStride() const;
+ size_t debugOnly_vertexAttributeOffset(int) const;
+ size_t debugOnly_instanceAttributeOffset(int) const;
+#endif
// Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
// we put these calls on the base class to prevent having to cast
@@ -129,24 +127,11 @@ public:
*/
virtual const char* getDestColorOverride() const { return nullptr; }
- virtual float getSampleShading() const {
- return 0.0;
- }
+ virtual float getSampleShading() const { return 0.0; }
protected:
- /**
- * Subclasses call these from their constructor to register vertex and instance attributes.
- */
- const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type) {
- fAttribs.push_back() = {name, type, fVertexStride, Attribute::InputRate::kPerVertex};
- fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
- return fAttribs.back();
- }
- const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type) {
- fAttribs.push_back() = {name, type, fInstanceStride, Attribute::InputRate::kPerInstance};
- fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
- return fAttribs.back();
- }
+ void setVertexAttributeCnt(int cnt) { fVertexAttributeCnt = cnt; }
+ void setInstanceAttributeCnt(int cnt) { fInstanceAttributeCnt = cnt; }
private:
void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
@@ -154,11 +139,69 @@ private:
void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
void notifyRefCntIsZero() const final {}
- SkSTArray<8, Attribute> fAttribs;
- int fVertexStride = 0;
- int fInstanceStride = 0;
+ virtual const Attribute& onVertexAttribute(int) const = 0;
+ virtual const Attribute& onInstanceAttribute(int) const = 0;
+ int fVertexAttributeCnt = 0;
+ int fInstanceAttributeCnt = 0;
typedef GrProcessor INHERITED;
};
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns the size of the attrib type in bytes.
+ * This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
+ * with C++11.
+ */
+static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
+ switch (type) {
+ case kFloat_GrVertexAttribType:
+ return sizeof(float);
+ case kFloat2_GrVertexAttribType:
+ return 2 * sizeof(float);
+ case kFloat3_GrVertexAttribType:
+ return 3 * sizeof(float);
+ case kFloat4_GrVertexAttribType:
+ return 4 * sizeof(float);
+ case kHalf_GrVertexAttribType:
+ return sizeof(float);
+ case kHalf2_GrVertexAttribType:
+ return 2 * sizeof(float);
+ case kHalf3_GrVertexAttribType:
+ return 3 * sizeof(float);
+ case kHalf4_GrVertexAttribType:
+ return 4 * sizeof(float);
+ case kInt2_GrVertexAttribType:
+ return 2 * sizeof(int32_t);
+ case kInt3_GrVertexAttribType:
+ return 3 * sizeof(int32_t);
+ case kInt4_GrVertexAttribType:
+ return 4 * sizeof(int32_t);
+ case kUByte_norm_GrVertexAttribType:
+ return 1 * sizeof(char);
+ case kUByte4_norm_GrVertexAttribType:
+ return 4 * sizeof(char);
+ case kShort2_GrVertexAttribType:
+ return 2 * sizeof(int16_t);
+ case kUShort2_GrVertexAttribType: // fall through
+ case kUShort2_norm_GrVertexAttribType:
+ return 2 * sizeof(uint16_t);
+ case kInt_GrVertexAttribType:
+ return sizeof(int32_t);
+ case kUint_GrVertexAttribType:
+ return sizeof(uint32_t);
+ }
+ // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
+ // unreachable and don't complain.
+#if defined(__clang__) || !defined(__GNUC__)
+ SK_ABORT("Unsupported type conversion");
+#endif
+ return 0;
+}
+
+constexpr size_t GrPrimitiveProcessor::Attribute::size() const {
+ return GrVertexAttribTypeSize(fType);
+}
+
#endif
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index e3ea34f8dd..89890486d3 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -246,6 +246,13 @@ private:
void initGS();
void initVS(GrResourceProvider*);
+ const Attribute& onVertexAttribute(int i) const override { return fVertexAttribute; }
+
+ const Attribute& onInstanceAttribute(int i) const override {
+ SkASSERT(fImpl == Impl::kVertexShader);
+ return fInstanceAttributes[i];
+ }
+
void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
SkTArray<GrMesh>* out) const;
void appendVSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
@@ -253,6 +260,8 @@ private:
GrGLSLPrimitiveProcessor* createGSImpl(std::unique_ptr<Shader>) const;
GrGLSLPrimitiveProcessor* createVSImpl(std::unique_ptr<Shader>) const;
+ // The type and meaning of this attribute depends on whether we're using VSImpl or GSImpl.
+ Attribute fVertexAttribute;
const PrimitiveType fPrimitiveType;
const Impl fImpl;
@@ -262,6 +271,7 @@ private:
const GSSubpass fGSSubpass = GSSubpass::kHulls;
// Used by VSImpl.
+ Attribute fInstanceAttributes[2];
sk_sp<const GrBuffer> fVSVertexBuffer;
sk_sp<const GrBuffer> fVSIndexBuffer;
int fVSNumIndicesPerInstance;
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
index aa7a8db8a5..8134fbe89b 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
@@ -31,9 +31,8 @@ protected:
const GrCCCoverageProcessor& proc = args.fGP.cast<GrCCCoverageProcessor>();
// The vertex shader simply forwards transposed x or y values to the geometry shader.
- SkASSERT(1 == proc.numAttribs());
- gpArgs->fPositionVar.set(GrVertexAttribTypeToSLType(proc.getAttrib(0).type()),
- proc.getAttrib(0).name());
+ SkASSERT(1 == proc.numVertexAttributes());
+ gpArgs->fPositionVar = proc.fVertexAttribute.asShaderVar();
// Geometry shader.
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
@@ -62,7 +61,7 @@ protected:
Shader::CalcWind(proc, g, "pts", wind.c_str());
if (PrimitiveType::kWeightedTriangles == proc.fPrimitiveType) {
SkASSERT(3 == numInputPoints);
- SkASSERT(kFloat4_GrVertexAttribType == proc.getAttrib(0).type());
+ SkASSERT(kFloat4_GrVertexAttribType == proc.fVertexAttribute.type());
g->codeAppendf("%s *= sk_in[0].sk_Position.w;", wind.c_str());
}
@@ -382,14 +381,19 @@ public:
void GrCCCoverageProcessor::initGS() {
SkASSERT(Impl::kGeometryShader == fImpl);
if (4 == this->numInputPoints() || this->hasInputWeight()) {
- this->addVertexAttrib("x_or_y_values", kFloat4_GrVertexAttribType);
- SkASSERT(sizeof(QuadPointInstance) == this->getVertexStride() * 2);
- SkASSERT(offsetof(QuadPointInstance, fY) == this->getVertexStride());
+ fVertexAttribute = {"x_or_y_values", kFloat4_GrVertexAttribType};
+ GR_STATIC_ASSERT(sizeof(QuadPointInstance) ==
+ 2 * GrVertexAttribTypeSize(kFloat4_GrVertexAttribType));
+ GR_STATIC_ASSERT(offsetof(QuadPointInstance, fY) ==
+ GrVertexAttribTypeSize(kFloat4_GrVertexAttribType));
} else {
- this->addVertexAttrib("x_or_y_values", kFloat3_GrVertexAttribType);
- SkASSERT(sizeof(TriPointInstance) == this->getVertexStride() * 2);
- SkASSERT(offsetof(TriPointInstance, fY) == this->getVertexStride());
+ fVertexAttribute = {"x_or_y_values", kFloat3_GrVertexAttribType};
+ GR_STATIC_ASSERT(sizeof(TriPointInstance) ==
+ 2 * GrVertexAttribTypeSize(kFloat3_GrVertexAttribType));
+ GR_STATIC_ASSERT(offsetof(TriPointInstance, fY) ==
+ GrVertexAttribTypeSize(kFloat3_GrVertexAttribType));
}
+ this->setVertexAttributeCnt(1);
this->setWillUseGeoShader();
}
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
index 3c9fe89fbc..5c5120cf45 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
@@ -28,9 +28,8 @@ private:
const int fNumSides;
};
-static constexpr int kAttribIdx_X = 0; // Transposed X values of all input points.
-static constexpr int kAttribIdx_Y = 1; // Transposed Y values of all input points.
-static constexpr int kAttribIdx_VertexData = 2;
+static constexpr int kInstanceAttribIdx_X = 0; // Transposed X values of all input points.
+static constexpr int kInstanceAttribIdx_Y = 1; // Transposed Y values of all input points.
// Vertex data tells the shader how to offset vertices for conservative raster, as well as how to
// calculate coverage values for corners and edges.
@@ -260,15 +259,16 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
int inputWidth = (4 == numInputPoints || proc.hasInputWeight()) ? 4 : 3;
const char* swizzle = (4 == inputWidth) ? "xyzw" : "xyz";
v->codeAppendf("float%ix2 pts = transpose(float2x%i(%s.%s, %s.%s));", inputWidth, inputWidth,
- proc.getAttrib(kAttribIdx_X).name(), swizzle,
- proc.getAttrib(kAttribIdx_Y).name(), swizzle);
+ proc.fInstanceAttributes[kInstanceAttribIdx_X].name(), swizzle,
+ proc.fInstanceAttributes[kInstanceAttribIdx_Y].name(), swizzle);
v->codeAppend ("half wind;");
Shader::CalcWind(proc, v, "pts", "wind");
if (PrimitiveType::kWeightedTriangles == proc.fPrimitiveType) {
SkASSERT(3 == numInputPoints);
- SkASSERT(kFloat4_GrVertexAttribType == proc.getAttrib(kAttribIdx_X).type());
- v->codeAppendf("wind *= %s.w;", proc.getAttrib(kAttribIdx_X).name());
+ SkASSERT(kFloat4_GrVertexAttribType ==
+ proc.fInstanceAttributes[kInstanceAttribIdx_X].type());
+ v->codeAppendf("wind *= %s.w;", proc.fInstanceAttributes[kInstanceAttribIdx_X].name());
}
float bloat = kAABloatRadius;
@@ -284,12 +284,12 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
// Reverse all indices if the wind is counter-clockwise: [0, 1, 2] -> [2, 1, 0].
v->codeAppendf("int clockwise_indices = wind > 0 ? %s : 0x%x - %s;",
- proc.getAttrib(kAttribIdx_VertexData).name(),
+ proc.fVertexAttribute.name(),
((fNumSides - 1) << kVertexData_LeftNeighborIdShift) |
((fNumSides - 1) << kVertexData_RightNeighborIdShift) |
(((1 << kVertexData_RightNeighborIdShift) - 1) ^ 3) |
(fNumSides - 1),
- proc.getAttrib(kAttribIdx_VertexData).name());
+ proc.fVertexAttribute.name());
// Here we generate conservative raster geometry for the input polygon. It is the convex
// hull of N pixel-size boxes, one centered on each the input points. Each corner has three
@@ -322,7 +322,7 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
v->codeAppend ("rightdir = (float2(0) != rightdir) ? normalize(rightdir) : float2(1, 0);");
v->codeAppendf("if (0 != (%s & %i)) {", // Are we a corner?
- proc.getAttrib(kAttribIdx_VertexData).name(), kVertexData_IsCornerBit);
+ proc.fVertexAttribute.name(), kVertexData_IsCornerBit);
// In corner boxes, all 4 coverage values will not map linearly.
// Therefore it is important to align the box so its diagonal shared
@@ -341,7 +341,7 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
// continue rotating 90 degrees clockwise until we reach the desired raster vertex for this
// invocation. Corners with less than 3 corresponding raster vertices will result in
// redundant vertices and degenerate triangles.
- v->codeAppendf("int bloatidx = (%s >> %i) & 3;", proc.getAttrib(kAttribIdx_VertexData).name(),
+ v->codeAppendf("int bloatidx = (%s >> %i) & 3;", proc.fVertexAttribute.name(),
kVertexData_BloatIdxShift);
v->codeAppend ("switch (bloatidx) {");
v->codeAppend ( "case 3:");
@@ -376,12 +376,12 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
v->codeAppend ("}");
v->codeAppendf("if (0 != (%s & %i)) {", // Are we an edge?
- proc.getAttrib(kAttribIdx_VertexData).name(), kVertexData_IsEdgeBit);
+ proc.fVertexAttribute.name(), kVertexData_IsEdgeBit);
v->codeAppend ( "coverage = left_coverage;");
v->codeAppend ("}");
v->codeAppendf("if (0 != (%s & %i)) {", // Invert coverage?
- proc.getAttrib(kAttribIdx_VertexData).name(),
+ proc.fVertexAttribute.name(),
kVertexData_InvertNegativeCoverageBit);
v->codeAppend ( "coverage = -1 - coverage;");
v->codeAppend ("}");
@@ -391,7 +391,7 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
v->codeAppend ("half2 corner_coverage = half2(0);");
v->codeAppendf("if (0 != (%s & %i)) {", // Are we a corner?
- proc.getAttrib(kAttribIdx_VertexData).name(), kVertexData_IsCornerBit);
+ proc.fVertexAttribute.name(), kVertexData_IsCornerBit);
// We use coverage=-1 to erase what the hull geometry wrote.
//
// In the context of curves, this effectively means "wind = -wind" and
@@ -495,31 +495,27 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) {
}
}
+ GrVertexAttribType xyAttribType;
if (4 == this->numInputPoints() || this->hasInputWeight()) {
- SkASSERT(kAttribIdx_X == this->numAttribs());
- this->addInstanceAttrib("X", kFloat4_GrVertexAttribType);
-
- SkASSERT(kAttribIdx_Y == this->numAttribs());
- this->addInstanceAttrib("Y", kFloat4_GrVertexAttribType);
-
- SkASSERT(offsetof(QuadPointInstance, fX) == this->getAttrib(kAttribIdx_X).offsetInRecord());
- SkASSERT(offsetof(QuadPointInstance, fY) == this->getAttrib(kAttribIdx_Y).offsetInRecord());
- SkASSERT(sizeof(QuadPointInstance) == this->getInstanceStride());
+ GR_STATIC_ASSERT(offsetof(QuadPointInstance, fX) == 0);
+ GR_STATIC_ASSERT(sizeof(QuadPointInstance::fX) ==
+ GrVertexAttribTypeSize(kFloat4_GrVertexAttribType));
+ GR_STATIC_ASSERT(sizeof(QuadPointInstance::fY) ==
+ GrVertexAttribTypeSize(kFloat4_GrVertexAttribType));
+ xyAttribType = kFloat4_GrVertexAttribType;
} else {
- SkASSERT(kAttribIdx_X == this->numAttribs());
- this->addInstanceAttrib("X", kFloat3_GrVertexAttribType);
-
- SkASSERT(kAttribIdx_Y == this->numAttribs());
- this->addInstanceAttrib("Y", kFloat3_GrVertexAttribType);
-
- SkASSERT(offsetof(TriPointInstance, fX) == this->getAttrib(kAttribIdx_X).offsetInRecord());
- SkASSERT(offsetof(TriPointInstance, fY) == this->getAttrib(kAttribIdx_Y).offsetInRecord());
- SkASSERT(sizeof(TriPointInstance) == this->getInstanceStride());
+ GR_STATIC_ASSERT(offsetof(TriPointInstance, fX) == 0);
+ GR_STATIC_ASSERT(sizeof(TriPointInstance::fX) ==
+ GrVertexAttribTypeSize(kFloat3_GrVertexAttribType));
+ GR_STATIC_ASSERT(sizeof(TriPointInstance::fY) ==
+ GrVertexAttribTypeSize(kFloat3_GrVertexAttribType));
+ xyAttribType = kFloat3_GrVertexAttribType;
}
-
- SkASSERT(kAttribIdx_VertexData == this->numAttribs());
- this->addVertexAttrib("vertexdata", kInt_GrVertexAttribType);
- SkASSERT(sizeof(int32_t) == this->getVertexStride());
+ fInstanceAttributes[kInstanceAttribIdx_X] = {"X", xyAttribType};
+ fInstanceAttributes[kInstanceAttribIdx_Y] = {"Y", xyAttribType};
+ this->setInstanceAttributeCnt(2);
+ fVertexAttribute = {"vertexdata", kInt_GrVertexAttribType};
+ this->setVertexAttributeCnt(1);
if (caps.usePrimitiveRestart()) {
fVSTriangleType = GrPrimitiveType::kTriangleStrip;
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index b8ebb44059..e180724f8a 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -65,6 +65,9 @@ static constexpr uint16_t kOctoIndicesAsTris[] = {
GR_DECLARE_STATIC_UNIQUE_KEY(gIndexBufferKey);
+constexpr GrPrimitiveProcessor::Attribute GrCCPathProcessor::kInstanceAttribs[];
+constexpr GrPrimitiveProcessor::Attribute GrCCPathProcessor::kEdgeNormsAttrib;
+
sk_sp<const GrBuffer> GrCCPathProcessor::FindIndexBuffer(GrOnFlushResourceProvider* onFlushRP) {
GR_DEFINE_STATIC_UNIQUE_KEY(gIndexBufferKey);
if (onFlushRP->caps()->usePrimitiveRestart()) {
@@ -82,24 +85,19 @@ GrCCPathProcessor::GrCCPathProcessor(GrResourceProvider* resourceProvider,
: INHERITED(kGrCCPathProcessor_ClassID)
, fAtlasAccess(std::move(atlas), GrSamplerState::Filter::kNearest,
GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag) {
- this->addInstanceAttrib("devbounds", kFloat4_GrVertexAttribType);
- this->addInstanceAttrib("devbounds45", kFloat4_GrVertexAttribType);
- this->addInstanceAttrib("dev_to_atlas_offset", kInt2_GrVertexAttribType);
- this->addInstanceAttrib("color", kUByte4_norm_GrVertexAttribType);
-
- SkASSERT(offsetof(Instance, fDevBounds) ==
- this->getInstanceAttrib(InstanceAttribs::kDevBounds).offsetInRecord());
- SkASSERT(offsetof(Instance, fDevBounds45) ==
- this->getInstanceAttrib(InstanceAttribs::kDevBounds45).offsetInRecord());
- SkASSERT(offsetof(Instance, fDevToAtlasOffset) ==
- this->getInstanceAttrib(InstanceAttribs::kDevToAtlasOffset).offsetInRecord());
- SkASSERT(offsetof(Instance, fColor) ==
- this->getInstanceAttrib(InstanceAttribs::kColor).offsetInRecord());
- SkASSERT(sizeof(Instance) == this->getInstanceStride());
-
- GR_STATIC_ASSERT(4 == kNumInstanceAttribs);
-
- this->addVertexAttrib("edge_norms", kFloat4_GrVertexAttribType);
+ this->setInstanceAttributeCnt(kNumInstanceAttribs);
+ // Check that instance attributes exactly match Instance struct layout.
+ SkASSERT(!strcmp(this->instanceAttribute(0).name(), "devbounds"));
+ SkASSERT(!strcmp(this->instanceAttribute(1).name(), "devbounds45"));
+ SkASSERT(!strcmp(this->instanceAttribute(2).name(), "dev_to_atlas_offset"));
+ SkASSERT(!strcmp(this->instanceAttribute(3).name(), "color"));
+ SkASSERT(this->debugOnly_instanceAttributeOffset(0) == offsetof(Instance, fDevBounds));
+ SkASSERT(this->debugOnly_instanceAttributeOffset(1) == offsetof(Instance, fDevBounds45));
+ SkASSERT(this->debugOnly_instanceAttributeOffset(2) == offsetof(Instance, fDevToAtlasOffset));
+ SkASSERT(this->debugOnly_instanceAttributeOffset(3) == offsetof(Instance, fColor));
+ SkASSERT(this->debugOnly_instanceStride() == sizeof(Instance));
+
+ this->setVertexAttributeCnt(1);
fAtlasAccess.instantiate(resourceProvider);
this->addTextureSampler(&fAtlasAccess);
@@ -170,7 +168,7 @@ void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVarying texcoord(kFloat3_GrSLType);
GrGLSLVarying color(kHalf4_GrSLType);
varyingHandler->addVarying("texcoord", &texcoord);
- varyingHandler->addPassThroughAttribute(&proc.getInstanceAttrib(InstanceAttribs::kColor),
+ varyingHandler->addPassThroughAttribute(proc.getInstanceAttrib(InstanceAttribs::kColor),
args.fOutputColor, Interpolation::kCanBeFlat);
// The vertex shader bloats and intersects the devBounds and devBounds45 rectangles, in order to
diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h
index 785dd2c919..54c1b7e2ed 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.h
+++ b/src/gpu/ccpr/GrCCPathProcessor.h
@@ -77,16 +77,11 @@ public:
const GrTexture* atlas() const { return fAtlasAccess.peekTexture(); }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
const Attribute& getInstanceAttrib(InstanceAttribs attribID) const {
- const Attribute& attrib = this->getAttrib((int)attribID);
- SkASSERT(Attribute::InputRate::kPerInstance == attrib.inputRate());
- return attrib;
- }
- const Attribute& getEdgeNormsAttrib() const {
- SkASSERT(1 + kNumInstanceAttribs == this->numAttribs());
- const Attribute& attrib = this->getAttrib(kNumInstanceAttribs);
- SkASSERT(Attribute::InputRate::kPerVertex == attrib.inputRate());
- return attrib;
+ int idx = static_cast<int>(attribID);
+ SkASSERT(idx >= 0 && idx < static_cast<int>(SK_ARRAY_COUNT(kInstanceAttribs)));
+ return kInstanceAttribs[idx];
}
+ const Attribute& getEdgeNormsAttrib() const { return kEdgeNormsAttrib; }
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
@@ -95,8 +90,18 @@ public:
int baseInstance, int endInstance, const SkRect& bounds) const;
private:
+ const Attribute& onVertexAttribute(int i) const override { return kEdgeNormsAttrib; }
+ const Attribute& onInstanceAttribute(int i) const override { return kInstanceAttribs[i]; }
+
const TextureSampler fAtlasAccess;
SkMatrix fLocalMatrix;
+ static constexpr Attribute kInstanceAttribs[kNumInstanceAttribs] = {
+ {"devbounds", kFloat4_GrVertexAttribType},
+ {"devbounds45", kFloat4_GrVertexAttribType},
+ {"dev_to_atlas_offset", kInt2_GrVertexAttribType},
+ {"color", kUByte4_norm_GrVertexAttribType}
+ };
+ static constexpr Attribute kEdgeNormsAttrib = {"edge_norms", kFloat4_GrVertexAttribType};
typedef GrGeometryProcessor INHERITED;
};
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 3dee2f4dab..d68b1bfed6 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -79,7 +79,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVarying v(kFloat4_GrSLType);
varyingHandler->addVarying("ConicCoeffs", &v);
- vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->name());
+ vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs().name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
@@ -89,7 +89,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
- gp.inPosition()->name(),
+ gp.inPosition().name(),
gp.viewMatrix(),
&fViewMatrixUniform);
@@ -97,7 +97,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- gp.inPosition()->asShaderVar(),
+ gp.inPosition().asShaderVar(),
gp.localMatrix(),
args.fFPCoordTransformHandler);
@@ -219,6 +219,8 @@ void GrGLConicEffect::GenKey(const GrGeometryProcessor& gp,
//////////////////////////////////////////////////////////////////////////////
+constexpr GrPrimitiveProcessor::Attribute GrConicEffect::kAttributes[];
+
GrConicEffect::~GrConicEffect() {}
void GrConicEffect::getGLSLProcessorKey(const GrShaderCaps& caps,
@@ -240,8 +242,7 @@ GrConicEffect::GrConicEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t
, fUsesLocalCoords(usesLocalCoords)
, fCoverageScale(coverage)
, fEdgeType(edgeType) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInConicCoeffs = &this->addVertexAttrib("inConicCoeffs", kHalf4_GrVertexAttribType);
+ this->setVertexAttributeCnt(2);
}
//////////////////////////////////////////////////////////////////////////////
@@ -331,7 +332,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVarying v(kHalf4_GrSLType);
varyingHandler->addVarying("HairQuadEdge", &v);
- vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->name());
+ vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge().name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
@@ -341,7 +342,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
- gp.inPosition()->name(),
+ gp.inPosition().name(),
gp.viewMatrix(),
&fViewMatrixUniform);
@@ -349,7 +350,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- gp.inPosition()->asShaderVar(),
+ gp.inPosition().asShaderVar(),
gp.localMatrix(),
args.fFPCoordTransformHandler);
@@ -420,6 +421,8 @@ void GrGLQuadEffect::GenKey(const GrGeometryProcessor& gp,
//////////////////////////////////////////////////////////////////////////////
+constexpr GrPrimitiveProcessor::Attribute GrQuadEffect::kAttributes[];
+
GrQuadEffect::~GrQuadEffect() {}
void GrQuadEffect::getGLSLProcessorKey(const GrShaderCaps& caps,
@@ -441,8 +444,7 @@ GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t co
, fUsesLocalCoords(usesLocalCoords)
, fCoverageScale(coverage)
, fEdgeType(edgeType) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInHairQuadEdge = &this->addVertexAttrib("inHairQuadEdge", kHalf4_GrVertexAttribType);
+ this->setVertexAttributeCnt(2);
}
//////////////////////////////////////////////////////////////////////////////
@@ -544,7 +546,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
- gp.inPosition()->name(),
+ gp.inPosition().name(),
gp.viewMatrix(),
&fViewMatrixUniform);
@@ -576,7 +578,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- gp.inPosition()->asShaderVar(),
+ gp.inPosition().asShaderVar(),
args.fFPCoordTransformHandler);
GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0);
@@ -647,6 +649,8 @@ void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp,
//////////////////////////////////////////////////////////////////////////////
+constexpr GrPrimitiveProcessor::Attribute GrCubicEffect::kInPosition;
+
GrCubicEffect::~GrCubicEffect() {}
void GrCubicEffect::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
@@ -664,7 +668,7 @@ GrCubicEffect::GrCubicEffect(GrColor color, const SkMatrix& viewMatrix, const Sk
, fViewMatrix(viewMatrix)
, fDevKLMMatrix(devKLMMatrix)
, fEdgeType(edgeType) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
+ this->setVertexAttributeCnt(1);
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h
index 174470410c..eebe42a5cd 100644
--- a/src/gpu/effects/GrBezierEffect.h
+++ b/src/gpu/effects/GrBezierEffect.h
@@ -93,8 +93,8 @@ public:
const char* name() const override { return "Conic"; }
- inline const Attribute* inPosition() const { return fInPosition; }
- inline const Attribute* inConicCoeffs() const { return fInConicCoeffs; }
+ inline const Attribute& inPosition() const { return kAttributes[0]; }
+ inline const Attribute& inConicCoeffs() const { return kAttributes[1]; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
@@ -112,14 +112,16 @@ private:
GrConicEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrClipEdgeType,
const SkMatrix& localMatrix, bool usesLocalCoords);
+ const Attribute& onVertexAttribute(int i) const override { return kAttributes[i]; }
+
GrColor fColor;
SkMatrix fViewMatrix;
SkMatrix fLocalMatrix;
bool fUsesLocalCoords;
uint8_t fCoverageScale;
GrClipEdgeType fEdgeType;
- const Attribute* fInPosition;
- const Attribute* fInConicCoeffs;
+ static constexpr Attribute kAttributes[] = {{"inPosition", kFloat2_GrVertexAttribType},
+ {"inConicCoeffs", kHalf4_GrVertexAttribType}};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@@ -175,8 +177,8 @@ public:
const char* name() const override { return "Quad"; }
- inline const Attribute* inPosition() const { return fInPosition; }
- inline const Attribute* inHairQuadEdge() const { return fInHairQuadEdge; }
+ inline const Attribute& inPosition() const { return kAttributes[0]; }
+ inline const Attribute& inHairQuadEdge() const { return kAttributes[1]; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
@@ -194,14 +196,17 @@ private:
GrQuadEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrClipEdgeType,
const SkMatrix& localMatrix, bool usesLocalCoords);
- GrColor fColor;
- SkMatrix fViewMatrix;
- SkMatrix fLocalMatrix;
- bool fUsesLocalCoords;
- uint8_t fCoverageScale;
+ const Attribute& onVertexAttribute(int i) const override { return kAttributes[i]; }
+
+ GrColor fColor;
+ SkMatrix fViewMatrix;
+ SkMatrix fLocalMatrix;
+ bool fUsesLocalCoords;
+ uint8_t fCoverageScale;
GrClipEdgeType fEdgeType;
- const Attribute* fInPosition;
- const Attribute* fInHairQuadEdge;
+
+ static constexpr Attribute kAttributes[] = {{"inPosition", kFloat2_GrVertexAttribType},
+ {"inHairQuadEdge", kHalf4_GrVertexAttribType}};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@@ -263,7 +268,7 @@ public:
const char* name() const override { return "Cubic"; }
- inline const Attribute* inPosition() const { return fInPosition; }
+ inline const Attribute& inPosition() const { return kInPosition; }
inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
@@ -280,11 +285,14 @@ private:
GrCubicEffect(GrColor, const SkMatrix& viewMatrix, const SkMatrix& devKLMMatrix,
GrClipEdgeType);
- GrColor fColor;
- SkMatrix fViewMatrix;
- SkMatrix fDevKLMMatrix;
+ const Attribute& onVertexAttribute(int) const override { return kInPosition; }
+
+ GrColor fColor;
+ SkMatrix fViewMatrix;
+ SkMatrix fDevKLMMatrix;
GrClipEdgeType fEdgeType;
- const Attribute* fInPosition;
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 4089555362..2594f40ee5 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -40,7 +40,7 @@ public:
GrGLSLVarying uv(kFloat2_GrSLType);
GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
GrGLSLVarying texIdx(texIdxType);
- append_index_uv_varyings(args, btgp.inTextureCoords()->name(), atlasSizeInvName, &uv,
+ append_index_uv_varyings(args, btgp.inTextureCoords().name(), atlasSizeInvName, &uv,
&texIdx, nullptr);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
@@ -53,13 +53,13 @@ public:
}
// Setup position
- gpArgs->fPositionVar = btgp.inPosition()->asShaderVar();
+ gpArgs->fPositionVar = btgp.inPosition().asShaderVar();
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- btgp.inPosition()->asShaderVar(),
+ btgp.inPosition().asShaderVar(),
btgp.localMatrix(),
args.fFPCoordTransformHandler);
@@ -129,23 +129,26 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color,
, fColor(color)
, fLocalMatrix(localMatrix)
, fUsesW(usesW)
- , fInColor(nullptr)
, fMaskFormat(format) {
SkASSERT(numActiveProxies <= kMaxTextures);
if (usesW) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat3_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat3_GrVertexAttribType};
} else {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat2_GrVertexAttribType};
}
+ fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType};
+ int cnt = 2;
bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
kA565_GrMaskFormat == fMaskFormat;
if (hasVertexColor) {
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
+ fInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ ++cnt;
}
- fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kUShort2_GrVertexAttribType);
+ this->setVertexAttributeCnt(cnt);
+
for (int i = 0; i < numActiveProxies; ++i) {
SkASSERT(proxies[i]);
@@ -154,6 +157,10 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color,
}
}
+const GrPrimitiveProcessor::Attribute& GrBitmapTextGeoProc::onVertexAttribute(int i) const {
+ return IthInitializedAttribute(i, fInPosition, fInColor, fInTextureCoords);
+}
+
void GrBitmapTextGeoProc::addNewProxies(const sk_sp<GrTextureProxy>* proxies,
int numActiveProxies,
const GrSamplerState& params) {
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h
index 40ba8559e5..5e444977c2 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.h
+++ b/src/gpu/effects/GrBitmapTextGeoProc.h
@@ -36,12 +36,12 @@ public:
const char* name() const override { return "Texture"; }
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inColor() const { return fInColor; }
- const Attribute* inTextureCoords() const { return fInTextureCoords; }
+ const Attribute& inPosition() const { return fInPosition; }
+ const Attribute& inColor() const { return fInColor; }
+ const Attribute& inTextureCoords() const { return fInTextureCoords; }
GrMaskFormat maskFormat() const { return fMaskFormat; }
GrColor color() const { return fColor; }
- bool hasVertexColor() const { return SkToBool(fInColor); }
+ bool hasVertexColor() const { return fInColor.isInitialized(); }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
bool usesW() const { return fUsesW; }
@@ -58,13 +58,15 @@ private:
const GrSamplerState& params, GrMaskFormat format,
const SkMatrix& localMatrix, bool usesW);
+ const Attribute& onVertexAttribute(int i) const override;
+
GrColor fColor;
SkMatrix fLocalMatrix;
bool fUsesW;
TextureSampler fTextureSamplers[kMaxTextures];
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInTextureCoords;
+ Attribute fInPosition;
+ Attribute fInColor;
+ Attribute fInTextureCoords;
GrMaskFormat fMaskFormat;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 5ac73989ee..4d5d50b8db 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -54,13 +54,13 @@ public:
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
// Setup position
- gpArgs->fPositionVar = dfTexEffect.inPosition()->asShaderVar();
+ gpArgs->fPositionVar = dfTexEffect.inPosition().asShaderVar();
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- dfTexEffect.inPosition()->asShaderVar(),
+ dfTexEffect.inPosition().asShaderVar(),
dfTexEffect.localMatrix(),
args.fFPCoordTransformHandler);
@@ -69,7 +69,7 @@ public:
GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
GrGLSLVarying texIdx(texIdxType);
GrGLSLVarying st(kFloat2_GrSLType);
- append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->name(), atlasSizeInvName, &uv,
+ append_index_uv_varyings(args, dfTexEffect.inTextureCoords().name(), atlasSizeInvName, &uv,
&texIdx, &st);
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
@@ -206,32 +206,34 @@ private:
///////////////////////////////////////////////////////////////////////////////
-GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(
- const sk_sp<GrTextureProxy>* proxies,
- int numProxies,
- const GrSamplerState& params,
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldA8TextGeoProc::kInColor;
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldA8TextGeoProc::kInTextureCoords;
+
+GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(const sk_sp<GrTextureProxy>* proxies,
+ int numProxies,
+ const GrSamplerState& params,
#ifdef SK_GAMMA_APPLY_TO_A8
- float distanceAdjust,
+ float distanceAdjust,
#endif
- uint32_t flags,
- const SkMatrix& localMatrix)
+ uint32_t flags,
+ const SkMatrix& localMatrix)
: INHERITED(kGrDistanceFieldA8TextGeoProc_ClassID)
+ , fLocalMatrix(localMatrix)
+ , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
#ifdef SK_GAMMA_APPLY_TO_A8
, fDistanceAdjust(distanceAdjust)
#endif
- , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
- , fInColor(nullptr)
- , fLocalMatrix(localMatrix) {
+{
SkASSERT(numProxies <= kMaxTextures);
-
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
+
if (flags & kPerspective_DistanceFieldEffectFlag) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat3_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat3_GrVertexAttribType};
} else {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat2_GrVertexAttribType};
}
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kUShort2_GrVertexAttribType);
+ this->setVertexAttributeCnt(3);
+
for (int i = 0; i < numProxies; ++i) {
SkASSERT(proxies[i]);
@@ -337,8 +339,8 @@ public:
GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
GrGLSLVarying texIdx(texIdxType);
GrGLSLVarying st(kFloat2_GrSLType);
- append_index_uv_varyings(args, dfPathEffect.inTextureCoords()->name(), atlasSizeInvName,
- &uv, &texIdx, &st);
+ append_index_uv_varyings(args, dfPathEffect.inTextureCoords().name(), atlasSizeInvName, &uv,
+ &texIdx, &st);
// setup pass through color
varyingHandler->addPassThroughAttribute(dfPathEffect.inColor(), args.fOutputColor);
@@ -348,7 +350,7 @@ public:
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
- dfPathEffect.inPosition()->name(),
+ dfPathEffect.inPosition().name(),
dfPathEffect.matrix(),
&fMatrixUniform);
@@ -356,17 +358,17 @@ public:
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- dfPathEffect.inPosition()->asShaderVar(),
+ dfPathEffect.inPosition().asShaderVar(),
args.fFPCoordTransformHandler);
} else {
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, dfPathEffect.inPosition()->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, dfPathEffect.inPosition().name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- dfPathEffect.inPosition()->asShaderVar(),
+ dfPathEffect.inPosition().asShaderVar(),
dfPathEffect.matrix(),
args.fFPCoordTransformHandler);
}
@@ -499,22 +501,22 @@ private:
};
///////////////////////////////////////////////////////////////////////////////
-GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
- const SkMatrix& matrix,
- const sk_sp<GrTextureProxy>* proxies,
- int numProxies,
- const GrSamplerState& params,
- uint32_t flags)
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldPathGeoProc::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldPathGeoProc::kInColor;
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldPathGeoProc::kInTextureCoords;
+
+GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(const SkMatrix& matrix,
+ const sk_sp<GrTextureProxy>* proxies,
+ int numProxies,
+ const GrSamplerState& params,
+ uint32_t flags)
: INHERITED(kGrDistanceFieldPathGeoProc_ClassID)
, fMatrix(matrix)
- , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
- , fInColor(nullptr) {
+ , fFlags(flags & kNonLCD_DistanceFieldEffectMask) {
SkASSERT(numProxies <= kMaxTextures);
-
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kUShort2_GrVertexAttribType);
+
+ this->setVertexAttributeCnt(3);
for (int i = 0; i < numProxies; ++i) {
SkASSERT(proxies[i]);
@@ -548,6 +550,10 @@ GrDistanceFieldPathGeoProc::createGLSLInstance(const GrShaderCaps&) const {
return new GrGLDistanceFieldPathGeoProc();
}
+const GrPrimitiveProcessor::Attribute& GrDistanceFieldPathGeoProc::onVertexAttribute(int i) const {
+ return IthAttribute(i, kInPosition, kInColor, kInTextureCoords);
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc);
@@ -614,13 +620,13 @@ public:
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
// Setup position
- gpArgs->fPositionVar = dfTexEffect.inPosition()->asShaderVar();
+ gpArgs->fPositionVar = dfTexEffect.inPosition().asShaderVar();
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- dfTexEffect.inPosition()->asShaderVar(),
+ dfTexEffect.inPosition().asShaderVar(),
dfTexEffect.localMatrix(),
args.fFPCoordTransformHandler);
@@ -629,7 +635,7 @@ public:
GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
GrGLSLVarying texIdx(texIdxType);
GrGLSLVarying st(kFloat2_GrSLType);
- append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->name(), atlasSizeInvName, &uv,
+ append_index_uv_varyings(args, dfTexEffect.inTextureCoords().name(), atlasSizeInvName, &uv,
&texIdx, &st);
GrGLSLVarying delta(kFloat_GrSLType);
@@ -802,27 +808,30 @@ private:
};
///////////////////////////////////////////////////////////////////////////////
-GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(
- const sk_sp<GrTextureProxy>* proxies,
- int numProxies,
- const GrSamplerState& params,
- DistanceAdjust distanceAdjust,
- uint32_t flags,
- const SkMatrix& localMatrix)
+
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldLCDTextGeoProc::kInColor;
+constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldLCDTextGeoProc::kInTextureCoords;
+
+GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(const sk_sp<GrTextureProxy>* proxies,
+ int numProxies,
+ const GrSamplerState& params,
+ DistanceAdjust distanceAdjust,
+ uint32_t flags,
+ const SkMatrix& localMatrix)
: INHERITED(kGrDistanceFieldLCDTextGeoProc_ClassID)
+ , fLocalMatrix(localMatrix)
, fDistanceAdjust(distanceAdjust)
- , fFlags(flags & kLCD_DistanceFieldEffectMask)
- , fLocalMatrix(localMatrix) {
+ , fFlags(flags & kLCD_DistanceFieldEffectMask) {
SkASSERT(numProxies <= kMaxTextures);
-
SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
+
if (fFlags & kPerspective_DistanceFieldEffectFlag) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat3_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat3_GrVertexAttribType};
} else {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
+ fInPosition = {"inPosition", kFloat2_GrVertexAttribType};
}
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kUShort2_GrVertexAttribType);
+ this->setVertexAttributeCnt(3);
+
for (int i = 0; i < numProxies; ++i) {
SkASSERT(proxies[i]);
@@ -855,6 +864,11 @@ GrGLSLPrimitiveProcessor* GrDistanceFieldLCDTextGeoProc::createGLSLInstance(cons
return new GrGLDistanceFieldLCDTextGeoProc();
}
+const GrPrimitiveProcessor::Attribute& GrDistanceFieldLCDTextGeoProc::onVertexAttribute(
+ int i) const {
+ return IthAttribute(i, fInPosition, kInColor, kInTextureCoords);
+}
+
///////////////////////////////////////////////////////////////////////////////
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc);
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.h b/src/gpu/effects/GrDistanceFieldGeoProc.h
index 5ba19ed5a5..71626fa938 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.h
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.h
@@ -76,9 +76,9 @@ public:
const char* name() const override { return "DistanceFieldA8Text"; }
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inColor() const { return fInColor; }
- const Attribute* inTextureCoords() const { return fInTextureCoords; }
+ const Attribute& inPosition() const { return fInPosition; }
+ const Attribute& inColor() const { return kInColor; }
+ const Attribute& inTextureCoords() const { return kInTextureCoords; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
#ifdef SK_GAMMA_APPLY_TO_A8
float getDistanceAdjust() const { return fDistanceAdjust; }
@@ -100,17 +100,22 @@ private:
#endif
uint32_t flags, const SkMatrix& localMatrix);
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, fInPosition, kInColor, kInTextureCoords);
+ }
+
static constexpr int kMaxTextures = 4;
TextureSampler fTextureSamplers[kMaxTextures];
+ SkMatrix fLocalMatrix;
+ Attribute fInPosition;
+ uint32_t fFlags;
#ifdef SK_GAMMA_APPLY_TO_A8
float fDistanceAdjust;
#endif
- uint32_t fFlags;
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInTextureCoords;
- SkMatrix fLocalMatrix;
+
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@@ -139,9 +144,9 @@ public:
const char* name() const override { return "DistanceFieldPath"; }
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inColor() const { return fInColor; }
- const Attribute* inTextureCoords() const { return fInTextureCoords; }
+ const Attribute& inPosition() const { return kInPosition; }
+ const Attribute& inColor() const { return kInColor; }
+ const Attribute& inTextureCoords() const { return kInTextureCoords; }
const SkMatrix& matrix() const { return fMatrix; }
uint32_t getFlags() const { return fFlags; }
@@ -159,12 +164,14 @@ private:
int numActiveProxies,
const GrSamplerState&, uint32_t flags);
+ const Attribute& onVertexAttribute(int i) const override;
+
SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise
TextureSampler fTextureSamplers[kMaxTextures];
uint32_t fFlags;
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInTextureCoords;
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@@ -209,9 +216,9 @@ public:
const char* name() const override { return "DistanceFieldLCDText"; }
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inColor() const { return fInColor; }
- const Attribute* inTextureCoords() const { return fInTextureCoords; }
+ const Attribute& inPosition() const { return fInPosition; }
+ const Attribute& inColor() const { return kInColor; }
+ const Attribute& inTextureCoords() const { return kInTextureCoords; }
DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
uint32_t getFlags() const { return fFlags; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
@@ -227,15 +234,18 @@ private:
const GrSamplerState& params, DistanceAdjust wa, uint32_t flags,
const SkMatrix& localMatrix);
+ const Attribute& onVertexAttribute(int) const override;
+
static constexpr int kMaxTextures = 4;
TextureSampler fTextureSamplers[kMaxTextures];
+ const SkMatrix fLocalMatrix;
DistanceAdjust fDistanceAdjust;
+ Attribute fInPosition;
uint32_t fFlags;
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInTextureCoords;
- const SkMatrix fLocalMatrix;
+
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
index 52bf287bea..bf78f41c97 100644
--- a/src/gpu/effects/GrShadowGeoProc.cpp
+++ b/src/gpu/effects/GrShadowGeoProc.cpp
@@ -33,13 +33,13 @@ public:
varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor);
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, rsgp.inPosition()->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, rsgp.inPosition().name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- rsgp.inPosition()->asShaderVar(),
+ rsgp.inPosition().asShaderVar(),
args.fFPCoordTransformHandler);
fragBuilder->codeAppend("half d = length(shadowParams.xy);");
@@ -62,11 +62,8 @@ private:
///////////////////////////////////////////////////////////////////////////////
-GrRRectShadowGeoProc::GrRRectShadowGeoProc()
-: INHERITED(kGrRRectShadowGeoProc_ClassID) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInShadowParams = &this->addVertexAttrib("inShadowParams", kHalf4_GrVertexAttribType);
+GrRRectShadowGeoProc::GrRRectShadowGeoProc() : INHERITED(kGrRRectShadowGeoProc_ClassID) {
+ this->setVertexAttributeCnt(3);
}
GrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrShaderCaps&) const {
@@ -75,6 +72,10 @@ GrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrShade
///////////////////////////////////////////////////////////////////////////////
+constexpr GrPrimitiveProcessor::Attribute GrRRectShadowGeoProc::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute GrRRectShadowGeoProc::kInColor;
+constexpr GrPrimitiveProcessor::Attribute GrRRectShadowGeoProc::kInShadowParams;
+
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc);
#if GR_TEST_UTILS
diff --git a/src/gpu/effects/GrShadowGeoProc.h b/src/gpu/effects/GrShadowGeoProc.h
index 0b4baf49b8..df3e501c59 100644
--- a/src/gpu/effects/GrShadowGeoProc.h
+++ b/src/gpu/effects/GrShadowGeoProc.h
@@ -25,9 +25,9 @@ public:
const char* name() const override { return "RRectShadow"; }
- const Attribute* inPosition() const { return fInPosition; }
- const Attribute* inColor() const { return fInColor; }
- const Attribute* inShadowParams() const { return fInShadowParams; }
+ const Attribute& inPosition() const { return kInPosition; }
+ const Attribute& inColor() const { return kInColor; }
+ const Attribute& inShadowParams() const { return kInShadowParams; }
GrColor color() const { return fColor; }
void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {}
@@ -37,10 +37,15 @@ public:
private:
GrRRectShadowGeoProc();
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInColor, kInShadowParams);
+ }
+
GrColor fColor;
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInShadowParams;
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInShadowParams = {"inShadowParams", kHalf4_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 88f5abecb4..be53222ee8 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1775,35 +1775,29 @@ void GrGLGpu::setupGeometry(const GrBuffer* indexBuffer,
attribState = fHWVertexArrayState.bindInternalVertexArray(this);
}
- struct {
- const GrBuffer* fBuffer;
- int fStride;
- size_t fBufferOffset;
- } bindings[2];
+ int numAttribs = fHWProgram->numVertexAttributes() + fHWProgram->numInstanceAttributes();
+ attribState->enableVertexArrays(this, numAttribs, enablePrimitiveRestart);
if (int vertexStride = fHWProgram->vertexStride()) {
SkASSERT(vertexBuffer && !vertexBuffer->isMapped());
- bindings[0].fBuffer = vertexBuffer;
- bindings[0].fStride = vertexStride;
- bindings[0].fBufferOffset = vertexBuffer->baseOffset() + baseVertex * vertexStride;
+ size_t bufferOffset = vertexBuffer->baseOffset() + baseVertex * vertexStride;
+ for (int i = 0; i < fHWProgram->numVertexAttributes(); ++i) {
+ const auto& attrib = fHWProgram->vertexAttribute(i);
+ static constexpr int kDivisor = 0;
+ attribState->set(this, attrib.fLocation, vertexBuffer, attrib.fType, vertexStride,
+ bufferOffset + attrib.fOffset, kDivisor);
+ }
}
if (int instanceStride = fHWProgram->instanceStride()) {
SkASSERT(instanceBuffer && !instanceBuffer->isMapped());
- bindings[1].fBuffer = instanceBuffer;
- bindings[1].fStride = instanceStride;
- bindings[1].fBufferOffset = instanceBuffer->baseOffset() + baseInstance * instanceStride;
- }
-
- auto numAttributes = fHWProgram->numAttributes();
- attribState->enableVertexArrays(this, numAttributes, enablePrimitiveRestart);
-
- for (int i = 0; i < numAttributes; ++i) {
- using InputRate = GrPrimitiveProcessor::Attribute::InputRate;
- const GrGLProgram::Attribute& attribute = fHWProgram->attribute(i);
- const int divisor = InputRate::kPerInstance == attribute.fInputRate ? 1 : 0;
- const auto& binding = bindings[divisor];
- attribState->set(this, attribute.fLocation, binding.fBuffer, attribute.fType,
- binding.fStride, binding.fBufferOffset + attribute.fOffset, divisor);
+ size_t bufferOffset = instanceBuffer->baseOffset() + baseInstance * instanceStride;
+ int attribIdx = fHWProgram->numVertexAttributes();
+ for (int i = 0; i < fHWProgram->numInstanceAttributes(); ++i, ++attribIdx) {
+ const auto& attrib = fHWProgram->instanceAttribute(i);
+ static constexpr int kDivisor = 1;
+ attribState->set(this, attrib.fLocation, instanceBuffer, attrib.fType, instanceStride,
+ bufferOffset + attrib.fOffset, kDivisor);
+ }
}
}
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 262f0b21c4..3d4bd380fa 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -38,7 +38,8 @@ GrGLProgram::GrGLProgram(
std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
int fragmentProcessorCnt,
std::unique_ptr<Attribute[]> attributes,
- int attributeCnt,
+ int vertexAttributeCnt,
+ int instanceAttributeCnt,
int vertexStride,
int instanceStride)
: fBuiltinUniformHandles(builtinUniforms)
@@ -48,7 +49,8 @@ GrGLProgram::GrGLProgram(
, fFragmentProcessors(std::move(fragmentProcessors))
, fFragmentProcessorCnt(fragmentProcessorCnt)
, fAttributes(std::move(attributes))
- , fAttributeCnt(attributeCnt)
+ , fVertexAttributeCnt(vertexAttributeCnt)
+ , fInstanceAttributeCnt(instanceAttributeCnt)
, fVertexStride(vertexStride)
, fInstanceStride(instanceStride)
, fGpu(gpu)
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 6ea1f2cbf9..ca4eddce4b 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -10,7 +10,6 @@
#define GrGLProgram_DEFINED
#include "GrGLProgramDataManager.h"
-#include "GrPrimitiveProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
@@ -35,15 +34,18 @@ public:
*/
struct Attribute {
GrVertexAttribType fType;
- int fOffset;
+ size_t fOffset;
GrGLint fLocation;
- GrPrimitiveProcessor::Attribute::InputRate fInputRate;
};
using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray;
using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray;
+ /**
+ * The attribute array consists of vertexAttributeCnt + instanceAttributeCnt elements with
+ * the vertex attributes preceding the instance attributes.
+ */
GrGLProgram(GrGLGpu*,
const GrGLSLBuiltinUniformHandles&,
GrGLuint programID,
@@ -56,7 +58,8 @@ public:
std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
int fragmentProcessorCnt,
std::unique_ptr<Attribute[]>,
- int attributeCnt,
+ int vertexAttributeCnt,
+ int instanceAttributeCnt,
int vertexStride,
int instanceStride);
@@ -124,8 +127,17 @@ public:
int vertexStride() const { return fVertexStride; }
int instanceStride() const { return fInstanceStride; }
- int numAttributes() const { return fAttributeCnt; }
- const Attribute& attribute(int i) const { return fAttributes[i]; }
+ int numVertexAttributes() const { return fVertexAttributeCnt; }
+ const Attribute& vertexAttribute(int i) const {
+ SkASSERT(i >= 0 && i < fVertexAttributeCnt);
+ return fAttributes[i];
+ }
+
+ int numInstanceAttributes() const { return fInstanceAttributeCnt; }
+ const Attribute& instanceAttribute(int i) const {
+ SkASSERT(i >= 0 && i < fInstanceAttributeCnt);
+ return fAttributes[i + fVertexAttributeCnt];
+ }
private:
// A helper to loop over effects, set the transforms (via subclass) and bind textures
@@ -153,7 +165,8 @@ private:
int fFragmentProcessorCnt;
std::unique_ptr<Attribute[]> fAttributes;
- int fAttributeCnt;
+ int fVertexAttributeCnt;
+ int fInstanceAttributeCnt;
int fVertexStride;
int fInstanceStride;
diff --git a/src/gpu/gl/GrGLVaryingHandler.cpp b/src/gpu/gl/GrGLVaryingHandler.cpp
index eecc63e617..e426d46e14 100644
--- a/src/gpu/gl/GrGLVaryingHandler.cpp
+++ b/src/gpu/gl/GrGLVaryingHandler.cpp
@@ -20,7 +20,8 @@ GrGLSLVaryingHandler::VaryingHandle GrGLVaryingHandler::addPathProcessingVarying
SkASSERT(glPB->gpu()->glCaps().shaderCaps()->pathRenderingSupport() &&
glPB->fPrimProc.isPathRendering() &&
!glPB->fPrimProc.willUseGeoShader() &&
- glPB->fPrimProc.numAttribs() == 0);
+ !glPB->fPrimProc.numVertexAttributes() &&
+ !glPB->fPrimProc.numInstanceAttributes());
#endif
this->addVarying(name, v);
auto varyingInfo = fPathProcVaryingInfos.push_back();
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 0cdc3b5b21..79e13d3555 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -70,7 +70,8 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
, fGpu(gpu)
, fVaryingHandler(this)
, fUniformHandler(this)
- , fAttributeCnt(0)
+ , fVertexAttributeCnt(0)
+ , fInstanceAttributeCnt(0)
, fVertexStride(0)
, fInstanceStride(0) {}
@@ -227,18 +228,30 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
// NVPR actually requires a vertex shader to compile
bool useNvpr = primProc.isPathRendering();
if (!useNvpr) {
- fAttributeCnt = primProc.numAttribs();
- fAttributes.reset(new GrGLProgram::Attribute[fAttributeCnt]);
- fVertexStride = primProc.getVertexStride();
- fInstanceStride = primProc.getInstanceStride();
- for (int i = 0; i < fAttributeCnt; i++) {
- const auto& attr = primProc.getAttrib(i);
- fAttributes[i].fInputRate = attr.inputRate();
- fAttributes[i].fType = attr.type();
- fAttributes[i].fOffset = attr.offsetInRecord();
+ fVertexAttributeCnt = primProc.numVertexAttributes();
+ fInstanceAttributeCnt = primProc.numInstanceAttributes();
+ fAttributes.reset(
+ new GrGLProgram::Attribute[fVertexAttributeCnt + fInstanceAttributeCnt]);
+ auto addAttr = [&](int i, const auto& a, size_t* stride) {
+ fAttributes[i].fType = a.type();
+ fAttributes[i].fOffset = *stride;
+ *stride += a.sizeAlign4();
fAttributes[i].fLocation = i;
- GL_CALL(BindAttribLocation(programID, i, attr.name()));
+ GL_CALL(BindAttribLocation(programID, i, a.name()));
+ };
+ fVertexStride = 0;
+ int i = 0;
+ for (; i < fVertexAttributeCnt; i++) {
+ addAttr(i, primProc.vertexAttribute(i), &fVertexStride);
+ SkASSERT(fAttributes[i].fOffset == primProc.debugOnly_vertexAttributeOffset(i));
}
+ SkASSERT(fVertexStride == primProc.debugOnly_vertexStride());
+ fInstanceStride = 0;
+ for (int j = 0; j < fInstanceAttributeCnt; j++, ++i) {
+ addAttr(i, primProc.instanceAttribute(j), &fInstanceStride);
+ SkASSERT(fAttributes[i].fOffset == primProc.debugOnly_instanceAttributeOffset(j));
+ }
+ SkASSERT(fInstanceStride == primProc.debugOnly_instanceStride());
}
if (primProc.willUseGeoShader()) {
@@ -406,7 +419,8 @@ GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
std::move(fFragmentProcessors),
fFragmentProcessorCnt,
std::move(fAttributes),
- fAttributeCnt,
+ fVertexAttributeCnt,
+ fInstanceAttributeCnt,
fVertexStride,
fInstanceStride);
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index ea3432bd04..30d5179325 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -81,9 +81,10 @@ private:
GrGLUniformHandler fUniformHandler;
std::unique_ptr<GrGLProgram::Attribute[]> fAttributes;
- int fAttributeCnt;
- int fVertexStride;
- int fInstanceStride;
+ int fVertexAttributeCnt;
+ int fInstanceAttributeCnt;
+ size_t fVertexStride;
+ size_t fInstanceStride;
// shader pulled from cache. Data is organized as:
// SkSL::Program::Inputs inputs
diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp
index f8ec1c24d9..0563406385 100644
--- a/src/gpu/glsl/GrGLSLVarying.cpp
+++ b/src/gpu/glsl/GrGLSLVarying.cpp
@@ -9,14 +9,15 @@
#include "glsl/GrGLSLVarying.h"
#include "glsl/GrGLSLProgramBuilder.h"
-void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input,
+void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute& input,
const char* output,
Interpolation interpolation) {
+ SkASSERT(input.isInitialized());
SkASSERT(!fProgramBuilder->primitiveProcessor().willUseGeoShader());
- GrSLType type = GrVertexAttribTypeToSLType(input->type());
+ GrSLType type = GrVertexAttribTypeToSLType(input.type());
GrGLSLVarying v(type);
- this->addVarying(input->name(), &v, interpolation);
- fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->name());
+ this->addVarying(input.name(), &v, interpolation);
+ fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input.name());
fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn());
}
@@ -67,10 +68,13 @@ void GrGLSLVaryingHandler::addVarying(const char* name, GrGLSLVarying* varying,
}
void GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) {
- int vaCount = gp.numAttribs();
+ int vaCount = gp.numVertexAttributes();
for (int i = 0; i < vaCount; i++) {
- const GrGeometryProcessor::Attribute& attr = gp.getAttrib(i);
- this->addAttribute(attr.asShaderVar());
+ this->addAttribute(gp.vertexAttribute(i).asShaderVar());
+ }
+ int iaCount = gp.numInstanceAttributes();
+ for (int i = 0; i < iaCount; i++) {
+ this->addAttribute(gp.instanceAttribute(i).asShaderVar());
}
}
diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h
index 57704ad075..0da88a0fbd 100644
--- a/src/gpu/glsl/GrGLSLVarying.h
+++ b/src/gpu/glsl/GrGLSLVarying.h
@@ -104,7 +104,7 @@ public:
* that will be set as the output varying for all emitted vertices.
* TODO it might be nicer behavior to have a flag to declare output inside these calls
*/
- void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output,
+ void addPassThroughAttribute(const GrGeometryProcessor::Attribute&, const char* output,
Interpolation = Interpolation::kInterpolated);
void emitAttributes(const GrGeometryProcessor& gp);
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 3237afeaed..566eebd827 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -576,21 +576,21 @@ public:
GrGLSLVarying v(kHalf4_GrSLType);
varyingHandler->addVarying("QuadEdge", &v);
- vertBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.fInQuadEdge->name());
+ vertBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.kInQuadEdge.name());
// Setup pass through color
- varyingHandler->addPassThroughAttribute(qe.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(qe.kInColor, args.fOutputColor);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, qe.fInPosition->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, qe.kInPosition.name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- qe.fInPosition->asShaderVar(),
+ qe.kInPosition.asShaderVar(),
qe.fLocalMatrix,
args.fFPCoordTransformHandler);
@@ -646,21 +646,25 @@ private:
: INHERITED(kQuadEdgeEffect_ClassID)
, fLocalMatrix(localMatrix)
, fUsesLocalCoords(usesLocalCoords) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInQuadEdge = &this->addVertexAttrib("inQuadEdge", kHalf4_GrVertexAttribType);
+ this->setVertexAttributeCnt(3);
}
- const Attribute* fInPosition;
- const Attribute* fInQuadEdge;
- const Attribute* fInColor;
- SkMatrix fLocalMatrix;
- bool fUsesLocalCoords;
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInColor, kInQuadEdge);
+ }
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInQuadEdge = {"inQuadEdge", kHalf4_GrVertexAttribType};
+ SkMatrix fLocalMatrix;
+ bool fUsesLocalCoords;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute QuadEdgeEffect::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute QuadEdgeEffect::kInColor;
+constexpr GrPrimitiveProcessor::Attribute QuadEdgeEffect::kInQuadEdge;
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect);
@@ -795,12 +799,10 @@ private:
return;
}
- size_t vertexStride = gp->getVertexStride();
-
- SkASSERT(fHelper.compatibleWithAlphaAsCoverage()
- ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
- : vertexStride ==
- sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
+ size_t vertexStride = fHelper.compatibleWithAlphaAsCoverage()
+ ? sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
+ : sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
GrAAConvexTessellator tess;
@@ -901,9 +903,9 @@ private:
const GrBuffer* vertexBuffer;
int firstVertex;
- size_t vertexStride = quadProcessor->getVertexStride();
+ SkASSERT(sizeof(QuadVertex) == quadProcessor->debugOnly_vertexStride());
QuadVertex* verts = reinterpret_cast<QuadVertex*>(target->makeVertexSpace(
- vertexStride, vertexCount, &vertexBuffer, &firstVertex));
+ sizeof(QuadVertex), vertexCount, &vertexBuffer, &firstVertex));
if (!verts) {
SkDebugf("Could not allocate vertices\n");
diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp
index 5472f11f71..76bc8128cf 100644
--- a/src/gpu/ops/GrAAFillRectOp.cpp
+++ b/src/gpu/ops/GrAAFillRectOp.cpp
@@ -242,12 +242,19 @@ private:
void onPrepareDraws(Target* target) override {
using namespace GrDefaultGeoProcFactory;
+ size_t vertexStride = sizeof(SkPoint) + sizeof(GrColor);
Color color(Color::kPremulGrColorAttribute_Type);
- Coverage::Type coverageType = fHelper.compatibleWithAlphaAsCoverage()
- ? Coverage::kSolid_Type
- : Coverage::kAttribute_Type;
- LocalCoords lc = fHelper.usesLocalCoords() ? LocalCoords::kHasExplicit_Type
- : LocalCoords::kUnused_Type;
+ Coverage::Type coverageType = Coverage::kSolid_Type;
+ if (!fHelper.compatibleWithAlphaAsCoverage()) {
+ coverageType = Coverage::kAttribute_Type;
+ vertexStride += sizeof(float);
+ }
+ LocalCoords lc = LocalCoords::kUnused_Type;
+ if (fHelper.usesLocalCoords()) {
+ lc = LocalCoords::kHasExplicit_Type;
+ vertexStride += sizeof(SkPoint);
+ }
+
sk_sp<GrGeometryProcessor> gp =
GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I());
if (!gp) {
@@ -255,7 +262,7 @@ private:
return;
}
- size_t vertexStride = gp->getVertexStride();
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
sk_sp<const GrBuffer> indexBuffer = get_index_buffer(target->resourceProvider());
PatternHelper helper(GrPrimitiveType::kTriangles);
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index b62c14b197..89dedc48a4 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -959,18 +959,16 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
const GrBuffer* vertexBuffer;
int firstVertex;
- size_t vertexStride = lineGP->getVertexStride();
+ SkASSERT(sizeof(LineVertex) == lineGP->debugOnly_vertexStride());
int vertexCount = kLineSegNumVertices * lineCount;
- LineVertex* verts = reinterpret_cast<LineVertex*>(
- target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex));
+ LineVertex* verts = reinterpret_cast<LineVertex*>(target->makeVertexSpace(
+ sizeof(LineVertex), vertexCount, &vertexBuffer, &firstVertex));
if (!verts|| !linesIndexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
- SkASSERT(lineGP->getVertexStride() == sizeof(LineVertex));
-
for (int i = 0; i < lineCount; ++i) {
add_line(&lines[2*i], toSrc, this->coverage(), &verts);
}
@@ -1004,10 +1002,11 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
sk_sp<const GrBuffer> quadsIndexBuffer = get_quads_index_buffer(target->resourceProvider());
- size_t vertexStride = sizeof(BezierVertex);
+ SkASSERT(sizeof(BezierVertex) == quadGP->debugOnly_vertexStride());
+ SkASSERT(sizeof(BezierVertex) == conicGP->debugOnly_vertexStride());
int vertexCount = kQuadNumVertices * quadAndConicCount;
- void *vertices = target->makeVertexSpace(vertexStride, vertexCount,
- &vertexBuffer, &firstVertex);
+ void* vertices = target->makeVertexSpace(sizeof(BezierVertex), vertexCount, &vertexBuffer,
+ &firstVertex);
if (!vertices || !quadsIndexBuffer) {
SkDebugf("Could not allocate vertices\n");
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 5659099c84..b6b70779ff 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -249,12 +249,10 @@ private:
return;
}
- size_t vertexStride = gp->getVertexStride();
-
- SkASSERT(fHelper.compatibleWithAlphaAsCoverage()
- ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
- : vertexStride ==
- sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
+ size_t vertexStride = fHelper.compatibleWithAlphaAsCoverage()
+ ? sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
+ : sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
int instanceCount = fPaths.count();
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index b9a6d88021..3347227f04 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -268,11 +268,11 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) {
return;
}
- size_t vertexStride = gp->getVertexStride();
+ size_t vertexStride = fHelper.compatibleWithAlphaAsCoverage()
+ ? sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
+ : sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr);
- SkASSERT(fHelper.compatibleWithAlphaAsCoverage()
- ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
- : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
int innerVertexNum = 4;
int outerVertexNum = this->miterStroke() ? 4 : 8;
int verticesPerInstance = (outerVertexNum + innerVertexNum) * 2;
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 1ea3ddfae6..fc5e5804eb 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -312,8 +312,8 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
}
flushInfo.fGlyphsToFlush = 0;
- size_t vertexStride = flushInfo.fGeometryProcessor->getVertexStride();
- SkASSERT(vertexStride == GrTextBlob::GetVertexStride(maskFormat, vmPerspective));
+ size_t vertexStride = GrTextBlob::GetVertexStride(maskFormat, vmPerspective);
+ SkASSERT(vertexStride == flushInfo.fGeometryProcessor->debugOnly_vertexStride());
int glyphCount = this->numGlyphs();
const GrBuffer* vertexBuffer;
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index cafb3e54c9..968d169376 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -626,7 +626,15 @@ private:
}
QuadHelper helper;
- void* vertices = helper.init(target, gp->getVertexStride(), totalRectCount);
+ size_t vertexStride;
+ if (fullDash) {
+ vertexStride =
+ SkPaint::kRound_Cap == fCap ? sizeof(DashCircleVertex) : sizeof(DashLineVertex);
+ } else {
+ vertexStride = sizeof(SkPoint);
+ }
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
+ void* vertices = helper.init(target, vertexStride, totalRectCount);
if (!vertices) {
return;
}
@@ -638,15 +646,13 @@ private:
if (!draws[i].fLineDone) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
- draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, draws[i].fLineLength,
- draws[i].fHalfDevStroke, draws[i].fIntervals[0],
- draws[i].fIntervals[1], draws[i].fStrokeWidth,
- capType, gp->getVertexStride());
+ setup_dashed_rect(
+ rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+ draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY,
+ draws[i].fLineLength, draws[i].fHalfDevStroke, draws[i].fIntervals[0],
+ draws[i].fIntervals[1], draws[i].fStrokeWidth, capType, vertexStride);
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
- SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
}
curVIdx += 4;
@@ -655,15 +661,13 @@ private:
if (draws[i].fHasStartRect) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
- draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, draws[i].fIntervals[0],
- draws[i].fHalfDevStroke, draws[i].fIntervals[0],
- draws[i].fIntervals[1], draws[i].fStrokeWidth, capType,
- gp->getVertexStride());
+ setup_dashed_rect(
+ rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+ draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY,
+ draws[i].fIntervals[0], draws[i].fHalfDevStroke, draws[i].fIntervals[0],
+ draws[i].fIntervals[1], draws[i].fStrokeWidth, capType, vertexStride);
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
- SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
}
curVIdx += 4;
@@ -672,15 +676,13 @@ private:
if (draws[i].fHasEndRect) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
- draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, draws[i].fIntervals[0],
- draws[i].fHalfDevStroke, draws[i].fIntervals[0],
- draws[i].fIntervals[1], draws[i].fStrokeWidth, capType,
- gp->getVertexStride());
+ setup_dashed_rect(
+ rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+ draws[i].fStartOffset, draws[i].fDevBloatX, draws[i].fDevBloatY,
+ draws[i].fIntervals[0], draws[i].fHalfDevStroke, draws[i].fIntervals[0],
+ draws[i].fIntervals[1], draws[i].fStrokeWidth, capType, vertexStride);
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
- SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
}
curVIdx += 4;
@@ -840,12 +842,6 @@ public:
const char* name() const override { return "DashingCircleEffect"; }
- const Attribute* inPosition() const { return fInPosition; }
-
- const Attribute* inDashParams() const { return fInDashParams; }
-
- const Attribute* inCircleParams() const { return fInCircleParams; }
-
AAMode aaMode() const { return fAAMode; }
GrColor color() const { return fColor; }
@@ -862,18 +858,27 @@ private:
DashingCircleEffect(GrColor, AAMode aaMode, const SkMatrix& localMatrix,
bool usesLocalCoords);
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInDashParams, kInCircleParams);
+ }
+
GrColor fColor;
SkMatrix fLocalMatrix;
bool fUsesLocalCoords;
AAMode fAAMode;
- const Attribute* fInPosition;
- const Attribute* fInDashParams;
- const Attribute* fInCircleParams;
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInDashParams = {"inDashParams", kHalf3_GrVertexAttribType};
+ static constexpr Attribute kInCircleParams = {"inCircleParams", kHalf2_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
+ friend class GLDashingCircleEffect;
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute DashingCircleEffect::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute DashingCircleEffect::kInDashParams;
+constexpr GrPrimitiveProcessor::Attribute DashingCircleEffect::kInCircleParams;
//////////////////////////////////////////////////////////////////////////////
@@ -918,25 +923,25 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// XY are dashPos, Z is dashInterval
GrGLSLVarying dashParams(kHalf3_GrSLType);
varyingHandler->addVarying("DashParam", &dashParams);
- vertBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->name());
+ vertBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.kInDashParams.name());
// x refers to circle radius - 0.5, y refers to cicle's center x coord
GrGLSLVarying circleParams(kHalf2_GrSLType);
varyingHandler->addVarying("CircleParams", &circleParams);
- vertBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams()->name());
+ vertBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.kInCircleParams.name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, dce.inPosition()->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, dce.kInPosition.name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- dce.inPosition()->asShaderVar(),
+ dce.kInPosition.asShaderVar(),
dce.localMatrix(),
args.fFPCoordTransformHandler);
@@ -1009,9 +1014,7 @@ DashingCircleEffect::DashingCircleEffect(GrColor color,
, fLocalMatrix(localMatrix)
, fUsesLocalCoords(usesLocalCoords)
, fAAMode(aaMode) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInDashParams = &this->addVertexAttrib("inDashParams", kHalf3_GrVertexAttribType);
- fInCircleParams = &this->addVertexAttrib("inCircleParams", kHalf2_GrVertexAttribType);
+ this->setVertexAttributeCnt(3);
}
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingCircleEffect);
@@ -1049,12 +1052,6 @@ public:
const char* name() const override { return "DashingEffect"; }
- const Attribute* inPosition() const { return fInPosition; }
-
- const Attribute* inDashParams() const { return fInDashParams; }
-
- const Attribute* inRectParams() const { return fInRectParams; }
-
AAMode aaMode() const { return fAAMode; }
GrColor color() const { return fColor; }
@@ -1071,18 +1068,28 @@ private:
DashingLineEffect(GrColor, AAMode aaMode, const SkMatrix& localMatrix,
bool usesLocalCoords);
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInDashParams, kInRectParams);
+ }
+
GrColor fColor;
SkMatrix fLocalMatrix;
bool fUsesLocalCoords;
AAMode fAAMode;
- const Attribute* fInPosition;
- const Attribute* fInDashParams;
- const Attribute* fInRectParams;
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInDashParams = {"inDashParams", kHalf3_GrVertexAttribType};
+ static constexpr Attribute kInRectParams = {"inRect", kHalf4_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
+ friend class GLDashingLineEffect;
+
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute DashingLineEffect::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute DashingLineEffect::kInDashParams;
+constexpr GrPrimitiveProcessor::Attribute DashingLineEffect::kInRectParams;
//////////////////////////////////////////////////////////////////////////////
@@ -1120,26 +1127,26 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// XY refers to dashPos, Z is the dash interval length
GrGLSLVarying inDashParams(kFloat3_GrSLType);
varyingHandler->addVarying("DashParams", &inDashParams);
- vertBuilder->codeAppendf("%s = %s;", inDashParams.vsOut(), de.inDashParams()->name());
+ vertBuilder->codeAppendf("%s = %s;", inDashParams.vsOut(), de.kInDashParams.name());
// The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
// respectively.
GrGLSLVarying inRectParams(kFloat4_GrSLType);
varyingHandler->addVarying("RectParams", &inRectParams);
- vertBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()->name());
+ vertBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.kInRectParams.name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, de.inPosition()->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, de.kInPosition.name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- de.inPosition()->asShaderVar(),
+ de.kInPosition.asShaderVar(),
de.localMatrix(),
args.fFPCoordTransformHandler);
@@ -1230,9 +1237,7 @@ DashingLineEffect::DashingLineEffect(GrColor color,
, fLocalMatrix(localMatrix)
, fUsesLocalCoords(usesLocalCoords)
, fAAMode(aaMode) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInDashParams = &this->addVertexAttrib("inDashParams", kHalf3_GrVertexAttribType);
- fInRectParams = &this->addVertexAttrib("inRect", kHalf4_GrVertexAttribType);
+ this->setVertexAttributeCnt(3);
}
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DashingLineEffect);
@@ -1244,8 +1249,8 @@ sk_sp<GrGeometryProcessor> DashingLineEffect::TestCreate(GrProcessorTestData* d)
aaMode, GrTest::TestMatrix(d->fRandom),
d->fRandom->nextBool());
}
-#endif
+#endif
//////////////////////////////////////////////////////////////////////////////
static sk_sp<GrGeometryProcessor> make_dash_gp(GrColor color,
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index df6f81f552..aa0963b02a 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -404,7 +404,7 @@ private:
gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, this->viewMatrix());
}
- SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
+ SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint));
int instanceCount = fPaths.count();
diff --git a/src/gpu/ops/GrDrawAtlasOp.cpp b/src/gpu/ops/GrDrawAtlasOp.cpp
index fa08e558f3..47bad8b2a4 100644
--- a/src/gpu/ops/GrDrawAtlasOp.cpp
+++ b/src/gpu/ops/GrDrawAtlasOp.cpp
@@ -122,9 +122,9 @@ void GrDrawAtlasOp::onPrepareDraws(Target* target) {
sk_sp<GrGeometryProcessor> gp(make_gp(this->hasColors(), this->color(), this->viewMatrix()));
int instanceCount = fGeoData.count();
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride ==
- sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0));
+ size_t vertexStride =
+ sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
QuadHelper helper;
int numQuads = this->quadCount();
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index c968611152..8f6ad9745d 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -140,10 +140,10 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) {
bool hasColorAttribute;
bool hasLocalCoordsAttribute;
sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute, &hasLocalCoordsAttribute);
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) +
- (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0));
+ size_t vertexStride = sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) +
+ (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
int instanceCount = fMeshes.count();
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 5903231cb2..7bfa72ec94 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -62,19 +62,19 @@ public:
latticeGP.fColorSpaceXform.get());
args.fVaryingHandler->emitAttributes(latticeGP);
- this->writeOutputPosition(args.fVertBuilder, gpArgs, latticeGP.fPositions.name());
+ this->writeOutputPosition(args.fVertBuilder, gpArgs, latticeGP.kPositions.name());
this->emitTransforms(args.fVertBuilder,
args.fVaryingHandler,
args.fUniformHandler,
- latticeGP.fTextureCoords.asShaderVar(),
+ latticeGP.kTextureCoords.asShaderVar(),
args.fFPCoordTransformHandler);
args.fFragBuilder->codeAppend("float2 textureCoords;");
- args.fVaryingHandler->addPassThroughAttribute(&latticeGP.fTextureCoords,
+ args.fVaryingHandler->addPassThroughAttribute(latticeGP.kTextureCoords,
"textureCoords");
args.fFragBuilder->codeAppend("float4 textureDomain;");
args.fVaryingHandler->addPassThroughAttribute(
- &latticeGP.fTextureDomain, "textureDomain", Interpolation::kCanBeFlat);
- args.fVaryingHandler->addPassThroughAttribute(&latticeGP.fColors, args.fOutputColor,
+ latticeGP.kTextureDomain, "textureDomain", Interpolation::kCanBeFlat);
+ args.fVaryingHandler->addPassThroughAttribute(latticeGP.kColors, args.fOutputColor,
Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
args.fFragBuilder->appendTextureLookupAndModulate(
@@ -95,24 +95,31 @@ private:
LatticeGP(sk_sp<GrTextureProxy> proxy, sk_sp<GrColorSpaceXform> csxf,
GrSamplerState::Filter filter)
: INHERITED(kLatticeGP_ClassID), fColorSpaceXform(std::move(csxf)) {
- fPositions = this->addVertexAttrib("position", kFloat2_GrVertexAttribType);
fSampler.reset(std::move(proxy), filter);
this->addTextureSampler(&fSampler);
- fTextureCoords = this->addVertexAttrib("textureCoords", kFloat2_GrVertexAttribType);
- fTextureDomain = this->addVertexAttrib("textureDomain", kFloat4_GrVertexAttribType);
- fColors = this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType);
+ this->setVertexAttributeCnt(4);
}
- Attribute fPositions;
- Attribute fTextureCoords;
- Attribute fTextureDomain;
- Attribute fColors;
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kPositions, kTextureCoords, kTextureDomain, kColors);
+ }
+
+ static constexpr Attribute kPositions = {"position", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kTextureCoords = {"textureCoords", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kTextureDomain = {"textureDomain", kFloat4_GrVertexAttribType};
+ static constexpr Attribute kColors = {"color", kUByte4_norm_GrVertexAttribType};
+
sk_sp<GrColorSpaceXform> fColorSpaceXform;
TextureSampler fSampler;
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute LatticeGP::kPositions;
+constexpr GrPrimitiveProcessor::Attribute LatticeGP::kTextureCoords;
+constexpr GrPrimitiveProcessor::Attribute LatticeGP::kTextureDomain;
+constexpr GrPrimitiveProcessor::Attribute LatticeGP::kColors;
+
class NonAALatticeOp final : public GrMeshDrawOp {
private:
using Helper = GrSimpleMeshDrawOpHelper;
@@ -200,7 +207,10 @@ private:
return;
}
- size_t vertexStride = gp->getVertexStride();
+ static constexpr size_t kVertexStide =
+ sizeof(SkPoint) + sizeof(SkPoint) + sizeof(SkRect) + sizeof(uint32_t);
+ SkASSERT(kVertexStide == gp->debugOnly_vertexStride());
+
int patchCnt = fPatches.count();
int numRects = 0;
for (int i = 0; i < patchCnt; i++) {
@@ -213,7 +223,7 @@ private:
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles);
- void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
+ void* vertices = helper.init(target, kVertexStide, indexBuffer.get(), kVertsPerRect,
kIndicesPerRect, numRects);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
@@ -241,7 +251,7 @@ private:
static const Sk4f kFlipMuls(1.f, -1.f, 1.f, -1.f);
while (patch.fIter->next(&srcR, &dstR)) {
auto vertices = reinterpret_cast<LatticeGP::Vertex*>(verts);
- SkPointPriv::SetRectTriStrip(&vertices->fPosition, dstR, vertexStride);
+ SkPointPriv::SetRectTriStrip(&vertices->fPosition, dstR, kVertexStide);
Sk4f coords(SkIntToScalar(srcR.fLeft), SkIntToScalar(srcR.fTop),
SkIntToScalar(srcR.fRight), SkIntToScalar(srcR.fBottom));
Sk4f domain = coords + kDomainOffsets;
@@ -252,7 +262,7 @@ private:
domain = SkNx_shuffle<0, 3, 2, 1>(kFlipMuls * domain + kFlipOffsets);
}
SkPointPriv::SetRectTriStrip(&vertices->fTextureCoords, coords[0], coords[1],
- coords[2], coords[3], vertexStride);
+ coords[2], coords[3], kVertexStide);
for (int j = 0; j < kVertsPerRect; ++j) {
vertices[j].fTextureDomain = {domain[0], domain[1], domain[2], domain[3]};
}
@@ -260,13 +270,13 @@ private:
for (int j = 0; j < kVertsPerRect; ++j) {
vertices[j].fColor = patch.fColor;
}
- verts += kVertsPerRect * vertexStride;
+ verts += kVertsPerRect * kVertexStide;
}
// If we didn't handle it above, apply the matrix here.
if (!isScaleTranslate) {
SkPoint* positions = reinterpret_cast<SkPoint*>(patchVerts);
- SkMatrixPriv::MapPointsWithStride(patch.fViewMatrix, positions, vertexStride,
+ SkMatrixPriv::MapPointsWithStride(patch.fViewMatrix, positions, kVertexStide,
kVertsPerRect * patch.fIter->numRectsToDraw());
}
}
diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp
index 20bd599133..d4ebedc6e1 100644
--- a/src/gpu/ops/GrNonAAFillRectOp.cpp
+++ b/src/gpu/ops/GrNonAAFillRectOp.cpp
@@ -181,15 +181,16 @@ private:
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
}
- SkASSERT(gp->getVertexStride() ==
- sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr));
- size_t vertexStride = gp->getVertexStride();
+ static constexpr size_t kVertexStride =
+ sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr);
+ SkASSERT(kVertexStride == gp->debugOnly_vertexStride());
+
int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles);
- void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
+ void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerRect,
kIndicesPerRect, rectCount);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
@@ -198,8 +199,8 @@ private:
for (int i = 0; i < rectCount; i++) {
intptr_t verts =
- reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
- tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
+ reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * kVertexStride;
+ tesselate(verts, kVertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
fRects[i].fRect, &fRects[i].fLocalQuad);
}
helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
@@ -311,13 +312,11 @@ private:
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
}
- SkASSERT(fHasLocalRect
- ? gp->getVertexStride() ==
- sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
- : gp->getVertexStride() ==
- sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
+ size_t vertexStride = fHasLocalRect
+ ? sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
+ : sizeof(GrDefaultGeoProcFactory::PositionColorAttr);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
- size_t vertexStride = gp->getVertexStride();
int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
index 5e00e559e7..11c2f8cda5 100644
--- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
@@ -152,9 +152,9 @@ private:
fViewMatrix);
}
- size_t vertexStride = gp->getVertexStride();
+ static constexpr size_t kVertexStride = sizeof(GrDefaultGeoProcFactory::PositionAttr);
- SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
+ SkASSERT(kVertexStride == gp->debugOnly_vertexStride());
int vertexCount = kVertsPerHairlineRect;
if (fStrokeWidth > 0) {
@@ -165,7 +165,7 @@ private:
int firstVertex;
void* verts =
- target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
+ target->makeVertexSpace(kVertexStride, vertexCount, &vertexBuffer, &firstVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index 7b0e4621e9..1655b76326 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -75,32 +75,26 @@ public:
: INHERITED(kCircleGeometryProcessor_ClassID)
, fLocalMatrix(localMatrix)
, fStroke(stroke) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInCircleEdge = &this->addVertexAttrib("inCircleEdge", kFloat4_GrVertexAttribType);
+ int cnt = 3;
if (clipPlane) {
- fInClipPlane = &this->addVertexAttrib("inClipPlane", kHalf3_GrVertexAttribType);
- } else {
- fInClipPlane = nullptr;
+ fInClipPlane = {"inClipPlane", kHalf3_GrVertexAttribType};
+ ++cnt;
}
if (isectPlane) {
- fInIsectPlane = &this->addVertexAttrib("inIsectPlane", kHalf3_GrVertexAttribType);
- } else {
- fInIsectPlane = nullptr;
+ fInIsectPlane = {"inIsectPlane", kHalf3_GrVertexAttribType};
+ ++cnt;
}
if (unionPlane) {
- fInUnionPlane = &this->addVertexAttrib("inUnionPlane", kHalf3_GrVertexAttribType);
- } else {
- fInUnionPlane = nullptr;
+ fInUnionPlane = {"inUnionPlane", kHalf3_GrVertexAttribType};
+ ++cnt;
}
if (roundCaps) {
SkASSERT(stroke);
SkASSERT(clipPlane);
- fInRoundCapCenters =
- &this->addVertexAttrib("inRoundCapCenters", kFloat4_GrVertexAttribType);
- } else {
- fInRoundCapCenters = nullptr;
+ fInRoundCapCenters = {"inRoundCapCenters", kFloat4_GrVertexAttribType};
+ ++cnt;
}
+ this->setVertexAttributeCnt(cnt);
}
~CircleGeometryProcessor() override {}
@@ -130,23 +124,22 @@ private:
// emit attributes
varyingHandler->emitAttributes(cgp);
fragBuilder->codeAppend("float4 circleEdge;");
- varyingHandler->addPassThroughAttribute(cgp.fInCircleEdge, "circleEdge");
- if (cgp.fInClipPlane) {
+ varyingHandler->addPassThroughAttribute(cgp.kInCircleEdge, "circleEdge");
+ if (cgp.fInClipPlane.isInitialized()) {
fragBuilder->codeAppend("half3 clipPlane;");
varyingHandler->addPassThroughAttribute(cgp.fInClipPlane, "clipPlane");
}
- if (cgp.fInIsectPlane) {
- SkASSERT(cgp.fInClipPlane);
+ if (cgp.fInIsectPlane.isInitialized()) {
fragBuilder->codeAppend("half3 isectPlane;");
varyingHandler->addPassThroughAttribute(cgp.fInIsectPlane, "isectPlane");
}
- if (cgp.fInUnionPlane) {
- SkASSERT(cgp.fInClipPlane);
+ if (cgp.fInUnionPlane.isInitialized()) {
+ SkASSERT(cgp.fInClipPlane.isInitialized());
fragBuilder->codeAppend("half3 unionPlane;");
varyingHandler->addPassThroughAttribute(cgp.fInUnionPlane, "unionPlane");
}
GrGLSLVarying capRadius(kFloat_GrSLType);
- if (cgp.fInRoundCapCenters) {
+ if (cgp.fInRoundCapCenters.isInitialized()) {
fragBuilder->codeAppend("float4 roundCapCenters;");
varyingHandler->addPassThroughAttribute(cgp.fInRoundCapCenters, "roundCapCenters");
varyingHandler->addVarying("capRadius", &capRadius,
@@ -154,20 +147,20 @@ private:
// This is the cap radius in normalized space where the outer radius is 1 and
// circledEdge.w is the normalized inner radius.
vertBuilder->codeAppendf("%s = (1.0 - %s.w) / 2.0;", capRadius.vsOut(),
- cgp.fInCircleEdge->name());
+ cgp.kInCircleEdge.name());
}
// setup pass through color
- varyingHandler->addPassThroughAttribute(cgp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(cgp.kInColor, args.fOutputColor);
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, cgp.fInPosition->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, cgp.kInPosition.name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- cgp.fInPosition->asShaderVar(),
+ cgp.kInPosition.asShaderVar(),
cgp.fLocalMatrix,
args.fFPCoordTransformHandler);
@@ -181,22 +174,22 @@ private:
fragBuilder->codeAppend("edgeAlpha *= innerAlpha;");
}
- if (cgp.fInClipPlane) {
+ if (cgp.fInClipPlane.isInitialized()) {
fragBuilder->codeAppend(
"half clip = clamp(circleEdge.z * dot(circleEdge.xy, clipPlane.xy) + "
"clipPlane.z, 0.0, 1.0);");
- if (cgp.fInIsectPlane) {
+ if (cgp.fInIsectPlane.isInitialized()) {
fragBuilder->codeAppend(
"clip *= clamp(circleEdge.z * dot(circleEdge.xy, isectPlane.xy) + "
"isectPlane.z, 0.0, 1.0);");
}
- if (cgp.fInUnionPlane) {
+ if (cgp.fInUnionPlane.isInitialized()) {
fragBuilder->codeAppend(
"clip += (1.0 - clip)*clamp(circleEdge.z * dot(circleEdge.xy, "
"unionPlane.xy) + unionPlane.z, 0.0, 1.0);");
}
fragBuilder->codeAppend("edgeAlpha *= clip;");
- if (cgp.fInRoundCapCenters) {
+ if (cgp.fInRoundCapCenters.isInitialized()) {
// We compute coverage of the round caps as circles at the butt caps produced
// by the clip planes. The inverse of the clip planes is applied so that there
// is no double counting.
@@ -220,10 +213,10 @@ private:
uint16_t key;
key = cgp.fStroke ? 0x01 : 0x0;
key |= cgp.fLocalMatrix.hasPerspective() ? 0x02 : 0x0;
- key |= cgp.fInClipPlane ? 0x04 : 0x0;
- key |= cgp.fInIsectPlane ? 0x08 : 0x0;
- key |= cgp.fInUnionPlane ? 0x10 : 0x0;
- key |= cgp.fInRoundCapCenters ? 0x20 : 0x0;
+ key |= cgp.fInClipPlane.isInitialized() ? 0x04 : 0x0;
+ key |= cgp.fInIsectPlane.isInitialized() ? 0x08 : 0x0;
+ key |= cgp.fInUnionPlane.isInitialized() ? 0x10 : 0x0;
+ key |= cgp.fInRoundCapCenters.isInitialized() ? 0x20 : 0x0;
b->add32(key);
}
@@ -237,19 +230,31 @@ private:
typedef GrGLSLGeometryProcessor INHERITED;
};
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthInitializedAttribute(i, kInPosition, kInColor, kInCircleEdge, fInClipPlane,
+ fInIsectPlane, fInUnionPlane, fInRoundCapCenters);
+ }
+
SkMatrix fLocalMatrix;
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInCircleEdge;
- const Attribute* fInClipPlane;
- const Attribute* fInIsectPlane;
- const Attribute* fInUnionPlane;
- const Attribute* fInRoundCapCenters;
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInCircleEdge = {"inCircleEdge", kFloat4_GrVertexAttribType};
+
+ // Optional attributes.
+ Attribute fInClipPlane;
+ Attribute fInIsectPlane;
+ Attribute fInUnionPlane;
+ Attribute fInRoundCapCenters;
+
bool fStroke;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute CircleGeometryProcessor::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute CircleGeometryProcessor::kInColor;
+constexpr GrPrimitiveProcessor::Attribute CircleGeometryProcessor::kInCircleEdge;
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleGeometryProcessor);
@@ -270,10 +275,7 @@ class ButtCapDashedCircleGeometryProcessor : public GrGeometryProcessor {
public:
ButtCapDashedCircleGeometryProcessor(const SkMatrix& localMatrix)
: INHERITED(kButtCapStrokedCircleGeometryProcessor_ClassID), fLocalMatrix(localMatrix) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInCircleEdge = &this->addVertexAttrib("inCircleEdge", kFloat4_GrVertexAttribType);
- fInDashParams = &this->addVertexAttrib("inDashParams", kFloat4_GrVertexAttribType);
+ this->setVertexAttributeCnt(4);
}
~ButtCapDashedCircleGeometryProcessor() override {}
@@ -304,11 +306,11 @@ private:
// emit attributes
varyingHandler->emitAttributes(bcscgp);
fragBuilder->codeAppend("float4 circleEdge;");
- varyingHandler->addPassThroughAttribute(bcscgp.fInCircleEdge, "circleEdge");
+ varyingHandler->addPassThroughAttribute(bcscgp.kInCircleEdge, "circleEdge");
fragBuilder->codeAppend("float4 dashParams;");
varyingHandler->addPassThroughAttribute(
- bcscgp.fInDashParams, "dashParams",
+ bcscgp.kInDashParams, "dashParams",
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
GrGLSLVarying wrapDashes(kHalf4_GrSLType);
varyingHandler->addVarying("wrapDashes", &wrapDashes,
@@ -316,7 +318,7 @@ private:
GrGLSLVarying lastIntervalLength(kHalf_GrSLType);
varyingHandler->addVarying("lastIntervalLength", &lastIntervalLength,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
- vertBuilder->codeAppendf("float4 dashParams = %s;", bcscgp.fInDashParams->name());
+ vertBuilder->codeAppendf("float4 dashParams = %s;", bcscgp.kInDashParams.name());
// Our fragment shader works in on/off intervals as specified by dashParams.xy:
// x = length of on interval, y = length of on + off.
// There are two other parameters in dashParams.zw:
@@ -378,17 +380,17 @@ private:
// setup pass through color
varyingHandler->addPassThroughAttribute(
- bcscgp.fInColor, args.fOutputColor,
+ bcscgp.kInColor, args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, bcscgp.fInPosition->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, bcscgp.kInPosition.name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- bcscgp.fInPosition->asShaderVar(),
+ bcscgp.kInPosition.asShaderVar(),
bcscgp.fLocalMatrix,
args.fFPCoordTransformHandler);
GrShaderVar fnArgs[] = {
@@ -482,16 +484,24 @@ private:
typedef GrGLSLGeometryProcessor INHERITED;
};
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInColor, kInCircleEdge, kInDashParams);
+ }
+
SkMatrix fLocalMatrix;
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInCircleEdge;
- const Attribute* fInDashParams;
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInCircleEdge = {"inCircleEdge", kFloat4_GrVertexAttribType};
+ static constexpr Attribute kInDashParams = {"inDashParams", kFloat4_GrVertexAttribType};
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute ButtCapDashedCircleGeometryProcessor::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute ButtCapDashedCircleGeometryProcessor::kInColor;
+constexpr GrPrimitiveProcessor::Attribute ButtCapDashedCircleGeometryProcessor::kInCircleEdge;
+constexpr GrPrimitiveProcessor::Attribute ButtCapDashedCircleGeometryProcessor::kInDashParams;
#if GR_TEST_UTILS
sk_sp<GrGeometryProcessor> ButtCapDashedCircleGeometryProcessor::TestCreate(GrProcessorTestData* d) {
@@ -515,10 +525,7 @@ public:
EllipseGeometryProcessor(bool stroke, const SkMatrix& localMatrix)
: INHERITED(kEllipseGeometryProcessor_ClassID)
, fLocalMatrix(localMatrix) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInEllipseOffset = &this->addVertexAttrib("inEllipseOffset", kHalf2_GrVertexAttribType);
- fInEllipseRadii = &this->addVertexAttrib("inEllipseRadii", kHalf4_GrVertexAttribType);
+ this->setVertexAttributeCnt(4);
fStroke = stroke;
}
@@ -551,24 +558,24 @@ private:
GrGLSLVarying ellipseOffsets(kHalf2_GrSLType);
varyingHandler->addVarying("EllipseOffsets", &ellipseOffsets);
vertBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
- egp.fInEllipseOffset->name());
+ egp.kInEllipseOffset.name());
GrGLSLVarying ellipseRadii(kHalf4_GrSLType);
varyingHandler->addVarying("EllipseRadii", &ellipseRadii);
- vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), egp.fInEllipseRadii->name());
+ vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), egp.kInEllipseRadii.name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// setup pass through color
- varyingHandler->addPassThroughAttribute(egp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(egp.kInColor, args.fOutputColor);
// Setup position
- this->writeOutputPosition(vertBuilder, gpArgs, egp.fInPosition->name());
+ this->writeOutputPosition(vertBuilder, gpArgs, egp.kInPosition.name());
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- egp.fInPosition->asShaderVar(),
+ egp.kInPosition.asShaderVar(),
egp.fLocalMatrix,
args.fFPCoordTransformHandler);
@@ -616,10 +623,15 @@ private:
typedef GrGLSLGeometryProcessor INHERITED;
};
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInEllipseOffset;
- const Attribute* fInEllipseRadii;
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInColor, kInEllipseOffset, kInEllipseRadii);
+ }
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInEllipseOffset = {"inEllipseOffset", kHalf2_GrVertexAttribType};
+ static constexpr Attribute kInEllipseRadii = {"inEllipseRadii", kHalf4_GrVertexAttribType};
+
SkMatrix fLocalMatrix;
bool fStroke;
@@ -627,6 +639,10 @@ private:
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute EllipseGeometryProcessor::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute EllipseGeometryProcessor::kInColor;
+constexpr GrPrimitiveProcessor::Attribute EllipseGeometryProcessor::kInEllipseOffset;
+constexpr GrPrimitiveProcessor::Attribute EllipseGeometryProcessor::kInEllipseRadii;
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseGeometryProcessor);
@@ -655,11 +671,8 @@ public:
DIEllipseGeometryProcessor(const SkMatrix& viewMatrix, DIEllipseStyle style)
: INHERITED(kDIEllipseGeometryProcessor_ClassID)
, fViewMatrix(viewMatrix) {
- fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
- fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
- fInEllipseOffsets0 = &this->addVertexAttrib("inEllipseOffsets0", kHalf2_GrVertexAttribType);
- fInEllipseOffsets1 = &this->addVertexAttrib("inEllipseOffsets1", kHalf2_GrVertexAttribType);
fStyle = style;
+ this->setVertexAttributeCnt(4);
}
~DIEllipseGeometryProcessor() override {}
@@ -690,22 +703,20 @@ private:
GrGLSLVarying offsets0(kHalf2_GrSLType);
varyingHandler->addVarying("EllipseOffsets0", &offsets0);
- vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
- diegp.fInEllipseOffsets0->name());
+ vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), diegp.kInEllipseOffsets0.name());
GrGLSLVarying offsets1(kHalf2_GrSLType);
varyingHandler->addVarying("EllipseOffsets1", &offsets1);
- vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
- diegp.fInEllipseOffsets1->name());
+ vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), diegp.kInEllipseOffsets1.name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- varyingHandler->addPassThroughAttribute(diegp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(diegp.kInColor, args.fOutputColor);
// Setup position
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
- diegp.fInPosition->name(),
+ diegp.kInPosition.name(),
diegp.fViewMatrix,
&fViewMatrixUniform);
@@ -713,7 +724,7 @@ private:
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
- diegp.fInPosition->asShaderVar(),
+ diegp.kInPosition.asShaderVar(),
args.fFPCoordTransformHandler);
// for outer curve
@@ -784,10 +795,17 @@ private:
typedef GrGLSLGeometryProcessor INHERITED;
};
- const Attribute* fInPosition;
- const Attribute* fInColor;
- const Attribute* fInEllipseOffsets0;
- const Attribute* fInEllipseOffsets1;
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kInPosition, kInColor, kInEllipseOffsets0, kInEllipseOffsets1);
+ }
+
+ static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
+ static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
+ static constexpr Attribute kInEllipseOffsets0 = {"inEllipseOffsets0",
+ kHalf2_GrVertexAttribType};
+ static constexpr Attribute kInEllipseOffsets1 = {"inEllipseOffsets1",
+ kHalf2_GrVertexAttribType};
+
SkMatrix fViewMatrix;
DIEllipseStyle fStyle;
@@ -795,6 +813,10 @@ private:
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute DIEllipseGeometryProcessor::kInPosition;
+constexpr GrPrimitiveProcessor::Attribute DIEllipseGeometryProcessor::kInColor;
+constexpr GrPrimitiveProcessor::Attribute DIEllipseGeometryProcessor::kInEllipseOffsets0;
+constexpr GrPrimitiveProcessor::Attribute DIEllipseGeometryProcessor::kInEllipseOffsets1;
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor);
@@ -1144,11 +1166,11 @@ private:
auto vertexCapCenters = [numPlanes](CircleVertex* v) {
return (void*)(v->fHalfPlanes + numPlanes);
};
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(CircleVertex) - (fClipPlane ? 0 : 3 * sizeof(SkScalar)) -
- (fClipPlaneIsect ? 0 : 3 * sizeof(SkScalar)) -
- (fClipPlaneUnion ? 0 : 3 * sizeof(SkScalar)) +
- (fRoundCaps ? 2 * sizeof(SkPoint) : 0));
+ size_t vertexStride = sizeof(CircleVertex) - (fClipPlane ? 0 : 3 * sizeof(SkScalar)) -
+ (fClipPlaneIsect ? 0 : 3 * sizeof(SkScalar)) -
+ (fClipPlaneUnion ? 0 : 3 * sizeof(SkScalar)) +
+ (fRoundCaps ? 2 * sizeof(SkPoint) : 0);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
const GrBuffer* vertexBuffer;
int firstVertex;
@@ -1632,12 +1654,12 @@ private:
SkScalar fPhaseAngle;
};
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(CircleVertex));
+ static constexpr size_t kVertexStride = sizeof(CircleVertex);
+ SkASSERT(kVertexStride == gp->debugOnly_vertexStride());
const GrBuffer* vertexBuffer;
int firstVertex;
- char* vertices = (char*)target->makeVertexSpace(vertexStride, fVertCount, &vertexBuffer,
+ char* vertices = (char*)target->makeVertexSpace(kVertexStride, fVertCount, &vertexBuffer,
&firstVertex);
if (!vertices) {
SkDebugf("Could not allocate vertices\n");
@@ -1688,7 +1710,7 @@ private:
SkPoint center = SkPoint::Make(bounds.centerX(), bounds.centerY());
SkScalar halfWidth = 0.5f * bounds.width();
auto init_outer_vertex = [&](int idx, SkScalar x, SkScalar y) {
- CircleVertex* v = reinterpret_cast<CircleVertex*>(vertices + idx * vertexStride);
+ CircleVertex* v = reinterpret_cast<CircleVertex*>(vertices + idx * kVertexStride);
v->fPos = center + SkPoint{x * halfWidth, y * halfWidth};
v->fOffset = {x, y};
init_const_attrs_and_reflect(v);
@@ -1706,7 +1728,7 @@ private:
// Compute the vertices of the inner octagon.
auto init_inner_vertex = [&](int idx, SkScalar x, SkScalar y) {
CircleVertex* v =
- reinterpret_cast<CircleVertex*>(vertices + (idx + 8) * vertexStride);
+ reinterpret_cast<CircleVertex*>(vertices + (idx + 8) * kVertexStride);
v->fPos = center + SkPoint{x * circle.fInnerRadius, y * circle.fInnerRadius};
v->fOffset = {x * normInnerRadius, y * normInnerRadius};
init_const_attrs_and_reflect(v);
@@ -1732,7 +1754,7 @@ private:
}
currStartVertex += circle_type_to_vert_count(true);
- vertices += circle_type_to_vert_count(true) * vertexStride;
+ vertices += circle_type_to_vert_count(true) * kVertexStride;
}
GrMesh mesh(GrPrimitiveType::kTriangles);
@@ -1934,10 +1956,9 @@ private:
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
QuadHelper helper;
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(EllipseVertex));
+ SkASSERT(sizeof(EllipseVertex) == gp->debugOnly_vertexStride());
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
- helper.init(target, vertexStride, fEllipses.count()));
+ helper.init(target, sizeof(EllipseVertex), fEllipses.count()));
if (!verts) {
return;
}
@@ -2163,11 +2184,10 @@ private:
sk_sp<GrGeometryProcessor> gp(
new DIEllipseGeometryProcessor(this->viewMatrix(), this->style()));
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(DIEllipseVertex));
+ SkASSERT(sizeof(DIEllipseVertex) == gp->debugOnly_vertexStride());
QuadHelper helper;
DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(
- helper.init(target, vertexStride, fEllipses.count()));
+ helper.init(target, sizeof(DIEllipseVertex), fEllipses.count()));
if (!verts) {
return;
}
@@ -2578,14 +2598,13 @@ private:
sk_sp<GrGeometryProcessor> gp(
new CircleGeometryProcessor(!fAllFill, false, false, false, false, localMatrix));
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(sizeof(CircleVertex) == vertexStride);
+ SkASSERT(sizeof(CircleVertex) == gp->debugOnly_vertexStride());
const GrBuffer* vertexBuffer;
int firstVertex;
- CircleVertex* verts = (CircleVertex*)target->makeVertexSpace(vertexStride, fVertCount,
- &vertexBuffer, &firstVertex);
+ CircleVertex* verts = (CircleVertex*)target->makeVertexSpace(
+ sizeof(CircleVertex), fVertCount, &vertexBuffer, &firstVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -2867,8 +2886,7 @@ private:
// Setup geometry processor
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(EllipseVertex));
+ SkASSERT(sizeof(EllipseVertex) == gp->debugOnly_vertexStride());
// drop out the middle quad if we're stroked
int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerFillRRect;
@@ -2877,8 +2895,8 @@ private:
PatternHelper helper(GrPrimitiveType::kTriangles);
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
- helper.init(target, vertexStride, indexBuffer.get(), kVertsPerStandardRRect,
- indicesPerInstance, fRRects.count()));
+ helper.init(target, sizeof(EllipseVertex), indexBuffer.get(),
+ kVertsPerStandardRRect, indicesPerInstance, fRRects.count()));
if (!verts || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp
index 9e81d66730..9a9814e0be 100644
--- a/src/gpu/ops/GrRegionOp.cpp
+++ b/src/gpu/ops/GrRegionOp.cpp
@@ -115,7 +115,8 @@ private:
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
}
- SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
+ static constexpr size_t kVertexStride = sizeof(GrDefaultGeoProcFactory::PositionColorAttr);
+ SkASSERT(kVertexStride == gp->debugOnly_vertexStride());
int numRegions = fRegions.count();
int numRects = 0;
@@ -126,12 +127,10 @@ private:
if (!numRects) {
return;
}
- size_t vertexStride = gp->getVertexStride();
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles);
- void* vertices =
- helper.init(target, vertexStride, indexBuffer.get(), kVertsPerInstance,
- kIndicesPerInstance, numRects);
+ void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerInstance,
+ kIndicesPerInstance, numRects);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -139,9 +138,9 @@ private:
intptr_t verts = reinterpret_cast<intptr_t>(vertices);
for (int i = 0; i < numRegions; i++) {
- tesselate_region(verts, vertexStride, fRegions[i].fColor, fRegions[i].fRegion);
+ tesselate_region(verts, kVertexStride, fRegions[i].fColor, fRegions[i].fRegion);
int numRectsInRegion = fRegions[i].fRegion.computeRegionComplexity();
- verts += numRectsInRegion * kVertsPerInstance * vertexStride;
+ verts += numRectsInRegion * kVertsPerInstance * kVertexStride;
}
helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
}
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index f61d11dd53..afb084dc36 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -576,13 +576,12 @@ private:
sk_sp<GrGeometryProcessor> gp = GrRRectShadowGeoProc::Make();
int instanceCount = fGeoData.count();
- size_t vertexStride = gp->getVertexStride();
- SkASSERT(sizeof(CircleVertex) == vertexStride);
+ SkASSERT(sizeof(CircleVertex) == gp->debugOnly_vertexStride());
const GrBuffer* vertexBuffer;
int firstVertex;
- CircleVertex* verts = (CircleVertex*)target->makeVertexSpace(vertexStride, fVertCount,
- &vertexBuffer, &firstVertex);
+ CircleVertex* verts = (CircleVertex*)target->makeVertexSpace(
+ sizeof(CircleVertex), fVertCount, &vertexBuffer, &firstVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 4ffe47855e..a0c9f9cf2b 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -351,8 +351,9 @@ private:
}
// allocate vertices
- size_t vertexStride = flushInfo.fGeometryProcessor->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(GrColor) + 2*sizeof(uint16_t));
+ static constexpr size_t kVertexStride =
+ sizeof(SkPoint) + sizeof(GrColor) + 2 * sizeof(uint16_t);
+ SkASSERT(kVertexStride == flushInfo.fGeometryProcessor->debugOnly_vertexStride());
const GrBuffer* vertexBuffer;
@@ -361,7 +362,7 @@ private:
if (instanceCount > SK_MaxS32 / kVerticesPerQuad) {
return;
}
- void* vertices = target->makeVertexSpace(vertexStride,
+ void* vertices = target->makeVertexSpace(kVertexStride,
kVerticesPerQuad * instanceCount,
&vertexBuffer,
&flushInfo.fVertexOffset);
@@ -476,13 +477,9 @@ private:
auto uploadTarget = target->deferredUploadTarget();
fAtlas->setLastUseToken(shapeData->fID, uploadTarget->tokenTracker()->nextDrawToken());
- this->writePathVertices(fAtlas,
- offset,
- args.fColor,
- vertexStride,
- args.fViewMatrix,
- shapeData);
- offset += kVerticesPerQuad * vertexStride;
+ this->writePathVertices(
+ fAtlas, offset, args.fColor, kVertexStride, args.fViewMatrix, shapeData);
+ offset += kVerticesPerQuad * kVertexStride;
flushInfo.fInstancesToFlush++;
}
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index 51dac5adff..4c436c291d 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -237,7 +237,7 @@ private:
return path;
}
- void draw(Target* target, const GrGeometryProcessor* gp) {
+ void draw(Target* target, const GrGeometryProcessor* gp, size_t vertexStride) {
SkASSERT(!fAntiAlias);
GrResourceProvider* rp = target->resourceProvider();
bool inverseFill = fShape.inverseFilled();
@@ -274,7 +274,7 @@ private:
vmi.mapRect(&clipBounds);
bool isLinear;
bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags();
- StaticVertexAllocator allocator(gp->getVertexStride(), rp, canMapVB);
+ StaticVertexAllocator allocator(vertexStride, rp, canMapVB);
int count = GrTessellator::PathToTriangles(getPath(), tol, clipBounds, &allocator,
false, GrColor(), false, &isLinear);
if (count == 0) {
@@ -289,7 +289,7 @@ private:
fShape.addGenIDChangeListener(sk_make_sp<PathInvalidator>(key));
}
- void drawAA(Target* target, const GrGeometryProcessor* gp) {
+ void drawAA(Target* target, const GrGeometryProcessor* gp, size_t vertexStride) {
SkASSERT(fAntiAlias);
SkPath path = getPath();
if (path.isEmpty()) {
@@ -299,7 +299,7 @@ private:
path.transform(fViewMatrix);
SkScalar tol = GrPathUtils::kDefaultTolerance;
bool isLinear;
- DynamicVertexAllocator allocator(gp->getVertexStride(), target);
+ DynamicVertexAllocator allocator(vertexStride, target);
int count =
GrTessellator::PathToTriangles(path, tol, clipBounds, &allocator, true, fColor,
fHelper.compatibleWithAlphaAsCoverage(), &isLinear);
@@ -311,9 +311,12 @@ private:
void onPrepareDraws(Target* target) override {
sk_sp<GrGeometryProcessor> gp;
+ size_t vertexStride;
{
using namespace GrDefaultGeoProcFactory;
+ vertexStride = sizeof(SkPoint); // position
+
Color color(fColor);
LocalCoords::Type localCoordsType = fHelper.usesLocalCoords()
? LocalCoords::kUsePosition_Type
@@ -321,10 +324,12 @@ private:
Coverage::Type coverageType;
if (fAntiAlias) {
color = Color(Color::kPremulGrColorAttribute_Type);
+ vertexStride += sizeof(uint32_t);
if (fHelper.compatibleWithAlphaAsCoverage()) {
coverageType = Coverage::kSolid_Type;
} else {
coverageType = Coverage::kAttribute_Type;
+ vertexStride += 4;
}
} else {
coverageType = Coverage::kSolid_Type;
@@ -340,10 +345,11 @@ private:
if (!gp.get()) {
return;
}
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
if (fAntiAlias) {
- this->drawAA(target, gp.get());
+ this->drawAA(target, gp.get(), vertexStride);
} else {
- this->draw(target, gp.get());
+ this->draw(target, gp.get(), vertexStride);
}
}
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index e06d94f806..a895230241 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -163,16 +163,14 @@ public:
args.fUniformHandler,
textureGP.fTextureCoords.asShaderVar(),
args.fFPCoordTransformHandler);
- args.fVaryingHandler->addPassThroughAttribute(&textureGP.fColors,
- args.fOutputColor,
- Interpolation::kCanBeFlat);
+ args.fVaryingHandler->addPassThroughAttribute(
+ textureGP.fColors, args.fOutputColor, Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppend("float2 texCoord;");
- args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureCoords,
- "texCoord");
+ args.fVaryingHandler->addPassThroughAttribute(textureGP.fTextureCoords, "texCoord");
if (textureGP.fDomain.isInitialized()) {
args.fFragBuilder->codeAppend("float4 domain;");
args.fVaryingHandler->addPassThroughAttribute(
- &textureGP.fDomain, "domain",
+ textureGP.fDomain, "domain",
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppend(
"texCoord = clamp(texCoord, domain.xy, domain.zw);");
@@ -182,7 +180,7 @@ public:
SkASSERT(kInt_GrVertexAttribType == textureGP.fTextureIdx.type());
SkASSERT(args.fShaderCaps->integerSupport());
args.fFragBuilder->codeAppend("int texIdx;");
- args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureIdx, "texIdx",
+ args.fVaryingHandler->addPassThroughAttribute(textureGP.fTextureIdx, "texIdx",
Interpolation::kMustBeFlat);
args.fFragBuilder->codeAppend("switch (texIdx) {");
for (int i = 0; i < textureGP.numTextureSamplers(); ++i) {
@@ -316,12 +314,13 @@ private:
}
if (perspective) {
- fPositions = this->addVertexAttrib("position", kFloat3_GrVertexAttribType);
+ fPositions = {"position", kFloat3_GrVertexAttribType};
} else {
- fPositions = this->addVertexAttrib("position", kFloat2_GrVertexAttribType);
+ fPositions = {"position", kFloat2_GrVertexAttribType};
}
- fColors = this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType);
- fTextureCoords = this->addVertexAttrib("textureCoords", kFloat2_GrVertexAttribType);
+ fColors = {"color", kUByte4_norm_GrVertexAttribType};
+ fTextureCoords = {"textureCoords", kFloat2_GrVertexAttribType};
+ int vertexAttributeCnt = 3;
if (samplerCnt > 1) {
// Here we initialize any extra samplers by repeating the last one samplerCnt - proxyCnt
@@ -332,17 +331,26 @@ private:
this->addTextureSampler(&fSamplers[i]);
}
SkASSERT(caps.integerSupport());
- fTextureIdx = this->addVertexAttrib("textureIdx", kInt_GrVertexAttribType);
+ fTextureIdx = {"textureIdx", kInt_GrVertexAttribType};
+ ++vertexAttributeCnt;
}
if (domain == Domain::kYes) {
- fDomain = this->addVertexAttrib("domain", kFloat4_GrVertexAttribType);
+ fDomain = {"domain", kFloat4_GrVertexAttribType};
+ ++vertexAttributeCnt;
}
if (coverageAA) {
- fAAEdges[0] = this->addVertexAttrib("aaEdge0", kFloat3_GrVertexAttribType);
- fAAEdges[1] = this->addVertexAttrib("aaEdge1", kFloat3_GrVertexAttribType);
- fAAEdges[2] = this->addVertexAttrib("aaEdge2", kFloat3_GrVertexAttribType);
- fAAEdges[3] = this->addVertexAttrib("aaEdge3", kFloat3_GrVertexAttribType);
+ fAAEdges[0] = {"aaEdge0", kFloat3_GrVertexAttribType};
+ fAAEdges[1] = {"aaEdge1", kFloat3_GrVertexAttribType};
+ fAAEdges[2] = {"aaEdge2", kFloat3_GrVertexAttribType};
+ fAAEdges[3] = {"aaEdge3", kFloat3_GrVertexAttribType};
+ vertexAttributeCnt += 4;
}
+ this->setVertexAttributeCnt(vertexAttributeCnt);
+ }
+
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthInitializedAttribute(i, fPositions, fColors, fTextureCoords, fTextureIdx, fDomain,
+ fAAEdges[0], fAAEdges[1], fAAEdges[2], fAAEdges[3]);
}
Attribute fPositions;
@@ -746,7 +754,7 @@ __attribute__((no_sanitize("float-cast-overflow")))
template <typename Pos, MultiTexture MT, Domain D, GrAA AA>
void tess(void* v, const float iw[], const float ih[], const GrGeometryProcessor* gp) {
using Vertex = TextureGeometryProcessor::Vertex<Pos, MT, D, AA>;
- SkASSERT(gp->getVertexStride() == sizeof(Vertex));
+ SkASSERT(gp->debugOnly_vertexStride() == sizeof(Vertex));
auto vertices = static_cast<Vertex*>(v);
auto proxies = this->proxies();
auto filters = this->filters();
@@ -787,10 +795,47 @@ __attribute__((no_sanitize("float-cast-overflow")))
const GrPipeline* pipeline = target->allocPipeline(args, GrProcessorSet::MakeEmptySet(),
target->detachAppliedClip());
+ using TessFn =
+ decltype(&TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kNo>);
+#define TESS_FN_AND_VERTEX_SIZE(Point, MT, Domain, AA) \
+ { \
+ &TextureOp::tess<Point, MT, Domain, AA>, \
+ sizeof(TextureGeometryProcessor::Vertex<Point, MT, Domain, AA>) \
+ }
+ static constexpr struct {
+ TessFn fTessFn;
+ size_t fVertexSize;
+ } kTessFnsAndVertexSizes[] = {
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kNo, Domain::kYes, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kNo, Domain::kYes, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kYes, Domain::kNo, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kYes, Domain::kNo, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kYes, Domain::kYes, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint, MultiTexture::kYes, Domain::kYes, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kNo, Domain::kNo, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kNo, Domain::kNo, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kNo, Domain::kYes, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kNo, Domain::kYes, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kYes, Domain::kNo, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kYes, Domain::kNo, GrAA::kYes),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kYes, Domain::kYes, GrAA::kNo),
+ TESS_FN_AND_VERTEX_SIZE(SkPoint3, MultiTexture::kYes, Domain::kYes, GrAA::kYes),
+ };
+#undef TESS_FN_AND_VERTEX_SIZE
+ int tessFnIdx = 0;
+ tessFnIdx |= coverageAA ? 0x1 : 0x0;
+ tessFnIdx |= fDomain ? 0x2 : 0x0;
+ tessFnIdx |= (fProxyCnt > 1) ? 0x4 : 0x0;
+ tessFnIdx |= fPerspective ? 0x8 : 0x0;
+
+ SkASSERT(kTessFnsAndVertexSizes[tessFnIdx].fVertexSize == gp->debugOnly_vertexStride());
+
int vstart;
const GrBuffer* vbuffer;
- void* vdata = target->makeVertexSpace(gp->getVertexStride(), 4 * fDraws.count(), &vbuffer,
- &vstart);
+ void* vdata = target->makeVertexSpace(kTessFnsAndVertexSizes[tessFnIdx].fVertexSize,
+ 4 * fDraws.count(), &vbuffer, &vstart);
if (!vdata) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -804,32 +849,7 @@ __attribute__((no_sanitize("float-cast-overflow")))
ih[t] = 1.f / texture->height();
}
- using TessFn =
- decltype(&TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kNo>);
- static constexpr TessFn kTessFns[] = {
- &TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kNo>,
- &TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kYes>,
- &TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kYes, GrAA::kNo>,
- &TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kYes, GrAA::kYes>,
- &TextureOp::tess<SkPoint, MultiTexture::kYes, Domain::kNo, GrAA::kNo>,
- &TextureOp::tess<SkPoint, MultiTexture::kYes, Domain::kNo, GrAA::kYes>,
- &TextureOp::tess<SkPoint, MultiTexture::kYes, Domain::kYes, GrAA::kNo>,
- &TextureOp::tess<SkPoint, MultiTexture::kYes, Domain::kYes, GrAA::kYes>,
- &TextureOp::tess<SkPoint3, MultiTexture::kNo, Domain::kNo, GrAA::kNo>,
- &TextureOp::tess<SkPoint3, MultiTexture::kNo, Domain::kNo, GrAA::kYes>,
- &TextureOp::tess<SkPoint3, MultiTexture::kNo, Domain::kYes, GrAA::kNo>,
- &TextureOp::tess<SkPoint3, MultiTexture::kNo, Domain::kYes, GrAA::kYes>,
- &TextureOp::tess<SkPoint3, MultiTexture::kYes, Domain::kNo, GrAA::kNo>,
- &TextureOp::tess<SkPoint3, MultiTexture::kYes, Domain::kNo, GrAA::kYes>,
- &TextureOp::tess<SkPoint3, MultiTexture::kYes, Domain::kYes, GrAA::kNo>,
- &TextureOp::tess<SkPoint3, MultiTexture::kYes, Domain::kYes, GrAA::kYes>,
- };
- int tessFnIdx = 0;
- tessFnIdx |= coverageAA ? 0x1 : 0x0;
- tessFnIdx |= fDomain ? 0x2 : 0x0;
- tessFnIdx |= (fProxyCnt > 1) ? 0x4 : 0x0;
- tessFnIdx |= fPerspective ? 0x8 : 0x0;
- (this->*(kTessFns[tessFnIdx]))(vdata, iw, ih, gp.get());
+ (this->*(kTessFnsAndVertexSizes[tessFnIdx].fTessFn))(vdata, iw, ih, gp.get());
GrPrimitiveType primitiveType =
fDraws.count() > 1 ? GrPrimitiveType::kTriangles : GrPrimitiveType::kTriangleStrip;
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index 500ab967cc..c5b4592950 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -59,37 +59,58 @@ static void setup_vertex_input_state(const GrPrimitiveProcessor& primProc,
VkVertexInputAttributeDescription* attributeDesc) {
uint32_t vertexBinding = 0, instanceBinding = 0;
- if (primProc.hasVertexAttribs()) {
- vertexBinding = bindingDescs->count();
- bindingDescs->push_back() = {
- vertexBinding,
- (uint32_t) primProc.getVertexStride(),
- VK_VERTEX_INPUT_RATE_VERTEX
- };
+ int nextBinding = bindingDescs->count();
+ if (primProc.hasVertexAttributes()) {
+ vertexBinding = nextBinding++;
}
- if (primProc.hasInstanceAttribs()) {
- instanceBinding = bindingDescs->count();
- bindingDescs->push_back() = {
- instanceBinding,
- (uint32_t) primProc.getInstanceStride(),
- VK_VERTEX_INPUT_RATE_INSTANCE
- };
+ if (primProc.hasInstanceAttributes()) {
+ instanceBinding = nextBinding;
}
// setup attribute descriptions
- int vaCount = primProc.numAttribs();
- if (vaCount > 0) {
- for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) {
- using InputRate = GrPrimitiveProcessor::Attribute::InputRate;
- const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(attribIndex);
- VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
- vkAttrib.location = attribIndex; // for now assume location = attribIndex
- vkAttrib.binding =
- InputRate::kPerInstance == attrib.inputRate() ? instanceBinding : vertexBinding;
- vkAttrib.format = attrib_type_to_vkformat(attrib.type());
- vkAttrib.offset = attrib.offsetInRecord();
- }
+ int vaCount = primProc.numVertexAttributes();
+ int attribIndex = 0;
+ size_t vertexAttributeOffset = 0;
+ for (; attribIndex < vaCount; attribIndex++) {
+ const GrGeometryProcessor::Attribute& attrib = primProc.vertexAttribute(attribIndex);
+ VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
+ vkAttrib.location = attribIndex; // for now assume location = attribIndex
+ vkAttrib.binding = vertexBinding;
+ vkAttrib.format = attrib_type_to_vkformat(attrib.type());
+ vkAttrib.offset = vertexAttributeOffset;
+ SkASSERT(vkAttrib.offset == primProc.debugOnly_vertexAttributeOffset(attribIndex));
+ vertexAttributeOffset += attrib.sizeAlign4();
+ }
+ SkASSERT(vertexAttributeOffset == primProc.debugOnly_vertexStride());
+
+ int iaCount = primProc.numInstanceAttributes();
+ size_t instanceAttributeOffset = 0;
+ for (int iaIndex = 0; iaIndex < iaCount; ++iaIndex, ++attribIndex) {
+ const GrGeometryProcessor::Attribute& attrib = primProc.instanceAttribute(iaIndex);
+ VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
+ vkAttrib.location = attribIndex; // for now assume location = attribIndex
+ vkAttrib.binding = instanceBinding;
+ vkAttrib.format = attrib_type_to_vkformat(attrib.type());
+ vkAttrib.offset = instanceAttributeOffset;
+ SkASSERT(vkAttrib.offset == primProc.debugOnly_instanceAttributeOffset(iaIndex));
+ instanceAttributeOffset += attrib.sizeAlign4();
+ }
+ SkASSERT(instanceAttributeOffset == primProc.debugOnly_instanceStride());
+
+ if (primProc.hasVertexAttributes()) {
+ bindingDescs->push_back() = {
+ vertexBinding,
+ (uint32_t) vertexAttributeOffset,
+ VK_VERTEX_INPUT_RATE_VERTEX
+ };
+ }
+ if (primProc.hasInstanceAttributes()) {
+ bindingDescs->push_back() = {
+ instanceBinding,
+ (uint32_t) instanceAttributeOffset,
+ VK_VERTEX_INPUT_RATE_INSTANCE
+ };
}
memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo));
@@ -98,7 +119,7 @@ static void setup_vertex_input_state(const GrPrimitiveProcessor& primProc,
vertexInputInfo->flags = 0;
vertexInputInfo->vertexBindingDescriptionCount = bindingDescs->count();
vertexInputInfo->pVertexBindingDescriptions = bindingDescs->begin();
- vertexInputInfo->vertexAttributeDescriptionCount = vaCount;
+ vertexInputInfo->vertexAttributeDescriptionCount = vaCount + iaCount;
vertexInputInfo->pVertexAttributeDescriptions = attributeDesc;
}
@@ -432,8 +453,9 @@ GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline,
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs;
SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc;
- SkASSERT(primProc.numAttribs() <= gpu->vkCaps().maxVertexAttributes());
- VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(primProc.numAttribs());
+ int totalAttributeCnt = primProc.numVertexAttributes() + primProc.numInstanceAttributes();
+ SkASSERT(totalAttributeCnt <= gpu->vkCaps().maxVertexAttributes());
+ VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(totalAttributeCnt);
setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDescs, pAttribs);
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index 4d9773b1a9..f95dbc8603 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -294,35 +294,46 @@ private:
class GrMeshTestProcessor : public GrGeometryProcessor {
public:
GrMeshTestProcessor(bool instanced, bool hasVertexBuffer)
- : INHERITED(kGrMeshTestProcessor_ClassID)
- , fInstanceLocation(nullptr)
- , fVertex(nullptr)
- , fColor(nullptr) {
+ : INHERITED(kGrMeshTestProcessor_ClassID) {
if (instanced) {
- fInstanceLocation = &this->addInstanceAttrib("location", kHalf2_GrVertexAttribType);
+ fInstanceLocation = {"location", kHalf2_GrVertexAttribType};
+ fColor = {"color", kUByte4_norm_GrVertexAttribType};
+ this->setInstanceAttributeCnt(2);
if (hasVertexBuffer) {
- fVertex = &this->addVertexAttrib("vertex", kHalf2_GrVertexAttribType);
+ fVertex = {"vertex", kHalf2_GrVertexAttribType};
+ this->setVertexAttributeCnt(1);
}
- fColor = &this->addInstanceAttrib("color", kUByte4_norm_GrVertexAttribType);
} else {
- fVertex = &this->addVertexAttrib("vertex", kHalf2_GrVertexAttribType);
- fColor = &this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType);
+ fVertex = {"vertex", kHalf2_GrVertexAttribType};
+ fColor = {"color", kUByte4_norm_GrVertexAttribType};
+ this->setVertexAttributeCnt(2);
}
}
const char* name() const override { return "GrMeshTest Processor"; }
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const final {
- b->add32(SkToBool(fInstanceLocation));
- b->add32(SkToBool(fVertex));
+ b->add32(fInstanceLocation.isInitialized());
+ b->add32(fVertex.isInitialized());
}
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
-protected:
- const Attribute* fInstanceLocation;
- const Attribute* fVertex;
- const Attribute* fColor;
+private:
+ const Attribute& onVertexAttribute(int i) const override {
+ if (fInstanceLocation.isInitialized()) {
+ return fVertex;
+ }
+ return IthAttribute(i, fVertex, fColor);
+ }
+
+ const Attribute& onInstanceAttribute(int i) const override {
+ return IthAttribute(i, fInstanceLocation, fColor);
+ }
+
+ Attribute fInstanceLocation;
+ Attribute fVertex;
+ Attribute fColor;
friend class GLSLMeshTestProcessor;
typedef GrGeometryProcessor INHERITED;
@@ -340,15 +351,15 @@ class GLSLMeshTestProcessor : public GrGLSLGeometryProcessor {
varyingHandler->addPassThroughAttribute(mp.fColor, args.fOutputColor);
GrGLSLVertexBuilder* v = args.fVertBuilder;
- if (!mp.fInstanceLocation) {
- v->codeAppendf("float2 vertex = %s;", mp.fVertex->name());
+ if (!mp.fInstanceLocation.isInitialized()) {
+ v->codeAppendf("float2 vertex = %s;", mp.fVertex.name());
} else {
- if (mp.fVertex) {
- v->codeAppendf("float2 offset = %s;", mp.fVertex->name());
+ if (mp.fVertex.isInitialized()) {
+ v->codeAppendf("float2 offset = %s;", mp.fVertex.name());
} else {
v->codeAppend ("float2 offset = float2(sk_VertexID / 2, sk_VertexID % 2);");
}
- v->codeAppendf("float2 vertex = %s + offset * %i;", mp.fInstanceLocation->name(),
+ v->codeAppendf("float2 vertex = %s + offset * %i;", mp.fInstanceLocation.name(),
kBoxSize);
}
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex");
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index a197650c4f..b5bc74d382 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -58,9 +58,9 @@ struct Vertex {
class GrPipelineDynamicStateTestProcessor : public GrGeometryProcessor {
public:
GrPipelineDynamicStateTestProcessor()
- : INHERITED(kGrPipelineDynamicStateTestProcessor_ClassID)
- , fVertex(this->addVertexAttrib("vertex", kHalf2_GrVertexAttribType))
- , fColor(this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType)) {}
+ : INHERITED(kGrPipelineDynamicStateTestProcessor_ClassID) {
+ this->setVertexAttributeCnt(2);
+ }
const char* name() const override { return "GrPipelineDynamicStateTest Processor"; }
@@ -68,13 +68,19 @@ public:
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
-protected:
- const Attribute& fVertex;
- const Attribute& fColor;
+private:
+ const Attribute& onVertexAttribute(int i) const override {
+ return IthAttribute(i, kVertex, kColor);
+ }
+
+ static constexpr Attribute kVertex = {"vertex", kHalf2_GrVertexAttribType};
+ static constexpr Attribute kColor = {"color", kUByte4_norm_GrVertexAttribType};
friend class GLSLPipelineDynamicStateTestProcessor;
typedef GrGeometryProcessor INHERITED;
};
+constexpr GrPrimitiveProcessor::Attribute GrPipelineDynamicStateTestProcessor::kVertex;
+constexpr GrPrimitiveProcessor::Attribute GrPipelineDynamicStateTestProcessor::kColor;
class GLSLPipelineDynamicStateTestProcessor : public GrGLSLGeometryProcessor {
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
@@ -86,10 +92,10 @@ class GLSLPipelineDynamicStateTestProcessor : public GrGLSLGeometryProcessor {
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
varyingHandler->emitAttributes(mp);
- varyingHandler->addPassThroughAttribute(&mp.fColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(mp.kColor, args.fOutputColor);
GrGLSLVertexBuilder* v = args.fVertBuilder;
- v->codeAppendf("float2 vertex = %s;", mp.fVertex.name());
+ v->codeAppendf("float2 vertex = %s;", mp.kVertex.name());
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex");
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index e2f6fbf9e1..a8752057c8 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -110,11 +110,10 @@ private:
return;
}
- size_t vertexStride = gp->getVertexStride();
-
- SkASSERT(fHasLocalRect
- ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
- : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
+ size_t vertexStride = fHasLocalRect
+ ? sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
+ : sizeof(GrDefaultGeoProcFactory::PositionColorAttr);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
const GrBuffer* indexBuffer;
int firstIndex;
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index 74a73a66a9..60b2205cf7 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -59,15 +59,15 @@ private:
void onPrepareDraws(Target* target) override {
class GP : public GrGeometryProcessor {
public:
- GP(int numAttribs)
- : INHERITED(kGP_ClassID) {
+ GP(int numAttribs) : INHERITED(kGP_ClassID), fNumAttribs(numAttribs) {
SkASSERT(numAttribs > 1);
+ fAttribNames.reset(new SkString[numAttribs]);
+ fAttributes.reset(new Attribute[numAttribs]);
for (auto i = 0; i < numAttribs; ++i) {
- fAttribNames.push_back().printf("attr%d", i);
- }
- for (auto i = 0; i < numAttribs; ++i) {
- this->addVertexAttrib(fAttribNames[i].c_str(), kFloat2_GrVertexAttribType);
+ fAttribNames[i].printf("attr%d", i);
+ fAttributes[i] = {fAttribNames[i].c_str(), kFloat2_GrVertexAttribType};
}
+ this->setVertexAttributeCnt(numAttribs);
}
const char* name() const override { return "Dummy GP"; }
@@ -78,7 +78,7 @@ private:
const GP& gp = args.fGP.cast<GP>();
args.fVaryingHandler->emitAttributes(gp);
this->writeOutputPosition(args.fVertBuilder, gpArgs,
- gp.getAttrib(0).name());
+ gp.fAttributes[0].name());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputColor);
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
@@ -91,17 +91,24 @@ private:
}
void getGLSLProcessorKey(const GrShaderCaps&,
GrProcessorKeyBuilder* builder) const override {
- builder->add32(this->numAttribs());
+ builder->add32(fNumAttribs);
}
private:
- SkTArray<SkString> fAttribNames;
+ const GrPrimitiveProcessor::Attribute& onVertexAttribute(int i) const override {
+ return fAttributes[i];
+ }
+
+ int fNumAttribs;
+ std::unique_ptr<SkString[]> fAttribNames;
+ std::unique_ptr<Attribute[]> fAttributes;
typedef GrGeometryProcessor INHERITED;
};
sk_sp<GrGeometryProcessor> gp(new GP(fNumAttribs));
QuadHelper helper;
- size_t vertexStride = gp->getVertexStride();
+ size_t vertexStride = fNumAttribs * GrVertexAttribTypeSize(kFloat2_GrVertexAttribType);
+ SkASSERT(vertexStride == gp->debugOnly_vertexStride());
SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
SkPointPriv::SetRectTriStrip(vertices, 0.f, 0.f, 1.f, 1.f, vertexStride);
helper.recordDraw(target, gp.get(),