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 "include/private/base/SkDebug.h" 12 #include "include/private/base/SkTArray.h" 13 #include "include/private/gpu/ganesh/GrTypesPriv.h" 14 #include "src/gpu/Swizzle.h" 15 #include "src/gpu/ganesh/GrCaps.h" 16 #include "src/gpu/ganesh/GrFragmentProcessor.h" 17 #include "src/gpu/ganesh/GrGeometryProcessor.h" 18 #include "src/gpu/ganesh/GrPipeline.h" 19 #include "src/gpu/ganesh/GrProgramInfo.h" 20 #include "src/gpu/ganesh/GrSamplerState.h" 21 #include "src/gpu/ganesh/GrShaderVar.h" 22 #include "src/gpu/ganesh/GrXferProcessor.h" 23 #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h" 24 #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h" 25 #include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h" 26 27 #include <cstdint> 28 #include <memory> 29 #include <string> 30 #include <vector> 31 32 class GrBackendFormat; 33 class GrGLSLVaryingHandler; 34 class GrProgramDesc; 35 class SkString; 36 enum GrSurfaceOrigin : int; 37 struct GrShaderCaps; 38 39 class GrGLSLProgramBuilder { 40 public: 41 using UniformHandle = GrGLSLUniformHandler::UniformHandle; 42 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 43 44 virtual ~GrGLSLProgramBuilder(); 45 46 virtual const GrCaps* caps() const = 0; shaderCaps()47 const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); } 48 origin()49 GrSurfaceOrigin origin() const { return fProgramInfo.origin(); } pipeline()50 const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); } geometryProcessor()51 const GrGeometryProcessor& geometryProcessor() const { return fProgramInfo.geomProc(); } snapVerticesToPixelCenters()52 bool snapVerticesToPixelCenters() const { 53 return fProgramInfo.pipeline().snapVerticesToPixelCenters(); 54 } hasPointSize()55 bool hasPointSize() const { return fProgramInfo.primitiveType() == GrPrimitiveType::kPoints; } 56 desc()57 const GrProgramDesc& desc() const { return fDesc; } 58 59 void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 60 samplerVariable(SamplerHandle handle)61 const char* samplerVariable(SamplerHandle handle) const { 62 return this->uniformHandler()->samplerVariable(handle); 63 } 64 samplerSwizzle(SamplerHandle handle)65 skgpu::Swizzle samplerSwizzle(SamplerHandle handle) const { 66 return this->uniformHandler()->samplerSwizzle(handle); 67 } 68 inputSamplerVariable(SamplerHandle handle)69 const char* inputSamplerVariable(SamplerHandle handle) const { 70 return this->uniformHandler()->inputSamplerVariable(handle); 71 } 72 inputSamplerSwizzle(SamplerHandle handle)73 skgpu::Swizzle inputSamplerSwizzle(SamplerHandle handle) const { 74 return this->uniformHandler()->inputSamplerSwizzle(handle); 75 } 76 77 // Used to add a uniform for render target flip (used for dFdy, sk_Clockwise, and sk_FragCoord) 78 // without mangling the name of the uniform inside of a stage. 79 void addRTFlipUniform(const char* name); 80 81 // Generates a name for a variable. The generated string will be name prefixed by the prefix 82 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 83 // explicitly asked not to. `nameVariable` can also be used to generate names for functions or 84 // other types of symbols where unique names are important. 85 SkString nameVariable(char prefix, const char* name, bool mangle = true); 86 87 /** 88 * Emits samplers for TextureEffect fragment processors as needed. `fp` can be a TextureEffect, 89 * or a tree containing zero or more TextureEffects. 90 */ 91 bool emitTextureSamplersForFPs(const GrFragmentProcessor& fp, 92 GrFragmentProcessor::ProgramImpl& impl, 93 int* samplerIndex); 94 95 /** 96 * advanceStage is called by program creator between each processor's emit code. It increments 97 * the stage index for variable name mangling, and also ensures verification variables in the 98 * fragment shader are cleared. 99 */ advanceStage()100 void advanceStage() { 101 fStageIndex++; 102 SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();) 103 fFS.nextStage(); 104 } 105 106 /** Adds the SkSL function that implements an FP assuming its children are already written. */ 107 void writeFPFunction(const GrFragmentProcessor& fp, GrFragmentProcessor::ProgramImpl& impl); 108 109 /** 110 * Returns a function-call invocation of `fp` in string form, passing the appropriate 111 * combination of `inputColor`, `destColor` and `fLocalCoordsVar` for the FP. 112 */ 113 std::string invokeFP(const GrFragmentProcessor& fp, 114 const GrFragmentProcessor::ProgramImpl& impl, 115 const char* inputColor, 116 const char* destColor, 117 const char* coords) const; 118 /** 119 * If the FP's coords are unused or all uses have been lifted to interpolated varyings then 120 * don't put coords in the FP's function signature or call sites. 121 */ 122 bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor*) const; 123 124 virtual GrGLSLUniformHandler* uniformHandler() = 0; 125 virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 126 virtual GrGLSLVaryingHandler* varyingHandler() = 0; 127 128 // Used for backend customization of the secondary color variable from the fragment processor. 129 // Only used if the output is explicitly declared in the shaders. finalizeFragmentSecondaryColor(GrShaderVar & outputColor)130 virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {} 131 132 // number of each input/output type in a single allocation block, used by many builders 133 static const int kVarsPerBlock; 134 135 GrGLSLVertexBuilder fVS; 136 GrGLSLFragmentShaderBuilder fFS; 137 138 const GrProgramDesc& fDesc; 139 const GrProgramInfo& fProgramInfo; 140 141 GrGLSLBuiltinUniformHandles fUniformHandles; 142 143 std::unique_ptr<GrGeometryProcessor::ProgramImpl> fGPImpl; 144 std::unique_ptr<GrXferProcessor::ProgramImpl> fXPImpl; 145 std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fFPImpls; 146 147 SamplerHandle fDstTextureSamplerHandle; 148 GrSurfaceOrigin fDstTextureOrigin; 149 150 protected: 151 explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&); 152 153 void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName); 154 155 bool emitAndInstallProcs(); 156 157 void finalizeShaders(); 158 fragColorIsInOut()159 bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); } 160 161 private: 162 SkString getMangleSuffix() const; 163 164 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. 165 void nameExpression(SkString*, const char* baseName); 166 167 bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage); 168 bool emitAndInstallDstTexture(); 169 /** Adds the root FPs */ 170 bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut); 171 /** Adds a single root FP tree. */ 172 SkString emitRootFragProc(const GrFragmentProcessor& fp, 173 GrFragmentProcessor::ProgramImpl& impl, 174 const SkString& input, 175 SkString output); 176 /** Recursive step to write out children FPs' functions before parent's. */ 177 void writeChildFPFunctions(const GrFragmentProcessor& fp, 178 GrFragmentProcessor::ProgramImpl& impl); 179 bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn); 180 SamplerHandle emitSampler(const GrBackendFormat&, GrSamplerState, const skgpu::Swizzle&, 181 const char* name); 182 SamplerHandle emitInputSampler(const skgpu::Swizzle& swizzle, const char* name); 183 bool checkSamplerCounts(); 184 185 #ifdef SK_DEBUG 186 void verify(const GrGeometryProcessor&); 187 void verify(const GrFragmentProcessor&); 188 void verify(const GrXferProcessor&); 189 #endif 190 191 // This is used to check that we don't excede the allowable number of resources in a shader. 192 int fNumFragmentSamplers; 193 194 GrGeometryProcessor::ProgramImpl::FPCoordsMap fFPCoordsMap; 195 GrShaderVar fLocalCoordsVar; 196 197 /** 198 * Each root processor has an stage index. The GP is stage 0. The first root FP is stage 1, 199 * the second root FP is stage 2, etc. The XP's stage index is last and its value depends on 200 * how many root FPs there are. Names are mangled by appending _S<stage-index>. 201 */ 202 int fStageIndex = -1; 203 204 /** 205 * When emitting FP stages we track the children FPs as "substages" and do additional name 206 * mangling based on where in the FP hierarchy we are. The first FP is stage index 1. It's first 207 * child would be substage 0 of stage 1. If that FP also has three children then its third child 208 * would be substage 2 of stubstage 0 of stage 1 and would be mangled as "_S1_c0_c2". 209 */ 210 skia_private::TArray<int> fSubstageIndices; 211 }; 212 213 #endif 214