• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 SKSL_UTIL
9 #define SKSL_UTIL
10 
11 #include <cstdarg>
12 #include <memory>
13 #include "stdlib.h"
14 #include "string.h"
15 #include "SkSLLexer.h"
16 #include "SkSLDefines.h"
17 #include "SkSLString.h"
18 #include "SkSLStringStream.h"
19 
20 #ifndef SKSL_STANDALONE
21 #include "SkTypes.h"
22 #if SK_SUPPORT_GPU
23 #include "GrContextOptions.h"
24 #include "GrShaderCaps.h"
25 #endif // SK_SUPPORT_GPU
26 #endif // SKSL_STANDALONE
27 
28 class GrShaderCaps;
29 
30 namespace SkSL {
31 
32 class OutputStream;
33 class StringStream;
34 
35 #if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
36 
37 // we're being compiled standalone, so we don't have access to caps...
38 enum GrGLSLGeneration {
39     k110_GrGLSLGeneration,
40     k130_GrGLSLGeneration,
41     k140_GrGLSLGeneration,
42     k150_GrGLSLGeneration,
43     k330_GrGLSLGeneration,
44     k400_GrGLSLGeneration,
45     k420_GrGLSLGeneration,
46     k310es_GrGLSLGeneration,
47     k320es_GrGLSLGeneration,
48 };
49 
50 #define SKSL_CAPS_CLASS StandaloneShaderCaps
51 class StandaloneShaderCaps {
52 public:
generation()53     GrGLSLGeneration generation() const {
54         return k400_GrGLSLGeneration;
55     }
56 
atan2ImplementedAsAtanYOverX()57     bool atan2ImplementedAsAtanYOverX() const {
58         return false;
59     }
60 
canUseMinAndAbsTogether()61     bool canUseMinAndAbsTogether() const {
62         return true;
63     }
64 
mustForceNegatedAtanParamToFloat()65     bool mustForceNegatedAtanParamToFloat() const {
66         return false;
67     }
68 
shaderDerivativeSupport()69     bool shaderDerivativeSupport() const {
70         return true;
71     }
72 
usesPrecisionModifiers()73     bool usesPrecisionModifiers() const {
74         return true;
75     }
76 
mustDeclareFragmentShaderOutput()77     bool mustDeclareFragmentShaderOutput() const {
78         return true;
79     }
80 
fbFetchSupport()81     bool fbFetchSupport() const {
82         return true;
83     }
84 
fbFetchNeedsCustomOutput()85     bool fbFetchNeedsCustomOutput() const {
86         return false;
87     }
88 
dropsTileOnZeroDivide()89     bool dropsTileOnZeroDivide() const {
90         return false;
91     }
92 
flatInterpolationSupport()93     bool flatInterpolationSupport() const {
94         return true;
95     }
96 
noperspectiveInterpolationSupport()97     bool noperspectiveInterpolationSupport() const {
98         return true;
99     }
100 
multisampleInterpolationSupport()101     bool multisampleInterpolationSupport() const {
102         return true;
103     }
104 
sampleVariablesSupport()105     bool sampleVariablesSupport() const {
106         return true;
107     }
108 
externalTextureSupport()109     bool externalTextureSupport() const {
110         return true;
111     }
112 
imageLoadStoreSupport()113     bool imageLoadStoreSupport() const {
114         return true;
115     }
116 
mustDoOpBetweenFloorAndAbs()117     bool mustDoOpBetweenFloorAndAbs() const {
118         return false;
119     }
120 
mustEnableAdvBlendEqs()121     bool mustEnableAdvBlendEqs() const {
122         return false;
123     }
124 
mustEnableSpecificAdvBlendEqs()125     bool mustEnableSpecificAdvBlendEqs() const {
126         return false;
127     }
128 
canUseAnyFunctionInShader()129     bool canUseAnyFunctionInShader() const {
130         return false;
131     }
132 
floatIs32Bits()133     bool floatIs32Bits() const {
134         return true;
135     }
136 
integerSupport()137     bool integerSupport() const {
138         return false;
139     }
140 
builtinFMASupport()141     bool builtinFMASupport() const {
142         return true;
143     }
144 
shaderDerivativeExtensionString()145     const char* shaderDerivativeExtensionString() const {
146         return nullptr;
147     }
148 
fragCoordConventionsExtensionString()149     const char* fragCoordConventionsExtensionString() const {
150         return nullptr;
151     }
152 
imageLoadStoreExtensionString()153     const char* imageLoadStoreExtensionString() const {
154         return nullptr;
155     }
156 
geometryShaderExtensionString()157     const char* geometryShaderExtensionString() const {
158         return nullptr;
159     }
160 
gsInvocationsExtensionString()161     const char* gsInvocationsExtensionString() const {
162         return nullptr;
163     }
164 
externalTextureExtensionString()165     const char* externalTextureExtensionString() const {
166         return nullptr;
167     }
168 
secondExternalTextureExtensionString()169     const char* secondExternalTextureExtensionString() const {
170         return nullptr;
171     }
172 
versionDeclString()173     const char* versionDeclString() const {
174         return "";
175     }
176 
gsInvocationsSupport()177     bool gsInvocationsSupport() const {
178         return true;
179     }
180 
canUseFractForNegativeValues()181     bool canUseFractForNegativeValues() const {
182         return true;
183     }
184 
canUseFragCoord()185     bool canUseFragCoord() const {
186         return true;
187     }
188 
incompleteShortIntPrecision()189     bool incompleteShortIntPrecision() const {
190         return false;
191     }
192 
addAndTrueToLoopCondition()193     bool addAndTrueToLoopCondition() const {
194         return false;
195     }
196 
unfoldShortCircuitAsTernary()197     bool unfoldShortCircuitAsTernary() const {
198         return false;
199     }
200 
emulateAbsIntFunction()201     bool emulateAbsIntFunction() const {
202         return false;
203     }
204 
rewriteDoWhileLoops()205     bool rewriteDoWhileLoops() const {
206         return false;
207     }
208 
removePowWithConstantExponent()209     bool removePowWithConstantExponent() const {
210         return false;
211     }
212 
fbFetchColorName()213     const char* fbFetchColorName() const {
214         return nullptr;
215     }
216 };
217 
218 extern StandaloneShaderCaps standaloneCaps;
219 
220 #else
221 
222 #define SKSL_CAPS_CLASS GrShaderCaps
223 // Various sets of caps for use in tests
224 class ShaderCapsFactory {
225 public:
Default()226     static sk_sp<GrShaderCaps> Default() {
227         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
228         result->fVersionDeclString = "#version 400";
229         result->fShaderDerivativeSupport = true;
230         return result;
231     }
232 
Version450Core()233     static sk_sp<GrShaderCaps> Version450Core() {
234         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
235         result->fVersionDeclString = "#version 450 core";
236         return result;
237     }
238 
Version110()239     static sk_sp<GrShaderCaps> Version110() {
240         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
241         result->fVersionDeclString = "#version 110";
242         result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
243         return result;
244     }
245 
UsesPrecisionModifiers()246     static sk_sp<GrShaderCaps> UsesPrecisionModifiers() {
247         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
248         result->fVersionDeclString = "#version 400";
249         result->fUsesPrecisionModifiers = true;
250         return result;
251     }
252 
CannotUseMinAndAbsTogether()253     static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() {
254         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
255         result->fVersionDeclString = "#version 400";
256         result->fCanUseMinAndAbsTogether = false;
257         return result;
258     }
259 
CannotUseFractForNegativeValues()260     static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() {
261         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
262         result->fVersionDeclString = "#version 400";
263         result->fCanUseFractForNegativeValues = false;
264         return result;
265     }
266 
MustForceNegatedAtanParamToFloat()267     static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() {
268         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
269         result->fVersionDeclString = "#version 400";
270         result->fMustForceNegatedAtanParamToFloat = true;
271         return result;
272     }
273 
ShaderDerivativeExtensionString()274     static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() {
275         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
276         result->fVersionDeclString = "#version 400";
277         result->fShaderDerivativeSupport = true;
278         result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
279         result->fUsesPrecisionModifiers = true;
280         return result;
281     }
282 
FragCoordsOld()283     static sk_sp<GrShaderCaps> FragCoordsOld() {
284         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
285         result->fVersionDeclString = "#version 110";
286         result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
287         result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
288         return result;
289     }
290 
FragCoordsNew()291     static sk_sp<GrShaderCaps> FragCoordsNew() {
292         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
293         result->fVersionDeclString = "#version 400";
294         result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
295         return result;
296     }
297 
GeometryShaderSupport()298     static sk_sp<GrShaderCaps> GeometryShaderSupport() {
299         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
300         result->fVersionDeclString = "#version 400";
301         result->fGeometryShaderSupport = true;
302         result->fGSInvocationsSupport = true;
303         return result;
304     }
305 
NoGSInvocationsSupport()306     static sk_sp<GrShaderCaps> NoGSInvocationsSupport() {
307         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
308         result->fVersionDeclString = "#version 400";
309         result->fGeometryShaderSupport = true;
310         result->fGSInvocationsSupport = false;
311         return result;
312     }
313 
GeometryShaderExtensionString()314     static sk_sp<GrShaderCaps> GeometryShaderExtensionString() {
315         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
316         result->fVersionDeclString = "#version 310es";
317         result->fGeometryShaderSupport = true;
318         result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
319         result->fGSInvocationsSupport = true;
320         return result;
321     }
322 
GSInvocationsExtensionString()323     static sk_sp<GrShaderCaps> GSInvocationsExtensionString() {
324         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
325         result->fVersionDeclString = "#version 400";
326         result->fGeometryShaderSupport = true;
327         result->fGSInvocationsSupport = true;
328         result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
329         return result;
330     }
331 
VariousCaps()332     static sk_sp<GrShaderCaps> VariousCaps() {
333         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
334         result->fVersionDeclString = "#version 400";
335         result->fExternalTextureSupport = true;
336         result->fFBFetchSupport = false;
337         result->fDropsTileOnZeroDivide = true;
338         result->fCanUseAnyFunctionInShader = false;
339         return result;
340     }
341 
CannotUseFragCoord()342     static sk_sp<GrShaderCaps> CannotUseFragCoord() {
343         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
344         result->fVersionDeclString = "#version 400";
345         result->fCanUseFragCoord = false;
346         return result;
347     }
348 
IncompleteShortIntPrecision()349     static sk_sp<GrShaderCaps> IncompleteShortIntPrecision() {
350         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
351         result->fVersionDeclString = "#version 310es";
352         result->fUsesPrecisionModifiers = true;
353         result->fIncompleteShortIntPrecision = true;
354         return result;
355     }
356 
AddAndTrueToLoopCondition()357     static sk_sp<GrShaderCaps> AddAndTrueToLoopCondition() {
358         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
359         result->fVersionDeclString = "#version 400";
360         result->fAddAndTrueToLoopCondition = true;
361         return result;
362     }
363 
UnfoldShortCircuitAsTernary()364     static sk_sp<GrShaderCaps> UnfoldShortCircuitAsTernary() {
365         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
366         result->fVersionDeclString = "#version 400";
367         result->fUnfoldShortCircuitAsTernary = true;
368         return result;
369     }
370 
EmulateAbsIntFunction()371     static sk_sp<GrShaderCaps> EmulateAbsIntFunction() {
372         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
373         result->fVersionDeclString = "#version 400";
374         result->fEmulateAbsIntFunction = true;
375         return result;
376     }
377 
RewriteDoWhileLoops()378     static sk_sp<GrShaderCaps> RewriteDoWhileLoops() {
379         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
380         result->fVersionDeclString = "#version 400";
381         result->fRewriteDoWhileLoops = true;
382         return result;
383     }
384 
RemovePowWithConstantExponent()385     static sk_sp<GrShaderCaps> RemovePowWithConstantExponent() {
386         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
387         result->fVersionDeclString = "#version 400";
388         result->fRemovePowWithConstantExponent = true;
389         return result;
390     }
391 };
392 #endif
393 
394 void write_stringstream(const StringStream& d, OutputStream& out);
395 
396 // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.)
397 bool is_assignment(Token::Kind op);
398 
399 // Given a compound assignment operator, returns the non-assignment version of the operator (e.g.
400 // '+=' becomes '+')
401 Token::Kind remove_assignment(Token::Kind op);
402 
403 NORETURN void sksl_abort();
404 
405 } // namespace
406 
407 #endif
408