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