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