diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageOp.cpp | 28 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageOp.h | 9 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor.cpp | 26 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor.h | 145 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp | 48 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 28 |
6 files changed, 143 insertions, 141 deletions
diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.cpp b/src/gpu/ccpr/GrCCPRCoverageOp.cpp index 5775c5aa86..57b73bf935 100644 --- a/src/gpu/ccpr/GrCCPRCoverageOp.cpp +++ b/src/gpu/ccpr/GrCCPRCoverageOp.cpp @@ -393,32 +393,28 @@ void GrCCPRCoverageOp::onExecute(GrOpFlushState* flushState) { fDynamicStatesScratchBuffer.reserve(1 + fScissorBatches.count()); // Triangles. - auto constexpr kTrianglesGrPrimitiveType = GrCCPRCoverageProcessor::kTrianglesGrPrimitiveType; this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleHulls, - kTrianglesGrPrimitiveType, 3, &PrimitiveTallies::fTriangles); + &PrimitiveTallies::fTriangles); this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleEdges, - kTrianglesGrPrimitiveType, 3, &PrimitiveTallies::fTriangles); + &PrimitiveTallies::fTriangles); this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleCorners, - kTrianglesGrPrimitiveType, 3, &PrimitiveTallies::fTriangles); + &PrimitiveTallies::fTriangles); // Quadratics. - auto constexpr kQuadraticsGrPrimitiveType = GrCCPRCoverageProcessor::kQuadraticsGrPrimitiveType; this->drawMaskPrimitives(flushState, pipeline, RenderPass::kQuadraticHulls, - kQuadraticsGrPrimitiveType, 3, &PrimitiveTallies::fQuadratics); + &PrimitiveTallies::fQuadratics); this->drawMaskPrimitives(flushState, pipeline, RenderPass::kQuadraticCorners, - kQuadraticsGrPrimitiveType, 3, &PrimitiveTallies::fQuadratics); + &PrimitiveTallies::fQuadratics); // Cubics. - auto constexpr kCubicsGrPrimitiveType = GrCCPRCoverageProcessor::kCubicsGrPrimitiveType; this->drawMaskPrimitives(flushState, pipeline, RenderPass::kCubicHulls, - kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fCubics); + &PrimitiveTallies::fCubics); this->drawMaskPrimitives(flushState, pipeline, RenderPass::kCubicCorners, - kCubicsGrPrimitiveType, 4, &PrimitiveTallies::fCubics); + &PrimitiveTallies::fCubics); } void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPipeline& pipeline, GrCCPRCoverageProcessor::RenderPass renderPass, - GrPrimitiveType primType, int vertexCount, int PrimitiveTallies::* instanceType) const { using ScissorMode = GrCCPRCoverageOpsBuilder::ScissorMode; SkASSERT(pipeline.getScissorState().enabled()); @@ -426,11 +422,12 @@ void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPi fMeshesScratchBuffer.reset(); fDynamicStatesScratchBuffer.reset(); + GrCCPRCoverageProcessor proc(renderPass); + if (const int instanceCount = fInstanceCounts[(int)ScissorMode::kNonScissored].*instanceType) { SkASSERT(instanceCount > 0); const int baseInstance = fBaseInstances[(int)ScissorMode::kNonScissored].*instanceType; - GrMesh& mesh = fMeshesScratchBuffer.emplace_back(primType); - mesh.setInstanced(fInstanceBuffer.get(), instanceCount, baseInstance, vertexCount); + proc.appendMesh(fInstanceBuffer.get(), instanceCount, baseInstance, &fMeshesScratchBuffer); fDynamicStatesScratchBuffer.push_back().fScissorRect.setXYWH(0, 0, fDrawBounds.width(), fDrawBounds.height()); } @@ -444,8 +441,8 @@ void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPi continue; } SkASSERT(instanceCount > 0); - GrMesh& mesh = fMeshesScratchBuffer.emplace_back(primType); - mesh.setInstanced(fInstanceBuffer.get(), instanceCount, baseInstance, vertexCount); + proc.appendMesh(fInstanceBuffer.get(), instanceCount, baseInstance, + &fMeshesScratchBuffer); fDynamicStatesScratchBuffer.push_back().fScissorRect = batch.fScissor; baseInstance += instanceCount; } @@ -454,7 +451,6 @@ void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPi SkASSERT(fMeshesScratchBuffer.count() == fDynamicStatesScratchBuffer.count()); if (!fMeshesScratchBuffer.empty()) { - GrCCPRCoverageProcessor proc(renderPass); SkASSERT(flushState->rtCommandBuffer()); flushState->rtCommandBuffer()->draw(pipeline, proc, fMeshesScratchBuffer.begin(), fDynamicStatesScratchBuffer.begin(), diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.h b/src/gpu/ccpr/GrCCPRCoverageOp.h index 571e29a8cf..7957586958 100644 --- a/src/gpu/ccpr/GrCCPRCoverageOp.h +++ b/src/gpu/ccpr/GrCCPRCoverageOp.h @@ -158,9 +158,8 @@ private: const PrimitiveTallies baseInstances[kNumScissorModes], const PrimitiveTallies endInstances[kNumScissorModes]); - void drawMaskPrimitives(GrOpFlushState*, const GrPipeline&, - const GrCCPRCoverageProcessor::RenderPass, GrPrimitiveType, - int vertexCount, int PrimitiveTallies::* instanceType) const; + void drawMaskPrimitives(GrOpFlushState*, const GrPipeline&, GrCCPRCoverageProcessor::RenderPass, + int PrimitiveTallies::* instanceType) const; sk_sp<GrBuffer> fInstanceBuffer; PrimitiveTallies fBaseInstances[kNumScissorModes]; @@ -168,8 +167,8 @@ private: const SkTArray<ScissorBatch, true> fScissorBatches; const SkISize fDrawBounds; - mutable SkTArray<GrMesh> fMeshesScratchBuffer; - mutable SkTArray<GrPipeline::DynamicState> fDynamicStatesScratchBuffer; + mutable SkTArray<GrMesh, true> fMeshesScratchBuffer; + mutable SkTArray<GrPipeline::DynamicState, true> fDynamicStatesScratchBuffer; friend class GrCCPRCoverageOpsBuilder; diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp index 61e431a2c9..c7b80390e9 100644 --- a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp +++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp @@ -13,32 +13,6 @@ #include "ccpr/GrCCPRTriangleShader.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" -GrCCPRCoverageProcessor::GrCCPRCoverageProcessor(RenderPass renderPass) - : INHERITED(kGrCCPRCoverageProcessor_ClassID) - , fRenderPass(renderPass) { - if (RenderPassIsCubic(fRenderPass)) { - this->addInstanceAttrib("X", kFloat4_GrVertexAttribType); - this->addInstanceAttrib("Y", kFloat4_GrVertexAttribType); - - SkASSERT(offsetof(CubicInstance, fX) == - this->getInstanceAttrib(InstanceAttribs::kX).fOffsetInRecord); - SkASSERT(offsetof(CubicInstance, fY) == - this->getInstanceAttrib(InstanceAttribs::kY).fOffsetInRecord); - SkASSERT(sizeof(CubicInstance) == this->getInstanceStride()); - } else { - this->addInstanceAttrib("X", kFloat3_GrVertexAttribType); - this->addInstanceAttrib("Y", kFloat3_GrVertexAttribType); - - SkASSERT(offsetof(TriangleInstance, fX) == - this->getInstanceAttrib(InstanceAttribs::kX).fOffsetInRecord); - SkASSERT(offsetof(TriangleInstance, fY) == - this->getInstanceAttrib(InstanceAttribs::kY).fOffsetInRecord); - SkASSERT(sizeof(TriangleInstance) == this->getInstanceStride()); - } - - this->setWillUseGeoShader(); -} - void GrCCPRCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varyingHandler, SkString* code, const char* position, const char* coverage, const char* wind) { diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.h b/src/gpu/ccpr/GrCCPRCoverageProcessor.h index 7ecb888005..dfd2e249c4 100644 --- a/src/gpu/ccpr/GrCCPRCoverageProcessor.h +++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.h @@ -15,6 +15,7 @@ class GrGLSLPPFragmentBuilder; class GrGLSLShaderBuilder; +class GrMesh; /** * This is the geometry processor for the simple convex primitive shapes (triangles and closed curve @@ -26,22 +27,12 @@ class GrGLSLShaderBuilder; * below). Once all of a path's primitives have been drawn, the render target contains a composite * coverage count that can then be used to draw the path (see GrCCPRPathProcessor). * - * Draw calls are instanced. They use use the corresponding GrPrimitiveTypes as defined below. - * Caller fills out the primitives' atlas-space vertices and control points in instance arrays - * using the provided structs below. There are no vertex attribs. + * To draw a renderer pass, see appendMesh below. */ class GrCCPRCoverageProcessor : public GrGeometryProcessor { public: - static constexpr GrPrimitiveType kTrianglesGrPrimitiveType = GrPrimitiveType::kTriangles; - static constexpr GrPrimitiveType kQuadraticsGrPrimitiveType = GrPrimitiveType::kTriangles; - static constexpr GrPrimitiveType kCubicsGrPrimitiveType = GrPrimitiveType::kLinesAdjacency; - - enum class InstanceAttribs : int { - kX, - kY - }; - - struct TriangleInstance { // Also used by quadratics. + // Defines a single triangle or closed quadratic bezier, with transposed x,y point values. + struct TriangleInstance { float fX[3]; float fY[3]; @@ -49,6 +40,7 @@ public: void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans); }; + // Defines a single closed cubic bezier, with transposed x,y point values. struct CubicInstance { float fX[4]; float fY[4]; @@ -56,11 +48,9 @@ public: void set(const SkPoint[4], float dx, float dy); }; - /** - * All primitive shapes (triangles and convex closed curve segments) require more than one - * render pass. Here we enumerate every render pass needed in order to produce a complete - * coverage count mask. This is an exhaustive list of all ccpr coverage shaders. - */ + // All primitive shapes (triangles and convex closed curve segments) require more than one + // render pass. Here we enumerate every render pass needed in order to produce a complete + // coverage count mask. This is an exhaustive list of all ccpr coverage shaders. enum class RenderPass { // Triangles. kTriangleHulls, @@ -75,42 +65,44 @@ public: kCubicHulls, kCubicCorners }; + static bool RenderPassIsCubic(RenderPass); + static const char* RenderPassName(RenderPass); - static inline bool RenderPassIsCubic(RenderPass pass) { - switch (pass) { - case RenderPass::kTriangleHulls: - case RenderPass::kTriangleEdges: - case RenderPass::kTriangleCorners: - case RenderPass::kQuadraticHulls: - case RenderPass::kQuadraticCorners: - return false; - case RenderPass::kCubicHulls: - case RenderPass::kCubicCorners: - return true; - } - SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass"); - return false; + GrCCPRCoverageProcessor(RenderPass pass) + : INHERITED(kGrCCPRCoverageProcessor_ClassID) + , fRenderPass(pass) { + this->initGS(); } - static inline const char* RenderPassName(RenderPass pass) { - switch (pass) { - case RenderPass::kTriangleHulls: return "kTriangleHulls"; - case RenderPass::kTriangleEdges: return "kTriangleEdges"; - case RenderPass::kTriangleCorners: return "kTriangleCorners"; - case RenderPass::kQuadraticHulls: return "kQuadraticHulls"; - case RenderPass::kQuadraticCorners: return "kQuadraticCorners"; - case RenderPass::kCubicHulls: return "kCubicHulls"; - case RenderPass::kCubicCorners: return "kCubicCorners"; - } - SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass"); - return ""; + // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array + // of either TriangleInstance or CubicInstance, depending on this processor's RendererPass, with + // coordinates in the desired shape's final atlas-space position. + // + // NOTE: Quadratics use TriangleInstance since both have 3 points. + void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance, + SkTArray<GrMesh, true>* out) { + this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out); } - /** - * This serves as the base class for each RenderPass's Shader. It indicates what type of - * geometry the Impl should generate and provides implementation-independent code to process - * the inputs and calculate coverage in the fragment Shader. - */ + // GrPrimitiveProcessor overrides. + const char* name() const override { return RenderPassName(fRenderPass); } + SkString dumpInfo() const override { + return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str()); + } + void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; + GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; + +#ifdef SK_DEBUG + // Increases the 1/2 pixel AA bloat by a factor of debugBloat and outputs color instead of + // coverage (coverage=+1 -> green, coverage=0 -> black, coverage=-1 -> red). + void enableDebugVisualizations(float debugBloat) { fDebugBloat = debugBloat; } + bool debugVisualizationsEnabled() const { return fDebugBloat > 0; } + float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; } +#endif + + // This serves as the base class for each RenderPass's Shader. It indicates what type of + // geometry the Impl should generate and provides implementation-independent code to process the + // inputs and calculate coverage in the fragment Shader. class Shader { public: using TexelBufferHandle = GrGLSLGeometryProcessor::TexelBufferHandle; @@ -211,27 +203,6 @@ public: GrGLSLVarying fWind{kHalf_GrSLType, GrGLSLVarying::Scope::kGeoToFrag}; }; - GrCCPRCoverageProcessor(RenderPass); - - const char* name() const override { return RenderPassName(fRenderPass); } - SkString dumpInfo() const override { - return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str()); - } - const Attribute& getInstanceAttrib(InstanceAttribs attribID) const { - return this->getAttrib((int)attribID); - } - - void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; - GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; - -#ifdef SK_DEBUG - // Increases the 1/2 pixel AA bloat by a factor of debugBloat and outputs color instead of - // coverage (coverage=+1 -> green, coverage=0 -> black, coverage=-1 -> red). - void enableDebugVisualizations(float debugBloat) { fDebugBloat = debugBloat; } - bool debugVisualizationsEnabled() const { return fDebugBloat > 0; } - float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; } -#endif - class GSImpl; private: @@ -239,6 +210,10 @@ private: // accidentally bleed into neighbor pixels. static constexpr float kAABloatRadius = 0.491111f; + void initGS(); + void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance, + SkTArray<GrMesh, true>* out); + int numInputPoints() const { return RenderPassIsCubic(fRenderPass) ? 4 : 3; } @@ -270,4 +245,34 @@ inline void GrCCPRCoverageProcessor::CubicInstance::set(const SkPoint p[4], floa (Y + dy).store(&fY); } +inline bool GrCCPRCoverageProcessor::RenderPassIsCubic(RenderPass pass) { + switch (pass) { + case RenderPass::kTriangleHulls: + case RenderPass::kTriangleEdges: + case RenderPass::kTriangleCorners: + case RenderPass::kQuadraticHulls: + case RenderPass::kQuadraticCorners: + return false; + case RenderPass::kCubicHulls: + case RenderPass::kCubicCorners: + return true; + } + SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass"); + return false; +} + +inline const char* GrCCPRCoverageProcessor::RenderPassName(RenderPass pass) { + switch (pass) { + case RenderPass::kTriangleHulls: return "kTriangleHulls"; + case RenderPass::kTriangleEdges: return "kTriangleEdges"; + case RenderPass::kTriangleCorners: return "kTriangleCorners"; + case RenderPass::kQuadraticHulls: return "kQuadraticHulls"; + case RenderPass::kQuadraticCorners: return "kQuadraticCorners"; + case RenderPass::kCubicHulls: return "kCubicHulls"; + case RenderPass::kCubicCorners: return "kCubicCorners"; + } + SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass"); + return ""; +} + #endif diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp index 5c9ba3bfc2..60928b6afc 100644 --- a/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp +++ b/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp @@ -7,6 +7,7 @@ #include "GrCCPRCoverageProcessor.h" +#include "GrMesh.h" #include "glsl/GrGLSLVertexGeoBuilder.h" using Shader = GrCCPRCoverageProcessor::Shader; @@ -26,17 +27,16 @@ protected: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final { const GrCCPRCoverageProcessor& proc = args.fGP.cast<GrCCPRCoverageProcessor>(); - // Vertex shader. - GrGLSLVertexBuilder* v = args.fVertBuilder; - v->codeAppendf("float2 self = float2(%s[sk_VertexID], %s[sk_VertexID]);", - proc.getInstanceAttrib(InstanceAttribs::kX).fName, - proc.getInstanceAttrib(InstanceAttribs::kY).fName); - gpArgs->fPositionVar.set(kFloat2_GrSLType, "self"); + // The vertex shader simply forwards transposed x or y values to the geometry shader. + SkASSERT(1 == proc.numAttribs()); + gpArgs->fPositionVar.set(4 == proc.numInputPoints() ? kFloat4_GrSLType : kFloat3_GrSLType, + proc.getAttrib(0).fName); // Geometry shader. GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; this->emitGeometryShader(proc, varyingHandler, args.fGeomBuilder, args.fRTAdjustName); varyingHandler->emitAttributes(proc); + varyingHandler->setNoPerspective(); SkASSERT(!args.fFPCoordTransformHandler->nextCoordTransform()); // Fragment shader. @@ -52,12 +52,9 @@ protected: int numInputPoints = proc.numInputPoints(); SkASSERT(3 == numInputPoints || 4 == numInputPoints); - g->codeAppendf("float%ix2 pts = float%ix2(", numInputPoints, numInputPoints); - for (int i = 0; i < numInputPoints; ++i) { - g->codeAppend (i ? ", " : ""); - g->codeAppendf("sk_in[%i].sk_Position.xy", i); - } - g->codeAppend (");"); + const char* posValues = (4 == numInputPoints) ? "sk_Position" : "sk_Position.xyz"; + g->codeAppendf("float%ix2 pts = transpose(float2x%i(sk_in[0].%s, sk_in[1].%s));", + numInputPoints, numInputPoints, posValues, posValues); GrShaderVar wind("wind", kHalf_GrSLType); g->declareGlobal(wind); @@ -89,9 +86,8 @@ protected: Shader::GeometryVars vars; fShader->emitSetupCode(g, "pts", "sk_InvocationID", wind.c_str(), &vars); int maxPoints = this->onEmitGeometryShader(g, wind, emitVertexFn.c_str(), vars); - InputType inputType = (3 == numInputPoints) ? InputType::kTriangles - : InputType::kLinesAdjacency; - g->configure(inputType, OutputType::kTriangleStrip, maxPoints, fShader->getNumSegments()); + g->configure(InputType::kLines, OutputType::kTriangleStrip, maxPoints, + fShader->getNumSegments()); } virtual int onEmitGeometryShader(GrGLSLGeometryBuilder*, const GrShaderVar& wind, @@ -255,6 +251,17 @@ public: } }; +void GrCCPRCoverageProcessor::initGS() { + if (RenderPassIsCubic(fRenderPass)) { + this->addVertexAttrib("x_or_y_values", kFloat4_GrVertexAttribType); // (See appendMesh.) + SkASSERT(sizeof(CubicInstance) == this->getVertexStride() * 2); + } else { + this->addVertexAttrib("x_or_y_values", kFloat3_GrVertexAttribType); // (See appendMesh.) + SkASSERT(sizeof(TriangleInstance) == this->getVertexStride() * 2); + } + this->setWillUseGeoShader(); +} + GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::CreateGSImpl(std::unique_ptr<Shader> shader) { switch (shader->getGeometryType()) { case Shader::GeometryType::kHull: @@ -267,3 +274,14 @@ GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::CreateGSImpl(std::unique_ptr< SK_ABORT("Unexpected Shader::GeometryType."); return nullptr; } + +void GrCCPRCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, + int baseInstance, SkTArray<GrMesh, true>* out) { + // GSImpl doesn't actually make instanced draw calls. Instead, we feed transposed x,y point + // values to the GPU in a regular vertex array and draw kLines (see initGS). Then, each vertex + // invocation receives either the shape's x or y values as inputs, which it forwards to the + // geometry shader. + GrMesh& mesh = out->emplace_back(GrPrimitiveType::kLines); + mesh.setNonIndexedNonInstanced(instanceCount * 2); + mesh.setVertexData(instanceBuffer, baseInstance * 2); +} diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp index ab27ffaa7b..9c71042413 100644 --- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp @@ -16,27 +16,37 @@ void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { GrGPArgs gpArgs; this->onEmitCode(args, &gpArgs); - SkASSERT(kFloat2_GrSLType == gpArgs.fPositionVar.getType() || - kFloat3_GrSLType == gpArgs.fPositionVar.getType()); GrGLSLVertexBuilder* vBuilder = args.fVertBuilder; if (!args.fGP.willUseGeoShader()) { // Emit the vertex position to the hardware in the normalized window coordinates it expects. + SkASSERT(kFloat2_GrSLType == gpArgs.fPositionVar.getType() || + kFloat3_GrSLType == gpArgs.fPositionVar.getType()); vBuilder->emitNormalizedSkPosition(gpArgs.fPositionVar.c_str(), args.fRTAdjustName, gpArgs.fPositionVar.getType()); + if (kFloat2_GrSLType == gpArgs.fPositionVar.getType()) { + args.fVaryingHandler->setNoPerspective(); + } } else { // Since we have a geometry shader, leave the vertex position in Skia device space for now. // The geometry Shader will operate in device space, and then convert the final positions to // normalized hardware window coordinates under the hood, once everything else has finished. + // The subclass must call setNoPerspective on the varying handler, if applicable. vBuilder->codeAppendf("sk_Position = float4(%s", gpArgs.fPositionVar.c_str()); - if (kFloat2_GrSLType == gpArgs.fPositionVar.getType()) { - vBuilder->codeAppend(", 0"); + switch (gpArgs.fPositionVar.getType()) { + case kFloat_GrSLType: + vBuilder->codeAppend(", 0"); // fallthru. + case kFloat2_GrSLType: + vBuilder->codeAppend(", 0"); // fallthru. + case kFloat3_GrSLType: + vBuilder->codeAppend(", 1"); // fallthru. + case kFloat4_GrSLType: + vBuilder->codeAppend(");"); + break; + default: + SK_ABORT("Invalid position var type"); + break; } - vBuilder->codeAppend(", 1);"); - } - - if (kFloat2_GrSLType == gpArgs.fPositionVar.getType()) { - args.fVaryingHandler->setNoPerspective(); } } |