/src/skia/src/sksl/ir/SkSLSetting.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2017 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 | | #include "src/sksl/SkSLIRGenerator.h" |
9 | | #include "src/sksl/ir/SkSLSetting.h" |
10 | | #include "src/sksl/ir/SkSLVariableReference.h" |
11 | | |
12 | | namespace SkSL { |
13 | | |
14 | | // Helper classes for converting caps fields to Expressions and Types in the CapsLookupTable. |
15 | | namespace { |
16 | | |
17 | | class CapsLookupMethod { |
18 | | public: |
19 | 0 | virtual ~CapsLookupMethod() {} |
20 | | virtual const Type* type(const Context& context) const = 0; |
21 | | virtual std::unique_ptr<Expression> value(const Context& context) const = 0; |
22 | | }; |
23 | | |
24 | | class BoolCapsLookup : public CapsLookupMethod { |
25 | | public: |
26 | | using CapsFn = bool (ShaderCapsClass::*)() const; |
27 | | |
28 | 119 | BoolCapsLookup(const CapsFn& fn) : fGetCap(fn) {} |
29 | | |
30 | 0 | const Type* type(const Context& context) const override { |
31 | 0 | return context.fTypes.fBool.get(); |
32 | 0 | } |
33 | 167k | std::unique_ptr<Expression> value(const Context& context) const override { |
34 | 167k | return BoolLiteral::Make(context, /*offset=*/-1, (context.fCaps.*fGetCap)()); |
35 | 167k | } |
36 | | |
37 | | private: |
38 | | CapsFn fGetCap; |
39 | | }; |
40 | | |
41 | | class IntCapsLookup : public CapsLookupMethod { |
42 | | public: |
43 | | using CapsFn = int (ShaderCapsClass::*)() const; |
44 | | |
45 | 0 | IntCapsLookup(const CapsFn& fn) : fGetCap(fn) {} |
46 | | |
47 | 0 | const Type* type(const Context& context) const override { |
48 | 0 | return context.fTypes.fInt.get(); |
49 | 0 | } |
50 | 0 | std::unique_ptr<Expression> value(const Context& context) const override { |
51 | 0 | return IntLiteral::Make(context, /*offset=*/-1, (context.fCaps.*fGetCap)()); |
52 | 0 | } |
53 | | |
54 | | private: |
55 | | CapsFn fGetCap; |
56 | | }; |
57 | | |
58 | | class CapsLookupTable { |
59 | | public: |
60 | | using Pair = std::pair<const char*, CapsLookupMethod*>; |
61 | | |
62 | 7 | CapsLookupTable(std::initializer_list<Pair> capsLookups) { |
63 | 119 | for (auto& entry : capsLookups) { |
64 | 119 | fMap[entry.first] = std::unique_ptr<CapsLookupMethod>(entry.second); |
65 | 119 | } |
66 | 7 | } |
67 | | |
68 | 170k | const CapsLookupMethod* lookup(skstd::string_view name) const { |
69 | 170k | auto iter = fMap.find(name); |
70 | 167k | return (iter != fMap.end()) ? iter->second.get() : nullptr; |
71 | 170k | } |
72 | | |
73 | | private: |
74 | | std::unordered_map<skstd::string_view, std::unique_ptr<CapsLookupMethod>> fMap; |
75 | | }; |
76 | | |
77 | 170k | static const CapsLookupTable& caps_lookup_table() { |
78 | | // Create a lookup table that converts strings into the equivalent ShaderCapsClass methods. |
79 | 170k | static CapsLookupTable* sCapsLookupTable = new CapsLookupTable({ |
80 | 2.89M | #define CAP(T, name) CapsLookupTable::Pair{#name, new T##CapsLookup{&ShaderCapsClass::name}} |
81 | 170k | CAP(Bool, fbFetchSupport), |
82 | 170k | CAP(Bool, fbFetchNeedsCustomOutput), |
83 | 170k | CAP(Bool, flatInterpolationSupport), |
84 | 170k | CAP(Bool, noperspectiveInterpolationSupport), |
85 | 170k | CAP(Bool, externalTextureSupport), |
86 | 170k | CAP(Bool, mustEnableAdvBlendEqs), |
87 | 170k | CAP(Bool, mustDeclareFragmentShaderOutput), |
88 | 170k | CAP(Bool, mustDoOpBetweenFloorAndAbs), |
89 | 170k | CAP(Bool, mustGuardDivisionEvenAfterExplicitZeroCheck), |
90 | 170k | CAP(Bool, inBlendModesFailRandomlyForAllZeroVec), |
91 | 170k | CAP(Bool, atan2ImplementedAsAtanYOverX), |
92 | 170k | CAP(Bool, canUseAnyFunctionInShader), |
93 | 170k | CAP(Bool, floatIs32Bits), |
94 | 170k | CAP(Bool, integerSupport), |
95 | 170k | CAP(Bool, builtinFMASupport), |
96 | 170k | CAP(Bool, builtinDeterminantSupport), |
97 | 170k | CAP(Bool, rewriteMatrixVectorMultiply), |
98 | 170k | #undef CAP |
99 | 170k | }); |
100 | 170k | return *sCapsLookupTable; |
101 | 170k | } |
102 | | |
103 | | } // namespace |
104 | | |
105 | 0 | static const Type* get_type(const Context& context, int offset, skstd::string_view name) { |
106 | 0 | if (const CapsLookupMethod* caps = caps_lookup_table().lookup(name)) { |
107 | 0 | return caps->type(context); |
108 | 0 | } |
109 | | |
110 | 0 | context.errors().error(offset, "unknown capability flag '" + name + "'"); |
111 | 0 | return nullptr; |
112 | 0 | } |
113 | | |
114 | | static std::unique_ptr<Expression> get_value(const Context& context, int offset, |
115 | 170k | const skstd::string_view& name) { |
116 | 170k | if (const CapsLookupMethod* caps = caps_lookup_table().lookup(name)) { |
117 | 167k | return caps->value(context); |
118 | 167k | } |
119 | | |
120 | 3.12k | context.errors().error(offset, "unknown capability flag '" + name + "'"); |
121 | 3.12k | return nullptr; |
122 | 3.12k | } |
123 | | |
124 | | std::unique_ptr<Expression> Setting::Convert(const Context& context, int offset, |
125 | 170k | const skstd::string_view& name) { |
126 | 170k | SkASSERT(context.fConfig); |
127 | | |
128 | 170k | if (context.fConfig->fSettings.fReplaceSettings) { |
129 | | // Insert the settings value directly into the IR. |
130 | 170k | return get_value(context, offset, name); |
131 | 170k | } |
132 | | |
133 | | // Generate a Setting IRNode. |
134 | 0 | const Type* type = get_type(context, offset, name); |
135 | 0 | return type ? std::make_unique<Setting>(offset, name, type) : nullptr; |
136 | 0 | } SkSL::Setting::Convert(SkSL::Context const&, int, skstd::string_view const&) Line | Count | Source | 125 | 2 | const skstd::string_view& name) { | 126 | 2 | SkASSERT(context.fConfig); | 127 | | | 128 | 2 | if (context.fConfig->fSettings.fReplaceSettings) { | 129 | | // Insert the settings value directly into the IR. | 130 | 2 | return get_value(context, offset, name); | 131 | 2 | } | 132 | | | 133 | | // Generate a Setting IRNode. | 134 | 0 | const Type* type = get_type(context, offset, name); | 135 | 0 | return type ? std::make_unique<Setting>(offset, name, type) : nullptr; | 136 | 0 | } |
SkSL::Setting::Convert(SkSL::Context const&, int, skstd::string_view const&) Line | Count | Source | 125 | 170k | const skstd::string_view& name) { | 126 | 170k | SkASSERT(context.fConfig); | 127 | | | 128 | 170k | if (context.fConfig->fSettings.fReplaceSettings) { | 129 | | // Insert the settings value directly into the IR. | 130 | 170k | return get_value(context, offset, name); | 131 | 170k | } | 132 | | | 133 | | // Generate a Setting IRNode. | 134 | 0 | const Type* type = get_type(context, offset, name); | 135 | 0 | return type ? std::make_unique<Setting>(offset, name, type) : nullptr; | 136 | 0 | } |
|
137 | | |
138 | | } // namespace SkSL |