OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2014 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 GrGLShaderBuilder_DEFINED | |
9 #define GrGLShaderBuilder_DEFINED | |
10 | |
11 #include "GrAllocator.h" | |
12 #include "glsl/GrGLSLShaderVar.h" | |
13 #include "SkTDArray.h" | |
14 | |
15 #include <stdarg.h> | |
16 | |
17 class GrGLSLProgramBuilder; | |
18 class GrGLSLTextureSampler; | |
19 | |
20 /** | |
21 base class for all shaders builders | |
22 */ | |
23 class GrGLShaderBuilder { | |
24 public: | |
25 GrGLShaderBuilder(GrGLSLProgramBuilder* program); | |
26 virtual ~GrGLShaderBuilder() {} | |
27 | |
28 void addInput(const GrGLSLShaderVar& input) { fInputs.push_back(input); } | |
29 void addOutput(const GrGLSLShaderVar& output) { fOutputs.push_back(output);
} | |
30 | |
31 /* | |
32 * We put texture lookups in the base class because it is TECHNICALLY possib
le to do texture | |
33 * lookups in any kind of shader. However, for the time being using these c
alls on non-fragment | |
34 * shaders will result in a shader compilation error as texture sampler unif
orms are only | |
35 * visible to the fragment shader. It would not be hard to change this beha
vior, if someone | |
36 * actually wants to do texture lookups in a non-fragment shader | |
37 * | |
38 * TODO if append texture lookup is used on a non-fragment shader, sampler u
niforms should be | |
39 * made visible to that shaders | |
40 */ | |
41 /** Appends a 2D texture sample with projection if necessary. coordType must
either be Vec2f or | |
42 Vec3f. The latter is interpreted as projective texture coords. The vec l
ength and swizzle | |
43 order of the result depends on the GrTextureAccess associated with the G
rGLSLTextureSampler. | |
44 */ | |
45 void appendTextureLookup(SkString* out, | |
46 const GrGLSLTextureSampler&, | |
47 const char* coordName, | |
48 GrSLType coordType = kVec2f_GrSLType) const; | |
49 | |
50 /** Version of above that appends the result to the fragment shader code ins
tead.*/ | |
51 void appendTextureLookup(const GrGLSLTextureSampler&, | |
52 const char* coordName, | |
53 GrSLType coordType = kVec2f_GrSLType); | |
54 | |
55 | |
56 /** Does the work of appendTextureLookup and modulates the result by modulat
ion. The result is | |
57 always a vec4. modulation and the swizzle specified by GrGLSLTextureSamp
ler must both be | |
58 vec4 or float. If modulation is "" or nullptr it this function acts as t
hough | |
59 appendTextureLookup were called. */ | |
60 void appendTextureLookupAndModulate(const char* modulation, | |
61 const GrGLSLTextureSampler&, | |
62 const char* coordName, | |
63 GrSLType coordType = kVec2f_GrSLType); | |
64 | |
65 /** | |
66 * Called by GrGLProcessors to add code to one of the shaders. | |
67 */ | |
68 void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | |
69 va_list args; | |
70 va_start(args, format); | |
71 this->code().appendVAList(format, args); | |
72 va_end(args); | |
73 } | |
74 | |
75 void codeAppend(const char* str) { this->code().append(str); } | |
76 | |
77 void codePrependf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | |
78 va_list args; | |
79 va_start(args, format); | |
80 this->code().prependVAList(format, args); | |
81 va_end(args); | |
82 } | |
83 | |
84 /** | |
85 * Appends a variable declaration to one of the shaders | |
86 */ | |
87 void declAppend(const GrGLSLShaderVar& var); | |
88 | |
89 /** Emits a helper function outside of main() in the fragment shader. */ | |
90 void emitFunction(GrSLType returnType, | |
91 const char* name, | |
92 int argCnt, | |
93 const GrGLSLShaderVar* args, | |
94 const char* body, | |
95 SkString* outName); | |
96 | |
97 /* | |
98 * Combines the various parts of the shader to create a single finalized sha
der string. | |
99 */ | |
100 void finalize(uint32_t visibility); | |
101 | |
102 /* | |
103 * Get parent builder for adding uniforms | |
104 */ | |
105 GrGLSLProgramBuilder* getProgramBuilder() { return fProgramBuilder; } | |
106 | |
107 /** | |
108 * Helper for begining and ending a block in the shader code. | |
109 */ | |
110 class ShaderBlock { | |
111 public: | |
112 ShaderBlock(GrGLShaderBuilder* builder) : fBuilder(builder) { | |
113 SkASSERT(builder); | |
114 fBuilder->codeAppend("{"); | |
115 } | |
116 | |
117 ~ShaderBlock() { | |
118 fBuilder->codeAppend("}"); | |
119 } | |
120 private: | |
121 GrGLShaderBuilder* fBuilder; | |
122 }; | |
123 | |
124 protected: | |
125 typedef GrTAllocator<GrGLSLShaderVar> VarArray; | |
126 void appendDecls(const VarArray& vars, SkString* out) const; | |
127 | |
128 /* | |
129 * A general function which enables an extension in a shader if the feature
bit is not present | |
130 */ | |
131 void addFeature(uint32_t featureBit, const char* extensionName); | |
132 | |
133 enum InterfaceQualifier { | |
134 kOut_InterfaceQualifier, | |
135 kLastInterfaceQualifier = kOut_InterfaceQualifier | |
136 }; | |
137 | |
138 /* | |
139 * A low level function to build default layout qualifiers. | |
140 * | |
141 * e.g. layout(param1, param2, ...) out; | |
142 * | |
143 * GLSL allows default layout qualifiers for in, out, and uniform. | |
144 */ | |
145 void addLayoutQualifier(const char* param, InterfaceQualifier); | |
146 | |
147 void compileAndAppendLayoutQualifiers(); | |
148 | |
149 void nextStage() { | |
150 fShaderStrings.push_back(); | |
151 fCompilerStrings.push_back(this->code().c_str()); | |
152 fCompilerStringLengths.push_back((int)this->code().size()); | |
153 fCodeIndex++; | |
154 } | |
155 | |
156 SkString& versionDecl() { return fShaderStrings[kVersionDecl]; } | |
157 SkString& extensions() { return fShaderStrings[kExtensions]; } | |
158 SkString& precisionQualifier() { return fShaderStrings[kPrecisionQualifier];
} | |
159 SkString& layoutQualifiers() { return fShaderStrings[kLayoutQualifiers]; } | |
160 SkString& uniforms() { return fShaderStrings[kUniforms]; } | |
161 SkString& inputs() { return fShaderStrings[kInputs]; } | |
162 SkString& outputs() { return fShaderStrings[kOutputs]; } | |
163 SkString& functions() { return fShaderStrings[kFunctions]; } | |
164 SkString& main() { return fShaderStrings[kMain]; } | |
165 SkString& code() { return fShaderStrings[fCodeIndex]; } | |
166 | |
167 virtual void onFinalize() = 0; | |
168 | |
169 enum { | |
170 kVersionDecl, | |
171 kExtensions, | |
172 kPrecisionQualifier, | |
173 kLayoutQualifiers, | |
174 kUniforms, | |
175 kInputs, | |
176 kOutputs, | |
177 kFunctions, | |
178 kMain, | |
179 kCode, | |
180 }; | |
181 | |
182 GrGLSLProgramBuilder* fProgramBuilder; | |
183 SkSTArray<kCode, const char*, true> fCompilerStrings; | |
184 SkSTArray<kCode, int, true> fCompilerStringLengths; | |
185 SkSTArray<kCode, SkString> fShaderStrings; | |
186 SkString fCode; | |
187 SkString fFunctions; | |
188 SkString fExtensions; | |
189 | |
190 VarArray fInputs; | |
191 VarArray fOutputs; | |
192 uint32_t fFeaturesAddedMask; | |
193 SkSTArray<1, SkString> fLayoutParams[kLastInterfaceQualifier + 1]; | |
194 int fCodeIndex; | |
195 bool fFinalized; | |
196 | |
197 friend class GrGLProgramBuilder; | |
198 friend class GrGLPathProgramBuilder; // to access fInputs. | |
199 }; | |
200 #endif | |
OLD | NEW |