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