Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / sksl / SkSLUtil.h
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 "include/sksl/SkSLVersion.h"
12 #include "src/core/SkSLTypeShared.h"
13 #include "src/sksl/SkSLGLSL.h"
14
15 #include <memory>
16
17 #ifndef SKSL_STANDALONE
18 #include "include/core/SkTypes.h"
19 #endif // SKSL_STANDALONE
20
21 namespace SkSL {
22
23 class Context;
24 class OutputStream;
25 class StringStream;
26 class Type;
27
28 struct ShaderCaps {
29     /**
30      * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
31      * special layout qualifiers in the fragment shader.
32      */
33     enum AdvBlendEqInteraction {
34         kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
35         kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
36         kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
37
38         kLast_AdvBlendEqInteraction = kGeneralEnable_AdvBlendEqInteraction
39     };
40
41     //
42     // TODO: Remove these accessors
43     //
44     bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
45     bool nonsquareMatrixSupport() const { return fNonsquareMatrixSupport; }
46
47     /** Indicates true 32-bit integer support, with unsigned types and bitwise operations */
48     bool integerSupport() const { return fIntegerSupport; }
49
50     /** asinh(), acosh(), atanh() */
51     bool inverseHyperbolicSupport() const { return fInverseHyperbolicSupport; }
52
53     /**
54      * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
55      *
56      * TODO: On desktop opengl 4.2+ we can achieve something similar to this effect
57      */
58     bool fbFetchSupport() const { return fFBFetchSupport; }
59
60     bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
61
62     const char* versionDeclString() const { return fVersionDeclString; }
63
64     const char* fbFetchColorName() const { return fFBFetchColorName; }
65
66     bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
67
68     bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
69
70     bool sampleMaskSupport() const { return fSampleMaskSupport; }
71
72     bool externalTextureSupport() const { return fExternalTextureSupport; }
73
74     bool floatIs32Bits() const { return fFloatIs32Bits; }
75
76     // SkSL only.
77     bool builtinFMASupport() const { return fBuiltinFMASupport; }
78
79     bool builtinDeterminantSupport() const { return fBuiltinDeterminantSupport; }
80
81     AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
82
83     bool mustEnableAdvBlendEqs() const {
84         return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
85     }
86
87     bool mustDeclareFragmentShaderOutput() const {
88         return fGLSLGeneration > SkSL::GLSLGeneration::k110;
89     }
90
91     bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
92
93     // Returns whether we can use the glsl function any() in our shader code.
94     bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
95
96     bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
97
98     bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; }
99
100     bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
101
102     // http://skbug.com/12076
103     bool mustForceNegatedLdexpParamToMultiply() const {
104         return fMustForceNegatedLdexpParamToMultiply;
105     }
106
107     // Returns whether a device incorrectly implements atan(y,x) as atan(y/x)
108     bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; }
109
110     // If this returns true some operation (could be a no op) must be called between floor and abs
111     // to make sure the driver compiler doesn't inline them together which can cause a driver bug in
112     // the shader.
113     bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; }
114
115     // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord
116     bool canUseFragCoord() const { return fCanUseFragCoord; }
117
118     // If true, short ints can't represent every integer in the 16-bit two's complement range as
119     // required by the spec. SKSL will always emit full ints.
120     bool incompleteShortIntPrecision() const { return fIncompleteShortIntPrecision; }
121
122     // If true, then conditions in for loops need "&& true" to work around driver bugs.
123     bool addAndTrueToLoopCondition() const { return fAddAndTrueToLoopCondition; }
124
125     // If true, then expressions such as "x && y" or "x || y" are rewritten as
126     // ternary to work around driver bugs.
127     bool unfoldShortCircuitAsTernary() const { return fUnfoldShortCircuitAsTernary; }
128
129     bool emulateAbsIntFunction() const { return fEmulateAbsIntFunction; }
130
131     bool rewriteDoWhileLoops() const { return fRewriteDoWhileLoops; }
132
133     bool rewriteSwitchStatements() const { return fRewriteSwitchStatements; }
134
135     bool removePowWithConstantExponent() const { return fRemovePowWithConstantExponent; }
136
137     // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain
138     // constructs. See detailed comments in GrGLCaps.cpp.
139     bool mustGuardDivisionEvenAfterExplicitZeroCheck() const {
140         return fMustGuardDivisionEvenAfterExplicitZeroCheck;
141     }
142
143     // The Android emulator claims samplerExternalOES is an unknown type if a default precision
144     // statement is made for the type.
145     bool noDefaultPrecisionForExternalSamplers() const {
146         return fNoDefaultPrecisionForExternalSamplers;
147     }
148
149     // ARM GPUs calculate `matrix * vector` in SPIR-V at full precision, even when the inputs are
150     // RelaxedPrecision. Rewriting the multiply as a sum of vector*scalar fixes this. (skia:11769)
151     bool rewriteMatrixVectorMultiply() const {
152         return fRewriteMatrixVectorMultiply;
153     }
154
155     // Rewrites matrix equality comparisons to avoid an Adreno driver bug. (skia:11308)
156     bool rewriteMatrixComparisons() const { return fRewriteMatrixComparisons; }
157
158     // By default, SkSL pools IR nodes per-program. To debug memory corruption, it is sometimes
159     // helpful to disable that feature.
160     bool useNodePools() const { return fUseNodePools; }
161
162     // Returns the string of an extension that must be enabled in the shader to support
163     // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
164     // this function, the caller should check that shaderDerivativeSupport exists.
165     const char* shaderDerivativeExtensionString() const {
166         SkASSERT(this->shaderDerivativeSupport());
167         return fShaderDerivativeExtensionString;
168     }
169
170     // This returns the name of an extension that must be enabled in the shader to support external
171     // textures. In some cases, two extensions must be enabled - the second extension is returned
172     // by secondExternalTextureExtensionString(). If that function returns nullptr, then only one
173     // extension is required.
174     const char* externalTextureExtensionString() const {
175         SkASSERT(this->externalTextureSupport());
176         return fExternalTextureExtensionString;
177     }
178
179     const char* secondExternalTextureExtensionString() const {
180         SkASSERT(this->externalTextureSupport());
181         return fSecondExternalTextureExtensionString;
182     }
183
184     /**
185      * SkSL 300 requires support for derivatives, nonsquare matrices and bitwise integer operations.
186      */
187     SkSL::Version supportedSkSLVerion() const {
188         if (fShaderDerivativeSupport && fNonsquareMatrixSupport && fIntegerSupport &&
189             fGLSLGeneration >= SkSL::GLSLGeneration::k330) {
190             return SkSL::Version::k300;
191         }
192         return SkSL::Version::k100;
193     }
194
195     SkSL::GLSLGeneration generation() const { return fGLSLGeneration; }
196
197     SkSL::GLSLGeneration fGLSLGeneration = SkSL::GLSLGeneration::k330;
198
199     bool fShaderDerivativeSupport = false;
200     bool fIntegerSupport = false;
201     bool fNonsquareMatrixSupport = false;
202     bool fInverseHyperbolicSupport = false;
203     bool fFBFetchSupport = false;
204     bool fFBFetchNeedsCustomOutput = false;
205     bool fUsesPrecisionModifiers = false;
206     bool fFlatInterpolationSupport = false;
207     bool fNoPerspectiveInterpolationSupport = false;
208     bool fSampleMaskSupport = false;
209     bool fExternalTextureSupport = false;
210     bool fFloatIs32Bits = true;
211
212     // Used by SkSL to know when to generate polyfills.
213     bool fBuiltinFMASupport = false;
214     bool fBuiltinDeterminantSupport = false;
215
216     // Used for specific driver bug work arounds
217     bool fCanUseAnyFunctionInShader = true;
218     bool fCanUseMinAndAbsTogether = true;
219     bool fCanUseFractForNegativeValues = true;
220     bool fMustForceNegatedAtanParamToFloat = false;
221     bool fMustForceNegatedLdexpParamToMultiply = false;
222     bool fAtan2ImplementedAsAtanYOverX = false;
223     bool fMustDoOpBetweenFloorAndAbs = false;
224     bool fMustGuardDivisionEvenAfterExplicitZeroCheck = false;
225     bool fCanUseFragCoord = true;
226     bool fIncompleteShortIntPrecision = false;
227     bool fAddAndTrueToLoopCondition = false;
228     bool fUnfoldShortCircuitAsTernary = false;
229     bool fEmulateAbsIntFunction = false;
230     bool fRewriteDoWhileLoops = false;
231     bool fRewriteSwitchStatements = false;
232     bool fRemovePowWithConstantExponent = false;
233     bool fNoDefaultPrecisionForExternalSamplers = false;
234     bool fRewriteMatrixVectorMultiply = false;
235     bool fRewriteMatrixComparisons = false;
236
237     // This controls behavior of the SkSL compiler, not the code we generate
238     bool fUseNodePools = true;
239
240     const char* fVersionDeclString = "";
241
242     const char* fShaderDerivativeExtensionString = nullptr;
243     const char* fExternalTextureExtensionString = nullptr;
244     const char* fSecondExternalTextureExtensionString = nullptr;
245     const char* fFBFetchColorName = nullptr;
246
247     AdvBlendEqInteraction fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
248 };
249
250 // Various sets of caps for use in tests
251 class ShaderCapsFactory {
252 public:
253     static std::unique_ptr<ShaderCaps> Default() {
254         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
255         result->fVersionDeclString = "#version 400";
256         result->fShaderDerivativeSupport = true;
257         result->fBuiltinDeterminantSupport = true;
258         return result;
259     }
260
261     static std::unique_ptr<ShaderCaps> Standalone() {
262         return MakeShaderCaps();
263     }
264
265     static std::unique_ptr<ShaderCaps> AddAndTrueToLoopCondition() {
266         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
267         result->fVersionDeclString = "#version 400";
268         result->fAddAndTrueToLoopCondition = true;
269         return result;
270     }
271
272     static std::unique_ptr<ShaderCaps> CannotUseFractForNegativeValues() {
273         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
274         result->fVersionDeclString = "#version 400";
275         result->fCanUseFractForNegativeValues = false;
276         return result;
277     }
278
279     static std::unique_ptr<ShaderCaps> CannotUseFragCoord() {
280         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
281         result->fVersionDeclString = "#version 400";
282         result->fCanUseFragCoord = false;
283         return result;
284     }
285
286     static std::unique_ptr<ShaderCaps> CannotUseMinAndAbsTogether() {
287         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
288         result->fVersionDeclString = "#version 400";
289         result->fCanUseMinAndAbsTogether = false;
290         return result;
291     }
292
293     static std::unique_ptr<ShaderCaps> EmulateAbsIntFunction() {
294         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
295         result->fVersionDeclString = "#version 400";
296         result->fEmulateAbsIntFunction = true;
297         return result;
298     }
299
300     static std::unique_ptr<ShaderCaps> FramebufferFetchSupport() {
301         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
302         result->fFBFetchSupport = true;
303         result->fFBFetchColorName = "gl_LastFragData[0]";
304         return result;
305     }
306
307     static std::unique_ptr<ShaderCaps> IncompleteShortIntPrecision() {
308         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
309         result->fVersionDeclString = "#version 310es";
310         result->fUsesPrecisionModifiers = true;
311         result->fIncompleteShortIntPrecision = true;
312         return result;
313     }
314
315     static std::unique_ptr<ShaderCaps> MustForceNegatedAtanParamToFloat() {
316         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
317         result->fVersionDeclString = "#version 400";
318         result->fMustForceNegatedAtanParamToFloat = true;
319         return result;
320     }
321
322     static std::unique_ptr<ShaderCaps> MustForceNegatedLdexpParamToMultiply() {
323         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
324         result->fVersionDeclString = "#version 400";
325         result->fMustForceNegatedLdexpParamToMultiply = true;
326         return result;
327     }
328
329     static std::unique_ptr<ShaderCaps> MustGuardDivisionEvenAfterExplicitZeroCheck() {
330         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
331         result->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
332         return result;
333     }
334
335     static std::unique_ptr<ShaderCaps> RemovePowWithConstantExponent() {
336         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
337         result->fVersionDeclString = "#version 400";
338         result->fRemovePowWithConstantExponent = true;
339         return result;
340     }
341
342     static std::unique_ptr<ShaderCaps> RewriteDoWhileLoops() {
343         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
344         result->fVersionDeclString = "#version 400";
345         result->fRewriteDoWhileLoops = true;
346         return result;
347     }
348
349     static std::unique_ptr<ShaderCaps> RewriteMatrixComparisons() {
350         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
351         result->fRewriteMatrixComparisons = true;
352         result->fUsesPrecisionModifiers = true;
353         return result;
354     }
355
356     static std::unique_ptr<ShaderCaps> RewriteMatrixVectorMultiply() {
357         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
358         result->fVersionDeclString = "#version 400";
359         result->fRewriteMatrixVectorMultiply = true;
360         return result;
361     }
362
363     static std::unique_ptr<ShaderCaps> RewriteSwitchStatements() {
364         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
365         result->fVersionDeclString = "#version 400";
366         result->fRewriteSwitchStatements = true;
367         return result;
368     }
369
370     static std::unique_ptr<ShaderCaps> SampleMaskSupport() {
371         std::unique_ptr<ShaderCaps> result = Default();
372         result->fSampleMaskSupport = true;
373         return result;
374     }
375
376     static std::unique_ptr<ShaderCaps> ShaderDerivativeExtensionString() {
377         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
378         result->fVersionDeclString = "#version 400";
379         result->fShaderDerivativeSupport = true;
380         result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
381         result->fUsesPrecisionModifiers = true;
382         return result;
383     }
384
385     static std::unique_ptr<ShaderCaps> UnfoldShortCircuitAsTernary() {
386         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
387         result->fVersionDeclString = "#version 400";
388         result->fUnfoldShortCircuitAsTernary = true;
389         return result;
390     }
391
392     static std::unique_ptr<ShaderCaps> UsesPrecisionModifiers() {
393         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
394         result->fVersionDeclString = "#version 400";
395         result->fUsesPrecisionModifiers = true;
396         return result;
397     }
398
399     static std::unique_ptr<ShaderCaps> Version110() {
400         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
401         result->fVersionDeclString = "#version 110";
402         result->fGLSLGeneration = SkSL::GLSLGeneration::k110;
403         return result;
404     }
405
406     static std::unique_ptr<ShaderCaps> Version450Core() {
407         std::unique_ptr<ShaderCaps> result = MakeShaderCaps();
408         result->fVersionDeclString = "#version 450 core";
409         return result;
410     }
411
412 private:
413     static std::unique_ptr<ShaderCaps> MakeShaderCaps();
414 };
415
416 #if !defined(SKSL_STANDALONE) && (SK_SUPPORT_GPU || defined(SK_GRAPHITE_ENABLED))
417 bool type_to_sksltype(const Context& context, const Type& type, SkSLType* outType);
418 #endif
419
420 void write_stringstream(const StringStream& d, OutputStream& out);
421
422 }  // namespace SkSL
423
424 #endif  // SKSL_UTIL