• 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 "src/gpu/ganesh/GrCaps.h"
12 #include "src/gpu/ganesh/GrFragmentProcessor.h"
13 #include "src/gpu/ganesh/GrGeometryProcessor.h"
14 #include "src/gpu/ganesh/GrProgramInfo.h"
15 #include "src/gpu/ganesh/GrXferProcessor.h"
16 #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
17 #include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
18 #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
19 #include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h"
20 #include "src/sksl/SkSLCompiler.h"
21 
22 #include <vector>
23 
24 class GrProgramDesc;
25 class GrRenderTarget;
26 class GrShaderVar;
27 class GrGLSLVaryingHandler;
28 class SkString;
29 struct GrShaderCaps;
30 
31 class GrGLSLProgramBuilder {
32 public:
33     using UniformHandle      = GrGLSLUniformHandler::UniformHandle;
34     using SamplerHandle      = GrGLSLUniformHandler::SamplerHandle;
35 
36     virtual ~GrGLSLProgramBuilder();
37 
38     virtual const GrCaps* caps() const = 0;
shaderCaps()39     const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
40 
origin()41     GrSurfaceOrigin origin() const { return fProgramInfo.origin(); }
pipeline()42     const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
geometryProcessor()43     const GrGeometryProcessor& geometryProcessor() const { return fProgramInfo.geomProc(); }
snapVerticesToPixelCenters()44     bool snapVerticesToPixelCenters() const {
45         return fProgramInfo.pipeline().snapVerticesToPixelCenters();
46     }
hasPointSize()47     bool hasPointSize() const { return fProgramInfo.primitiveType() == GrPrimitiveType::kPoints; }
48     virtual SkSL::Compiler* shaderCompiler() const = 0;
49 
desc()50     const GrProgramDesc& desc() const { return fDesc; }
51 
52     void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
53 
samplerVariable(SamplerHandle handle)54     const char* samplerVariable(SamplerHandle handle) const {
55         return this->uniformHandler()->samplerVariable(handle);
56     }
57 
samplerSwizzle(SamplerHandle handle)58     skgpu::Swizzle samplerSwizzle(SamplerHandle handle) const {
59         return this->uniformHandler()->samplerSwizzle(handle);
60     }
61 
inputSamplerVariable(SamplerHandle handle)62     const char* inputSamplerVariable(SamplerHandle handle) const {
63         return this->uniformHandler()->inputSamplerVariable(handle);
64     }
65 
inputSamplerSwizzle(SamplerHandle handle)66     skgpu::Swizzle inputSamplerSwizzle(SamplerHandle handle) const {
67         return this->uniformHandler()->inputSamplerSwizzle(handle);
68     }
69 
70     // Used to add a uniform for render target flip (used for dFdy, sk_Clockwise, and sk_FragCoord)
71     // without mangling the name of the uniform inside of a stage.
72     void addRTFlipUniform(const char* name);
73 
74     // Generates a name for a variable. The generated string will be name prefixed by the prefix
75     // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
76     // explicitly asked not to. `nameVariable` can also be used to generate names for functions or
77     // other types of symbols where unique names are important.
78     SkString nameVariable(char prefix, const char* name, bool mangle = true);
79 
80     /**
81      * If the FP's coords are unused or all uses have been lifted to interpolated varyings then
82      * don't put coords in the FP's function signature or call sites.
83      */
84     bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor*);
85 
86     virtual GrGLSLUniformHandler* uniformHandler() = 0;
87     virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
88     virtual GrGLSLVaryingHandler* varyingHandler() = 0;
89 
90     // Used for backend customization of the secondary color variable from the fragment processor.
91     // Only used if the output is explicitly declared in the shaders.
finalizeFragmentSecondaryColor(GrShaderVar & outputColor)92     virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
93 
94     // number of each input/output type in a single allocation block, used by many builders
95     static const int kVarsPerBlock;
96 
97     GrGLSLVertexBuilder          fVS;
98     GrGLSLFragmentShaderBuilder  fFS;
99 
100     const GrProgramDesc&         fDesc;
101     const GrProgramInfo&         fProgramInfo;
102 
103     GrGLSLBuiltinUniformHandles  fUniformHandles;
104 
105     std::unique_ptr<GrGeometryProcessor::ProgramImpl>               fGPImpl;
106     std::unique_ptr<GrXferProcessor::ProgramImpl>                   fXPImpl;
107     std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>>  fFPImpls;
108 
109     SamplerHandle fDstTextureSamplerHandle;
110     GrSurfaceOrigin fDstTextureOrigin;
111 
112 protected:
113     explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&);
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     // advanceStage is called by program creator between each processor's emit code.  It increments
125     // the stage index for variable name mangling, and also ensures verification variables in the
126     // fragment shader are cleared.
advanceStage()127     void advanceStage() {
128         fStageIndex++;
129         SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();)
130         fFS.nextStage();
131     }
132 
133     SkString getMangleSuffix() const;
134 
135     // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
136     void nameExpression(SkString*, const char* baseName);
137 
138     bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
139     bool emitAndInstallDstTexture();
140     /** Adds the root FPs */
141     bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
142     /** Adds a single root FP tree. */
143     SkString emitRootFragProc(const GrFragmentProcessor& fp,
144                               GrFragmentProcessor::ProgramImpl& impl,
145                               const SkString& input,
146                               SkString output);
147     /** Recursive step to write out children FPs' functions before parent's. */
148     void writeChildFPFunctions(const GrFragmentProcessor& fp,
149                                GrFragmentProcessor::ProgramImpl& impl);
150     /** Adds the SkSL function that implements an FP assuming its children are already written. */
151     void writeFPFunction(const GrFragmentProcessor& fp, GrFragmentProcessor::ProgramImpl& impl);
152     bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
153     SamplerHandle emitSampler(const GrBackendFormat&, GrSamplerState, const skgpu::Swizzle&,
154                               const char* name);
155     SamplerHandle emitInputSampler(const skgpu::Swizzle& swizzle, const char* name);
156     bool checkSamplerCounts();
157 
158 #ifdef SK_DEBUG
159     void verify(const GrGeometryProcessor&);
160     void verify(const GrFragmentProcessor&);
161     void verify(const GrXferProcessor&);
162 #endif
163 
164     // This is used to check that we don't excede the allowable number of resources in a shader.
165     int fNumFragmentSamplers;
166 
167     GrGeometryProcessor::ProgramImpl::FPCoordsMap fFPCoordsMap;
168     GrShaderVar                                   fLocalCoordsVar;
169 
170     /**
171      * Each root processor has an stage index. The GP is stage 0. The first root FP is stage 1,
172      * the second root FP is stage 2, etc. The XP's stage index is last and its value depends on
173      * how many root FPs there are. Names are mangled by appending _S<stage-index>.
174      */
175     int fStageIndex = -1;
176 
177     /**
178      * When emitting FP stages we track the children FPs as "substages" and do additional name
179      * mangling based on where in the FP hierarchy we are. The first FP is stage index 1. It's first
180      * child would be substage 0 of stage 1. If that FP also has three children then its third child
181      * would be substage 2 of stubstage 0 of stage 1 and would be mangled as "_S1_c0_c2".
182      */
183     SkTArray<int> fSubstageIndices;
184 };
185 
186 #endif
187