Flutter Engine
The Flutter Engine
GrGLSLProgramBuilder.h
Go to the documentation of this file.
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
14#include "src/gpu/Swizzle.h"
26
27#include <cstdint>
28#include <memory>
29#include <string>
30#include <vector>
31
32class GrBackendFormat;
34class GrProgramDesc;
35class SkString;
36enum GrSurfaceOrigin : int;
37struct GrShaderCaps;
38
40public:
42 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
43
45
46 virtual const GrCaps* caps() const = 0;
47 const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
48
50 const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
54 }
56
57 const GrProgramDesc& desc() const { return fDesc; }
58
59 void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
60
61 const char* samplerVariable(SamplerHandle handle) const {
62 return this->uniformHandler()->samplerVariable(handle);
63 }
64
66 return this->uniformHandler()->samplerSwizzle(handle);
67 }
68
69 const char* inputSamplerVariable(SamplerHandle handle) const {
70 return this->uniformHandler()->inputSamplerVariable(handle);
71 }
72
74 return this->uniformHandler()->inputSamplerSwizzle(handle);
75 }
76
77 // Used to add a uniform for render target flip (used for dFdy, sk_Clockwise, and sk_FragCoord)
78 // without mangling the name of the uniform inside of a stage.
79 void addRTFlipUniform(const char* name);
80
81 // Generates a name for a variable. The generated string will be name prefixed by the prefix
82 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
83 // explicitly asked not to. `nameVariable` can also be used to generate names for functions or
84 // other types of symbols where unique names are important.
85 SkString nameVariable(char prefix, const char* name, bool mangle = true);
86
87 /**
88 * Emits samplers for TextureEffect fragment processors as needed. `fp` can be a TextureEffect,
89 * or a tree containing zero or more TextureEffects.
90 */
93 int* samplerIndex);
94
95 /**
96 * advanceStage is called by program creator between each processor's emit code. It increments
97 * the stage index for variable name mangling, and also ensures verification variables in the
98 * fragment shader are cleared.
99 */
101 fStageIndex++;
102 SkDEBUGCODE(fFS.debugOnly_resetPerStageVerification();)
103 fFS.nextStage();
104 }
105
106 /** Adds the SkSL function that implements an FP assuming its children are already written. */
108
109 /**
110 * Returns a function-call invocation of `fp` in string form, passing the appropriate
111 * combination of `inputColor`, `destColor` and `fLocalCoordsVar` for the FP.
112 */
113 std::string invokeFP(const GrFragmentProcessor& fp,
115 const char* inputColor,
116 const char* destColor,
117 const char* coords) const;
118 /**
119 * If the FP's coords are unused or all uses have been lifted to interpolated varyings then
120 * don't put coords in the FP's function signature or call sites.
121 */
123
125 virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
127
128 // Used for backend customization of the secondary color variable from the fragment processor.
129 // Only used if the output is explicitly declared in the shaders.
130 virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
131
132 // number of each input/output type in a single allocation block, used by many builders
133 static const int kVarsPerBlock;
134
137
140
142
143 std::unique_ptr<GrGeometryProcessor::ProgramImpl> fGPImpl;
144 std::unique_ptr<GrXferProcessor::ProgramImpl> fXPImpl;
145 std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fFPImpls;
146
149
150protected:
151 explicit GrGLSLProgramBuilder(const GrProgramDesc&, const GrProgramInfo&);
152
153 void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
154
155 bool emitAndInstallProcs();
156
157 void finalizeShaders();
158
159 bool fragColorIsInOut() const { return fFS.primaryColorOutputIsInOut(); }
160
161private:
162 SkString getMangleSuffix() const;
163
164 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
165 void nameExpression(SkString*, const char* baseName);
166
167 bool emitAndInstallPrimProc(SkString* outputColor, SkString* outputCoverage);
168 bool emitAndInstallDstTexture();
169 /** Adds the root FPs */
170 bool emitAndInstallFragProcs(SkString* colorInOut, SkString* coverageInOut);
171 /** Adds a single root FP tree. */
172 SkString emitRootFragProc(const GrFragmentProcessor& fp,
174 const SkString& input,
176 /** Recursive step to write out children FPs' functions before parent's. */
177 void writeChildFPFunctions(const GrFragmentProcessor& fp,
179 bool emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
181 const char* name);
182 SamplerHandle emitInputSampler(const skgpu::Swizzle& swizzle, const char* name);
183 bool checkSamplerCounts();
184
185#ifdef SK_DEBUG
186 void verify(const GrGeometryProcessor&);
187 void verify(const GrFragmentProcessor&);
188 void verify(const GrXferProcessor&);
189#endif
190
191 // This is used to check that we don't excede the allowable number of resources in a shader.
192 int fNumFragmentSamplers;
193
195 GrShaderVar fLocalCoordsVar;
196
197 /**
198 * Each root processor has an stage index. The GP is stage 0. The first root FP is stage 1,
199 * the second root FP is stage 2, etc. The XP's stage index is last and its value depends on
200 * how many root FPs there are. Names are mangled by appending _S<stage-index>.
201 */
202 int fStageIndex = -1;
203
204 /**
205 * When emitting FP stages we track the children FPs as "substages" and do additional name
206 * mangling based on where in the FP hierarchy we are. The first FP is stage index 1. It's first
207 * child would be substage 0 of stage 1. If that FP also has three children then its third child
208 * would be substage 2 of stubstage 0 of stage 1 and would be mangled as "_S1_c0_c2".
209 */
210 skia_private::TArray<int> fSubstageIndices;
211};
212
213#endif
GrShaderFlags
Definition: GrTypesPriv.h:284
GrSurfaceOrigin
Definition: GrTypes.h:147
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
Definition: GrCaps.h:57
const GrShaderCaps * shaderCaps() const
Definition: GrCaps.h:63
SkString nameVariable(char prefix, const char *name, bool mangle=true)
virtual GrGLSLUniformHandler * uniformHandler()=0
GrSurfaceOrigin fDstTextureOrigin
const char * samplerVariable(SamplerHandle handle) const
bool fragmentProcessorHasCoordsParam(const GrFragmentProcessor *) const
const GrProgramDesc & fDesc
const GrProgramDesc & desc() const
std::vector< std::unique_ptr< GrFragmentProcessor::ProgramImpl > > fFPImpls
virtual const GrCaps * caps() const =0
std::unique_ptr< GrGeometryProcessor::ProgramImpl > fGPImpl
virtual void finalizeFragmentSecondaryColor(GrShaderVar &outputColor)
skgpu::Swizzle samplerSwizzle(SamplerHandle handle) const
const GrShaderCaps * shaderCaps() const
SamplerHandle fDstTextureSamplerHandle
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char *extensionName)
const char * inputSamplerVariable(SamplerHandle handle) const
bool snapVerticesToPixelCenters() const
GrGLSLVertexBuilder fVS
const GrGeometryProcessor & geometryProcessor() const
GrGLSLUniformHandler::SamplerHandle SamplerHandle
skgpu::Swizzle inputSamplerSwizzle(SamplerHandle handle) const
bool emitTextureSamplersForFPs(const GrFragmentProcessor &fp, GrFragmentProcessor::ProgramImpl &impl, int *samplerIndex)
virtual const GrGLSLUniformHandler * uniformHandler() const =0
void appendUniformDecls(GrShaderFlags visibility, SkString *) const
virtual GrGLSLVaryingHandler * varyingHandler()=0
std::string invokeFP(const GrFragmentProcessor &fp, const GrFragmentProcessor::ProgramImpl &impl, const char *inputColor, const char *destColor, const char *coords) const
std::unique_ptr< GrXferProcessor::ProgramImpl > fXPImpl
virtual ~GrGLSLProgramBuilder()
static const int kVarsPerBlock
GrGLSLBuiltinUniformHandles fUniformHandles
GrSurfaceOrigin origin() const
const GrProgramInfo & fProgramInfo
GrGLSLUniformHandler::UniformHandle UniformHandle
GrGLSLFragmentShaderBuilder fFS
void addRTFlipUniform(const char *name)
GrGLSLProgramBuilder(const GrProgramDesc &, const GrProgramInfo &)
void writeFPFunction(const GrFragmentProcessor &fp, GrFragmentProcessor::ProgramImpl &impl)
const GrPipeline & pipeline() const
virtual skgpu::Swizzle inputSamplerSwizzle(SamplerHandle) const
virtual skgpu::Swizzle samplerSwizzle(SamplerHandle) const =0
virtual const char * samplerVariable(SamplerHandle) const =0
virtual const char * inputSamplerVariable(SamplerHandle) const
GrGLSLProgramDataManager::UniformHandle UniformHandle
std::unordered_map< const GrFragmentProcessor *, FPCoords > FPCoordsMap
bool snapVerticesToPixelCenters() const
Definition: GrPipeline.h:171
GrSurfaceOrigin origin() const
Definition: GrProgramInfo.h:38
GrPrimitiveType primitiveType() const
Definition: GrProgramInfo.h:42
const GrPipeline & pipeline() const
Definition: GrProgramInfo.h:39
const GrGeometryProcessor & geomProc() const
Definition: GrProgramInfo.h:40
const uint32_t fp
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32