• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrProgramDesc.h"
14 #include "glsl/GrGLSLFragmentProcessor.h"
15 #include "glsl/GrGLSLFragmentShaderBuilder.h"
16 #include "glsl/GrGLSLPrimitiveProcessor.h"
17 #include "glsl/GrGLSLProgramDataManager.h"
18 #include "glsl/GrGLSLUniformHandler.h"
19 #include "glsl/GrGLSLVertexGeoBuilder.h"
20 #include "glsl/GrGLSLXferProcessor.h"
21 
22 class GrShaderVar;
23 class GrGLSLVaryingHandler;
24 class SkString;
25 class GrShaderCaps;
26 
27 typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
28 
29 class GrGLSLProgramBuilder {
30 public:
31     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
32     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
33     using TexelBufferHandle  = GrGLSLUniformHandler::TexelBufferHandle;
34 
~GrGLSLProgramBuilder()35     virtual ~GrGLSLProgramBuilder() {}
36 
37     virtual const GrCaps* caps() const = 0;
shaderCaps()38     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
39 
primitiveProcessor()40     const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
pipeline()41     const GrPipeline& pipeline() const { return fPipeline; }
desc()42     GrProgramDesc* desc() { return fDesc; }
header()43     const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
44 
45     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
46 
samplerVariable(SamplerHandle handle)47     const GrShaderVar& samplerVariable(SamplerHandle handle) const {
48         return this->uniformHandler()->samplerVariable(handle);
49     }
50 
samplerSwizzle(SamplerHandle handle)51     GrSwizzle samplerSwizzle(SamplerHandle handle) const {
52         return this->uniformHandler()->samplerSwizzle(handle);
53     }
54 
texelBufferVariable(TexelBufferHandle handle)55     const GrShaderVar& texelBufferVariable(TexelBufferHandle handle) const {
56         return this->uniformHandler()->texelBufferVariable(handle);
57     }
58 
59     // Handles for program uniforms (other than per-effect uniforms)
60     struct BuiltinUniformHandles {
61         UniformHandle       fRTAdjustmentUni;
62 
63         // We use the render target height to provide a y-down frag coord when specifying
64         // origin_upper_left is not supported.
65         UniformHandle       fRTHeightUni;
66     };
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);
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
finalizeFragmentOutputColor(GrShaderVar & outputColor)83     virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
finalizeFragmentSecondaryColor(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     GrProgramDesc*              fDesc;
98 
99     BuiltinUniformHandles fUniformHandles;
100 
101     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
102     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
103     GrGLSLFragProcs fFragmentProcessors;
104 
105 protected:
106     explicit GrGLSLProgramBuilder(const GrPipeline&,
107                                   const GrPrimitiveProcessor&,
108                                   GrProgramDesc*);
109 
110     void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
111 
112     bool emitAndInstallProcs();
113 
114     void cleanupFragmentProcessors();
115 
116     void finalizeShaders();
117 
fragColorIsInOut()118     bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
119 
120 private:
121     // reset is called by program creator between each processor's emit code.  It increments the
122     // stage offset for variable name mangling, and also ensures verfication variables in the
123     // fragment shader are cleared.
reset()124     void reset() {
125         this->addStage();
126         SkDEBUGCODE(fFS.resetVerification();)
127     }
addStage()128     void addStage() { fStageIndex++; }
129 
130     class AutoStageAdvance {
131     public:
AutoStageAdvance(GrGLSLProgramBuilder * pb)132         AutoStageAdvance(GrGLSLProgramBuilder* pb)
133             : fPB(pb) {
134             fPB->reset();
135             // Each output to the fragment processor gets its own code section
136             fPB->fFS.nextStage();
137         }
~AutoStageAdvance()138         ~AutoStageAdvance() {}
139     private:
140         GrGLSLProgramBuilder* fPB;
141     };
142 
143     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
144     void nameExpression(SkString*, const char* baseName);
145 
146     void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
147                                 SkString* outputColor,
148                                 SkString* outputCoverage);
149     void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
150     SkString emitAndInstallFragProc(const GrFragmentProcessor&,
151                                     int index,
152                                     int transformedCoordVarsIdx,
153                                     const SkString& input,
154                                     SkString output);
155     void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
156     void emitSamplers(const GrResourceIOProcessor& processor,
157                       SkTArray<SamplerHandle>* outTexSamplerHandles,
158                       SkTArray<TexelBufferHandle>* outTexelBufferHandles);
159     SamplerHandle emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
160                               GrShaderFlags visibility);
161     TexelBufferHandle emitTexelBuffer(GrPixelConfig, const char* name, GrShaderFlags visibility);
162     void emitFSOutputSwizzle(bool hasSecondaryOutput);
163     void updateSamplerCounts(GrShaderFlags visibility);
164     bool checkSamplerCounts();
165 
166 #ifdef SK_DEBUG
167     void verify(const GrPrimitiveProcessor&);
168     void verify(const GrXferProcessor&);
169     void verify(const GrFragmentProcessor&);
170 #endif
171 
172     // These are used to check that we don't excede the allowable number of resources in a shader.
173     // The sampler counts include both normal texure samplers as well as texel buffers.
174     int                         fNumVertexSamplers;
175     int                         fNumGeometrySamplers;
176     int                         fNumFragmentSamplers;
177     SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
178 };
179 
180 #endif
181