GrGLSLProgramBuilder.h revision 59dc41175d99d0a31c046aec0c26c4d82a3a3574
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/GrGLSLFragmentProcessor.h" 14#include "glsl/GrGLSLFragmentShaderBuilder.h" 15#include "glsl/GrGLSLGeometryShaderBuilder.h" 16#include "glsl/GrGLSLPrimitiveProcessor.h" 17#include "glsl/GrGLSLProgramDataManager.h" 18#include "glsl/GrGLSLUniformHandler.h" 19#include "glsl/GrGLSLVertexShaderBuilder.h" 20#include "glsl/GrGLSLXferProcessor.h" 21 22class GrGLSLCaps; 23class GrShaderVar; 24class GrGLSLVaryingHandler; 25class GrGLSLExpr4; 26 27typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs; 28 29class GrGLSLProgramBuilder { 30public: 31 typedef GrGLSLUniformHandler::UniformHandle UniformHandle; 32 33 virtual ~GrGLSLProgramBuilder() {} 34 35 virtual const GrCaps* caps() const = 0; 36 virtual const GrGLSLCaps* glslCaps() const = 0; 37 38 const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; } 39 const GrPipeline& pipeline() const { return fPipeline; } 40 const GrProgramDesc& desc() const { return fDesc; } 41 const GrProgramDesc::KeyHeader& header() const { return fDesc.header(); } 42 43 void appendUniformDecls(GrShaderFlags visibility, SkString*) const; 44 45 typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle; 46 47 const GrShaderVar& samplerVariable(SamplerHandle handle) const { 48 return this->uniformHandler()->samplerVariable(handle); 49 } 50 51 GrSwizzle samplerSwizzle(SamplerHandle handle) const { 52 return this->uniformHandler()->samplerSwizzle(handle); 53 } 54 55 // Handles for program uniforms (other than per-effect uniforms) 56 struct BuiltinUniformHandles { 57 UniformHandle fRTAdjustmentUni; 58 59 // We use the render target height to provide a y-down frag coord when specifying 60 // origin_upper_left is not supported. 61 UniformHandle fRTHeightUni; 62 }; 63 64 // Used to add a uniform in the vertex shader for transforming into normalized device space. 65 void addRTAdjustmentUniform(GrSLPrecision precision, const char* name, const char** outName); 66 const char* rtAdjustment() const { return "rtAdjustment"; } 67 68 // Used to add a uniform for the RenderTarget height (used for frag position) without mangling 69 // the name of the uniform inside of a stage. 70 void addRTHeightUniform(const char* name, const char** outName); 71 72 // Generates a name for a variable. The generated string will be name prefixed by the prefix 73 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless 74 // explicitly asked not to. 75 void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true); 76 77 virtual GrGLSLUniformHandler* uniformHandler() = 0; 78 virtual const GrGLSLUniformHandler* uniformHandler() const = 0; 79 virtual GrGLSLVaryingHandler* varyingHandler() = 0; 80 81 // Used for backend customization of the output color and secondary color variables from the 82 // fragment processor. Only used if the outputs are explicitly declared in the shaders 83 virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {} 84 virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {} 85 86 // number of each input/output type in a single allocation block, used by many builders 87 static const int kVarsPerBlock; 88 89 GrGLSLVertexBuilder fVS; 90 GrGLSLGeometryBuilder fGS; 91 GrGLSLFragmentShaderBuilder fFS; 92 93 int fStageIndex; 94 95 const GrPipeline& fPipeline; 96 const GrPrimitiveProcessor& fPrimProc; 97 const GrProgramDesc& fDesc; 98 99 BuiltinUniformHandles fUniformHandles; 100 101 GrGLSLPrimitiveProcessor* fGeometryProcessor; 102 GrGLSLXferProcessor* fXferProcessor; 103 GrGLSLFragProcs fFragmentProcessors; 104 105protected: 106 explicit GrGLSLProgramBuilder(const GrPipeline&, 107 const GrPrimitiveProcessor&, 108 const GrProgramDesc&); 109 110 void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName); 111 112 bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage); 113 114 void cleanupFragmentProcessors(); 115 116 void finalizeShaders(); 117 118private: 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. 122 void reset() { 123 this->addStage(); 124 SkDEBUGCODE(fFS.resetVerification();) 125 } 126 void addStage() { fStageIndex++; } 127 128 class AutoStageAdvance { 129 public: 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 } 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 // If GrGLSLExpr4 has a valid name then it will use that instead 143 void nameExpression(GrGLSLExpr4*, const char* baseName); 144 145 void emitAndInstallPrimProc(const GrPrimitiveProcessor&, 146 GrGLSLExpr4* outputColor, 147 GrGLSLExpr4* outputCoverage); 148 void emitAndInstallFragProcs(GrGLSLExpr4* colorInOut, GrGLSLExpr4* coverageInOut); 149 void emitAndInstallFragProc(const GrFragmentProcessor&, 150 int index, 151 int transformedCoordVarsIdx, 152 const GrGLSLExpr4& input, 153 GrGLSLExpr4* output); 154 void emitAndInstallXferProc(const GrXferProcessor&, 155 const GrGLSLExpr4& colorIn, 156 const GrGLSLExpr4& coverageIn, 157 bool ignoresCoverage, 158 GrPixelLocalStorageState plsState); 159 160 void emitSamplers(const GrProcessor& processor, 161 SkTArray<SamplerHandle>* outTexSamplers, 162 SkTArray<SamplerHandle>* outBufferSamplers); 163 void emitSampler(GrSLType samplerType, 164 GrPixelConfig, 165 const char* name, 166 GrShaderFlags visibility, 167 SkTArray<SamplerHandle>* outSamplers); 168 void emitFSOutputSwizzle(bool hasSecondaryOutput); 169 bool checkSamplerCounts(); 170 171#ifdef SK_DEBUG 172 void verify(const GrPrimitiveProcessor&); 173 void verify(const GrXferProcessor&); 174 void verify(const GrFragmentProcessor&); 175#endif 176 177 int fNumVertexSamplers; 178 int fNumGeometrySamplers; 179 int fNumFragmentSamplers; 180 SkSTArray<4, GrShaderVar> fTransformedCoordVars; 181}; 182 183#endif 184