1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrGLSLProgramBuilder_DEFINED 9 #define GrGLSLProgramBuilder_DEFINED 10 11 #include "src/gpu/GrCaps.h" 12 #include "src/gpu/GrGeometryProcessor.h" 13 #include "src/gpu/GrProgramInfo.h" 14 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" 15 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 16 #include "src/gpu/glsl/GrGLSLGeometryProcessor.h" 17 #include "src/gpu/glsl/GrGLSLProgramDataManager.h" 18 #include "src/gpu/glsl/GrGLSLUniformHandler.h" 19 #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" 20 #include "src/gpu/glsl/GrGLSLXferProcessor.h" 21 #include "src/sksl/SkSLCompiler.h" 22 23 #include <vector> 24 25 class GrProgramDesc; 26 class GrRenderTarget; 27 class GrShaderVar; 28 class GrGLSLVaryingHandler; 29 class SkString; 30 class GrShaderCaps; 31 32 class GrGLSLProgramBuilder { 33 public: 34 using UniformHandle = GrGLSLUniformHandler::UniformHandle; 35 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 36 37 virtual ~GrGLSLProgramBuilder(); 38 39 virtual const GrCaps* caps() const = 0; shaderCaps()40 const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); } 41 origin()42 GrSurfaceOrigin origin() const { return fProgramInfo.origin(); } pipeline()43 const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); } geometryProcessor()44 const GrGeometryProcessor& geometryProcessor() const { return fProgramInfo.geomProc(); } processorFeatures()45 GrProcessor::CustomFeatures processorFeatures() const { 46 return fProgramInfo.requestedFeatures(); 47 } snapVerticesToPixelCenters()48 bool snapVerticesToPixelCenters() const { 49 return fProgramInfo.pipeline().snapVerticesToPixelCenters(); 50 } hasPointSize()51 bool hasPointSize() const { return fProgramInfo.primitiveType() == GrPrimitiveType::kPoints; } 52 virtual SkSL::Compiler* shaderCompiler() const = 0; 53 desc()54 const GrProgramDesc& desc() const { return fDesc; } 55 56 void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 57 samplerVariable(SamplerHandle handle)58 const char* samplerVariable(SamplerHandle handle) const { 59 return this->uniformHandler()->samplerVariable(handle); 60 } 61 samplerSwizzle(SamplerHandle handle)62 GrSwizzle samplerSwizzle(SamplerHandle handle) const { 63 return this->uniformHandler()->samplerSwizzle(handle); 64 } 65 inputSamplerVariable(SamplerHandle handle)66 const char* inputSamplerVariable(SamplerHandle handle) const { 67 return this->uniformHandler()->inputSamplerVariable(handle); 68 } 69 inputSamplerSwizzle(SamplerHandle handle)70 GrSwizzle inputSamplerSwizzle(SamplerHandle handle) const { 71 return this->uniformHandler()->inputSamplerSwizzle(handle); 72 } 73 74 // Used to add a uniform for the RenderTarget height (used for u_skRTHeight and frag position) 75 // without mangling the name of the uniform inside of a stage. 76 void addRTHeightUniform(const char* name); 77 78 // Generates a name for a variable. The generated string will be name prefixed by the prefix 79 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 80 // explicitly asked not to. `nameVariable` can also be used to generate names for functions or 81 // other types of symbols where unique names are important. 82 SkString nameVariable(char prefix, const char* name, bool mangle = true); 83 84 virtual GrGLSLUniformHandler* uniformHandler() = 0; 85 virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 86 virtual GrGLSLVaryingHandler* varyingHandler() = 0; 87 88 // Used for backend customization of the output color and secondary color variables from the 89 // fragment processor. Only used if the outputs are explicitly declared in the shaders finalizeFragmentOutputColor(GrShaderVar & outputColor)90 virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {} finalizeFragmentSecondaryColor(GrShaderVar & outputColor)91 virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {} 92 93 // number of each input/output type in a single allocation block, used by many builders 94 static const int kVarsPerBlock; 95 96 GrGLSLVertexBuilder fVS; 97 GrGLSLGeometryBuilder fGS; 98 GrGLSLFragmentShaderBuilder fFS; 99 100 int fStageIndex; 101 102 const GrProgramDesc& fDesc; 103 const GrProgramInfo& fProgramInfo; 104 105 GrGLSLBuiltinUniformHandles fUniformHandles; 106 107 std::unique_ptr<GrGLSLGeometryProcessor> fGeometryProcessor; 108 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor; 109 std::vector<std::unique_ptr<GrGLSLFragmentProcessor>> fFPImpls; 110 111 protected: 112 explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&); 113 114 void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName); 115 116 bool emitAndInstallProcs(); 117 118 void finalizeShaders(); 119 fragColorIsInOut()120 bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); } 121 122 private: 123 // reset is called by program creator between each processor's emit code. It increments the 124 // stage offset for variable name mangling, and also ensures verfication variables in the 125 // fragment shader are cleared. reset()126 void reset() { 127 this->addStage(); 128 SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();) 129 } addStage()130 void addStage() { fStageIndex++; } 131 132 class AutoStageAdvance { 133 public: AutoStageAdvance(GrGLSLProgramBuilder * pb)134 AutoStageAdvance(GrGLSLProgramBuilder* pb) 135 : fPB(pb) { 136 fPB->reset(); 137 // Each output to the fragment processor gets its own code section 138 fPB->fFS.nextStage(); 139 } ~AutoStageAdvance()140 ~AutoStageAdvance() {} 141 private: 142 GrGLSLProgramBuilder* fPB; 143 }; 144 145 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. 146 void nameExpression(SkString*, const char* baseName); 147 148 bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage); 149 bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut); 150 SkString emitFragProc(const GrFragmentProcessor&, 151 GrGLSLFragmentProcessor&, 152 int transformedCoordVarsIdx, 153 const SkString& input, 154 SkString output); 155 bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn); 156 SamplerHandle emitSampler(const GrBackendFormat&, GrSamplerState, const GrSwizzle&, 157 const char* name); 158 SamplerHandle emitInputSampler(const GrSwizzle& swizzle, const char* name); 159 bool checkSamplerCounts(); 160 161 #ifdef SK_DEBUG 162 void verify(const GrGeometryProcessor&); 163 void verify(const GrFragmentProcessor&); 164 void verify(const GrXferProcessor&); 165 #endif 166 167 // These are used to check that we don't excede the allowable number of resources in a shader. 168 int fNumFragmentSamplers; 169 SkSTArray<4, GrShaderVar> fTransformedCoordVars; 170 }; 171 172 #endif 173