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 "GrCaps.h" 12 #include "GrGeometryProcessor.h" 13 #include "GrProgramDesc.h" 14 #include "glsl/GrGLSLFragmentProcessor.h" 15 #include "glsl/GrGLSLFragmentShaderBuilder.h" 16 #include "glsl/GrGLSLPrimitiveProcessor.h" 17 #include "glsl/GrGLSLProgramDataManager.h" 18 #include "glsl/GrGLSLUniformHandler.h" 19 #include "glsl/GrGLSLVertexGeoBuilder.h" 20 #include "glsl/GrGLSLXferProcessor.h" 21 22 class GrShaderVar; 23 class GrGLSLVaryingHandler; 24 class SkString; 25 class GrShaderCaps; 26 27 class GrGLSLProgramBuilder { 28 public: 29 using UniformHandle = GrGLSLUniformHandler::UniformHandle; 30 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 31 ~GrGLSLProgramBuilder()32 virtual ~GrGLSLProgramBuilder() {} 33 34 virtual const GrCaps* caps() const = 0; shaderCaps()35 const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); } 36 primitiveProcessor()37 const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; } primProcProxies()38 const GrTextureProxy* const* primProcProxies() const { return fPrimProcProxies; } config()39 GrPixelConfig config() const { return fConfig; } numColorSamples()40 int numColorSamples() const { return fNumColorSamples; } origin()41 GrSurfaceOrigin origin() const { return fOrigin; } pipeline()42 const GrPipeline& pipeline() const { return fPipeline; } desc()43 GrProgramDesc* desc() { return fDesc; } header()44 const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); } 45 46 void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 47 samplerVariable(SamplerHandle handle)48 const GrShaderVar& samplerVariable(SamplerHandle handle) const { 49 return this->uniformHandler()->samplerVariable(handle); 50 } 51 samplerSwizzle(SamplerHandle handle)52 GrSwizzle samplerSwizzle(SamplerHandle handle) const { 53 return this->uniformHandler()->samplerSwizzle(handle); 54 } 55 56 // Used to add a uniform for the RenderTarget width (used for sk_Width) without mangling 57 // the name of the uniform inside of a stage. 58 void addRTWidthUniform(const char* name); 59 60 // Used to add a uniform for the RenderTarget height (used for sk_Height and frag position) 61 // without mangling the name of the uniform inside of a stage. 62 void addRTHeightUniform(const char* name); 63 64 // Generates a name for a variable. The generated string will be name prefixed by the prefix 65 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 66 // explicitly asked not to. 67 void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true); 68 69 virtual GrGLSLUniformHandler* uniformHandler() = 0; 70 virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 71 virtual GrGLSLVaryingHandler* varyingHandler() = 0; 72 73 // Used for backend customization of the output color and secondary color variables from the 74 // fragment processor. Only used if the outputs are explicitly declared in the shaders finalizeFragmentOutputColor(GrShaderVar & outputColor)75 virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {} finalizeFragmentSecondaryColor(GrShaderVar & outputColor)76 virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {} 77 78 // number of each input/output type in a single allocation block, used by many builders 79 static const int kVarsPerBlock; 80 81 GrGLSLVertexBuilder fVS; 82 GrGLSLGeometryBuilder fGS; 83 GrGLSLFragmentShaderBuilder fFS; 84 85 int fStageIndex; 86 87 const GrPixelConfig fConfig; 88 const int fNumColorSamples; 89 const GrSurfaceOrigin fOrigin; 90 const GrPipeline& fPipeline; 91 const GrPrimitiveProcessor& fPrimProc; 92 const GrTextureProxy* const* fPrimProcProxies; 93 94 GrProgramDesc* fDesc; 95 96 GrGLSLBuiltinUniformHandles fUniformHandles; 97 98 std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor; 99 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor; 100 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors; 101 int fFragmentProcessorCnt; 102 103 protected: 104 explicit GrGLSLProgramBuilder(GrRenderTarget* renderTarget, GrSurfaceOrigin origin, 105 const GrPrimitiveProcessor&, 106 const GrTextureProxy* const primProcProxies[], 107 const GrPipeline&, 108 GrProgramDesc*); 109 110 void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName); 111 112 bool emitAndInstallProcs(); 113 114 void finalizeShaders(); 115 fragColorIsInOut()116 bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); } 117 118 private: 119 // reset is called by program creator between each processor's emit code. It increments the 120 // stage offset for variable name mangling, and also ensures verfication variables in the 121 // fragment shader are cleared. reset()122 void reset() { 123 this->addStage(); 124 SkDEBUGCODE(fFS.resetVerification();) 125 } addStage()126 void addStage() { fStageIndex++; } 127 128 class AutoStageAdvance { 129 public: AutoStageAdvance(GrGLSLProgramBuilder * pb)130 AutoStageAdvance(GrGLSLProgramBuilder* pb) 131 : fPB(pb) { 132 fPB->reset(); 133 // Each output to the fragment processor gets its own code section 134 fPB->fFS.nextStage(); 135 } ~AutoStageAdvance()136 ~AutoStageAdvance() {} 137 private: 138 GrGLSLProgramBuilder* fPB; 139 }; 140 141 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. 142 void nameExpression(SkString*, const char* baseName); 143 144 void emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage); 145 void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut); 146 SkString emitAndInstallFragProc(const GrFragmentProcessor&, 147 int index, 148 int transformedCoordVarsIdx, 149 const SkString& input, 150 SkString output, 151 SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*); 152 void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn); 153 SamplerHandle emitSampler(const GrTexture*, const GrSamplerState&, const char* name); 154 void emitFSOutputSwizzle(bool hasSecondaryOutput); 155 bool checkSamplerCounts(); 156 157 #ifdef SK_DEBUG 158 void verify(const GrPrimitiveProcessor&); 159 void verify(const GrXferProcessor&); 160 void verify(const GrFragmentProcessor&); 161 #endif 162 163 // These are used to check that we don't excede the allowable number of resources in a shader. 164 int fNumFragmentSamplers; 165 SkSTArray<4, GrShaderVar> fTransformedCoordVars; 166 }; 167 168 #endif 169