From 8dcdedc4a087ea46ce1e2458d335d60918e56310 Mon Sep 17 00:00:00 2001 From: egdaniel Date: Wed, 11 Nov 2015 06:27:20 -0800 Subject: [PATCH] Make GrGLSLProgramBuilder base class for GrGLProgramBuilder. This CL still keeps the weird diamond shape we have for all our ProgramBuilders. However, the GrGLSL base class will allow us to pull multiple other parts of our program setup away from GL which will eventually allow us to break up the diamond. As part of this all ShaderBuilder subclass have been made gl independent, however I will move them to GLSL files/class names in a follow on CL. BUG=skia: Review URL: https://codereview.chromium.org/1416423003 --- gyp/gpu.gypi | 2 + src/effects/SkArithmeticMode_gpu.cpp | 2 +- src/effects/SkLightingImageFilter.cpp | 36 +-- src/effects/SkTableColorFilter.cpp | 6 +- src/effects/gradients/SkGradientShader.cpp | 6 +- src/effects/gradients/SkGradientShaderPriv.h | 4 +- src/effects/gradients/SkSweepGradient.cpp | 7 +- src/gpu/GrDefaultGeoProcFactory.cpp | 2 +- src/gpu/GrOvalRenderer.cpp | 16 +- src/gpu/GrPathProcessor.cpp | 6 +- src/gpu/batches/GrAAConvexPathRenderer.cpp | 4 +- src/gpu/effects/GrBezierEffect.cpp | 10 +- src/gpu/effects/GrBitmapTextGeoProc.cpp | 4 +- src/gpu/effects/GrConvexPolyEffect.cpp | 5 - src/gpu/effects/GrCustomXfermode.cpp | 2 +- src/gpu/effects/GrDashingEffect.cpp | 12 +- src/gpu/effects/GrDistanceFieldGeoProc.cpp | 20 +- src/gpu/effects/GrPorterDuffXferProcessor.cpp | 2 +- src/gpu/effects/GrTextureDomain.cpp | 6 +- src/gpu/gl/GrGLCaps.cpp | 37 ++- src/gpu/gl/GrGLCaps.h | 4 - src/gpu/gl/GrGLFragmentProcessor.h | 6 +- src/gpu/gl/GrGLGeometryProcessor.cpp | 12 +- src/gpu/gl/GrGLGeometryProcessor.h | 12 +- src/gpu/gl/GrGLPrimitiveProcessor.cpp | 2 +- src/gpu/gl/GrGLPrimitiveProcessor.h | 10 +- src/gpu/gl/GrGLXferProcessor.h | 13 +- src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 54 ++--- src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 28 ++- src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp | 4 +- src/gpu/gl/builders/GrGLGeometryShaderBuilder.h | 6 +- src/gpu/gl/builders/GrGLProgramBuilder.cpp | 57 ++--- src/gpu/gl/builders/GrGLProgramBuilder.h | 262 ++-------------------- src/gpu/gl/builders/GrGLShaderBuilder.cpp | 12 +- src/gpu/gl/builders/GrGLShaderBuilder.h | 8 +- src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp | 24 +- src/gpu/gl/builders/GrGLVertexShaderBuilder.h | 12 +- src/gpu/glsl/GrGLSLCaps.cpp | 9 +- src/gpu/glsl/GrGLSLCaps.h | 26 +++ src/gpu/glsl/GrGLSLProgramBuilder.cpp | 39 ++++ src/gpu/glsl/GrGLSLProgramBuilder.h | 261 +++++++++++++++++++++ 41 files changed, 558 insertions(+), 492 deletions(-) create mode 100644 src/gpu/glsl/GrGLSLProgramBuilder.cpp create mode 100644 src/gpu/glsl/GrGLSLProgramBuilder.h diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 47c7a6b..1f1b6a3 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -370,6 +370,8 @@ '<(skia_src_path)/gpu/glsl/GrGLSLCaps.cpp', '<(skia_src_path)/gpu/glsl/GrGLSLCaps.h', '<(skia_src_path)/gpu/glsl/GrGLSLProcessorTypes.h', + '<(skia_src_path)/gpu/glsl/GrGLSLProgramBuilder.cpp', + '<(skia_src_path)/gpu/glsl/GrGLSLProgramBuilder.h', '<(skia_src_path)/gpu/glsl/GrGLSLProgramDataManager.h', '<(skia_src_path)/gpu/glsl/GrGLSLShaderVar.h', '<(skia_src_path)/gpu/glsl/GrGLSLTextureSampler.h', diff --git a/src/effects/SkArithmeticMode_gpu.cpp b/src/effects/SkArithmeticMode_gpu.cpp index dd015ca..7ceaffa 100644 --- a/src/effects/SkArithmeticMode_gpu.cpp +++ b/src/effects/SkArithmeticMode_gpu.cpp @@ -206,7 +206,7 @@ public: } private: - void emitBlendCodeForDstRead(GrGLXPBuilder* pb, const char* srcColor, const char* dstColor, + void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, const char* srcColor, const char* dstColor, const char* outColor, const GrXferProcessor& proc) override { GrGLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index 3d3a069..6121c3c 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -597,7 +597,7 @@ public: * This is called by GrGLLightingEffect::emitCode() before either of the two virtual functions * below. It adds a vec3f uniform visible in the FS that represents the constant light color. */ - void emitLightColorUniform(GrGLFPBuilder*); + void emitLightColorUniform(GrGLSLFPBuilder*); /** * These two functions are called from GrGLLightingEffect's emitCode() function. @@ -607,8 +607,8 @@ public: * the FS. The default of emitLightColor appends the name of the constant light color uniform * and so this function only needs to be overridden if the light color varies spatially. */ - virtual void emitSurfaceToLight(GrGLFPBuilder*, const char* z) = 0; - virtual void emitLightColor(GrGLFPBuilder*, const char *surfaceToLight); + virtual void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) = 0; + virtual void emitLightColor(GrGLSLFPBuilder*, const char *surfaceToLight); // This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call // INHERITED::setData(). @@ -633,7 +633,7 @@ class GrGLDistantLight : public GrGLLight { public: virtual ~GrGLDistantLight() {} void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override; - void emitSurfaceToLight(GrGLFPBuilder*, const char* z) override; + void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) override; private: typedef GrGLLight INHERITED; @@ -646,7 +646,7 @@ class GrGLPointLight : public GrGLLight { public: virtual ~GrGLPointLight() {} void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override; - void emitSurfaceToLight(GrGLFPBuilder*, const char* z) override; + void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) override; private: typedef GrGLLight INHERITED; @@ -659,8 +659,8 @@ class GrGLSpotLight : public GrGLLight { public: virtual ~GrGLSpotLight() {} void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override; - void emitSurfaceToLight(GrGLFPBuilder*, const char* z) override; - void emitLightColor(GrGLFPBuilder*, const char *surfaceToLight) override; + void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) override; + void emitLightColor(GrGLSLFPBuilder*, const char *surfaceToLight) override; private: typedef GrGLLight INHERITED; @@ -1522,7 +1522,7 @@ protected: */ void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; - virtual void emitLightFunc(GrGLFPBuilder*, SkString* funcName) = 0; + virtual void emitLightFunc(GrGLSLFPBuilder*, SkString* funcName) = 0; private: typedef GrGLFragmentProcessor INHERITED; @@ -1538,7 +1538,7 @@ private: class GrGLDiffuseLightingEffect : public GrGLLightingEffect { public: GrGLDiffuseLightingEffect(const GrProcessor&); - void emitLightFunc(GrGLFPBuilder*, SkString* funcName) override; + void emitLightFunc(GrGLSLFPBuilder*, SkString* funcName) override; protected: void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; @@ -1554,7 +1554,7 @@ private: class GrGLSpecularLightingEffect : public GrGLLightingEffect { public: GrGLSpecularLightingEffect(const GrProcessor&); - void emitLightFunc(GrGLFPBuilder*, SkString* funcName) override; + void emitLightFunc(GrGLSLFPBuilder*, SkString* funcName) override; protected: void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; @@ -1763,7 +1763,7 @@ GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrProcessor& proc) : INHERITED(proc) { } -void GrGLDiffuseLightingEffect::emitLightFunc(GrGLFPBuilder* builder, SkString* funcName) { +void GrGLDiffuseLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder, SkString* funcName) { const char* kd; fKDUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kFloat_GrSLType, kDefault_GrSLPrecision, @@ -1845,7 +1845,7 @@ GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrProcessor& proc) : INHERITED(proc) { } -void GrGLSpecularLightingEffect::emitLightFunc(GrGLFPBuilder* builder, SkString* funcName) { +void GrGLSpecularLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder, SkString* funcName) { const char* ks; const char* shininess; @@ -1884,13 +1884,13 @@ void GrGLSpecularLightingEffect::onSetData(const GrGLSLProgramDataManager& pdman } /////////////////////////////////////////////////////////////////////////////// -void GrGLLight::emitLightColorUniform(GrGLFPBuilder* builder) { +void GrGLLight::emitLightColorUniform(GrGLSLFPBuilder* builder) { fColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType, kDefault_GrSLPrecision, "LightColor"); } -void GrGLLight::emitLightColor(GrGLFPBuilder* builder, const char *surfaceToLight) { +void GrGLLight::emitLightColor(GrGLSLFPBuilder* builder, const char *surfaceToLight) { builder->getFragmentShaderBuilder()->codeAppend(builder->getUniformCStr(this->lightColorUni())); } @@ -1910,7 +1910,7 @@ void GrGLDistantLight::setData(const GrGLSLProgramDataManager& pdman, setUniformNormal3(pdman, fDirectionUni, distantLight->direction()); } -void GrGLDistantLight::emitSurfaceToLight(GrGLFPBuilder* builder, const char* z) { +void GrGLDistantLight::emitSurfaceToLight(GrGLSLFPBuilder* builder, const char* z) { const char* dir; fDirectionUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType, kDefault_GrSLPrecision, @@ -1928,7 +1928,7 @@ void GrGLPointLight::setData(const GrGLSLProgramDataManager& pdman, setUniformPoint3(pdman, fLocationUni, pointLight->location()); } -void GrGLPointLight::emitSurfaceToLight(GrGLFPBuilder* builder, const char* z) { +void GrGLPointLight::emitSurfaceToLight(GrGLSLFPBuilder* builder, const char* z) { const char* loc; fLocationUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType, kDefault_GrSLPrecision, @@ -1953,7 +1953,7 @@ void GrGLSpotLight::setData(const GrGLSLProgramDataManager& pdman, setUniformNormal3(pdman, fSUni, spotLight->s()); } -void GrGLSpotLight::emitSurfaceToLight(GrGLFPBuilder* builder, const char* z) { +void GrGLSpotLight::emitSurfaceToLight(GrGLSLFPBuilder* builder, const char* z) { const char* location; fLocationUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType, kDefault_GrSLPrecision, @@ -1964,7 +1964,7 @@ void GrGLSpotLight::emitSurfaceToLight(GrGLFPBuilder* builder, const char* z) { location, fsBuilder->fragmentPosition(), z); } -void GrGLSpotLight::emitLightColor(GrGLFPBuilder* builder, +void GrGLSpotLight::emitLightColor(GrGLSLFPBuilder* builder, const char *surfaceToLight) { const char* color = builder->getUniformCStr(this->lightColorUni()); // created by parent class. diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 0f95a81..7b99700 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -414,9 +414,9 @@ void GLColorTableEffect::onSetData(const GrGLSLProgramDataManager& pdm, const Gr void GLColorTableEffect::emitCode(EmitArgs& args) { const char* yoffsets; - fRGBAYValuesUni = args.fBuilder->addUniform(GrGLFPBuilder::kFragment_Visibility, - kVec4f_GrSLType, kDefault_GrSLPrecision, - "yoffsets", &yoffsets); + fRGBAYValuesUni = args.fBuilder->addUniform(GrGLSLFPBuilder::kFragment_Visibility, + kVec4f_GrSLType, kDefault_GrSLPrecision, + "yoffsets", &yoffsets); static const float kColorScaleFactor = 255.0f / 256.0f; static const float kColorOffsetFactor = 1.0f / 512.0f; GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index e3a3759..9909f31 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -919,7 +919,7 @@ GrGLGradientEffect::GrGLGradientEffect() GrGLGradientEffect::~GrGLGradientEffect() { } -void GrGLGradientEffect::emitUniforms(GrGLFPBuilder* builder, const GrGradientEffect& ge) { +void GrGLGradientEffect::emitUniforms(GrGLSLFPBuilder* builder, const GrGradientEffect& ge) { if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()) { // 2 Color case fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, @@ -1025,7 +1025,7 @@ uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrProcessor& processor) { return key; } -void GrGLGradientEffect::emitColor(GrGLFPBuilder* builder, +void GrGLGradientEffect::emitColor(GrGLSLFPBuilder* builder, const GrGradientEffect& ge, const char* gradientTValue, const char* outputColor, @@ -1053,7 +1053,7 @@ void GrGLGradientEffect::emitColor(GrGLFPBuilder* builder, gradientTValue); fsBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n", builder->getUniformVariable(fColorStartUni).c_str()); - if (kTegra3_GrGLRenderer == builder->ctxInfo().renderer()) { + if (!builder->glslCaps()->canUseMinAndAbsTogether()) { // The Tegra3 compiler will sometimes never return if we have // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression. fsBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index 2286c22..a295b5c 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -414,13 +414,13 @@ protected: // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses // should call this method from their emitCode(). - void emitUniforms(GrGLFPBuilder* builder, const GrGradientEffect&); + void emitUniforms(GrGLSLFPBuilder* builder, const GrGradientEffect&); // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using // native GLSL mix), and 4+ color gradients that use the traditional texture lookup. - void emitColor(GrGLFPBuilder* builder, + void emitColor(GrGLSLFPBuilder* builder, const GrGradientEffect&, const char* gradientTValue, const char* outputColor, diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index 35d2f74..172c7d1 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -250,16 +250,15 @@ void GrGLSweepGradient::emitCode(EmitArgs& args) { this->emitUniforms(args.fBuilder, ge); SkString coords2D = args.fBuilder->getFragmentShaderBuilder() ->ensureFSCoords2D(args.fCoords, 0); - const GrGLContextInfo& ctxInfo = args.fBuilder->ctxInfo(); SkString t; // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi] // On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int // thus must us -1.0 * %s.x to work correctly - if (kIntel_GrGLVendor != ctxInfo.vendor()){ - t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", + if (args.fBuilder->glslCaps()->mustForceNegatedAtanParamToFloat()){ + t.printf("atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5", coords2D.c_str(), coords2D.c_str()); } else { - t.printf("atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5", + t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords2D.c_str(), coords2D.c_str()); } this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor, diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index 23530ac..b1cedd2 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -61,7 +61,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const DefaultGeoProc& gp = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index b0a7f3a..4f51c03 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -95,13 +95,13 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const CircleEdgeEffect& ce = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(ce); - GrGLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("CircleEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName); @@ -243,18 +243,18 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const EllipseEdgeEffect& ee = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(ee); - GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType); + GrGLSLVertToFrag ellipseOffsets(kVec2f_GrSLType); args.fPB->addVarying("EllipseOffsets", &ellipseOffsets); vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), ee.inEllipseOffset()->fName); - GrGLVertToFrag ellipseRadii(kVec4f_GrSLType); + GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType); args.fPB->addVarying("EllipseRadii", &ellipseRadii); vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), ee.inEllipseRadii()->fName); @@ -418,18 +418,18 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const DIEllipseEdgeEffect& ee = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(ee); - GrGLVertToFrag offsets0(kVec2f_GrSLType); + GrGLSLVertToFrag offsets0(kVec2f_GrSLType); args.fPB->addVarying("EllipseOffsets0", &offsets0); vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), ee.inEllipseOffsets0()->fName); - GrGLVertToFrag offsets1(kVec2f_GrSLType); + GrGLSLVertToFrag offsets1(kVec2f_GrSLType); args.fPB->addVarying("EllipseOffsets1", &offsets1); vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), ee.inEllipseOffsets1()->fName); diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp index 9728e59..6a78568 100644 --- a/src/gpu/GrPathProcessor.cpp +++ b/src/gpu/GrPathProcessor.cpp @@ -23,7 +23,7 @@ public: } void emitCode(EmitArgs& args) override { - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); const GrPathProcessor& pathProc = args.fGP.cast(); @@ -47,7 +47,7 @@ public: } } - void emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin, TransformsOut* tout) { + void emitTransforms(GrGLSLGPBuilder* pb, 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++) { @@ -60,7 +60,7 @@ public: SkString strVaryingName("MatrixCoord"); strVaryingName.appendf("_%i_%i", i, t); - GrGLVertToFrag v(varyingType); + GrGLSLVertToFrag v(varyingType); fInstalledTransforms[i][t].fHandle = pb->addSeparableVarying(strVaryingName.c_str(), &v).toIndex(); fInstalledTransforms[i][t].fType = varyingType; diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp index 02f4143..d30053b 100644 --- a/src/gpu/batches/GrAAConvexPathRenderer.cpp +++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp @@ -548,13 +548,13 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const QuadEdgeEffect& qe = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(qe); - GrGLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("QuadEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName); diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 41fe7fc..1cf5e18 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -73,14 +73,14 @@ GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor) } void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrConicEffect& gp = args.fGP.cast(); // emit attributes vsBuilder->emitAttributes(gp); - GrGLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("ConicCoeffs", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName); @@ -289,14 +289,14 @@ GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor) } void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrQuadEffect& gp = args.fGP.cast(); // emit attributes vsBuilder->emitAttributes(gp); - GrGLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("HairQuadEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName); @@ -483,7 +483,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit attributes vsBuilder->emitAttributes(gp); - GrGLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName); diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 371ef01..c1a9dae 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -21,7 +21,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const GrBitmapTextGeoProc& cte = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); // emit attributes @@ -34,7 +34,7 @@ public: SkScalar recipWidth = 1.0f / atlas->width(); SkScalar recipHeight = 1.0f / atlas->height(); - GrGLVertToFrag v(kVec2f_GrSLType); + GrGLSLVertToFrag v(kVec2f_GrSLType); pb->addVarying("TextureCoords", &v); vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", v.vsOut(), GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index b37964d..714c68a 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -212,11 +212,6 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) { fsBuilder->codeAppend("\t\talpha *= edge;\n"); } - // Woe is me. See https://bug.skia.org/2149 . - if (kTegra2_GrGLRenderer == args.fBuilder->ctxInfo().renderer()) { - fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n"); - } - if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) { fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n"); } diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index 8ebb80a..abcd9a5 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -160,7 +160,7 @@ private: } } - void emitBlendCodeForDstRead(GrGLXPBuilder* pb, const char* srcColor, const char* dstColor, + void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, const char* srcColor, const char* dstColor, const char* outColor, const GrXferProcessor& proc) override { const CustomXP& xp = proc.cast(); SkASSERT(!xp.hasHWBlendEquation()); diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 4a8c09e..b724082 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -850,19 +850,19 @@ GLDashingCircleEffect::GLDashingCircleEffect() { void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { const DashingCircleEffect& dce = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(dce); // XY are dashPos, Z is dashInterval - GrGLVertToFrag dashParams(kVec3f_GrSLType); + GrGLSLVertToFrag dashParams(kVec3f_GrSLType); args.fPB->addVarying("DashParam", &dashParams); vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->fName); // x refers to circle radius - 0.5, y refers to cicle's center x coord - GrGLVertToFrag circleParams(kVec2f_GrSLType); + GrGLSLVertToFrag circleParams(kVec2f_GrSLType); args.fPB->addVarying("CircleParams", &circleParams); vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams()->fName); @@ -1054,7 +1054,7 @@ GLDashingLineEffect::GLDashingLineEffect() { void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { const DashingLineEffect& de = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); @@ -1062,13 +1062,13 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { vsBuilder->emitAttributes(de); // XY refers to dashPos, Z is the dash interval length - GrGLVertToFrag inDashParams(kVec3f_GrSLType); + GrGLSLVertToFrag inDashParams(kVec3f_GrSLType); args.fPB->addVarying("DashParams", &inDashParams, GrSLPrecision::kHigh_GrSLPrecision); vsBuilder->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. - GrGLVertToFrag inRectParams(kVec4f_GrSLType); + GrGLSLVertToFrag inRectParams(kVec4f_GrSLType); args.fPB->addVarying("RectParams", &inRectParams, GrSLPrecision::kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()->fName); diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 0cef6be..41e1aea 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -33,7 +33,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldA8TextGeoProc& dfTexEffect = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); @@ -70,8 +70,8 @@ public: args.fTransformsIn, args.fTransformsOut); // add varyings - GrGLVertToFrag recipScale(kFloat_GrSLType); - GrGLVertToFrag st(kVec2f_GrSLType); + GrGLSLVertToFrag recipScale(kFloat_GrSLType); + GrGLSLVertToFrag st(kVec2f_GrSLType); bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); @@ -83,7 +83,7 @@ public: SkScalar recipWidth = 1.0f / atlas->width(); SkScalar recipHeight = 1.0f / atlas->height(); - GrGLVertToFrag uv(kVec2f_GrSLType); + GrGLSLVertToFrag uv(kVec2f_GrSLType); pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, @@ -284,7 +284,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); @@ -294,7 +294,7 @@ public: // emit attributes vsBuilder->emitAttributes(dfTexEffect); - GrGLVertToFrag v(kVec2f_GrSLType); + GrGLSLVertToFrag v(kVec2f_GrSLType); pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); // setup pass through color @@ -499,7 +499,7 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldLCDTextGeoProc& dfTexEffect = args.fGP.cast(); - GrGLGPBuilder* pb = args.fPB; + GrGLSLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); @@ -521,8 +521,8 @@ public: // set up varyings bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); - GrGLVertToFrag recipScale(kFloat_GrSLType); - GrGLVertToFrag st(kVec2f_GrSLType); + GrGLSLVertToFrag recipScale(kFloat_GrSLType); + GrGLSLVertToFrag st(kVec2f_GrSLType); pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); @@ -533,7 +533,7 @@ public: SkScalar recipWidth = 1.0f / atlas->width(); SkScalar recipHeight = 1.0f / atlas->height(); - GrGLVertToFrag uv(kVec2f_GrSLType); + GrGLSLVertToFrag uv(kVec2f_GrSLType); pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index a7f390a..2866380 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -543,7 +543,7 @@ public: } private: - void emitBlendCodeForDstRead(GrGLXPBuilder* pb, const char* srcColor, const char* dstColor, + void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, const char* srcColor, const char* dstColor, const char* outColor, const GrXferProcessor& proc) override { const ShaderPDXferProcessor& xp = proc.cast(); GrGLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 29d5fc9..b6458dc 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -11,7 +11,7 @@ #include "SkFloatingPoint.h" #include "gl/GrGLContext.h" #include "gl/GrGLFragmentProcessor.h" -#include "gl/builders/GrGLProgramBuilder.h" +#include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLTextureSampler.h" @@ -51,7 +51,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder, SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode); SkDEBUGCODE(fMode = textureDomain.mode();) - GrGLProgramBuilder* program = builder->getProgramBuilder(); + GrGLSLProgramBuilder* program = builder->getProgramBuilder(); if (textureDomain.mode() != kIgnore_Mode && !fDomainUni.isValid()) { const char* name; @@ -59,7 +59,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder, if (textureDomain.fIndex >= 0) { uniName.appendS32(textureDomain.fIndex); } - fDomainUni = program->addUniform(GrGLProgramBuilder::kFragment_Visibility, + fDomainUni = program->addUniform(GrGLSLProgramBuilder::kFragment_Visibility, kVec4f_GrSLType, kDefault_GrSLPrecision, uniName.c_str(), &name); fDomainName = name; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index f5ce0af..b02f387 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -37,7 +37,6 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, fTextureRedSupport = false; fImagingSupport = false; fTwoFormatLimit = false; - fFragCoordsConventionSupport = false; fVertexArrayObjectSupport = false; fInstancedDrawingSupport = false; fDirectStateAccessSupport = false; @@ -172,14 +171,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control"); } - // Frag Coords Convention support is not part of ES - // Known issue on at least some Intel platforms: - // http://code.google.com/p/skia/issues/detail?id=946 - if (kIntel_GrGLVendor != ctxInfo.vendor() && kGLES_GrGLStandard != standard) { - fFragCoordsConventionSupport = ctxInfo.glslGeneration() >= k150_GrGLSLGeneration || - ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"); - } - // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with // frequently changing VBOs. We've measured a performance increase using non-VBO vertex // data for dynamic content on these GPUs. Perhaps we should read the renderer string and @@ -593,6 +584,32 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) { if (kGLES_GrGLStandard == standard && k110_GrGLSLGeneration == glslCaps->fGLSLGeneration) { glslCaps->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives"; } + + // Frag Coords Convention support is not part of ES + // Known issue on at least some Intel platforms: + // http://code.google.com/p/skia/issues/detail?id=946 + if (kIntel_GrGLVendor != ctxInfo.vendor() && + kGLES_GrGLStandard != standard && + (ctxInfo.glslGeneration() >= k150_GrGLSLGeneration || + ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"))) { + glslCaps->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions"; + } + + if (kGLES_GrGLStandard == standard) { + glslCaps->fSecondaryOutputExtensionString = "GL_EXT_blend_func_extended"; + } + + // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), so we must do + // the abs first in a separate expression. + if (kTegra3_GrGLRenderer == ctxInfo.renderer()) { + glslCaps->fCanUseMinAndAbsTogether = false; + } + + // On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int + // thus must us -1.0 * %s.x to work correctly + if (kIntel_GrGLVendor == ctxInfo.vendor()) { + glslCaps->fMustForceNegatedAtanParamToFloat = true; + } } bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { @@ -1177,8 +1194,6 @@ SkString GrGLCaps::dump() const { r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO")); r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO")); r.appendf("Two Format Limit: %s\n", (fTwoFormatLimit ? "YES": "NO")); - r.appendf("Fragment coord conventions support: %s\n", - (fFragCoordsConventionSupport ? "YES": "NO")); r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO")); r.appendf("Instanced drawing support: %s\n", (fInstancedDrawingSupport ? "YES": "NO")); r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO")); diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 10d62b0..5f1ca3e 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -195,9 +195,6 @@ public: /// Is GL_ARB_IMAGING supported bool imagingSupport() const { return fImagingSupport; } - /// Is GL_ARB_fragment_coord_conventions supported? - bool fragCoordConventionsSupport() const { return fFragCoordsConventionSupport; } - /// Is there support for Vertex Array Objects? bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; } @@ -350,7 +347,6 @@ private: bool fTextureRedSupport : 1; bool fImagingSupport : 1; bool fTwoFormatLimit : 1; - bool fFragCoordsConventionSupport : 1; bool fVertexArrayObjectSupport : 1; bool fInstancedDrawingSupport : 1; bool fDirectStateAccessSupport : 1; diff --git a/src/gpu/gl/GrGLFragmentProcessor.h b/src/gpu/gl/GrGLFragmentProcessor.h index 2a78bbd..311612d 100644 --- a/src/gpu/gl/GrGLFragmentProcessor.h +++ b/src/gpu/gl/GrGLFragmentProcessor.h @@ -14,7 +14,7 @@ class GrProcessor; class GrProcessorKeyBuilder; -class GrGLFPBuilder; +class GrGLSLFPBuilder; class GrGLSLCaps; class GrGLFragmentProcessor { @@ -50,7 +50,7 @@ public: */ struct EmitArgs { - EmitArgs(GrGLFPBuilder* builder, + EmitArgs(GrGLSLFPBuilder* builder, const GrFragmentProcessor& fp, const char* outputColor, const char* inputColor, @@ -62,7 +62,7 @@ public: , fInputColor(inputColor) , fCoords(coords) , fSamplers(samplers) {} - GrGLFPBuilder* fBuilder; + GrGLSLFPBuilder* fBuilder; const GrFragmentProcessor& fFp; const char* fOutputColor; const char* fInputColor; diff --git a/src/gpu/gl/GrGLGeometryProcessor.cpp b/src/gpu/gl/GrGLGeometryProcessor.cpp index ff45742..c01e305 100644 --- a/src/gpu/gl/GrGLGeometryProcessor.cpp +++ b/src/gpu/gl/GrGLGeometryProcessor.cpp @@ -17,7 +17,7 @@ void GrGLGeometryProcessor::emitCode(EmitArgs& args) { vsBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar); } -void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, +void GrGLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, const GrShaderVar& posVar, const char* localCoords, const SkMatrix& localMatrix, @@ -53,7 +53,7 @@ void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, SkString strVaryingName("MatrixCoord"); strVaryingName.appendf("_%i_%i", i, t); - GrGLVertToFrag v(varyingType); + GrGLSLVertToFrag v(varyingType); pb->addVarying(strVaryingName.c_str(), &v, precision); SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); @@ -90,7 +90,7 @@ void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, } } -void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, +void GrGLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb, const char* localCoords, const TransformsIn& tin, TransformsOut* tout) { @@ -108,7 +108,7 @@ void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, SkString strVaryingName("MatrixCoord"); strVaryingName.appendf("_%i_%i", i, t); - GrGLVertToFrag v(varyingType); + GrGLSLVertToFrag v(varyingType); pb->addVarying(strVaryingName.c_str(), &v, precision); vb->codeAppendf("%s = %s;", v.vsOut(), localCoords); @@ -119,7 +119,7 @@ void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, } } -void GrGLGeometryProcessor::setupPosition(GrGLGPBuilder* pb, +void GrGLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb, GrGPArgs* gpArgs, const char* posName) { GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); @@ -127,7 +127,7 @@ void GrGLGeometryProcessor::setupPosition(GrGLGPBuilder* pb, vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); } -void GrGLGeometryProcessor::setupPosition(GrGLGPBuilder* pb, +void GrGLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb, GrGPArgs* gpArgs, const char* posName, const SkMatrix& mat, diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h index 1b3b8d9..8151c32 100644 --- a/src/gpu/gl/GrGLGeometryProcessor.h +++ b/src/gpu/gl/GrGLGeometryProcessor.h @@ -10,7 +10,7 @@ #include "GrGLPrimitiveProcessor.h" -class GrGLGPBuilder; +class GrGLSLGPBuilder; /** * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit @@ -42,7 +42,7 @@ public: protected: // Emit a uniform matrix for each coord transform. - void emitTransforms(GrGLGPBuilder* gp, + void emitTransforms(GrGLSLGPBuilder* gp, const GrShaderVar& posVar, const char* localCoords, const TransformsIn& tin, @@ -51,7 +51,7 @@ protected: } // Emit pre-transformed coords as a vertex attribute per coord-transform. - void emitTransforms(GrGLGPBuilder*, + void emitTransforms(GrGLSLGPBuilder*, const GrShaderVar& posVar, const char* localCoords, const SkMatrix& localMatrix, @@ -59,7 +59,7 @@ protected: TransformsOut*); // caller has emitted transforms via attributes - void emitTransforms(GrGLGPBuilder*, + void emitTransforms(GrGLSLGPBuilder*, const char* localCoords, const TransformsIn& tin, TransformsOut* tout); @@ -71,8 +71,8 @@ protected: }; // Create the correct type of position variable given the CTM - void setupPosition(GrGLGPBuilder*, GrGPArgs*, const char* posName); - void setupPosition(GrGLGPBuilder*, GrGPArgs*, const char* posName, const SkMatrix& mat, + void setupPosition(GrGLSLGPBuilder*, GrGPArgs*, const char* posName); + void setupPosition(GrGLSLGPBuilder*, GrGPArgs*, const char* posName, const SkMatrix& mat, UniformHandle* viewMatrixUniform); static uint32_t ComputePosKey(const SkMatrix& mat) { diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.cpp b/src/gpu/gl/GrGLPrimitiveProcessor.cpp index 6dd112c..35fa235 100644 --- a/src/gpu/gl/GrGLPrimitiveProcessor.cpp +++ b/src/gpu/gl/GrGLPrimitiveProcessor.cpp @@ -31,7 +31,7 @@ SkMatrix GrGLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix, return combined; } -void GrGLPrimitiveProcessor::setupUniformColor(GrGLGPBuilder* pb, +void GrGLPrimitiveProcessor::setupUniformColor(GrGLSLGPBuilder* pb, const char* outputName, UniformHandle* colorUniform) { GrGLFragmentBuilder* fs = pb->getFragmentShaderBuilder(); diff --git a/src/gpu/gl/GrGLPrimitiveProcessor.h b/src/gpu/gl/GrGLPrimitiveProcessor.h index 6d4c195..0f3c42e 100644 --- a/src/gpu/gl/GrGLPrimitiveProcessor.h +++ b/src/gpu/gl/GrGLPrimitiveProcessor.h @@ -15,7 +15,7 @@ class GrBatchTracker; class GrPrimitiveProcessor; -class GrGLGPBuilder; +class GrGLSLGPBuilder; class GrGLPrimitiveProcessor { public: @@ -29,7 +29,7 @@ public: typedef SkSTArray<8, GrGLSLTransformedCoordsArray> TransformsOut; struct EmitArgs { - EmitArgs(GrGLGPBuilder* pb, + EmitArgs(GrGLSLGPBuilder* pb, const GrPrimitiveProcessor& gp, const char* outputColor, const char* outputCoverage, @@ -43,7 +43,7 @@ public: , fSamplers(samplers) , fTransformsIn(transformsIn) , fTransformsOut(transformsOut) {} - GrGLGPBuilder* fPB; + GrGLSLGPBuilder* fPB; const GrPrimitiveProcessor& fGP; const char* fOutputColor; const char* fOutputCoverage; @@ -75,7 +75,9 @@ public: const SkTArray& transforms) = 0; protected: - void setupUniformColor(GrGLGPBuilder* pb, const char* outputName, UniformHandle* colorUniform); + void setupUniformColor(GrGLSLGPBuilder* pb, + const char* outputName, + UniformHandle* colorUniform); struct Transform { Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidMatrix(); } diff --git a/src/gpu/gl/GrGLXferProcessor.h b/src/gpu/gl/GrGLXferProcessor.h index d461997..1e505f3 100644 --- a/src/gpu/gl/GrGLXferProcessor.h +++ b/src/gpu/gl/GrGLXferProcessor.h @@ -11,7 +11,7 @@ #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLTextureSampler.h" -class GrGLXPBuilder; +class GrGLSLXPBuilder; class GrXferProcessor; class GrGLXferProcessor { @@ -21,7 +21,7 @@ public: typedef GrGLSLTextureSampler::TextureSamplerArray TextureSamplerArray; struct EmitArgs { - EmitArgs(GrGLXPBuilder* pb, + EmitArgs(GrGLSLXPBuilder* pb, const GrXferProcessor& xp, const char* inputColor, const char* inputCoverage, @@ -36,7 +36,7 @@ public: , fOutputSecondary(outputSecondary) , fSamplers(samplers) {} - GrGLXPBuilder* fPB; + GrGLSLXPBuilder* fPB; const GrXferProcessor& fXP; const char* fInputColor; const char* fInputCoverage; @@ -74,8 +74,11 @@ private: * the blending logic. The base class applies coverage. A subclass only needs to implement this * method if it can construct a GrXferProcessor that reads the dst color. */ - virtual void emitBlendCodeForDstRead(GrGLXPBuilder*, const char* srcColor, const char* dstColor, - const char* outColor, const GrXferProcessor&) { + virtual void emitBlendCodeForDstRead(GrGLSLXPBuilder*, + const char* srcColor, + const char* dstColor, + const char* outColor, + const GrXferProcessor&) { SkFAIL("emitBlendCodeForDstRead not implemented."); } diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index d06c2f3..c464ffd 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -7,17 +7,11 @@ #include "GrGLFragmentShaderBuilder.h" #include "GrRenderTarget.h" -#include "GrGLProgramBuilder.h" -#include "gl/GrGLGpu.h" #include "glsl/GrGLSL.h" #include "glsl/GrGLSLCaps.h" - -#define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X) -#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X) +#include "glsl/GrGLSLProgramBuilder.h" const char* GrGLFragmentShaderBuilder::kDstTextureColorName = "_dstColor"; -static const char* declared_color_output_name() { return "fsColorOut"; } -static const char* declared_secondary_color_output_name() { return "fsSecondaryColorOut"; } static const char* specific_layout_qualifier_name(GrBlendEquation equation) { SkASSERT(GrBlendEquationIsAdvanced(equation)); @@ -69,11 +63,9 @@ GrGLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst) { } } -GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, +GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey) : INHERITED(program) - , fHasCustomColorOutput(false) - , fHasSecondaryOutput(false) , fSetupFragPosition(false) , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == fragPosKey) , fCustomColorOutputIndex(-1) @@ -118,18 +110,18 @@ SkString GrGLFragmentShaderBuilder::ensureFSCoords2D(const GrGLSLTransformedCoor const char* GrGLFragmentShaderBuilder::fragmentPosition() { fHasReadFragmentPosition = true; - GrGLGpu* gpu = fProgramBuilder->gpu(); + const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps(); // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the // declaration varies in earlier GLSL specs. So it is simpler to omit it. if (fTopLeftFragPosRead) { fSetupFragPosition = true; return "gl_FragCoord"; - } else if (gpu->glCaps().fragCoordConventionsSupport()) { + } else if (const char* extension = glslCaps->fragCoordConventionsExtensionString()) { if (!fSetupFragPosition) { - if (gpu->glslGeneration() < k150_GrGLSLGeneration) { + if (glslCaps->generation() < k150_GrGLSLGeneration) { this->addFeature(1 << kFragCoordConventions_GLSLPrivateFeature, - "GL_ARB_fragment_coord_conventions"); + extension); } fInputs.push_back().set(kVec4f_GrSLType, GrGLSLShaderVar::kIn_TypeModifier, @@ -147,7 +139,7 @@ const char* GrGLFragmentShaderBuilder::fragmentPosition() { const char* rtHeightName; fProgramBuilder->fUniformHandles.fRTHeightUni = - fProgramBuilder->addFragPosUniform(GrGLProgramBuilder::kFragment_Visibility, + fProgramBuilder->addFragPosUniform(GrGLSLProgramBuilder::kFragment_Visibility, kFloat_GrSLType, kDefault_GrSLPrecision, "RTHeight", @@ -181,7 +173,7 @@ const char* GrGLFragmentShaderBuilder::dstColor() { if (glslCaps->fbFetchNeedsCustomOutput()) { this->enableCustomOutput(); fOutputs[fCustomColorOutputIndex].setTypeModifier(GrShaderVar::kInOut_TypeModifier); - fbFetchColorName = declared_color_output_name(); + fbFetchColorName = DeclaredColorOutputName(); } return fbFetchColorName; } else { @@ -212,35 +204,35 @@ void GrGLFragmentShaderBuilder::enableCustomOutput() { fCustomColorOutputIndex = fOutputs.count(); fOutputs.push_back().set(kVec4f_GrSLType, GrGLSLShaderVar::kOut_TypeModifier, - declared_color_output_name()); + DeclaredColorOutputName()); } } void GrGLFragmentShaderBuilder::enableSecondaryOutput() { SkASSERT(!fHasSecondaryOutput); fHasSecondaryOutput = true; - if (kGLES_GrGLStandard == fProgramBuilder->gpu()->ctxInfo().standard()) { - this->addFeature(1 << kBlendFuncExtended_GLSLPrivateFeature, "GL_EXT_blend_func_extended"); + const GrGLSLCaps& caps = *fProgramBuilder->glslCaps(); + if (const char* extension = caps.secondaryOutputExtensionString()) { + this->addFeature(1 << kBlendFuncExtended_GLSLPrivateFeature, extension); } // If the primary output is declared, we must declare also the secondary output // and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom // output. The condition also co-incides with the condition in whici GLES SL 2.0 // requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output. - const GrGLSLCaps& caps = *fProgramBuilder->glslCaps(); if (caps.mustDeclareFragmentShaderOutput()) { fOutputs.push_back().set(kVec4f_GrSLType, GrGLSLShaderVar::kOut_TypeModifier, - declared_secondary_color_output_name()); + DeclaredSecondaryColorOutputName()); } } const char* GrGLFragmentShaderBuilder::getPrimaryColorOutputName() const { - return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor"; + return fHasCustomColorOutput ? DeclaredColorOutputName() : "gl_FragColor"; } const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const { - const GrGLSLCaps& caps = *fProgramBuilder->gpu()->glCaps().glslCaps(); - return caps.mustDeclareFragmentShaderOutput() ? declared_secondary_color_output_name() + const GrGLSLCaps& caps = *fProgramBuilder->glslCaps(); + return caps.mustDeclareFragmentShaderOutput() ? DeclaredSecondaryColorOutputName() : "gl_SecondaryFragColorEXT"; } @@ -250,18 +242,7 @@ void GrGLFragmentShaderBuilder::onFinalize() { &this->precisionQualifier()); } -void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID) { - const GrGLCaps& caps = fProgramBuilder->gpu()->glCaps(); - if (fHasCustomColorOutput && caps.bindFragDataLocationSupport()) { - GL_CALL(BindFragDataLocation(programID, 0, declared_color_output_name())); - } - if (fHasSecondaryOutput && caps.glslCaps()->mustDeclareFragmentShaderOutput()) { - GL_CALL(BindFragDataLocationIndexed(programID, 0, 1, - declared_secondary_color_output_name())); - } -} - -void GrGLFragmentShaderBuilder::addVarying(GrGLVarying* v, GrSLPrecision fsPrec) { +void GrGLFragmentShaderBuilder::addVarying(GrGLSLVarying* v, GrSLPrecision fsPrec) { v->fFsIn = v->fVsOut; if (v->fGsOut) { v->fFsIn = v->fGsOut; @@ -284,3 +265,4 @@ void GrGLFragmentBuilder::onAfterChildProcEmitCode() { int removeAt = fMangleString.findLastOf('_'); fMangleString.remove(removeAt, fMangleString.size() - removeAt); } + diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 39ca5e7..16cc8cf 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -10,19 +10,20 @@ #include "GrGLShaderBuilder.h" -#include "gl/GrGLTypes.h" #include "glsl/GrGLSLProcessorTypes.h" class GrRenderTarget; -class GrGLVarying; +class GrGLSLVarying; /* * This base class encapsulates the functionality which the GP uses to build fragment shaders */ class GrGLFragmentBuilder : public GrGLShaderBuilder { public: - GrGLFragmentBuilder(GrGLProgramBuilder* program) - : INHERITED(program) { + GrGLFragmentBuilder(GrGLSLProgramBuilder* program) + : INHERITED(program) + , fHasCustomColorOutput(false) + , fHasSecondaryOutput(false) { fSubstageIndices.push_back(0); } virtual ~GrGLFragmentBuilder() {} @@ -62,6 +63,13 @@ public: const SkString& getMangleString() const { return fMangleString; } + bool hasCustomColorOutput() const { return fHasCustomColorOutput; } + bool hasSecondaryOutput() const { return fHasSecondaryOutput; } + +protected: + bool fHasCustomColorOutput; + bool fHasSecondaryOutput; + private: /* * State that tracks which child proc in the proc tree is currently emitting code. This is @@ -95,7 +103,7 @@ private: */ class GrGLXPFragmentBuilder : public GrGLFragmentBuilder { public: - GrGLXPFragmentBuilder(GrGLProgramBuilder* program) : INHERITED(program) {} + GrGLXPFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {} /** Returns the variable name that holds the color of the destination pixel. This may be nullptr if no effect advertised that it will read the destination. */ @@ -120,7 +128,7 @@ public: the key is 0. */ static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst); - GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, uint8_t fragPosKey); + GrGLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey); // true public interface, defined explicitly in the abstract interfaces above bool enableFeature(GLSLFeature) override; @@ -137,7 +145,6 @@ private: void enableSecondaryOutput(); const char* getPrimaryColorOutputName() const; const char* getSecondaryColorOutputName() const; - void bindFragmentShaderLocations(GrGLuint programID); // As GLProcessors emit code, there are some conditions we need to verify. We use the below // state to track this. The reset call is called per processor emitted. @@ -148,10 +155,13 @@ private: fHasReadFragmentPosition = false; } + static const char* DeclaredColorOutputName() { return "fsColorOut"; } + static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; } + /* * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader */ - void addVarying(GrGLVarying*, GrSLPrecision); + void addVarying(GrGLSLVarying*, GrSLPrecision); void onFinalize() override; @@ -174,8 +184,6 @@ private: static const char* kDstTextureColorName; - bool fHasCustomColorOutput; - bool fHasSecondaryOutput; bool fSetupFragPosition; bool fTopLeftFragPosRead; int fCustomColorOutputIndex; diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp index 159b904..420c513 100644 --- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp @@ -9,12 +9,12 @@ #include "GrGLProgramBuilder.h" #include "../GrGLGpu.h" -GrGLGeometryBuilder::GrGLGeometryBuilder(GrGLProgramBuilder* program) +GrGLGeometryBuilder::GrGLGeometryBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) { } -void GrGLGeometryBuilder::addVarying(const char* name, GrSLPrecision precision, GrGLVarying* v) { +void GrGLGeometryBuilder::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()) { diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h index 7691666..e807646 100644 --- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h @@ -10,17 +10,17 @@ #include "GrGLShaderBuilder.h" -class GrGLVarying; +class GrGLSLVarying; class GrGLGeometryBuilder : public GrGLShaderBuilder { public: - GrGLGeometryBuilder(GrGLProgramBuilder* program); + GrGLGeometryBuilder(GrGLSLProgramBuilder* program); private: /* * an internal call for GrGLFullProgramBuilder to add varyings */ - void addVarying(const char* name, GrSLPrecision precision, GrGLVarying*); + void addVarying(const char* name, GrSLPrecision precision, GrGLSLVarying*); void onFinalize() override {} diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 232c7ba..d336ff1 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -27,8 +27,6 @@ #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) -const int GrGLProgramBuilder::kVarsPerBlock = 8; - GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gpu) { GrAutoLocaleSetter als("C"); @@ -53,13 +51,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp ///////////////////////////////////////////////////////////////////////////// GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) - : fVS(this) - , fGS(this) - , fFS(this, args.fDesc->header().fFragPosKey) - , fStageIndex(-1) + : INHERITED(args) , fGeometryProcessor(nullptr) , fXferProcessor(nullptr) - , fArgs(args) , fGpu(gpu) , fUniforms(kVarsPerBlock) , fSamplerUniforms(4) @@ -67,7 +61,7 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) } void GrGLProgramBuilder::addVarying(const char* name, - GrGLVarying* varying, + GrGLSLVarying* varying, GrSLPrecision precision) { SkASSERT(varying); if (varying->vsVarying()) { @@ -84,7 +78,7 @@ void GrGLProgramBuilder::addVarying(const char* name, void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Attribute* input, const char* output) { GrSLType type = GrVertexAttribTypeToSLType(input->fType); - GrGLVertToFrag v(type); + GrGLSLVertToFrag v(type); this->addVarying(input->fName, &v); fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); fFS.codeAppendf("%s = %s;", output, v.fsIn()); @@ -92,7 +86,7 @@ void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVarying( const char* name, - GrGLVertToFrag* v, + GrGLSLVertToFrag* v, GrSLPrecision fsPrecision) { // This call is not used for non-NVPR backends. SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport() && @@ -106,21 +100,6 @@ GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi return SeparableVaryingHandle(varyingInfo.fLocation); } -void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name, bool mangle) { - if ('\0' == prefix) { - *out = name; - } else { - out->printf("%c%s", prefix, name); - } - if (mangle) { - if (out->endsWith('_')) { - // Names containing "__" are reserved. - out->append("x"); - } - out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str()); - } -} - GrGLSLProgramDataManager::UniformHandle GrGLProgramBuilder::internalAddUniformArray( uint32_t visibility, GrSLType type, @@ -159,8 +138,7 @@ GrGLSLProgramDataManager::UniformHandle GrGLProgramBuilder::internalAddUniformAr return GrGLSLProgramDataManager::UniformHandle(fUniforms.count() - 1); } -void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility, - SkString* out) const { +void GrGLProgramBuilder::onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const { for (int i = 0; i < fUniforms.count(); ++i) { if (fUniforms[i].fVisibility & visibility) { fUniforms[i].fVariable.appendDecl(this->glslCaps(), out); @@ -169,12 +147,8 @@ void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility, } } -const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const { - return fGpu->ctxInfo(); -} - const GrGLSLCaps* GrGLProgramBuilder::glslCaps() const { - return this->ctxInfo().caps()->glslCaps(); + return this->fGpu->ctxInfo().caps()->glslCaps(); } bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) { @@ -330,7 +304,7 @@ void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp, fFS.enableSecondaryOutput(); } - if (this->ctxInfo().caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { + if (this->glslCaps()->mustDeclareFragmentShaderOutput()) { fFS.enableCustomOutput(); } @@ -423,7 +397,12 @@ GrGLProgram* GrGLProgramBuilder::finalize() { // NVPR actually requires a vertex shader to compile bool useNvpr = primitiveProcessor().isPathRendering(); if (!useNvpr) { - fVS.bindVertexAttributes(programID); + const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); + + int vaCount = primProc.numAttribs(); + for (int i = 0; i < vaCount; i++) { + GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName)); + } } fFS.finalize(kFragment_Visibility); @@ -460,7 +439,15 @@ void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { } } - fFS.bindFragmentShaderLocations(programID); + const GrGLCaps& caps = this->gpu()->glCaps(); + if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) { + GL_CALL(BindFragDataLocation(programID, 0, + GrGLFragmentShaderBuilder::DeclaredColorOutputName())); + } + if (fFS.hasSecondaryOutput() && caps.glslCaps()->mustDeclareFragmentShaderOutput()) { + GL_CALL(BindFragDataLocationIndexed(programID, 0, 1, + GrGLFragmentShaderBuilder::DeclaredSecondaryColorOutputName())); + } // handle NVPR separable varyings if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 3a1a50e..c524f59 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -8,10 +8,8 @@ #ifndef GrGLProgramBuilder_DEFINED #define GrGLProgramBuilder_DEFINED -#include "GrGLFragmentShaderBuilder.h" -#include "GrGLGeometryShaderBuilder.h" -#include "GrGLVertexShaderBuilder.h" #include "gl/GrGLProgramDataManager.h" +#include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLTextureSampler.h" #include "../GrGLPrimitiveProcessor.h" @@ -20,199 +18,12 @@ class GrFragmentProcessor; class GrGLContextInfo; +class GrGLShaderBuilder; class GrGLSLCaps; // Enough precision to represent 1 / 2048 accurately in printf #define GR_SIGNIFICANT_POW2_DECIMAL_DIG 11 -/* - * This is the base class for a series of interfaces. This base class *MUST* remain abstract with - * NO data members because it is used in multiple interface inheritance. - * Heirarchy: - * GrGLUniformBuilder - * / \ - * GrGLFPBuilder GrGLGPBuilder - * \ / - * GrGLProgramBuilder(internal use only) - */ -class GrGLUniformBuilder { -public: - enum ShaderVisibility { - kVertex_Visibility = 1 << kVertex_GrShaderType, - kGeometry_Visibility = 1 << kGeometry_GrShaderType, - kFragment_Visibility = 1 << kFragment_GrShaderType, - }; - - virtual ~GrGLUniformBuilder() {} - - 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 - uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not - supported at this time. The actual uniform name will be mangled. If outName is not nullptr then - it will refer to the final uniform name after return. Use the addUniformArray variant to add - an array of uniforms. */ - UniformHandle addUniform(uint32_t visibility, - GrSLType type, - GrSLPrecision precision, - const char* name, - const char** outName = nullptr) { - return this->addUniformArray(visibility, type, precision, name, 0, outName); - } - - virtual UniformHandle addUniformArray( - uint32_t visibility, - GrSLType type, - GrSLPrecision precision, - const char* name, - int arrayCount, - const char** outName = nullptr) { - return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount, - outName); - } - - - virtual const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const = 0; - - /** - * Shortcut for getUniformVariable(u).c_str() - */ - virtual const char* getUniformCStr(UniformHandle u) const = 0; - - virtual const GrGLContextInfo& ctxInfo() const = 0; - - virtual const GrGLSLCaps* glslCaps() const = 0; - - virtual GrGLGpu* gpu() const = 0; - - /* - * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE - */ -private: - virtual UniformHandle internalAddUniformArray( - uint32_t visibility, - GrSLType type, - GrSLPrecision precision, - const char* name, - bool mangleName, - int arrayCount, - const char** outName) = 0; -}; - -// TODO move this into GrGLGPBuilder and move them both out of this file -class GrGLVarying { -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, - }; - - GrGLVarying(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 GrGLVertexBuilder; - friend class GrGLGeometryBuilder; - friend class GrGLXferBuilder; - friend class GrGLFragmentShaderBuilder; -}; - -struct GrGLVertToFrag : public GrGLVarying { - GrGLVertToFrag(GrSLType type) - : GrGLVarying(type, kVertToFrag_Varying) {} -}; - -struct GrGLVertToGeo : public GrGLVarying { - GrGLVertToGeo(GrSLType type) - : GrGLVarying(type, kVertToGeo_Varying) {} -}; - -struct GrGLGeoToFrag : public GrGLVarying { - GrGLGeoToFrag(GrSLType type) - : GrGLVarying(type, kGeoToFrag_Varying) {} -}; - -/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */ -class GrGLGPBuilder : public virtual GrGLUniformBuilder { -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, - GrGLVarying*, - 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 GrGLUniformBuilder::addUniform(). - */ - virtual SeparableVaryingHandle addSeparableVarying( - const char* name, GrGLVertToFrag*, GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0; - - // TODO rename getFragmentBuilder - virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0; - virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0; - - /* - * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE - */ -}; - -/* a specializations for FPs. Lets the user add uniforms and FS code */ -class GrGLFPBuilder : public virtual GrGLUniformBuilder { -public: - virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0; - - /* - * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE - */ -}; - -/* a specializations for XPs. Lets the user add uniforms and FS code */ -class GrGLXPBuilder : public virtual GrGLUniformBuilder { -public: - virtual GrGLXPFragmentBuilder* getFragmentShaderBuilder() = 0; - - /* - * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE - */ -}; - /** * The below struct represent processors installed in programs. */ @@ -238,11 +49,8 @@ struct GrGLInstalledFragProcs : public SkRefCnt { * each of the elements of the shader pipeline, ie vertex, fragment, geometry, etc, lives in those * respective builders */ -class GrGLProgramBuilder : public GrGLGPBuilder, - public GrGLFPBuilder, - public GrGLXPBuilder { +class GrGLProgramBuilder : public GrGLSLProgramBuilder { public: - typedef GrGpu::DrawArgs DrawArgs; /** Generates a shader program. * * The program implements what is specified in the stages given as input. @@ -260,18 +68,13 @@ public: return this->getUniformVariable(u).c_str(); } - const GrGLContextInfo& ctxInfo() const override; - const GrGLSLCaps* glslCaps() const override; - GrGLGpu* gpu() const override { return fGpu; } - - GrGLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; } - GrGLVertexBuilder* getVertexShaderBuilder() override { return &fVS; } + GrGLGpu* gpu() const { return fGpu; } void addVarying( const char* name, - GrGLVarying*, + GrGLSLVarying*, GrSLPrecision precision = kDefault_GrSLPrecision) override; void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*, @@ -279,19 +82,10 @@ public: SeparableVaryingHandle addSeparableVarying( const char* name, - GrGLVertToFrag*, + GrGLSLVertToFrag*, GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override; - // Handles for program uniforms (other than per-effect uniforms) - struct BuiltinUniformHandles { - UniformHandle fRTAdjustmentUni; - - // We use the render target height to provide a y-down frag coord when specifying - // origin_upper_left is not supported. - UniformHandle fRTHeightUni; - }; - -protected: +private: typedef GrGLProgramDataManager::UniformInfo UniformInfo; typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; typedef GrGLProgramDataManager::SeparableVaryingInfo SeparableVaryingInfo; @@ -299,11 +93,6 @@ protected: GrGLProgramBuilder(GrGLGpu*, const DrawArgs&); - const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; } - const GrPipeline& pipeline() const { return *fArgs.fPipeline; } - const GrProgramDesc& desc() const { return *fArgs.fDesc; } - const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); } - UniformHandle internalAddUniformArray(uint32_t visibility, GrSLType type, GrSLPrecision precision, @@ -312,20 +101,6 @@ protected: int arrayCount, const char** outName) override; - // Used to add a uniform for frag position without mangling the name of the uniform inside of a - // stage. - UniformHandle addFragPosUniform(uint32_t visibility, - GrSLType type, - GrSLPrecision precision, - const char* name, - const char** outName) { - return this->internalAddUniformArray(visibility, type, precision, name, false, 0, outName); - } - - // Generates a name for a variable. The generated string will be name prefixed by the prefix - // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless - // explicitly asked not to. - void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true); // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. // If GrGLSLExpr4 has a valid name then it will use that instead void nameExpression(GrGLSLExpr4*, const char* baseName); @@ -365,16 +140,16 @@ protected: GrGLenum type, SkTDArray* shaderIds); GrGLProgram* finalize(); - virtual void bindProgramResourceLocations(GrGLuint programID); + void bindProgramResourceLocations(GrGLuint programID); bool checkLinkStatus(GrGLuint programID); - virtual void resolveProgramResourceLocations(GrGLuint programID); + void resolveProgramResourceLocations(GrGLuint programID); void cleanupProgram(GrGLuint programID, const SkTDArray& shaderIDs); void cleanupShaders(const SkTDArray& shaderIDs); // Subclasses create different programs - virtual GrGLProgram* createProgram(GrGLuint programID); + GrGLProgram* createProgram(GrGLuint programID); - void appendUniformDecls(ShaderVisibility, SkString*) const; + void onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const override; // 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 @@ -397,24 +172,11 @@ protected: private: GrGLProgramBuilder* fPB; }; - int stageIndex() const { return fStageIndex; } - - const char* rtAdjustment() const { return "rtAdjustment"; } - - // number of each input/output type in a single allocation block, used by many builders - static const int kVarsPerBlock; - - BuiltinUniformHandles fUniformHandles; - GrGLVertexBuilder fVS; - GrGLGeometryBuilder fGS; - GrGLFragmentShaderBuilder fFS; - int fStageIndex; GrGLInstalledGeoProc* fGeometryProcessor; GrGLInstalledXferProc* fXferProcessor; SkAutoTUnref fFragmentProcessors; - const DrawArgs& fArgs; GrGLGpu* fGpu; UniformInfoArray fUniforms; GrGLPrimitiveProcessor::TransformsIn fCoordTransforms; @@ -426,5 +188,7 @@ protected: friend class GrGLVertexBuilder; friend class GrGLFragmentShaderBuilder; friend class GrGLGeometryBuilder; + + typedef GrGLSLProgramBuilder INHERITED; }; #endif diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp index 2c00baf..ed5c3d4 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp @@ -6,10 +6,10 @@ */ #include "GrGLShaderBuilder.h" -#include "gl/builders/GrGLProgramBuilder.h" #include "glsl/GrGLSLCaps.h" #include "glsl/GrGLSLShaderVar.h" #include "glsl/GrGLSLTextureSampler.h" +#include "glsl/GrGLSLProgramBuilder.h" static void map_swizzle(const char* swizzleMap, const char* swizzle, char* mangledSwizzle) { int i; @@ -69,10 +69,10 @@ static void append_texture_lookup(SkString* out, } } -GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program) +GrGLShaderBuilder::GrGLShaderBuilder(GrGLSLProgramBuilder* program) : fProgramBuilder(program) - , fInputs(GrGLProgramBuilder::kVarsPerBlock) - , fOutputs(GrGLProgramBuilder::kVarsPerBlock) + , fInputs(GrGLSLProgramBuilder::kVarsPerBlock) + , fOutputs(GrGLSLProgramBuilder::kVarsPerBlock) , fFeaturesAddedMask(0) , fCodeIndex(kCode) , fFinalized(false) { @@ -187,11 +187,11 @@ void GrGLShaderBuilder::finalize(uint32_t visibility) { this->versionDecl() = fProgramBuilder->glslCaps()->versionDeclString(); this->compileAndAppendLayoutQualifiers(); SkASSERT(visibility); - fProgramBuilder->appendUniformDecls((GrGLProgramBuilder::ShaderVisibility) 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(GrGLProgramBuilder::kFragment_Visibility != visibility || + SkASSERT(GrGLSLProgramBuilder::kFragment_Visibility != visibility || k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() || fOutputs.empty()); this->appendDecls(fOutputs, &this->outputs()); diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h index d63a679..2978db3 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLShaderBuilder.h @@ -14,7 +14,7 @@ #include -class GrGLProgramBuilder; +class GrGLSLProgramBuilder; class GrGLSLTextureSampler; /** @@ -22,7 +22,7 @@ class GrGLSLTextureSampler; */ class GrGLShaderBuilder { public: - GrGLShaderBuilder(GrGLProgramBuilder* program); + GrGLShaderBuilder(GrGLSLProgramBuilder* program); virtual ~GrGLShaderBuilder() {} void addInput(const GrGLSLShaderVar& input) { fInputs.push_back(input); } @@ -102,7 +102,7 @@ public: /* * Get parent builder for adding uniforms */ - GrGLProgramBuilder* getProgramBuilder() { return fProgramBuilder; } + GrGLSLProgramBuilder* getProgramBuilder() { return fProgramBuilder; } /** * Helper for begining and ending a block in the shader code. @@ -179,7 +179,7 @@ protected: kCode, }; - GrGLProgramBuilder* fProgramBuilder; + GrGLSLProgramBuilder* fProgramBuilder; SkSTArray fCompilerStrings; SkSTArray fCompilerStringLengths; SkSTArray fShaderStrings; diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp index f19d63f..c4054e2 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp @@ -6,19 +6,14 @@ */ #include "GrGLVertexShaderBuilder.h" -#include "GrGLProgramBuilder.h" -#include "../GrGLGLSL.h" -#include "../GrGLGpu.h" +#include "glsl/GrGLSLProgramBuilder.h" -#define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X) -#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X) - -GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program) +GrGLVertexBuilder::GrGLVertexBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) , fRtAdjustName(nullptr) { } -void GrGLVertexBuilder::addVarying(const char* name, GrSLPrecision precision, GrGLVarying* v) { +void GrGLVertexBuilder::addVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v) { fOutputs.push_back(); fOutputs.back().setType(v->fType); fOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); @@ -45,7 +40,7 @@ void GrGLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& posV // setup RT Uniform fProgramBuilder->fUniformHandles.fRTAdjustmentUni = - fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility, + fProgramBuilder->addUniform(GrGLSLProgramBuilder::kVertex_Visibility, kVec4f_GrSLType, precision, fProgramBuilder->rtAdjustment(), &fRtAdjustName); @@ -77,16 +72,6 @@ void GrGLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& posV this->codeAppend("gl_PointSize = 1.0;"); } -void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) { - const GrPrimitiveProcessor& primProc = fProgramBuilder->primitiveProcessor(); - - int vaCount = primProc.numAttribs(); - for (int i = 0; i < vaCount; i++) { - GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName)); - } - return; -} - bool GrGLVertexBuilder::addAttribute(const GrShaderVar& var) { SkASSERT(GrShaderVar::kAttribute_TypeModifier == var.getTypeModifier()); for (int i = 0; i < fInputs.count(); ++i) { @@ -99,3 +84,4 @@ bool GrGLVertexBuilder::addAttribute(const GrShaderVar& var) { fInputs.push_back(var); return true; } + diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h index 81aebd4..4662c40 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h @@ -9,14 +9,13 @@ #define GrGLVertexShader_DEFINED #include "GrGLShaderBuilder.h" -#include "gl/GrGLTypes.h" #include "GrGeometryProcessor.h" -class GrGLVarying; +class GrGLSLVarying; class GrGLVertexBuilder : public GrGLShaderBuilder { public: - GrGLVertexBuilder(GrGLProgramBuilder* program); + GrGLVertexBuilder(GrGLSLProgramBuilder* program); void transformToNormalizedDeviceSpace(const GrShaderVar& posVar); void emitAttributes(const GrGeometryProcessor& gp); @@ -33,12 +32,7 @@ private: /* * Internal call for GrGLProgramBuilder.addVarying */ - void addVarying(const char* name, GrSLPrecision, GrGLVarying*); - - /* - * private helpers for compilation by GrGLProgramBuilder - */ - void bindVertexAttributes(GrGLuint programID); + 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); diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp index 140cb11..aed9888 100755 --- a/src/gpu/glsl/GrGLSLCaps.cpp +++ b/src/gpu/glsl/GrGLSLCaps.cpp @@ -22,8 +22,12 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) { fUsesPrecisionModifiers = false; fCanUseAnyFunctionInShader = true; fForceHighPrecisionNDSTransform = false; + fCanUseMinAndAbsTogether = true; + fMustForceNegatedAtanParamToFloat = false; fVersionDeclString = nullptr; fShaderDerivativeExtensionString = nullptr; + fFragCoordConventionsExtensionString = nullptr; + fSecondaryOutputExtensionString = nullptr; fFBFetchColorName = nullptr; fFBFetchExtensionString = nullptr; fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction; @@ -53,9 +57,12 @@ SkString GrGLSLCaps::dump() const { r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO")); r.appendf("Bindless texture support: %s\n", (fBindlessTextureSupport ? "YES" : "NO")); r.appendf("Uses precision modifiers: %s\n", (fUsesPrecisionModifiers ? "YES" : "NO")); - r.appendf("Can Use any() function: %s\n", (fCanUseAnyFunctionInShader ? "YES" : "NO")); + r.appendf("Can use any() function: %s\n", (fCanUseAnyFunctionInShader ? "YES" : "NO")); r.appendf("Force high precision on NDS transform: %s\n", (fForceHighPrecisionNDSTransform ? "YES" : "NO")); + r.appendf("Can use min() and abs() together: %s\n", (fCanUseMinAndAbsTogether ? "YES" : "NO")); + r.appendf("Must force negated atan param to float: %s\n", (fMustForceNegatedAtanParamToFloat ? + "YES" : "NO")); r.appendf("Advanced blend equation interaction: %s\n", kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]); return r; diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h index e703fb8..68e91b6 100755 --- a/src/gpu/glsl/GrGLSLCaps.h +++ b/src/gpu/glsl/GrGLSLCaps.h @@ -74,6 +74,10 @@ public: bool forceHighPrecisionNDSTransform() const { return fForceHighPrecisionNDSTransform; } + bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; } + + bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; } + // Returns the string of an extension that must be enabled in the shader to support // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling // this function, the caller should check that shaderDerivativeSupport exists. @@ -81,6 +85,22 @@ public: SkASSERT(this->shaderDerivativeSupport()); return fShaderDerivativeExtensionString; } + + // Returns the string of an extension that will do all necessary coord transfomations needed + // when reading the fragment position. If such an extension does not exisits, this function + // returns a nullptr, and all transforms of the frag position must be done manually in the + // shader. + const char* fragCoordConventionsExtensionString() const { + return fFragCoordConventionsExtensionString; + } + + // This returns the name of an extension that must be enabled in the shader, if such a thing is + // required in order to use a secondary output in the shader. This returns a nullptr if no such + // extension is required. However, the return value of this function does not say whether dual + // source blending is supported. + const char* secondaryOutputExtensionString() const { + return fSecondaryOutputExtensionString; + } bool mustSwizzleInShader() const { return fMustSwizzleInShader; } @@ -111,9 +131,15 @@ private: bool fCanUseAnyFunctionInShader : 1; bool fForceHighPrecisionNDSTransform : 1; + // Used for specific driver bug work arounds + bool fCanUseMinAndAbsTogether : 1; + bool fMustForceNegatedAtanParamToFloat : 1; + const char* fVersionDeclString; const char* fShaderDerivativeExtensionString; + const char* fFragCoordConventionsExtensionString; + const char* fSecondaryOutputExtensionString; const char* fFBFetchColorName; const char* fFBFetchExtensionString; diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp new file mode 100644 index 0000000..54e82b3 --- /dev/null +++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp @@ -0,0 +1,39 @@ +/* + * 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/GrGLSLProgramBuilder.h" + +const int GrGLSLProgramBuilder::kVarsPerBlock = 8; + +GrGLSLProgramBuilder::GrGLSLProgramBuilder(const DrawArgs& args) + : fVS(this) + , fGS(this) + , fFS(this, args.fDesc->header().fFragPosKey) + , fStageIndex(-1) + , fArgs(args) { +} + +void GrGLSLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name, bool mangle) { + if ('\0' == prefix) { + *out = name; + } else { + out->printf("%c%s", prefix, name); + } + if (mangle) { + if (out->endsWith('_')) { + // Names containing "__" are reserved. + out->append("x"); + } + out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str()); + } +} + +void GrGLSLProgramBuilder::appendUniformDecls(ShaderVisibility visibility, + SkString* out) const { + this->onAppendUniformDecls(visibility, out); +} + diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h new file mode 100644 index 0000000..f783a40 --- /dev/null +++ b/src/gpu/glsl/GrGLSLProgramBuilder.h @@ -0,0 +1,261 @@ +/* + * 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 GrGLSLProgramBuilder_DEFINED +#define GrGLSLProgramBuilder_DEFINED + +#include "GrGeometryProcessor.h" +#include "GrGpu.h" +#include "gl/builders/GrGLFragmentShaderBuilder.h" +#include "gl/builders/GrGLGeometryShaderBuilder.h" +#include "gl/builders/GrGLVertexShaderBuilder.h" +#include "glsl/GrGLSLProgramDataManager.h" + +class GrGLSLCaps; +class GrGLSLShaderVar; + +class GrGLSLUniformBuilder { +public: + enum ShaderVisibility { + kVertex_Visibility = 1 << kVertex_GrShaderType, + kGeometry_Visibility = 1 << kGeometry_GrShaderType, + kFragment_Visibility = 1 << kFragment_GrShaderType, + }; + + 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 + uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not + supported at this time. The actual uniform name will be mangled. If outName is not nullptr + then it will refer to the final uniform name after return. Use the addUniformArray variant + to add an array of uniforms. */ + UniformHandle addUniform(uint32_t visibility, + GrSLType type, + GrSLPrecision precision, + const char* name, + const char** outName = nullptr) { + return this->addUniformArray(visibility, type, precision, name, 0, outName); + } + + UniformHandle addUniformArray(uint32_t visibility, + GrSLType type, + GrSLPrecision precision, + const char* name, + int arrayCount, + const char** outName = nullptr) { + return this->internalAddUniformArray(visibility, type, precision, name, true, arrayCount, + outName); + } + + virtual const GrGLSLShaderVar& getUniformVariable(UniformHandle u) const = 0; + + /** + * Shortcut for getUniformVariable(u).c_str() + */ + virtual const char* getUniformCStr(UniformHandle u) const = 0; + + virtual const GrGLSLCaps* glslCaps() const = 0; + + /* + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE + */ +protected: + virtual UniformHandle internalAddUniformArray( + uint32_t visibility, + GrSLType type, + GrSLPrecision precision, + const char* name, + bool mangleName, + int arrayCount, + 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 GrGLVertexBuilder; + friend class GrGLGeometryBuilder; + friend class GrGLXferBuilder; + friend class GrGLFragmentShaderBuilder; +}; + +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; + + // TODO rename getFragmentBuilder + virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0; + virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0; + + /* + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE + */ +}; + + +/* a specializations for FPs. Lets the user add uniforms and FS code */ +class GrGLSLFPBuilder : public virtual GrGLSLUniformBuilder { +public: + virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0; + + /* + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE + */ +}; + +/* a specializations for XPs. Lets the user add uniforms and FS code */ +class GrGLSLXPBuilder : public virtual GrGLSLUniformBuilder { +public: + virtual GrGLXPFragmentBuilder* getFragmentShaderBuilder() = 0; + + /* + * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE + */ +}; + +class GrGLSLProgramBuilder : public GrGLSLGPBuilder, + public GrGLSLFPBuilder, + public GrGLSLXPBuilder { +public: + typedef GrGpu::DrawArgs DrawArgs; + + GrGLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; } + GrGLVertexBuilder* getVertexShaderBuilder() override { return &fVS; } + + // Handles for program uniforms (other than per-effect uniforms) + struct BuiltinUniformHandles { + UniformHandle fRTAdjustmentUni; + + // We use the render target height to provide a y-down frag coord when specifying + // origin_upper_left is not supported. + UniformHandle fRTHeightUni; + }; + +protected: + explicit GrGLSLProgramBuilder(const DrawArgs& args); + + const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; } + const GrPipeline& pipeline() const { return *fArgs.fPipeline; } + const GrProgramDesc& desc() const { return *fArgs.fDesc; } + const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); } + + void appendUniformDecls(ShaderVisibility, SkString*) const; + + // Used to add a uniform for frag position without mangling the name of the uniform inside of a + // stage. + UniformHandle addFragPosUniform(uint32_t visibility, + GrSLType type, + GrSLPrecision precision, + const char* name, + const char** outName) { + return this->internalAddUniformArray(visibility, type, precision, name, false, 0, outName); + } + + const char* rtAdjustment() const { return "rtAdjustment"; } + + // Generates a name for a variable. The generated string will be name prefixed by the prefix + // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless + // explicitly asked not to. + void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true); + + // number of each input/output type in a single allocation block, used by many builders + static const int kVarsPerBlock; + + GrGLVertexBuilder fVS; + GrGLGeometryBuilder fGS; + GrGLFragmentShaderBuilder fFS; + int fStageIndex; + + BuiltinUniformHandles fUniformHandles; + + const DrawArgs& fArgs; + +private: + virtual void onAppendUniformDecls(ShaderVisibility visibility, SkString* out) const = 0; + + friend class GrGLShaderBuilder; + friend class GrGLVertexBuilder; + friend class GrGLFragmentShaderBuilder; + friend class GrGLGeometryBuilder; +}; + +#endif -- 2.7.4