diff options
author | Brian Salomon <bsalomon@google.com> | 2018-06-18 12:52:47 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-18 17:13:58 +0000 |
commit | 19c1233c447f625c2522e7ecd0a0adecc629bb2f (patch) | |
tree | 891e06143986ade3aae8d4176ec8b426f70b896f /src/gpu/ccpr | |
parent | 146cf3ce7935019ecc63ce9e93450a8c122880d8 (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.h | 10 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp | 24 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp | 68 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPathProcessor.cpp | 36 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPathProcessor.h | 23 |
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; }; |