• 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 "GrRenderTarget.h"
15 #include "GrRenderTargetPriv.h"
16 #include "glsl/GrGLSLFragmentProcessor.h"
17 #include "glsl/GrGLSLFragmentShaderBuilder.h"
18 #include "glsl/GrGLSLPrimitiveProcessor.h"
19 #include "glsl/GrGLSLProgramDataManager.h"
20 #include "glsl/GrGLSLUniformHandler.h"
21 #include "glsl/GrGLSLVertexGeoBuilder.h"
22 #include "glsl/GrGLSLXferProcessor.h"
23 
24 class GrShaderVar;
25 class GrGLSLVaryingHandler;
26 class SkString;
27 class GrShaderCaps;
28 
29 class GrGLSLProgramBuilder {
30 public:
31     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
32     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
33 
~GrGLSLProgramBuilder()34     virtual ~GrGLSLProgramBuilder() {}
35 
36     virtual const GrCaps* caps() const = 0;
shaderCaps()37     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
38 
primitiveProcessor()39     const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
primProcProxies()40     const GrTextureProxy* const* primProcProxies() const { return fPrimProcProxies; }
renderTarget()41     const GrRenderTarget* renderTarget() const { return fRenderTarget; }
config()42     GrPixelConfig config() const { return fRenderTarget->config(); }
effectiveSampleCnt()43     int effectiveSampleCnt() const {
44         SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & header().processorFeatures());
45         return fRenderTarget->renderTargetPriv().getSampleLocations(fPipeline).count();
46     }
origin()47     GrSurfaceOrigin origin() const { return fOrigin; }
pipeline()48     const GrPipeline& pipeline() const { return fPipeline; }
desc()49     GrProgramDesc* desc() { return fDesc; }
header()50     const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
51 
52     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
53 
samplerVariable(SamplerHandle handle)54     const GrShaderVar& samplerVariable(SamplerHandle handle) const {
55         return this->uniformHandler()->samplerVariable(handle);
56     }
57 
samplerSwizzle(SamplerHandle handle)58     GrSwizzle samplerSwizzle(SamplerHandle handle) const {
59         return this->uniformHandler()->samplerSwizzle(handle);
60     }
61 
62     // Used to add a uniform for the RenderTarget width (used for sk_Width) without mangling
63     // the name of the uniform inside of a stage.
64     void addRTWidthUniform(const char* name);
65 
66     // Used to add a uniform for the RenderTarget height (used for sk_Height and frag position)
67     // without mangling the name of the uniform inside of a stage.
68     void addRTHeightUniform(const char* name);
69 
70     // Generates a name for a variable. The generated string will be name prefixed by the prefix
71     // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
72     // explicitly asked not to.
73     void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
74 
75     virtual GrGLSLUniformHandler* uniformHandler() = 0;
76     virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
77     virtual GrGLSLVaryingHandler* varyingHandler() = 0;
78 
79     // Used for backend customization of the output color and secondary color variables from the
80     // fragment processor. Only used if the outputs are explicitly declared in the shaders
finalizeFragmentOutputColor(GrShaderVar & outputColor)81     virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
finalizeFragmentSecondaryColor(GrShaderVar & outputColor)82     virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
83 
84     // number of each input/output type in a single allocation block, used by many builders
85     static const int kVarsPerBlock;
86 
87     GrGLSLVertexBuilder          fVS;
88     GrGLSLGeometryBuilder        fGS;
89     GrGLSLFragmentShaderBuilder  fFS;
90 
91     int fStageIndex;
92 
93     const GrRenderTarget*        fRenderTarget;
94     const GrSurfaceOrigin        fOrigin;
95     const GrPipeline&            fPipeline;
96     const GrPrimitiveProcessor&  fPrimProc;
97     const GrTextureProxy* const* fPrimProcProxies;
98 
99     GrProgramDesc*               fDesc;
100 
101     GrGLSLBuiltinUniformHandles  fUniformHandles;
102 
103     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
104     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
105     std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
106     int fFragmentProcessorCnt;
107 
108 protected:
109     explicit GrGLSLProgramBuilder(GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
110                                   const GrPrimitiveProcessor&,
111                                   const GrTextureProxy* const primProcProxies[],
112                                   const GrPipeline&,
113                                   GrProgramDesc*);
114 
115     void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
116 
117     bool emitAndInstallProcs();
118 
119     void finalizeShaders();
120 
fragColorIsInOut()121     bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
122 
123 private:
124     // reset is called by program creator between each processor's emit code.  It increments the
125     // stage offset for variable name mangling, and also ensures verfication variables in the
126     // fragment shader are cleared.
reset()127     void reset() {
128         this->addStage();
129         SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();)
130     }
addStage()131     void addStage() { fStageIndex++; }
132 
133     class AutoStageAdvance {
134     public:
AutoStageAdvance(GrGLSLProgramBuilder * pb)135         AutoStageAdvance(GrGLSLProgramBuilder* pb)
136             : fPB(pb) {
137             fPB->reset();
138             // Each output to the fragment processor gets its own code section
139             fPB->fFS.nextStage();
140         }
~AutoStageAdvance()141         ~AutoStageAdvance() {}
142     private:
143         GrGLSLProgramBuilder* fPB;
144     };
145 
146     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
147     void nameExpression(SkString*, const char* baseName);
148 
149     void emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
150     void emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
151     SkString emitAndInstallFragProc(const GrFragmentProcessor&,
152                                     int index,
153                                     int transformedCoordVarsIdx,
154                                     const SkString& input,
155                                     SkString output,
156                                     SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*);
157     void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
158     SamplerHandle emitSampler(const GrTexture*, const GrSamplerState&, const char* name);
159     void emitFSOutputSwizzle(bool hasSecondaryOutput);
160     bool checkSamplerCounts();
161 
162 #ifdef SK_DEBUG
163     void verify(const GrPrimitiveProcessor&);
164     void verify(const GrFragmentProcessor&);
165     void verify(const GrXferProcessor&);
166 #endif
167 
168     // These are used to check that we don't excede the allowable number of resources in a shader.
169     int                         fNumFragmentSamplers;
170     SkSTArray<4, GrShaderVar>   fTransformedCoordVars;
171 };
172 
173 #endif
174