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 "GrCaps.h"
12 #include "GrGeometryProcessor.h"
13 #include "GrGpu.h"
14 #include "glsl/GrGLSLFragmentProcessor.h"
15 #include "glsl/GrGLSLFragmentShaderBuilder.h"
16 #include "glsl/GrGLSLGeometryShaderBuilder.h"
17 #include "glsl/GrGLSLPrimitiveProcessor.h"
18 #include "glsl/GrGLSLProgramDataManager.h"
19 #include "glsl/GrGLSLUniformHandler.h"
20 #include "glsl/GrGLSLVertexShaderBuilder.h"
21 #include "glsl/GrGLSLXferProcessor.h"
22 
23 class GrShaderVar;
24 class GrGLSLVaryingHandler;
25 class GrGLSLExpr4;
26 class GrShaderCaps;
27 
28 typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
29 
30 class GrGLSLProgramBuilder {
31 public:
32     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
33     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
34     using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
35 
~GrGLSLProgramBuilder()36     virtual ~GrGLSLProgramBuilder() {}
37 
38     virtual const GrCaps* caps() const = 0;
shaderCaps()39     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
40 
primitiveProcessor()41     const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
pipeline()42     const GrPipeline& pipeline() const { return fPipeline; }
desc()43     GrProgramDesc* desc() { return fDesc; }
header()44     const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
45 
46     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
47 
samplerVariable(SamplerHandle handle)48     const GrShaderVar& samplerVariable(SamplerHandle handle) const {
49         return this->uniformHandler()->samplerVariable(handle);
50     }
51 
samplerSwizzle(SamplerHandle handle)52     GrSwizzle samplerSwizzle(SamplerHandle handle) const {
53         return this->uniformHandler()->samplerSwizzle(handle);
54     }
55 
imageStorageVariable(ImageStorageHandle handle)56     const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const {
57         return this->uniformHandler()->imageStorageVariable(handle);
58     }
59 
60     // Handles for program uniforms (other than per-effect uniforms)
61     struct BuiltinUniformHandles {
62         UniformHandle       fRTAdjustmentUni;
63 
64         // We use the render target height to provide a y-down frag coord when specifying
65         // origin_upper_left is not supported.
66         UniformHandle       fRTHeightUni;
67     };
68 
69     // Used to add a uniform for the RenderTarget height (used for frag position) without mangling
70     // 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 GrPipeline&           fPipeline;
97     const GrPrimitiveProcessor& fPrimProc;
98     GrProgramDesc*              fDesc;
99 
100     BuiltinUniformHandles fUniformHandles;
101 
102     GrGLSLPrimitiveProcessor* fGeometryProcessor;
103     GrGLSLXferProcessor* fXferProcessor;
104     GrGLSLFragProcs fFragmentProcessors;
105 
106 protected:
107     explicit GrGLSLProgramBuilder(const GrPipeline&,
108                                   const GrPrimitiveProcessor&,
109                                   GrProgramDesc*);
110 
111     void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
112 
113     bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage);
114 
115     void cleanupFragmentProcessors();
116 
117     void finalizeShaders();
118 
119 private:
120     // reset is called by program creator between each processor's emit code.  It increments the
121     // stage offset for variable name mangling, and also ensures verfication variables in the
122     // fragment shader are cleared.
reset()123     void reset() {
124         this->addStage();
125         SkDEBUGCODE(fFS.resetVerification();)
126     }
addStage()127     void addStage() { fStageIndex++; }
128 
129     class AutoStageAdvance {
130     public:
AutoStageAdvance(GrGLSLProgramBuilder * pb)131         AutoStageAdvance(GrGLSLProgramBuilder* pb)
132             : fPB(pb) {
133             fPB->reset();
134             // Each output to the fragment processor gets its own code section
135             fPB->fFS.nextStage();
136         }
~AutoStageAdvance()137         ~AutoStageAdvance() {}
138     private:
139         GrGLSLProgramBuilder* fPB;
140     };
141 
142     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
143     // If GrGLSLExpr4 has a valid name then it will use that instead
144     void nameExpression(GrGLSLExpr4*, const char* baseName);
145 
146     void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
147                                 GrGLSLExpr4* outputColor,
148                                 GrGLSLExpr4* outputCoverage);
149     void emitAndInstallFragProcs(GrGLSLExpr4* colorInOut, GrGLSLExpr4* coverageInOut);
150     void emitAndInstallFragProc(const GrFragmentProcessor&,
151                                 int index,
152                                 int transformedCoordVarsIdx,
153                                 const GrGLSLExpr4& input,
154                                 GrGLSLExpr4* output);
155     void emitAndInstallXferProc(const GrXferProcessor&,
156                                 const GrGLSLExpr4& colorIn,
157                                 const GrGLSLExpr4& coverageIn);
158     void emitSamplersAndImageStorages(const GrProcessor& processor,
159                                       SkTArray<SamplerHandle>* outTexSamplerHandles,
160                                       SkTArray<SamplerHandle>* outBufferSamplerHandles,
161                                       SkTArray<ImageStorageHandle>* outImageStorageHandles);
162     void emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
163                      GrShaderFlags visibility, SkTArray<SamplerHandle >* outSamplerHandles);
164     void emitImageStorage(const GrProcessor::ImageStorageAccess&,
165                           const char* name,
166                           SkTArray<ImageStorageHandle>* outImageStorageHandles);
167     void emitFSOutputSwizzle(bool hasSecondaryOutput);
168     bool checkSamplerCounts();
169     bool checkImageStorageCounts();
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     int                         fNumVertexImageStorages;
181     int                         fNumGeometryImageStorages;
182     int                         fNumFragmentImageStorages;
183     SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
184 };
185 
186 #endif
187