diff options
author | egdaniel <egdaniel@google.com> | 2015-11-20 14:01:22 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-20 14:01:22 -0800 |
commit | 0eafe79f42e3c675f3c504aed4a41abf511df2b7 (patch) | |
tree | 564912e8c811c3eb1bff5fd18131e9015b4a9fd6 /src/gpu | |
parent | a7006d45217d128a94fa53cb4b827cca79bc7049 (diff) |
Create GrGLSLVaryingHandler class for program building
BUG=skia:
Review URL: https://codereview.chromium.org/1462123003
Diffstat (limited to 'src/gpu')
30 files changed, 496 insertions, 319 deletions
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index 7b9213315d..85339ea9b5 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -12,6 +12,7 @@ #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLVertexShaderBuilder.h" +#include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLUtil.h" /* @@ -66,14 +67,15 @@ public: GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(gp); + varyingHandler->emitAttributes(gp); // Setup pass through color if (!gp.colorIgnored()) { if (gp.hasVertexColor()) { - pb->addPassThroughAttribute(gp.inColor(), args.fOutputColor); + varyingHandler->addPassThroughAttribute(gp.inColor(), args.fOutputColor); } else { this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform); } @@ -91,6 +93,7 @@ public: // emit transforms with explicit local coords this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, gp.inLocalCoords()->fName, gp.localMatrix(), @@ -100,6 +103,7 @@ public: // transforms have already been applied to vertex attributes on the cpu this->emitTransforms(pb, vertBuilder, + varyingHandler, gp.inLocalCoords()->fName, args.fTransformsIn, args.fTransformsOut); @@ -107,6 +111,7 @@ public: // emit transforms with position this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), @@ -118,7 +123,7 @@ public: if (!gp.coverageWillBeIgnored()) { if (gp.hasVertexCoverage()) { fragBuilder->codeAppendf("float alpha = 1.0;"); - args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha"); + varyingHandler->addPassThroughAttribute(gp.inCoverage(), "alpha"); fragBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); } else if (gp.coverage() == 0xff) { fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage); diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 128894c305..c66e12575c 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -25,6 +25,7 @@ #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" +#include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLVertexShaderBuilder.h" #include "glsl/GrGLSLUtil.h" @@ -99,12 +100,13 @@ public: const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>(); GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(ce); + varyingHandler->emitAttributes(ce); GrGLSLVertToFrag v(kVec4f_GrSLType); - args.fPB->addVarying("CircleEdge", &v); + varyingHandler->addVarying("CircleEdge", &v); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -119,6 +121,7 @@ public: // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, ce.inPosition()->fName, ce.localMatrix(), @@ -253,17 +256,18 @@ public: const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>(); GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(ee); + varyingHandler->emitAttributes(ee); GrGLSLVertToFrag ellipseOffsets(kVec2f_GrSLType); - args.fPB->addVarying("EllipseOffsets", &ellipseOffsets); + varyingHandler->addVarying("EllipseOffsets", &ellipseOffsets); vertBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), ee.inEllipseOffset()->fName); GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType); - args.fPB->addVarying("EllipseRadii", &ellipseRadii); + varyingHandler->addVarying("EllipseRadii", &ellipseRadii); vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), ee.inEllipseRadii()->fName); @@ -279,6 +283,7 @@ public: // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, ee.inPosition()->fName, ee.localMatrix(), @@ -433,17 +438,18 @@ public: const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>(); GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(ee); + varyingHandler->emitAttributes(ee); GrGLSLVertToFrag offsets0(kVec2f_GrSLType); - args.fPB->addVarying("EllipseOffsets0", &offsets0); + varyingHandler->addVarying("EllipseOffsets0", &offsets0); vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), ee.inEllipseOffsets0()->fName); GrGLSLVertToFrag offsets1(kVec2f_GrSLType); - args.fPB->addVarying("EllipseOffsets1", &offsets1); + varyingHandler->addVarying("EllipseOffsets1", &offsets1); vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), ee.inEllipseOffsets1()->fName); @@ -464,6 +470,7 @@ public: // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, ee.inPosition()->fName, args.fTransformsIn, diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp index 0e856520d4..f52ef489ee 100644 --- a/src/gpu/GrPathProcessor.cpp +++ b/src/gpu/GrPathProcessor.cpp @@ -12,6 +12,7 @@ #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProcessorTypes.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "glsl/GrGLSLVarying.h" class GrGLPathProcessor : public GrGLSLPrimitiveProcessor { public: @@ -30,7 +31,7 @@ public: const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>(); // emit transforms - this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut); + this->emitTransforms(args.fVaryingHandler, args.fTransformsIn, args.fTransformsOut); // Setup uniform color if (pathProc.opts().readsColor()) { @@ -49,7 +50,9 @@ public: } } - void emitTransforms(GrGLSLGPBuilder* pb, const TransformsIn& tin, TransformsOut* tout) { + void emitTransforms(GrGLSLVaryingHandler* varyingHandler, + const TransformsIn& tin, + TransformsOut* tout) { tout->push_back_n(tin.count()); fInstalledTransforms.push_back_n(tin.count()); for (int i = 0; i < tin.count(); i++) { @@ -63,8 +66,10 @@ public: SkString strVaryingName("MatrixCoord"); strVaryingName.appendf("_%i_%i", i, t); GrGLSLVertToFrag v(varyingType); + GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler; fInstalledTransforms[i][t].fHandle = - pb->addSeparableVarying(strVaryingName.c_str(), &v).toIndex(); + glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), + &v).toIndex(); fInstalledTransforms[i][t].fType = varyingType; SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLSLTransformedCoords, diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp index b78ecd80bc..aee18b720a 100644 --- a/src/gpu/batches/GrAAConvexPathRenderer.cpp +++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp @@ -28,6 +28,7 @@ #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" +#include "glsl/GrGLSLVarying.h" GrAAConvexPathRenderer::GrAAConvexPathRenderer() { } @@ -550,12 +551,13 @@ public: const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>(); GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(qe); + varyingHandler->emitAttributes(qe); GrGLSLVertToFrag v(kVec4f_GrSLType); - args.fPB->addVarying("QuadEdge", &v); + varyingHandler->addVarying("QuadEdge", &v); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -570,6 +572,7 @@ public: // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, qe.inPosition()->fName, qe.localMatrix(), diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 7ce2b31a8c..13672da6ea 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -11,6 +11,7 @@ #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLUtil.h" +#include "glsl/GrGLSLVarying.h" class GrGLConicEffect : public GrGLSLGeometryProcessor { public: @@ -75,12 +76,13 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; const GrConicEffect& gp = args.fGP.cast<GrConicEffect>(); + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(gp); + varyingHandler->emitAttributes(gp); GrGLSLVertToFrag v(kVec4f_GrSLType); - args.fPB->addVarying("ConicCoeffs", &v); + varyingHandler->addVarying("ConicCoeffs", &v); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -100,6 +102,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit transforms with position this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), @@ -301,12 +304,13 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>(); + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(gp); + varyingHandler->emitAttributes(gp); GrGLSLVertToFrag v(kVec4f_GrSLType); - args.fPB->addVarying("HairQuadEdge", &v); + varyingHandler->addVarying("HairQuadEdge", &v); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -326,6 +330,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit transforms with position this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), @@ -501,12 +506,13 @@ GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor) void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>(); + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(gp); + varyingHandler->emitAttributes(gp); GrGLSLVertToFrag v(kVec4f_GrSLType); - args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision); + varyingHandler->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -526,6 +532,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit transforms with position this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, gp.inPosition()->fName, args.fTransformsIn, diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 28c6f0ffc4..594646256e 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -12,6 +12,7 @@ #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" +#include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLVertexShaderBuilder.h" class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor { @@ -23,9 +24,10 @@ public: GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(cte); + varyingHandler->emitAttributes(cte); // compute numbers to be hardcoded to convert texture coordinates from int to float SkASSERT(cte.numTextures() == 1); @@ -35,7 +37,7 @@ public: SkScalar recipHeight = 1.0f / atlas->height(); GrGLSLVertToFrag v(kVec2f_GrSLType); - pb->addVarying("TextureCoords", &v); + varyingHandler->addVarying("TextureCoords", &v); vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", v.vsOut(), GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, @@ -45,7 +47,7 @@ public: // Setup pass through color if (!cte.colorIgnored()) { if (cte.hasVertexColor()) { - pb->addPassThroughAttribute(cte.inColor(), args.fOutputColor); + varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor); } else { this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform); } @@ -57,6 +59,7 @@ public: // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, cte.inPosition()->fName, cte.localMatrix(), diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 94cfd80b0c..c1e2011e08 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -25,6 +25,7 @@ #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" +#include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLVertexShaderBuilder.h" /////////////////////////////////////////////////////////////////////////////// @@ -853,18 +854,19 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>(); GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(dce); + varyingHandler->emitAttributes(dce); // XY are dashPos, Z is dashInterval GrGLSLVertToFrag dashParams(kVec3f_GrSLType); - args.fPB->addVarying("DashParam", &dashParams); + varyingHandler->addVarying("DashParam", &dashParams); vertBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->fName); // x refers to circle radius - 0.5, y refers to cicle's center x coord GrGLSLVertToFrag circleParams(kVec2f_GrSLType); - args.fPB->addVarying("CircleParams", &circleParams); + varyingHandler->addVarying("CircleParams", &circleParams); vertBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -879,6 +881,7 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, dce.inPosition()->fName, dce.localMatrix(), @@ -1064,19 +1067,20 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(de); + varyingHandler->emitAttributes(de); // XY refers to dashPos, Z is the dash interval length GrGLSLVertToFrag inDashParams(kVec3f_GrSLType); - args.fPB->addVarying("DashParams", &inDashParams, GrSLPrecision::kHigh_GrSLPrecision); + varyingHandler->addVarying("DashParams", &inDashParams, GrSLPrecision::kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", inDashParams.vsOut(), de.inDashParams()->fName); // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), // respectively. GrGLSLVertToFrag inRectParams(kVec4f_GrSLType); - args.fPB->addVarying("RectParams", &inRectParams, GrSLPrecision::kHigh_GrSLPrecision); + varyingHandler->addVarying("RectParams", &inRectParams, GrSLPrecision::kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()->fName); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -1091,6 +1095,7 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit transforms this->emitTransforms(args.fPB, vertBuilder, + varyingHandler, gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(), diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 1f3fedef76..cf77157e0d 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -15,8 +15,9 @@ #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" -#include "glsl/GrGLSLVertexShaderBuilder.h" #include "glsl/GrGLSLUtil.h" +#include "glsl/GrGLSLVarying.h" +#include "glsl/GrGLSLVertexShaderBuilder.h" // Assuming a radius of a little less than the diagonal of the fragment #define SK_DistanceFieldAAFactor "0.65" @@ -40,9 +41,10 @@ public: GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(dfTexEffect); + varyingHandler->emitAttributes(dfTexEffect); #ifdef SK_GAMMA_APPLY_TO_A8 // adjust based on gamma @@ -56,7 +58,7 @@ public: // Setup pass through color if (!dfTexEffect.colorIgnored()) { if (dfTexEffect.hasVertexColor()) { - pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); + varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); } else { this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform); } @@ -73,6 +75,7 @@ public: // emit transforms this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, args.fTransformsIn, @@ -82,7 +85,7 @@ public: GrGLSLVertToFrag recipScale(kFloat_GrSLType); GrGLSLVertToFrag st(kVec2f_GrSLType); bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); - pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); + varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); // compute numbers to be hardcoded to convert texture coordinates from int to float @@ -93,7 +96,7 @@ public: SkScalar recipHeight = 1.0f / atlas->height(); GrGLSLVertToFrag uv(kVec2f_GrSLType); - pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); + varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, @@ -299,17 +302,18 @@ public: GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(dfTexEffect); + varyingHandler->emitAttributes(dfTexEffect); GrGLSLVertToFrag v(kVec2f_GrSLType); - pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); + varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); // setup pass through color if (!dfTexEffect.colorIgnored()) { if (dfTexEffect.hasVertexColor()) { - pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); + varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); } else { this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform); } @@ -327,6 +331,7 @@ public: // emit transforms this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, args.fTransformsIn, @@ -519,9 +524,10 @@ public: GrGLSLGPBuilder* pb = args.fPB; GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; + GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; // emit attributes - vertBuilder->emitAttributes(dfTexEffect); + varyingHandler->emitAttributes(dfTexEffect); GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -541,6 +547,7 @@ public: // emit transforms this->emitTransforms(pb, vertBuilder, + varyingHandler, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, args.fTransformsIn, @@ -550,7 +557,7 @@ public: bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); GrGLSLVertToFrag recipScale(kFloat_GrSLType); GrGLSLVertToFrag st(kVec2f_GrSLType); - pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); + varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); // compute numbers to be hardcoded to convert texture coordinates from int to float @@ -561,7 +568,7 @@ public: SkScalar recipHeight = 1.0f / atlas->height(); GrGLSLVertToFrag uv(kVec2f_GrSLType); - pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); + varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 1fe1d1772a..3cf9e4dd7c 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -30,7 +30,7 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu, const BuiltinUniformHandles& builtinUniforms, GrGLuint programID, const UniformInfoArray& uniforms, - const SeparableVaryingInfoArray& separableVaryings, + const VaryingInfoArray& pathProcVaryings, GrGLInstalledGeoProc* geometryProcessor, GrGLInstalledXferProc* xferProcessor, GrGLInstalledFragProcs* fragmentProcessors, @@ -42,7 +42,7 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu, , fFragmentProcessors(SkRef(fragmentProcessors)) , fDesc(desc) , fGpu(gpu) - , fProgramDataManager(gpu, programID, uniforms, separableVaryings) { + , fProgramDataManager(gpu, programID, uniforms, pathProcVaryings) { fSamplerUniforms.swap(passSamplerUniforms); // Assign texture units to sampler uniforms one time up front. GL_CALL(UseProgram(fProgramID)); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 117d5a2a53..72fa9b01a0 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -99,14 +99,14 @@ public: protected: typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; - typedef GrGLProgramDataManager::SeparableVaryingInfoArray SeparableVaryingInfoArray; + typedef GrGLProgramDataManager::VaryingInfoArray VaryingInfoArray; GrGLProgram(GrGLGpu*, const GrProgramDesc&, const BuiltinUniformHandles&, GrGLuint programID, const UniformInfoArray&, - const SeparableVaryingInfoArray&, + const VaryingInfoArray&, // used for NVPR only currently GrGLInstalledGeoProc* geometryProcessor, GrGLInstalledXferProc* xferProcessor, GrGLInstalledFragProcs* fragmentProcessors, diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp index 7320b2dd8a..a61e6974b6 100644 --- a/src/gpu/gl/GrGLProgramDataManager.cpp +++ b/src/gpu/gl/GrGLProgramDataManager.cpp @@ -15,7 +15,7 @@ GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, GrGLuint programID, const UniformInfoArray& uniforms, - const SeparableVaryingInfoArray& separableVaryings) + const VaryingInfoArray& pathProcVaryings) : fGpu(gpu) , fProgramID(programID) { int count = uniforms.count(); @@ -44,19 +44,19 @@ GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, GrGLuint programID, } // NVPR programs have separable varyings - count = separableVaryings.count(); - fSeparableVaryings.push_back_n(count); + count = pathProcVaryings.count(); + fPathProcVaryings.push_back_n(count); for (int i = 0; i < count; i++) { SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport()); - SeparableVarying& separableVarying = fSeparableVaryings[i]; - const SeparableVaryingInfo& builderSeparableVarying = separableVaryings[i]; - SkASSERT(GrGLSLShaderVar::kNonArray == builderSeparableVarying.fVariable.getArrayCount() || - builderSeparableVarying.fVariable.getArrayCount() > 0); + PathProcVarying& pathProcVarying = fPathProcVaryings[i]; + const VaryingInfo& builderPathProcVarying = pathProcVaryings[i]; + SkASSERT(GrGLSLShaderVar::kNonArray == builderPathProcVarying.fVariable.getArrayCount() || + builderPathProcVarying.fVariable.getArrayCount() > 0); SkDEBUGCODE( - separableVarying.fArrayCount = builderSeparableVarying.fVariable.getArrayCount(); - separableVarying.fType = builderSeparableVarying.fVariable.getType(); + pathProcVarying.fArrayCount = builderPathProcVarying.fVariable.getArrayCount(); + pathProcVarying.fType = builderPathProcVarying.fVariable.getType(); ); - separableVarying.fLocation = builderSeparableVarying.fLocation; + pathProcVarying.fLocation = builderPathProcVarying.fLocation; } } @@ -276,11 +276,11 @@ void GrGLProgramDataManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix this->setMatrix3f(u, mt); } -void GrGLProgramDataManager::setPathFragmentInputTransform(SeparableVaryingHandle u, +void GrGLProgramDataManager::setPathFragmentInputTransform(VaryingHandle u, int components, const SkMatrix& matrix) const { SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport()); - const SeparableVarying& fragmentInput = fSeparableVaryings[u.toIndex()]; + const PathProcVarying& fragmentInput = fPathProcVaryings[u.toIndex()]; SkASSERT((components == 2 && fragmentInput.fType == kVec2f_GrSLType) || (components == 3 && fragmentInput.fType == kVec3f_GrSLType)); diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h index ea7b19e034..d47745334d 100644 --- a/src/gpu/gl/GrGLProgramDataManager.h +++ b/src/gpu/gl/GrGLProgramDataManager.h @@ -33,7 +33,7 @@ public: GrGLint fLocation; }; - struct SeparableVaryingInfo { + struct VaryingInfo { GrGLSLShaderVar fVariable; GrGLint fLocation; }; @@ -42,10 +42,10 @@ public: // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their // name strings. Otherwise, we'd have to hand out copies. typedef GrTAllocator<UniformInfo> UniformInfoArray; - typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray; + typedef GrTAllocator<VaryingInfo> VaryingInfoArray; GrGLProgramDataManager(GrGLGpu*, GrGLuint programID, const UniformInfoArray&, - const SeparableVaryingInfoArray&); + const VaryingInfoArray&); /** Functions for uploading uniform values. The varities ending in v can be used to upload to an * array of uniforms. arrayCount must be <= the array count of the uniform. @@ -71,7 +71,7 @@ public: void setSkMatrix(UniformHandle, const SkMatrix&) const override; // for nvpr only - void setPathFragmentInputTransform(SeparableVaryingHandle u, int components, + void setPathFragmentInputTransform(VaryingHandle u, int components, const SkMatrix& matrix) const override; private: @@ -89,9 +89,9 @@ private: }; enum { - kUnusedSeparableVarying = -1, + kUnusedPathProcVarying = -1, }; - struct SeparableVarying { + struct PathProcVarying { GrGLint fLocation; SkDEBUGCODE( GrSLType fType; @@ -102,7 +102,7 @@ private: SkDEBUGCODE(void printUnused(const Uniform&) const;) SkTArray<Uniform, true> fUniforms; - SkTArray<SeparableVarying, true> fSeparableVaryings; + SkTArray<PathProcVarying, true> fPathProcVaryings; GrGLGpu* fGpu; GrGLuint fProgramID; diff --git a/src/gpu/gl/GrGLVaryingHandler.cpp b/src/gpu/gl/GrGLVaryingHandler.cpp new file mode 100644 index 0000000000..b27a9960ec --- /dev/null +++ b/src/gpu/gl/GrGLVaryingHandler.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gl/GrGLVaryingHandler.h" + +#include "gl/GrGLGpu.h" +#include "gl/builders/GrGLProgramBuilder.h" + + +GrGLSLVaryingHandler::VaryingHandle GrGLVaryingHandler::addPathProcessingVarying( + const char* name, + GrGLSLVertToFrag* v, + GrSLPrecision fsPrecision) { +#ifdef SK_DEBUG + GrGLProgramBuilder* glPB = (GrGLProgramBuilder*) fProgramBuilder; + // This call is not used for non-NVPR backends. + SkASSERT(glPB->gpu()->glCaps().shaderCaps()->pathRenderingSupport() && + glPB->fArgs.fPrimitiveProcessor->isPathRendering() && + !glPB->fArgs.fPrimitiveProcessor->willUseGeoShader() && + glPB->fArgs.fPrimitiveProcessor->numAttribs() == 0); +#endif + this->addVarying(name, v, fsPrecision); + VaryingInfo& varyingInfo = fPathProcVaryingInfos.push_back(); + varyingInfo.fVariable = fFragInputs.back(); + varyingInfo.fLocation = fPathProcVaryingInfos.count() - 1; + return VaryingHandle(varyingInfo.fLocation); +} diff --git a/src/gpu/gl/GrGLVaryingHandler.h b/src/gpu/gl/GrGLVaryingHandler.h new file mode 100644 index 0000000000..ab931debd7 --- /dev/null +++ b/src/gpu/gl/GrGLVaryingHandler.h @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLVaryingHandler_DEFINED +#define GrGLVaryingHandler_DEFINED + +#include "glsl/GrGLSLVarying.h" +#include "GrTypesPriv.h" +#include "gl/GrGLProgramDataManager.h" + +class GrGLVaryingHandler : public GrGLSLVaryingHandler { +public: + GrGLVaryingHandler(GrGLSLProgramBuilder* program) + : INHERITED(program), + fPathProcVaryingInfos(kVaryingsPerBlock) {} + + // This function is used by the NVPR PathProcessor to add a varying directly into the fragment + // shader since there is no vertex shader. + VaryingHandle addPathProcessingVarying(const char* name, GrGLSLVertToFrag*, + GrSLPrecision fsPrecision = kDefault_GrSLPrecision); + +private: + typedef GrGLProgramDataManager::VaryingInfo VaryingInfo; + typedef GrGLProgramDataManager::VaryingInfoArray VaryingInfoArray; + + VaryingInfoArray fPathProcVaryingInfos; + + friend class GrGLProgramBuilder; + + typedef GrGLSLVaryingHandler INHERITED; +}; + +#endif + diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 22834053f0..0ae4f96101 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -57,47 +57,7 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) , fGpu(gpu) , fUniforms(kVarsPerBlock) , fSamplerUniforms(4) - , fSeparableVaryingInfos(kVarsPerBlock) { -} - -void GrGLProgramBuilder::addVarying(const char* name, - GrGLSLVarying* varying, - GrSLPrecision precision) { - SkASSERT(varying); - if (varying->vsVarying()) { - fVS.addVarying(name, precision, varying); - } - if (this->primitiveProcessor().willUseGeoShader()) { - fGS.addVarying(name, precision, varying); - } - if (varying->fsVarying()) { - fFS.addVarying(varying, precision); - } -} - -void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Attribute* input, - const char* output) { - GrSLType type = GrVertexAttribTypeToSLType(input->fType); - GrGLSLVertToFrag v(type); - this->addVarying(input->fName, &v); - fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); - fFS.codeAppendf("%s = %s;", output, v.fsIn()); -} - -GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVarying( - const char* name, - GrGLSLVertToFrag* v, - GrSLPrecision fsPrecision) { - // This call is not used for non-NVPR backends. - SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport() && - fArgs.fPrimitiveProcessor->isPathRendering() && - !fArgs.fPrimitiveProcessor->willUseGeoShader() && - fArgs.fPrimitiveProcessor->numAttribs() == 0); - this->addVarying(name, v, fsPrecision); - SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); - varyingInfo.fVariable = fFS.fInputs.back(); - varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; - return SeparableVaryingHandle(varyingInfo.fLocation); + , fVaryingHandler(this) { } GrGLSLProgramDataManager::UniformHandle GrGLProgramBuilder::internalAddUniformArray( @@ -289,6 +249,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp, GrGLSLGeometryProcessor::EmitArgs args(this, &fVS, &fFS, + &fVaryingHandler, this->glslCaps(), gp, outColor, @@ -474,12 +435,11 @@ void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { !fGpu->glPathRendering()->shouldBindFragmentInputs()) { return; } - int count = fSeparableVaryingInfos.count(); + int count = fVaryingHandler.fPathProcVaryingInfos.count(); for (int i = 0; i < count; ++i) { - GL_CALL(BindFragmentInputLocation(programID, - i, - fSeparableVaryingInfos[i].fVariable.c_str())); - fSeparableVaryingInfos[i].fLocation = i; + GL_CALL(BindFragmentInputLocation(programID, i, + fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str())); + fVaryingHandler.fPathProcVaryingInfos[i].fLocation = i; } } @@ -522,14 +482,14 @@ void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { !fGpu->glPathRendering()->shouldBindFragmentInputs()) { return; } - int count = fSeparableVaryingInfos.count(); + int count = fVaryingHandler.fPathProcVaryingInfos.count(); for (int i = 0; i < count; ++i) { GrGLint location; - GL_CALL_RET(location, - GetProgramResourceLocation(programID, - GR_GL_FRAGMENT_INPUT, - fSeparableVaryingInfos[i].fVariable.c_str())); - fSeparableVaryingInfos[i].fLocation = location; + GL_CALL_RET(location, GetProgramResourceLocation( + programID, + GR_GL_FRAGMENT_INPUT, + fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str())); + fVaryingHandler.fPathProcVaryingInfos[i].fLocation = location; } } @@ -545,7 +505,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUniforms, - fSeparableVaryingInfos, + fVaryingHandler.fPathProcVaryingInfos, fGeometryProcessor, fXferProcessor, fFragmentProcessors.get(), &fSamplerUniforms); } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 3a8dcd8500..edc467c407 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -10,6 +10,7 @@ #include "GrPipeline.h" #include "gl/GrGLProgramDataManager.h" +#include "gl/GrGLVaryingHandler.h" #include "glsl/GrGLSLPrimitiveProcessor.h" #include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" @@ -69,24 +70,9 @@ public: GrGLGpu* gpu() const { return fGpu; } - void addVarying( - const char* name, - GrGLSLVarying*, - GrSLPrecision precision = kDefault_GrSLPrecision) override; - - void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*, - const char* output) override; - - SeparableVaryingHandle addSeparableVarying( - const char* name, - GrGLSLVertToFrag*, - GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override; - private: typedef GrGLProgramDataManager::UniformInfo UniformInfo; typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; - typedef GrGLProgramDataManager::SeparableVaryingInfo SeparableVaryingInfo; - typedef GrGLProgramDataManager::SeparableVaryingInfoArray SeparableVaryingInfoArray; GrGLProgramBuilder(GrGLGpu*, const DrawArgs&); @@ -148,6 +134,8 @@ private: void onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const override; + GrGLSLVaryingHandler* varyingHandler() override { return &fVaryingHandler; } + // reset is called by program creator between each processor's emit code. It increments the // stage offset for variable name mangling, and also ensures verfication variables in the // fragment shader are cleared. @@ -179,13 +167,11 @@ private: GrGLSLPrimitiveProcessor::TransformsIn fCoordTransforms; GrGLSLPrimitiveProcessor::TransformsOut fOutCoords; SkTArray<UniformHandle> fSamplerUniforms; - SeparableVaryingInfoArray fSeparableVaryingInfos; - friend class GrGLSLShaderBuilder; - friend class GrGLSLVertexBuilder; - friend class GrGLSLFragmentShaderBuilder; - friend class GrGLSLGeometryBuilder; + GrGLVaryingHandler fVaryingHandler; + + friend class GrGLVaryingHandler; - typedef GrGLSLProgramBuilder INHERITED; + typedef GrGLSLProgramBuilder INHERITED; }; #endif diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index 5a3e09d151..122db10ec9 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -10,6 +10,7 @@ #include "glsl/GrGLSL.h" #include "glsl/GrGLSLCaps.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "glsl/GrGLSLVarying.h" const char* GrGLSLFragmentShaderBuilder::kDstTextureColorName = "_dstColor"; @@ -237,19 +238,12 @@ const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const { } void GrGLSLFragmentShaderBuilder::onFinalize() { + fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs()); GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *fProgramBuilder->glslCaps(), &this->precisionQualifier()); } -void GrGLSLFragmentShaderBuilder::addVarying(GrGLSLVarying* v, GrSLPrecision fsPrec) { - v->fFsIn = v->fVsOut; - if (v->fGsOut) { - v->fFsIn = v->fGsOut; - } - fInputs.push_back().set(v->fType, GrGLSLShaderVar::kVaryingIn_TypeModifier, v->fFsIn, fsPrec); -} - void GrGLSLFragmentBuilder::onBeforeChildProcEmitCode() { SkASSERT(fSubstageIndices.count() >= 1); fSubstageIndices.push_back(0); diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp index 706a8a8461..8a1e81a1f8 100644 --- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp @@ -10,6 +10,7 @@ #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProcessorTypes.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLVertexShaderBuilder.h" void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { @@ -21,6 +22,7 @@ void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, GrGLSLVertexBuilder* vb, + GrGLSLVaryingHandler* varyingHandler, const GrShaderVar& posVar, const char* localCoords, const SkMatrix& localMatrix, @@ -56,7 +58,7 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, strVaryingName.appendf("_%i_%i", i, t); GrGLSLVertToFrag v(varyingType); - pb->addVarying(strVaryingName.c_str(), &v, precision); + varyingHandler->addVarying(strVaryingName.c_str(), &v, precision); SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLSLTransformedCoords, @@ -94,6 +96,7 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, GrGLSLVertexBuilder* vb, + GrGLSLVaryingHandler* varyingHandler, const char* localCoords, const TransformsIn& tin, TransformsOut* tout) { @@ -111,7 +114,7 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, strVaryingName.appendf("_%i_%i", i, t); GrGLSLVertToFrag v(varyingType); - pb->addVarying(strVaryingName.c_str(), &v, precision); + varyingHandler->addVarying(strVaryingName.c_str(), &v, precision); vb->codeAppendf("%s = %s;", v.vsOut(), localCoords); SkNEW_APPEND_TO_TARRAY(&(*tout)[i], diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h index 1d9c51267b..4c586a7900 100644 --- a/src/gpu/glsl/GrGLSLGeometryProcessor.h +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.h @@ -44,16 +44,18 @@ protected: // Emit a uniform matrix for each coord transform. void emitTransforms(GrGLSLGPBuilder* gp, GrGLSLVertexBuilder* vb, + GrGLSLVaryingHandler* varyingHandler, const GrShaderVar& posVar, const char* localCoords, const TransformsIn& tin, TransformsOut* tout) { - this->emitTransforms(gp, vb, posVar, localCoords, SkMatrix::I(), tin, tout); + this->emitTransforms(gp, vb, varyingHandler, posVar, localCoords, SkMatrix::I(), tin, tout); } // Emit pre-transformed coords as a vertex attribute per coord-transform. void emitTransforms(GrGLSLGPBuilder*, GrGLSLVertexBuilder*, + GrGLSLVaryingHandler*, const GrShaderVar& posVar, const char* localCoords, const SkMatrix& localMatrix, @@ -63,6 +65,7 @@ protected: // caller has emitted transforms via attributes void emitTransforms(GrGLSLGPBuilder*, GrGLSLVertexBuilder*, + GrGLSLVaryingHandler*, const char* localCoords, const TransformsIn& tin, TransformsOut* tout); diff --git a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp index 275972b8a7..25e9f9e320 100644 --- a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp @@ -7,34 +7,14 @@ #include "GrGLSLGeometryShaderBuilder.h" #include "GrGLSLProgramBuilder.h" +#include "GrGLSLVarying.h" GrGLSLGeometryBuilder::GrGLSLGeometryBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) { } -void GrGLSLGeometryBuilder::addVarying(const char* name, - GrSLPrecision precision, - GrGLSLVarying* v) { - // if we have a GS take each varying in as an array - // and output as non-array. - if (v->vsVarying()) { - fInputs.push_back(); - fInputs.back().setType(v->fType); - fInputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingIn_TypeModifier); - fInputs.back().setPrecision(precision); - fInputs.back().setUnsizedArray(); - *fInputs.back().accessName() = v->fVsOut; - v->fGsIn = v->fVsOut; - } - - if (v->fsVarying()) { - fOutputs.push_back(); - fOutputs.back().setType(v->fType); - fOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); - fOutputs.back().setPrecision(precision); - fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name); - v->fGsOut = fOutputs.back().getName().c_str(); - } +void GrGLSLGeometryBuilder::onFinalize() { + fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs()); } diff --git a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h index ca24c79157..f5e09f11a2 100644 --- a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h @@ -17,12 +17,7 @@ public: GrGLSLGeometryBuilder(GrGLSLProgramBuilder* program); private: - /* - * an internal call for GrGLFullProgramBuilder to add varyings - */ - void addVarying(const char* name, GrSLPrecision precision, GrGLSLVarying*); - - void onFinalize() override {} + void onFinalize() override; friend class GrGLProgramBuilder; diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h index a4582378c3..d164bbe53e 100644 --- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h @@ -18,6 +18,7 @@ class GrPrimitiveProcessor; class GrGLSLCaps; class GrGLSLFragmentBuilder; class GrGLSLGPBuilder; +class GrGLSLVaryingHandler; class GrGLSLVertexBuilder; class GrGLSLPrimitiveProcessor { @@ -35,6 +36,7 @@ public: EmitArgs(GrGLSLGPBuilder* pb, GrGLSLVertexBuilder* vertBuilder, GrGLSLFragmentBuilder* fragBuilder, + GrGLSLVaryingHandler* varyingHandler, const GrGLSLCaps* caps, const GrPrimitiveProcessor& gp, const char* outputColor, @@ -45,6 +47,7 @@ public: : fPB(pb) , fVertBuilder(vertBuilder) , fFragBuilder(fragBuilder) + , fVaryingHandler(varyingHandler) , fGLSLCaps(caps) , fGP(gp) , fOutputColor(outputColor) @@ -55,6 +58,7 @@ public: GrGLSLGPBuilder* fPB; GrGLSLVertexBuilder* fVertBuilder; GrGLSLFragmentBuilder* fFragBuilder; + GrGLSLVaryingHandler* fVaryingHandler; const GrGLSLCaps* fGLSLCaps; const GrPrimitiveProcessor& fGP; const char* fOutputColor; diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h index e87ab0aee9..81037084e9 100644 --- a/src/gpu/glsl/GrGLSLProgramBuilder.h +++ b/src/gpu/glsl/GrGLSLProgramBuilder.h @@ -17,6 +17,7 @@ class GrGLSLCaps; class GrGLSLShaderVar; +class GrGLSLVaryingHandler; // Enough precision to represent 1 / 2048 accurately in printf #define GR_SIGNIFICANT_POW2_DECIMAL_DIG 11 @@ -32,7 +33,6 @@ public: virtual ~GrGLSLUniformBuilder() {} typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; - typedef GrGLSLProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle; /** Add a uniform variable to the current program, that has visibility in one or more shaders. visibility is a bitfield of ShaderVisibility values indicating from which shaders the @@ -79,91 +79,10 @@ protected: const char** outName) = 0; }; -// TODO move this into GrGLSLGPBuilder and move them both out of this file -class GrGLSLVarying { -public: - bool vsVarying() const { return kVertToFrag_Varying == fVarying || - kVertToGeo_Varying == fVarying; } - bool fsVarying() const { return kVertToFrag_Varying == fVarying || - kGeoToFrag_Varying == fVarying; } - const char* vsOut() const { return fVsOut; } - const char* gsIn() const { return fGsIn; } - const char* gsOut() const { return fGsOut; } - const char* fsIn() const { return fFsIn; } - GrSLType type() const { return fType; } - -protected: - enum Varying { - kVertToFrag_Varying, - kVertToGeo_Varying, - kGeoToFrag_Varying, - }; - - GrGLSLVarying(GrSLType type, Varying varying) - : fVarying(varying), fType(type), fVsOut(nullptr), fGsIn(nullptr), fGsOut(nullptr), - fFsIn(nullptr) {} - - Varying fVarying; - -private: - GrSLType fType; - const char* fVsOut; - const char* fGsIn; - const char* fGsOut; - const char* fFsIn; - - friend class GrGLSLVertexBuilder; - friend class GrGLSLGeometryBuilder; - friend class GrGLSLXferBuilder; - friend class GrGLSLFragmentShaderBuilder; -}; - -struct GrGLSLVertToFrag : public GrGLSLVarying { - GrGLSLVertToFrag(GrSLType type) - : GrGLSLVarying(type, kVertToFrag_Varying) {} -}; - -struct GrGLSLVertToGeo : public GrGLSLVarying { - GrGLSLVertToGeo(GrSLType type) - : GrGLSLVarying(type, kVertToGeo_Varying) {} -}; - -struct GrGLSLGeoToFrag : public GrGLSLVarying { - GrGLSLGeoToFrag(GrSLType type) - : GrGLSLVarying(type, kGeoToFrag_Varying) {} -}; - /* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */ class GrGLSLGPBuilder : public virtual GrGLSLUniformBuilder { public: /* - * addVarying allows fine grained control for setting up varyings between stages. If you just - * need to take an attribute and pass it through to an output value in a fragment shader, use - * addPassThroughAttribute. - * TODO convert most uses of addVarying to addPassThroughAttribute - */ - virtual void addVarying(const char* name, - GrGLSLVarying*, - GrSLPrecision precision = kDefault_GrSLPrecision) = 0; - - /* - * This call can be used by GP to pass an attribute through all shaders directly to 'output' in - * the fragment shader. Though this call effects both the vertex shader and fragment shader, - * it expects 'output' to be defined in the fragment shader before this call is made. - * TODO it might be nicer behavior to have a flag to declare output inside this call - */ - virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, - const char* output) = 0; - - /* - * Creates a fragment shader varying that can be referred to. - * Comparable to GrGLSLUniformBuilder::addUniform(). - */ - virtual SeparableVaryingHandle addSeparableVarying( - const char* name, GrGLSLVertToFrag*, - GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0; - - /* * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE */ }; @@ -229,12 +148,15 @@ protected: // explicitly asked not to. void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true); + virtual GrGLSLVaryingHandler* varyingHandler() = 0; + // number of each input/output type in a single allocation block, used by many builders static const int kVarsPerBlock; - GrGLSLVertexBuilder fVS; - GrGLSLGeometryBuilder fGS; + GrGLSLVertexBuilder fVS; + GrGLSLGeometryBuilder fGS; GrGLSLFragmentShaderBuilder fFS; + int fStageIndex; BuiltinUniformHandles fUniformHandles; @@ -248,6 +170,7 @@ private: friend class GrGLSLVertexBuilder; friend class GrGLSLFragmentShaderBuilder; friend class GrGLSLGeometryBuilder; + friend class GrGLSLVaryingHandler; }; #endif diff --git a/src/gpu/glsl/GrGLSLProgramDataManager.h b/src/gpu/glsl/GrGLSLProgramDataManager.h index 2009feab13..1a8f6391aa 100644 --- a/src/gpu/glsl/GrGLSLProgramDataManager.h +++ b/src/gpu/glsl/GrGLSLProgramDataManager.h @@ -65,8 +65,8 @@ public: virtual void setSkMatrix(UniformHandle, const SkMatrix&) const = 0; // for nvpr only - typedef ShaderResourceHandle SeparableVaryingHandle; - virtual void setPathFragmentInputTransform(SeparableVaryingHandle u, int components, + typedef ShaderResourceHandle VaryingHandle; + virtual void setPathFragmentInputTransform(VaryingHandle u, int components, const SkMatrix& matrix) const = 0; protected: diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp index d4d16fcfcb..1fc15ecb3c 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp @@ -190,10 +190,6 @@ void GrGLSLShaderBuilder::finalize(uint32_t visibility) { fProgramBuilder->appendUniformDecls((GrGLSLProgramBuilder::ShaderVisibility) visibility, &this->uniforms()); this->appendDecls(fInputs, &this->inputs()); - // We should not have any outputs in the fragment shader when using version 1.10 - SkASSERT(GrGLSLProgramBuilder::kFragment_Visibility != visibility || - k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() || - fOutputs.empty()); this->appendDecls(fOutputs, &this->outputs()); this->onFinalize(); // append the 'footer' to code diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h index fde48dc570..1a8255dbb4 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLShaderBuilder.h @@ -25,9 +25,6 @@ public: GrGLSLShaderBuilder(GrGLSLProgramBuilder* program); virtual ~GrGLSLShaderBuilder() {} - void addInput(const GrGLSLShaderVar& input) { fInputs.push_back(input); } - void addOutput(const GrGLSLShaderVar& output) { fOutputs.push_back(output); } - /* * We put texture lookups in the base class because it is TECHNICALLY possible to do texture * lookups in any kind of shader. However, for the time being using these calls on non-fragment diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp new file mode 100644 index 0000000000..279dd5937e --- /dev/null +++ b/src/gpu/glsl/GrGLSLVarying.cpp @@ -0,0 +1,132 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "glsl/GrGLSLVarying.h" + +#include "glsl/GrGLSLProgramBuilder.h" + +void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input, + const char* output) { + GrSLType type = GrVertexAttribTypeToSLType(input->fType); + GrGLSLVertToFrag v(type); + this->addVarying(input->fName, &v); + fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); + + if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { + fProgramBuilder->fGS.codeAppendf("%s = %s[0];", v.gsOut(), v.gsIn()); + } + + fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn()); +} + +void GrGLSLVaryingHandler::addVarying(const char* name, + GrGLSLVarying* varying, + GrSLPrecision precision) { + SkASSERT(varying); + if (varying->vsVarying()) { + this->addVertexVarying(name, precision, varying); + } + if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { + this->addGeomVarying(name, precision, varying); + } + if (varying->fsVarying()) { + this->addFragVarying(precision, varying); + } +} + +void GrGLSLVaryingHandler::addVertexVarying(const char* name, + GrSLPrecision precision, + GrGLSLVarying* v) { + fVertexOutputs.push_back(); + fVertexOutputs.back().setType(v->fType); + fVertexOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); + fVertexOutputs.back().setPrecision(precision); + fProgramBuilder->nameVariable(fVertexOutputs.back().accessName(), 'v', name); + v->fVsOut = fVertexOutputs.back().getName().c_str(); +} +void GrGLSLVaryingHandler::addGeomVarying(const char* name, + GrSLPrecision precision, + GrGLSLVarying* v) { + // if we have a GS take each varying in as an array + // and output as non-array. + if (v->vsVarying()) { + fGeomInputs.push_back(); + fGeomInputs.back().setType(v->fType); + fGeomInputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingIn_TypeModifier); + fGeomInputs.back().setPrecision(precision); + fGeomInputs.back().setUnsizedArray(); + *fGeomInputs.back().accessName() = v->fVsOut; + v->fGsIn = v->fVsOut; + } + + if (v->fsVarying()) { + fGeomOutputs.push_back(); + fGeomOutputs.back().setType(v->fType); + fGeomOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); + fGeomOutputs.back().setPrecision(precision); + fProgramBuilder->nameVariable(fGeomOutputs.back().accessName(), 'g', name); + v->fGsOut = fGeomOutputs.back().getName().c_str(); + } +} + +void GrGLSLVaryingHandler::addFragVarying(GrSLPrecision precision, GrGLSLVarying* v) { + v->fFsIn = v->fGsOut ? v->fGsOut : v->fVsOut; + fFragInputs.push_back().set(v->fType, + GrGLSLShaderVar::kVaryingIn_TypeModifier, + v->fFsIn, + precision); +} + +void GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) { + int vaCount = gp.numAttribs(); + for (int i = 0; i < vaCount; i++) { + const GrGeometryProcessor::Attribute& attr = gp.getAttrib(i); + this->addAttribute(GrShaderVar(attr.fName, + GrVertexAttribTypeToSLType(attr.fType), + GrShaderVar::kAttribute_TypeModifier, + GrShaderVar::kNonArray, + attr.fPrecision)); + } +} + +void GrGLSLVaryingHandler::addAttribute(const GrShaderVar& var) { + SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier()); + for (int j = 0; j < fVertexInputs.count(); ++j) { + const GrGLSLShaderVar& attr = fVertexInputs[j]; + // if attribute already added, don't add it again + if (attr.getName().equals(var.getName())) { + return; + } + } + fVertexInputs.push_back(var); +} + +void GrGLSLVaryingHandler::appendDecls(const VarArray& vars, SkString* out) const { + for (int i = 0; i < vars.count(); ++i) { + vars[i].appendDecl(fProgramBuilder->glslCaps(), out); + out->append(";"); + } +} + +void GrGLSLVaryingHandler::getVertexDecls(SkString* inputDecls, SkString* outputDecls) const { + this->appendDecls(fVertexInputs, inputDecls); + this->appendDecls(fVertexOutputs, outputDecls); +} + +void GrGLSLVaryingHandler::getGeomDecls(SkString* inputDecls, SkString* outputDecls) const { + this->appendDecls(fGeomInputs, inputDecls); + this->appendDecls(fGeomOutputs, outputDecls); +} + +void GrGLSLVaryingHandler::getFragDecls(SkString* inputDecls, SkString* outputDecls) const { + // We should not have any outputs in the fragment shader when using version 1.10 + SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() || + fFragOutputs.empty()); + this->appendDecls(fFragInputs, inputDecls); + this->appendDecls(fFragOutputs, outputDecls); +} + diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h new file mode 100644 index 0000000000..116ba09b99 --- /dev/null +++ b/src/gpu/glsl/GrGLSLVarying.h @@ -0,0 +1,136 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLSLVarying_DEFINED +#define GrGLSLVarying_DEFINED + +#include "GrAllocator.h" +#include "GrGeometryProcessor.h" +#include "GrTypesPriv.h" +#include "glsl/GrGLSLProgramDataManager.h" +#include "glsl/GrGLSLShaderVar.h" + +class GrGLSLProgramBuilder; + +class GrGLSLVarying { +public: + bool vsVarying() const { return kVertToFrag_Varying == fVarying || + kVertToGeo_Varying == fVarying; } + bool fsVarying() const { return kVertToFrag_Varying == fVarying || + kGeoToFrag_Varying == fVarying; } + const char* vsOut() const { return fVsOut; } + const char* gsIn() const { return fGsIn; } + const char* gsOut() const { return fGsOut; } + const char* fsIn() const { return fFsIn; } + GrSLType type() const { return fType; } + +protected: + enum Varying { + kVertToFrag_Varying, + kVertToGeo_Varying, + kGeoToFrag_Varying, + }; + + GrGLSLVarying(GrSLType type, Varying varying) + : fVarying(varying), fType(type), fVsOut(nullptr), fGsIn(nullptr), fGsOut(nullptr), + fFsIn(nullptr) {} + + Varying fVarying; + +private: + GrSLType fType; + const char* fVsOut; + const char* fGsIn; + const char* fGsOut; + const char* fFsIn; + + friend class GrGLSLVaryingHandler; +}; + +struct GrGLSLVertToFrag : public GrGLSLVarying { + GrGLSLVertToFrag(GrSLType type) + : GrGLSLVarying(type, kVertToFrag_Varying) {} +}; + +struct GrGLSLVertToGeo : public GrGLSLVarying { + GrGLSLVertToGeo(GrSLType type) + : GrGLSLVarying(type, kVertToGeo_Varying) {} +}; + +struct GrGLSLGeoToFrag : public GrGLSLVarying { + GrGLSLGeoToFrag(GrSLType type) + : GrGLSLVarying(type, kGeoToFrag_Varying) {} +}; + +static const int kVaryingsPerBlock = 8; + +class GrGLSLVaryingHandler { +public: + explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program) + : fVertexInputs(kVaryingsPerBlock) + , fVertexOutputs(kVaryingsPerBlock) + , fGeomInputs(kVaryingsPerBlock) + , fGeomOutputs(kVaryingsPerBlock) + , fFragInputs(kVaryingsPerBlock) + , fFragOutputs(kVaryingsPerBlock) + , fProgramBuilder(program) {} + + typedef GrTAllocator<GrGLSLShaderVar> VarArray; + typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; + + /* + * addVarying allows fine grained control for setting up varyings between stages. Calling this + * functions will make sure all necessary decls are setup for the client. The client however is + * responsible for setting up all shader code (e.g "vOut = vIn;") If you just need to take an + * attribute and pass it through to an output value in a fragment shader, use + * addPassThroughAttribute. + * TODO convert most uses of addVarying to addPassThroughAttribute + */ + void addVarying(const char* name, + GrGLSLVarying*, + GrSLPrecision precision = kDefault_GrSLPrecision); + + /* + * This call can be used by GP to pass an attribute through all shaders directly to 'output' in + * the fragment shader. Though this call effects both the vertex shader and fragment shader, + * it expects 'output' to be defined in the fragment shader before this call is made. If there + * is a geometry shader, we will simply take the value of the varying from the first vertex and + * 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 this call + */ + void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output); + + void emitAttributes(const GrGeometryProcessor& gp); + + void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const; + void getGeomDecls(SkString* inputDecls, SkString* outputDecls) const; + void getFragDecls(SkString* inputDecls, SkString* outputDecls) const; +protected: + VarArray fVertexInputs; + VarArray fVertexOutputs; + VarArray fGeomInputs; + VarArray fGeomOutputs; + VarArray fFragInputs; + VarArray fFragOutputs; + + // This is not owned by the class + GrGLSLProgramBuilder* fProgramBuilder; + +private: + void addVertexVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); + void addGeomVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); + void addFragVarying(GrSLPrecision precision, GrGLSLVarying* v); + + void addAttribute(const GrShaderVar& var); + + // helper function for get*Decls + void appendDecls(const VarArray& vars, SkString* out) const; + + friend class GrGLSLProgramBuilder; +}; + +#endif diff --git a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp index 1f68d0e7b9..73c0fcd81e 100644 --- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp @@ -7,29 +7,13 @@ #include "GrGLSLVertexShaderBuilder.h" #include "glsl/GrGLSLProgramBuilder.h" +#include "glsl/GrGLSLVarying.h" GrGLSLVertexBuilder::GrGLSLVertexBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) , fRtAdjustName(nullptr) { } -void GrGLSLVertexBuilder::addVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v) { - fOutputs.push_back(); - fOutputs.back().setType(v->fType); - fOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); - fOutputs.back().setPrecision(precision); - fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name); - v->fVsOut = fOutputs.back().getName().c_str(); -} - -void GrGLSLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) { - int vaCount = gp.numAttribs(); - for (int i = 0; i < vaCount; i++) { - this->addAttribute(&gp.getAttrib(i)); - } - return; -} - void GrGLSLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& posVar) { SkASSERT(!fRtAdjustName); @@ -72,16 +56,7 @@ void GrGLSLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& po this->codeAppend("gl_PointSize = 1.0;"); } -bool GrGLSLVertexBuilder::addAttribute(const GrShaderVar& var) { - SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier()); - for (int i = 0; i < fInputs.count(); ++i) { - const GrGLSLShaderVar& attr = fInputs[i]; - // if attribute already added, don't add it again - if (attr.getName().equals(var.getName())) { - return false; - } - } - fInputs.push_back(var); - return true; +void GrGLSLVertexBuilder::onFinalize() { + fProgramBuilder->varyingHandler()->getVertexDecls(&this->inputs(), &this->outputs()); } diff --git a/src/gpu/glsl/GrGLSLVertexShaderBuilder.h b/src/gpu/glsl/GrGLSLVertexShaderBuilder.h index 92edd9ae81..b76721fd00 100644 --- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.h @@ -18,26 +18,8 @@ public: GrGLSLVertexBuilder(GrGLSLProgramBuilder* program); void transformToNormalizedDeviceSpace(const GrShaderVar& posVar); - void emitAttributes(const GrGeometryProcessor& gp); - - void addAttribute(const GrGeometryProcessor::Attribute* attr) { - this->addAttribute(GrShaderVar(attr->fName, - GrVertexAttribTypeToSLType(attr->fType), - GrShaderVar::kAttribute_TypeModifier, - GrShaderVar::kNonArray, - attr->fPrecision)); - } - private: - /* - * Internal call for GrGLProgramBuilder.addVarying - */ - void addVarying(const char* name, GrSLPrecision, GrGLSLVarying*); - - // an internal call which checks for uniquness of a var before adding it to the list of inputs - bool addAttribute(const GrShaderVar& var); - - void onFinalize() override {} + void onFinalize() override; const char* fRtAdjustName; |