aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-06-18 12:52:47 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-18 17:13:58 +0000
commit19c1233c447f625c2522e7ecd0a0adecc629bb2f (patch)
tree891e06143986ade3aae8d4176ec8b426f70b896f /src/gpu/ccpr
parent146cf3ce7935019ecc63ce9e93450a8c122880d8 (diff)
Change how vertex/instance attributes are handled in geometry processors.
* No longer register vertex/instance attributes on base class, just counts * Separate instance and vertex attributes and remove InputRate and offset * Make attributes constexpr where possible Change-Id: I1f1d5e772fa177a96d2aeb805aab7b69f35bfae6 Reviewed-on: https://skia-review.googlesource.com/132405 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu/ccpr')
-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
5 files changed, 87 insertions, 74 deletions
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;
};