1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Random Shader Generator
3 * ----------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Variable Value class.
22 *//*--------------------------------------------------------------------*/
23
24 #include "rsgVariableValue.hpp"
25
26 namespace rsg
27 {
28
29 namespace
30 {
31
32 template <class CompareOp>
compareValueRangesAllTrue(const ConstValueRangeAccess & a,const ConstValueRangeAccess & b)33 bool compareValueRangesAllTrue(const ConstValueRangeAccess &a, const ConstValueRangeAccess &b)
34 {
35 DE_ASSERT(a.getType() == b.getType());
36
37 if (a.getType().isStruct())
38 {
39 int numMembers = (int)a.getType().getMembers().size();
40 for (int ndx = 0; ndx < numMembers; ndx++)
41 {
42 if (!compareValueRangesAllTrue<CompareOp>(a.member(ndx), b.member(ndx)))
43 return false;
44 }
45 }
46 else if (a.getType().isArray())
47 {
48 int numElements = (int)a.getType().getNumElements();
49 for (int ndx = 0; ndx < numElements; ndx++)
50 {
51 if (!compareValueRangesAllTrue<CompareOp>(a.arrayElement(ndx), b.arrayElement(ndx)))
52 return false;
53 }
54 }
55 else
56 {
57 int numElements = (int)a.getType().getNumElements();
58 switch (a.getType().getBaseType())
59 {
60 case VariableType::TYPE_FLOAT:
61 for (int ndx = 0; ndx < numElements; ndx++)
62 {
63 float aMin = a.component(ndx).getMin().asFloat();
64 float aMax = a.component(ndx).getMax().asFloat();
65 float bMin = b.component(ndx).getMin().asFloat();
66 float bMax = b.component(ndx).getMax().asFloat();
67
68 if (!CompareOp()(aMin, aMax, bMin, bMax))
69 return false;
70 }
71 break;
72
73 case VariableType::TYPE_INT:
74 case VariableType::TYPE_SAMPLER_2D:
75 case VariableType::TYPE_SAMPLER_CUBE:
76 for (int ndx = 0; ndx < numElements; ndx++)
77 {
78 int aMin = a.component(ndx).getMin().asInt();
79 int aMax = a.component(ndx).getMax().asInt();
80 int bMin = b.component(ndx).getMin().asInt();
81 int bMax = b.component(ndx).getMax().asInt();
82
83 if (!CompareOp()(aMin, aMax, bMin, bMax))
84 return false;
85 }
86 break;
87
88 case VariableType::TYPE_BOOL:
89 for (int ndx = 0; ndx < numElements; ndx++)
90 {
91 bool aMin = a.component(ndx).getMin().asBool();
92 bool aMax = a.component(ndx).getMax().asBool();
93 bool bMin = b.component(ndx).getMin().asBool();
94 bool bMax = b.component(ndx).getMax().asBool();
95
96 if (!CompareOp()(aMin, aMax, bMin, bMax))
97 return false;
98 }
99 break;
100
101 default:
102 DE_ASSERT(false);
103 return false;
104 }
105 }
106
107 return true;
108 }
109
toInt(bool boolVal)110 inline int toInt(bool boolVal)
111 {
112 return boolVal ? 1 : 0;
113 }
114
115 struct CompareIntersection
116 {
operator ()rsg::__anon1cbb0bf70111::CompareIntersection117 inline bool operator()(float aMin, float aMax, float bMin, float bMax) const
118 {
119 return (aMin <= bMax && bMin <= aMax);
120 }
operator ()rsg::__anon1cbb0bf70111::CompareIntersection121 inline bool operator()(int aMin, int aMax, int bMin, int bMax) const
122 {
123 return (aMin <= bMax && bMin <= aMax);
124 }
125
operator ()rsg::__anon1cbb0bf70111::CompareIntersection126 inline bool operator()(bool aMin, bool aMax, bool bMin, bool bMax) const
127 {
128 return CompareIntersection()(toInt(aMin), toInt(aMax), toInt(bMin), toInt(bMax));
129 }
130 };
131
132 struct CompareIsSubsetOf
133 {
operator ()rsg::__anon1cbb0bf70111::CompareIsSubsetOf134 inline bool operator()(float aMin, float aMax, float bMin, float bMax) const
135 {
136 return de::inRange(aMin, bMin, bMax) && de::inRange(aMax, bMin, bMax);
137 }
138
operator ()rsg::__anon1cbb0bf70111::CompareIsSubsetOf139 inline bool operator()(int aMin, int aMax, int bMin, int bMax) const
140 {
141 return de::inRange(aMin, bMin, bMax) && de::inRange(aMax, bMin, bMax);
142 }
143
operator ()rsg::__anon1cbb0bf70111::CompareIsSubsetOf144 inline bool operator()(bool aMin, bool aMax, bool bMin, bool bMax) const
145 {
146 return CompareIsSubsetOf()(toInt(aMin), toInt(aMax), toInt(bMin), toInt(bMax));
147 }
148 };
149
150 } // namespace
151
intersects(const ConstValueRangeAccess & other) const152 bool ConstValueRangeAccess::intersects(const ConstValueRangeAccess &other) const
153 {
154 return compareValueRangesAllTrue<CompareIntersection>(*this, other);
155 }
156
isSubsetOf(const ConstValueRangeAccess & other) const157 bool ConstValueRangeAccess::isSubsetOf(const ConstValueRangeAccess &other) const
158 {
159 return compareValueRangesAllTrue<CompareIsSubsetOf>(*this, other);
160 }
161
isSupersetOf(const ConstValueRangeAccess & other) const162 bool ConstValueRangeAccess::isSupersetOf(const ConstValueRangeAccess &other) const
163 {
164 return other.isSubsetOf(*this);
165 }
166
ValueRange(const VariableType & type)167 ValueRange::ValueRange(const VariableType &type)
168 : m_type(type)
169 , m_min(type.getScalarSize())
170 , m_max(type.getScalarSize())
171 {
172 }
173
ValueRange(const VariableType & type,const ConstValueAccess & minVal,const ConstValueAccess & maxVal)174 ValueRange::ValueRange(const VariableType &type, const ConstValueAccess &minVal, const ConstValueAccess &maxVal)
175 : m_type(type)
176 , m_min(type.getScalarSize())
177 , m_max(type.getScalarSize())
178 {
179 getMin() = minVal.value();
180 getMax() = maxVal.value();
181 }
182
ValueRange(const VariableType & type,const Scalar * minVal,const Scalar * maxVal)183 ValueRange::ValueRange(const VariableType &type, const Scalar *minVal, const Scalar *maxVal)
184 : m_type(type)
185 , m_min(type.getScalarSize())
186 , m_max(type.getScalarSize())
187 {
188 getMin() = ConstValueAccess(type, minVal).value();
189 getMax() = ConstValueAccess(type, maxVal).value();
190 }
191
ValueRange(ConstValueRangeAccess other)192 ValueRange::ValueRange(ConstValueRangeAccess other)
193 : m_type(other.getType())
194 , m_min(other.getType().getScalarSize())
195 , m_max(other.getType().getScalarSize())
196 {
197 getMin() = other.getMin().value();
198 getMax() = other.getMax().value();
199 }
200
~ValueRange(void)201 ValueRange::~ValueRange(void)
202 {
203 }
204
computeIntersection(ValueRange & dst,const ConstValueRangeAccess & a,const ConstValueRangeAccess & b)205 void ValueRange::computeIntersection(ValueRange &dst, const ConstValueRangeAccess &a, const ConstValueRangeAccess &b)
206 {
207 computeIntersection(dst.asAccess(), a, b);
208 }
209
computeIntersection(ValueRangeAccess dst,const ConstValueRangeAccess & a,const ConstValueRangeAccess & b)210 void ValueRange::computeIntersection(ValueRangeAccess dst, const ConstValueRangeAccess &a,
211 const ConstValueRangeAccess &b)
212 {
213 DE_ASSERT(dst.getType() == a.getType() && dst.getType() == b.getType());
214
215 if (a.getType().isStruct())
216 {
217 int numMembers = (int)a.getType().getMembers().size();
218 for (int ndx = 0; ndx < numMembers; ndx++)
219 computeIntersection(dst.member(ndx), a.member(ndx), b.member(ndx));
220 }
221 else if (a.getType().isArray())
222 {
223 int numElements = (int)a.getType().getNumElements();
224 for (int ndx = 0; ndx < numElements; ndx++)
225 computeIntersection(dst.arrayElement(ndx), a.arrayElement(ndx), b.arrayElement(ndx));
226 }
227 else
228 {
229 int numElements = (int)a.getType().getNumElements();
230 switch (a.getType().getBaseType())
231 {
232 case VariableType::TYPE_FLOAT:
233 for (int ndx = 0; ndx < numElements; ndx++)
234 {
235 float aMin = a.component(ndx).getMin().asFloat();
236 float aMax = a.component(ndx).getMax().asFloat();
237 float bMin = b.component(ndx).getMin().asFloat();
238 float bMax = b.component(ndx).getMax().asFloat();
239
240 dst.component(ndx).getMin() = de::max(aMin, bMin);
241 dst.component(ndx).getMax() = de::min(aMax, bMax);
242 }
243 break;
244
245 case VariableType::TYPE_INT:
246 case VariableType::TYPE_SAMPLER_2D:
247 case VariableType::TYPE_SAMPLER_CUBE:
248 for (int ndx = 0; ndx < numElements; ndx++)
249 {
250 int aMin = a.component(ndx).getMin().asInt();
251 int aMax = a.component(ndx).getMax().asInt();
252 int bMin = b.component(ndx).getMin().asInt();
253 int bMax = b.component(ndx).getMax().asInt();
254
255 dst.component(ndx).getMin() = de::max(aMin, bMin);
256 dst.component(ndx).getMax() = de::min(aMax, bMax);
257 }
258 break;
259
260 case VariableType::TYPE_BOOL:
261 for (int ndx = 0; ndx < numElements; ndx++)
262 {
263 bool aMin = a.component(ndx).getMin().asBool();
264 bool aMax = a.component(ndx).getMax().asBool();
265 bool bMin = b.component(ndx).getMin().asBool();
266 bool bMax = b.component(ndx).getMax().asBool();
267
268 dst.component(ndx).getMin() = aMin || bMin;
269 dst.component(ndx).getMax() = aMax && bMax;
270 }
271 break;
272
273 default:
274 DE_ASSERT(false);
275 }
276 }
277 }
278
VariableValue(const VariableValue & other)279 VariableValue::VariableValue(const VariableValue &other)
280 : m_variable(other.m_variable)
281 , m_storage(other.m_variable->getType())
282 {
283 m_storage.getValue(getType()) = other.getValue().value();
284 }
285
operator =(const VariableValue & other)286 VariableValue &VariableValue::operator=(const VariableValue &other)
287 {
288 m_variable = other.m_variable;
289 m_storage.setStorage(getType());
290 m_storage.getValue(getType()) = other.getValue().value();
291 return *this;
292 }
293
294 } // namespace rsg
295