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