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 | #include "src/sksl/SkSLContext.h" |
9 | #include "src/sksl/ir/SkSLType.h" |
10 | |
11 | namespace SkSL { |
12 | |
13 | int Type::coercionCost(const Type& other) const { |
14 | if (*this == other) { |
15 | return 0; |
16 | } |
17 | if (this->kind() == kNullable_Kind && other.kind() != kNullable_Kind) { |
18 | int result = this->componentType().coercionCost(other); |
19 | if (result != INT_MAX) { |
20 | ++result; |
21 | } |
22 | return result; |
23 | } |
24 | if (this->fName == "null" && other.kind() == kNullable_Kind) { |
25 | return 0; |
26 | } |
27 | if (this->kind() == kVector_Kind && other.kind() == kVector_Kind) { |
28 | if (this->columns() == other.columns()) { |
29 | return this->componentType().coercionCost(other.componentType()); |
30 | } |
31 | return INT_MAX; |
32 | } |
33 | if (this->kind() == kMatrix_Kind) { |
34 | if (this->columns() == other.columns() && this->rows() == other.rows()) { |
35 | return this->componentType().coercionCost(other.componentType()); |
36 | } |
37 | return INT_MAX; |
38 | } |
39 | if (this->isNumber() && other.isNumber() && other.priority() > this->priority()) { |
40 | return other.priority() - this->priority(); |
41 | } |
42 | for (size_t i = 0; i < fCoercibleTypes.size(); i++) { |
43 | if (*fCoercibleTypes[i] == other) { |
44 | return (int) i + 1; |
45 | } |
46 | } |
47 | return INT_MAX; |
48 | } |
49 | |
50 | const Type& Type::toCompound(const Context& context, int columns, int rows) const { |
51 | SkASSERT(this->kind() == Type::kScalar_Kind); |
52 | if (columns == 1 && rows == 1) { |
53 | return *this; |
54 | } |
55 | if (*this == *context.fFloat_Type || *this == *context.fFloatLiteral_Type) { |
56 | switch (rows) { |
57 | case 1: |
58 | switch (columns) { |
59 | case 2: return *context.fFloat2_Type; |
60 | case 3: return *context.fFloat3_Type; |
61 | case 4: return *context.fFloat4_Type; |
62 | default: ABORT("unsupported vector column count (%d)" , columns); |
63 | } |
64 | case 2: |
65 | switch (columns) { |
66 | case 2: return *context.fFloat2x2_Type; |
67 | case 3: return *context.fFloat3x2_Type; |
68 | case 4: return *context.fFloat4x2_Type; |
69 | default: ABORT("unsupported matrix column count (%d)" , columns); |
70 | } |
71 | case 3: |
72 | switch (columns) { |
73 | case 2: return *context.fFloat2x3_Type; |
74 | case 3: return *context.fFloat3x3_Type; |
75 | case 4: return *context.fFloat4x3_Type; |
76 | default: ABORT("unsupported matrix column count (%d)" , columns); |
77 | } |
78 | case 4: |
79 | switch (columns) { |
80 | case 2: return *context.fFloat2x4_Type; |
81 | case 3: return *context.fFloat3x4_Type; |
82 | case 4: return *context.fFloat4x4_Type; |
83 | default: ABORT("unsupported matrix column count (%d)" , columns); |
84 | } |
85 | default: ABORT("unsupported row count (%d)" , rows); |
86 | } |
87 | } else if (*this == *context.fHalf_Type) { |
88 | switch (rows) { |
89 | case 1: |
90 | switch (columns) { |
91 | case 2: return *context.fHalf2_Type; |
92 | case 3: return *context.fHalf3_Type; |
93 | case 4: return *context.fHalf4_Type; |
94 | default: ABORT("unsupported vector column count (%d)" , columns); |
95 | } |
96 | case 2: |
97 | switch (columns) { |
98 | case 2: return *context.fHalf2x2_Type; |
99 | case 3: return *context.fHalf3x2_Type; |
100 | case 4: return *context.fHalf4x2_Type; |
101 | default: ABORT("unsupported matrix column count (%d)" , columns); |
102 | } |
103 | case 3: |
104 | switch (columns) { |
105 | case 2: return *context.fHalf2x3_Type; |
106 | case 3: return *context.fHalf3x3_Type; |
107 | case 4: return *context.fHalf4x3_Type; |
108 | default: ABORT("unsupported matrix column count (%d)" , columns); |
109 | } |
110 | case 4: |
111 | switch (columns) { |
112 | case 2: return *context.fHalf2x4_Type; |
113 | case 3: return *context.fHalf3x4_Type; |
114 | case 4: return *context.fHalf4x4_Type; |
115 | default: ABORT("unsupported matrix column count (%d)" , columns); |
116 | } |
117 | default: ABORT("unsupported row count (%d)" , rows); |
118 | } |
119 | } else if (*this == *context.fDouble_Type) { |
120 | switch (rows) { |
121 | case 1: |
122 | switch (columns) { |
123 | case 2: return *context.fDouble2_Type; |
124 | case 3: return *context.fDouble3_Type; |
125 | case 4: return *context.fDouble4_Type; |
126 | default: ABORT("unsupported vector column count (%d)" , columns); |
127 | } |
128 | case 2: |
129 | switch (columns) { |
130 | case 2: return *context.fDouble2x2_Type; |
131 | case 3: return *context.fDouble3x2_Type; |
132 | case 4: return *context.fDouble4x2_Type; |
133 | default: ABORT("unsupported matrix column count (%d)" , columns); |
134 | } |
135 | case 3: |
136 | switch (columns) { |
137 | case 2: return *context.fDouble2x3_Type; |
138 | case 3: return *context.fDouble3x3_Type; |
139 | case 4: return *context.fDouble4x3_Type; |
140 | default: ABORT("unsupported matrix column count (%d)" , columns); |
141 | } |
142 | case 4: |
143 | switch (columns) { |
144 | case 2: return *context.fDouble2x4_Type; |
145 | case 3: return *context.fDouble3x4_Type; |
146 | case 4: return *context.fDouble4x4_Type; |
147 | default: ABORT("unsupported matrix column count (%d)" , columns); |
148 | } |
149 | default: ABORT("unsupported row count (%d)" , rows); |
150 | } |
151 | } else if (*this == *context.fInt_Type || *this == *context.fIntLiteral_Type) { |
152 | switch (rows) { |
153 | case 1: |
154 | switch (columns) { |
155 | case 2: return *context.fInt2_Type; |
156 | case 3: return *context.fInt3_Type; |
157 | case 4: return *context.fInt4_Type; |
158 | default: ABORT("unsupported vector column count (%d)" , columns); |
159 | } |
160 | default: ABORT("unsupported row count (%d)" , rows); |
161 | } |
162 | } else if (*this == *context.fShort_Type) { |
163 | switch (rows) { |
164 | case 1: |
165 | switch (columns) { |
166 | case 2: return *context.fShort2_Type; |
167 | case 3: return *context.fShort3_Type; |
168 | case 4: return *context.fShort4_Type; |
169 | default: ABORT("unsupported vector column count (%d)" , columns); |
170 | } |
171 | default: ABORT("unsupported row count (%d)" , rows); |
172 | } |
173 | } else if (*this == *context.fByte_Type) { |
174 | switch (rows) { |
175 | case 1: |
176 | switch (columns) { |
177 | case 2: return *context.fByte2_Type; |
178 | case 3: return *context.fByte3_Type; |
179 | case 4: return *context.fByte4_Type; |
180 | default: ABORT("unsupported vector column count (%d)" , columns); |
181 | } |
182 | default: ABORT("unsupported row count (%d)" , rows); |
183 | } |
184 | } else if (*this == *context.fUInt_Type) { |
185 | switch (rows) { |
186 | case 1: |
187 | switch (columns) { |
188 | case 2: return *context.fUInt2_Type; |
189 | case 3: return *context.fUInt3_Type; |
190 | case 4: return *context.fUInt4_Type; |
191 | default: ABORT("unsupported vector column count (%d)" , columns); |
192 | } |
193 | default: ABORT("unsupported row count (%d)" , rows); |
194 | } |
195 | } else if (*this == *context.fUShort_Type) { |
196 | switch (rows) { |
197 | case 1: |
198 | switch (columns) { |
199 | case 2: return *context.fUShort2_Type; |
200 | case 3: return *context.fUShort3_Type; |
201 | case 4: return *context.fUShort4_Type; |
202 | default: ABORT("unsupported vector column count (%d)" , columns); |
203 | } |
204 | default: ABORT("unsupported row count (%d)" , rows); |
205 | } |
206 | } else if (*this == *context.fUByte_Type) { |
207 | switch (rows) { |
208 | case 1: |
209 | switch (columns) { |
210 | case 2: return *context.fUByte2_Type; |
211 | case 3: return *context.fUByte3_Type; |
212 | case 4: return *context.fUByte4_Type; |
213 | default: ABORT("unsupported vector column count (%d)" , columns); |
214 | } |
215 | default: ABORT("unsupported row count (%d)" , rows); |
216 | } |
217 | } else if (*this == *context.fBool_Type) { |
218 | switch (rows) { |
219 | case 1: |
220 | switch (columns) { |
221 | case 2: return *context.fBool2_Type; |
222 | case 3: return *context.fBool3_Type; |
223 | case 4: return *context.fBool4_Type; |
224 | default: ABORT("unsupported vector column count (%d)" , columns); |
225 | } |
226 | default: ABORT("unsupported row count (%d)" , rows); |
227 | } |
228 | } |
229 | #ifdef SK_DEBUG |
230 | ABORT("unsupported scalar_to_compound type %s" , this->description().c_str()); |
231 | #endif |
232 | return *context.fVoid_Type; |
233 | } |
234 | |
235 | } // namespace |
236 | |