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 "GrGeometryProcessor.h" 12 #include "GrGpu.h" 13 #include "glsl/GrGLSLFragmentShaderBuilder.h" 14 #include "glsl/GrGLSLGeometryShaderBuilder.h" 15 #include "glsl/GrGLSLPrimitiveProcessor.h" 16 #include "glsl/GrGLSLProgramDataManager.h" 17 #include "glsl/GrGLSLUniformHandler.h" 18 #include "glsl/GrGLSLTextureSampler.h" 19 #include "glsl/GrGLSLVertexShaderBuilder.h" 20 #include "glsl/GrGLSLXferProcessor.h" 21 22 class GrGLSLCaps; 23 class GrGLSLShaderVar; 24 class GrGLSLVaryingHandler; 25 26 typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs; 27 28 class GrGLSLProgramBuilder { 29 public: 30 typedef GrGpu::DrawArgs DrawArgs; 31 typedef GrGLSLUniformHandler::UniformHandle UniformHandle; 32 ~GrGLSLProgramBuilder()33 virtual ~GrGLSLProgramBuilder() {} 34 35 virtual const GrCaps* caps() const = 0; 36 virtual const GrGLSLCaps* glslCaps() const = 0; 37 primitiveProcessor()38 const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; } pipeline()39 const GrPipeline& pipeline() const { return *fArgs.fPipeline; } desc()40 const GrProgramDesc& desc() const { return *fArgs.fDesc; } header()41 const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); } 42 43 void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 44 45 // Handles for program uniforms (other than per-effect uniforms) 46 struct BuiltinUniformHandles { 47 UniformHandle fRTAdjustmentUni; 48 49 // We use the render target height to provide a y-down frag coord when specifying 50 // origin_upper_left is not supported. 51 UniformHandle fRTHeightUni; 52 }; 53 54 // Used to add a uniform in the vertex shader for transforming into normalized device space. 55 void addRTAdjustmentUniform(GrSLPrecision precision, const char* name, const char** outName); rtAdjustment()56 const char* rtAdjustment() const { return "rtAdjustment"; } 57 58 // Used to add a uniform for the RenderTarget height (used for frag position) without mangling 59 // the name of the uniform inside of a stage. 60 void addRTHeightUniform(const char* name, const char** outName); 61 62 // Generates a name for a variable. The generated string will be name prefixed by the prefix 63 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 64 // explicitly asked not to. 65 void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true); 66 67 virtual GrGLSLUniformHandler* uniformHandler() = 0; 68 virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 69 virtual GrGLSLVaryingHandler* varyingHandler() = 0; 70 71 // Used for backend customization of the output color and secondary color variables from the 72 // fragment processor. Only used if the outputs are explicitly declared in the shaders finalizeFragmentOutputColor(GrGLSLShaderVar & outputColor)73 virtual void finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {} finalizeFragmentSecondaryColor(GrGLSLShaderVar & outputColor)74 virtual void finalizeFragmentSecondaryColor(GrGLSLShaderVar& outputColor) {} 75 76 // number of each input/output type in a single allocation block, used by many builders 77 static const int kVarsPerBlock; 78 79 GrGLSLVertexBuilder fVS; 80 GrGLSLGeometryBuilder fGS; 81 GrGLSLFragmentShaderBuilder fFS; 82 83 int fStageIndex; 84 85 const DrawArgs& fArgs; 86 87 BuiltinUniformHandles fUniformHandles; 88 89 GrGLSLPrimitiveProcessor* fGeometryProcessor; 90 GrGLSLXferProcessor* fXferProcessor; 91 GrGLSLFragProcs fFragmentProcessors; 92 93 protected: 94 explicit GrGLSLProgramBuilder(const DrawArgs& args); 95 96 bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage, int maxTextures); 97 98 void cleanupFragmentProcessors(); 99 100 void finalizeShaders(); 101 102 private: 103 // reset is called by program creator between each processor's emit code. It increments the 104 // stage offset for variable name mangling, and also ensures verfication variables in the 105 // fragment shader are cleared. reset()106 void reset() { 107 this->addStage(); 108 fFS.reset(); 109 } addStage()110 void addStage() { fStageIndex++; } 111 112 class AutoStageAdvance { 113 public: AutoStageAdvance(GrGLSLProgramBuilder * pb)114 AutoStageAdvance(GrGLSLProgramBuilder* pb) 115 : fPB(pb) { 116 fPB->reset(); 117 // Each output to the fragment processor gets its own code section 118 fPB->fFS.nextStage(); 119 } ~AutoStageAdvance()120 ~AutoStageAdvance() {} 121 private: 122 GrGLSLProgramBuilder* fPB; 123 }; 124 125 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader. 126 // If GrGLSLExpr4 has a valid name then it will use that instead 127 void nameExpression(GrGLSLExpr4*, const char* baseName); 128 129 void emitAndInstallPrimProc(const GrPrimitiveProcessor&, 130 GrGLSLExpr4* outputColor, 131 GrGLSLExpr4* outputCoverage); 132 void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut); 133 void emitAndInstallFragProc(const GrFragmentProcessor&, 134 int index, 135 const GrGLSLExpr4& input, 136 GrGLSLExpr4* output); 137 void emitAndInstallXferProc(const GrXferProcessor&, 138 const GrGLSLExpr4& colorIn, 139 const GrGLSLExpr4& coverageIn, 140 bool ignoresCoverage, 141 GrPixelLocalStorageState plsState); 142 void emitFSOutputSwizzle(bool hasSecondaryOutput); 143 144 void verify(const GrPrimitiveProcessor&); 145 void verify(const GrXferProcessor&); 146 void verify(const GrFragmentProcessor&); 147 148 virtual void emitSamplers(const GrProcessor& processor, 149 GrGLSLTextureSampler::TextureSamplerArray* outSamplers) = 0; 150 151 GrGLSLPrimitiveProcessor::TransformsIn fCoordTransforms; 152 GrGLSLPrimitiveProcessor::TransformsOut fOutCoords; 153 }; 154 155 #endif 156