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 class GrGLSLProgramBuilder {
28 public:
29     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
30     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
31 
~GrGLSLProgramBuilder()32     virtual ~GrGLSLProgramBuilder() {}
33 
34     virtual const GrCaps* caps() const = 0;
shaderCaps()35     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
36 
primitiveProcessor()37     const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
primProcProxies()38     const GrTextureProxy* const* primProcProxies() const { return fPrimProcProxies; }
config()39     GrPixelConfig config() const { return fConfig; }
numColorSamples()40     int numColorSamples() const { return fNumColorSamples; }
origin()41     GrSurfaceOrigin origin() const { return fOrigin; }
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 
56     // Used to add a uniform for the RenderTarget width (used for sk_Width) without mangling
57     // the name of the uniform inside of a stage.
58     void addRTWidthUniform(const char* name);
59 
60     // Used to add a uniform for the RenderTarget height (used for sk_Height and frag position)
61     // without mangling the name of the uniform inside of a stage.
62     void addRTHeightUniform(const char* name);
63 
64     // Generates a name for a variable. The generated string will be name prefixed by the prefix
65     // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
66     // explicitly asked not to.
67     void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
68 
69     virtual GrGLSLUniformHandler* uniformHandler() = 0;
70     virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
71     virtual GrGLSLVaryingHandler* varyingHandler() = 0;
72 
73     // Used for backend customization of the output color and secondary color variables from the
74     // fragment processor. Only used if the outputs are explicitly declared in the shaders
finalizeFragmentOutputColor(GrShaderVar & outputColor)75     virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
finalizeFragmentSecondaryColor(GrShaderVar & outputColor)76     virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
77 
78     // number of each input/output type in a single allocation block, used by many builders
79     static const int kVarsPerBlock;
80 
81     GrGLSLVertexBuilder          fVS;
82     GrGLSLGeometryBuilder        fGS;
83     GrGLSLFragmentShaderBuilder  fFS;
84 
85     int fStageIndex;
86 
87     const GrPixelConfig          fConfig;
88     const int                    fNumColorSamples;
89     const GrSurfaceOrigin        fOrigin;
90     const GrPipeline&            fPipeline;
91     const GrPrimitiveProcessor&  fPrimProc;
92     const GrTextureProxy* const* fPrimProcProxies;
93 
94     GrProgramDesc*               fDesc;
95 
96     GrGLSLBuiltinUniformHandles  fUniformHandles;
97 
98     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
99     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
100     std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
101     int fFragmentProcessorCnt;
102 
103 protected:
104     explicit GrGLSLProgramBuilder(GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
105                                   const GrPrimitiveProcessor&,
106                                   const GrTextureProxy* const primProcProxies[],
107                                   const GrPipeline&,
108                                   GrProgramDesc*);
109 
110     void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
111 
112     bool emitAndInstallProcs();
113 
114     void finalizeShaders();
115 
fragColorIsInOut()116     bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
117 
118 private:
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.
reset()122     void reset() {
123         this->addStage();
124         SkDEBUGCODE(fFS.resetVerification();)
125     }
addStage()126     void addStage() { fStageIndex++; }
127 
128     class AutoStageAdvance {
129     public:
AutoStageAdvance(GrGLSLProgramBuilder * pb)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         }
~AutoStageAdvance()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     void nameExpression(SkString*, const char* baseName);
143 
144     void emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
145     void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
146     SkString emitAndInstallFragProc(const GrFragmentProcessor&,
147                                     int index,
148                                     int transformedCoordVarsIdx,
149                                     const SkString& input,
150                                     SkString output,
151                                     SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*);
152     void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
153     SamplerHandle emitSampler(const GrTexture*, const GrSamplerState&, const char* name);
154     void emitFSOutputSwizzle(bool hasSecondaryOutput);
155     bool checkSamplerCounts();
156 
157 #ifdef SK_DEBUG
158     void verify(const GrPrimitiveProcessor&);
159     void verify(const GrXferProcessor&);
160     void verify(const GrFragmentProcessor&);
161 #endif
162 
163     // These are used to check that we don't excede the allowable number of resources in a shader.
164     int                         fNumFragmentSamplers;
165     SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
166 };
167 
168 #endif
169