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