1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrGLSLProgramBuilder_DEFINED
#define GrGLSLProgramBuilder_DEFINED
#include "GrCaps.h"
#include "GrGeometryProcessor.h"
#include "GrGpu.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLGeometryShaderBuilder.h"
#include "glsl/GrGLSLPrimitiveProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
#include "glsl/GrGLSLVertexShaderBuilder.h"
#include "glsl/GrGLSLXferProcessor.h"
class GrShaderVar;
class GrGLSLVaryingHandler;
class GrGLSLExpr4;
class GrShaderCaps;
typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
class GrGLSLProgramBuilder {
public:
using UniformHandle = GrGLSLUniformHandler::UniformHandle;
using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
virtual ~GrGLSLProgramBuilder() {}
virtual const GrCaps* caps() const = 0;
const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
const GrPipeline& pipeline() const { return fPipeline; }
const GrProgramDesc& desc() const { return fDesc; }
const GrProgramDesc::KeyHeader& header() const { return fDesc.header(); }
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
const GrShaderVar& samplerVariable(SamplerHandle handle) const {
return this->uniformHandler()->samplerVariable(handle);
}
GrSwizzle samplerSwizzle(SamplerHandle handle) const {
return this->uniformHandler()->samplerSwizzle(handle);
}
const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const {
return this->uniformHandler()->imageStorageVariable(handle);
}
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
UniformHandle fRTAdjustmentUni;
// We use the render target height to provide a y-down frag coord when specifying
// origin_upper_left is not supported.
UniformHandle fRTHeightUni;
};
// Used to add a uniform in the vertex shader for transforming into normalized device space.
void addRTAdjustmentUniform(GrSLPrecision precision, const char* name, const char** outName);
const char* rtAdjustment() const { return "rtAdjustment"; }
// Used to add a uniform for the RenderTarget height (used for frag position) without mangling
// the name of the uniform inside of a stage.
void addRTHeightUniform(const char* name);
// Generates a name for a variable. The generated string will be name prefixed by the prefix
// char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
// explicitly asked not to.
void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
virtual GrGLSLUniformHandler* uniformHandler() = 0;
virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
virtual GrGLSLVaryingHandler* varyingHandler() = 0;
// Used for backend customization of the output color and secondary color variables from the
// fragment processor. Only used if the outputs are explicitly declared in the shaders
virtual void finalizeFragmentOutputColor(GrShaderVar& outputColor) {}
virtual void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {}
// number of each input/output type in a single allocation block, used by many builders
static const int kVarsPerBlock;
GrGLSLVertexBuilder fVS;
GrGLSLGeometryBuilder fGS;
GrGLSLFragmentShaderBuilder fFS;
int fStageIndex;
const GrPipeline& fPipeline;
const GrPrimitiveProcessor& fPrimProc;
const GrProgramDesc& fDesc;
BuiltinUniformHandles fUniformHandles;
GrGLSLPrimitiveProcessor* fGeometryProcessor;
GrGLSLXferProcessor* fXferProcessor;
GrGLSLFragProcs fFragmentProcessors;
protected:
explicit GrGLSLProgramBuilder(const GrPipeline&,
const GrPrimitiveProcessor&,
const GrProgramDesc&);
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage);
void cleanupFragmentProcessors();
void finalizeShaders();
private:
// reset is called by program creator between each processor's emit code. It increments the
// stage offset for variable name mangling, and also ensures verfication variables in the
// fragment shader are cleared.
void reset() {
this->addStage();
SkDEBUGCODE(fFS.resetVerification();)
}
void addStage() { fStageIndex++; }
class AutoStageAdvance {
public:
AutoStageAdvance(GrGLSLProgramBuilder* pb)
: fPB(pb) {
fPB->reset();
// Each output to the fragment processor gets its own code section
fPB->fFS.nextStage();
}
~AutoStageAdvance() {}
private:
GrGLSLProgramBuilder* fPB;
};
// Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
// If GrGLSLExpr4 has a valid name then it will use that instead
void nameExpression(GrGLSLExpr4*, const char* baseName);
void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
GrGLSLExpr4* outputColor,
GrGLSLExpr4* outputCoverage);
void emitAndInstallFragProcs(GrGLSLExpr4* colorInOut, GrGLSLExpr4* coverageInOut);
void emitAndInstallFragProc(const GrFragmentProcessor&,
int index,
int transformedCoordVarsIdx,
const GrGLSLExpr4& input,
GrGLSLExpr4* output);
void emitAndInstallXferProc(const GrXferProcessor&,
const GrGLSLExpr4& colorIn,
const GrGLSLExpr4& coverageIn,
bool ignoresCoverage,
GrPixelLocalStorageState plsState);
void emitSamplersAndImageStorages(const GrProcessor& processor,
SkTArray<SamplerHandle>* outTexSamplerHandles,
SkTArray<SamplerHandle>* outBufferSamplerHandles,
SkTArray<ImageStorageHandle>* outImageStorageHandles);
void emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
GrShaderFlags visibility, SkTArray<SamplerHandle >* outSamplerHandles);
void emitImageStorage(const GrProcessor::ImageStorageAccess&,
const char* name,
SkTArray<ImageStorageHandle>* outImageStorageHandles);
void emitFSOutputSwizzle(bool hasSecondaryOutput);
bool checkSamplerCounts();
bool checkImageStorageCounts();
#ifdef SK_DEBUG
void verify(const GrPrimitiveProcessor&);
void verify(const GrXferProcessor&);
void verify(const GrFragmentProcessor&);
#endif
int fNumVertexSamplers;
int fNumGeometrySamplers;
int fNumFragmentSamplers;
int fNumVertexImageStorages;
int fNumGeometryImageStorages;
int fNumFragmentImageStorages;
SkSTArray<4, GrShaderVar> fTransformedCoordVars;
};
#endif
|