1 #ifndef _RSGVARIABLEMANAGER_HPP
2 #define _RSGVARIABLEMANAGER_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Random Shader Generator
5 * ----------------------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Variable manager.
24 *
25 * Memory management:
26 * Variable manager owns variable objects until they are either explictly
27 * removed or moved to currently active scope. After that the ownership
28 * is transferred to Scope or the object that called removeEntry().
29 *//*--------------------------------------------------------------------*/
30
31 #include "rsgDefs.hpp"
32 #include "rsgVariable.hpp"
33 #include "rsgVariableValue.hpp"
34 #include "rsgNameAllocator.hpp"
35
36 #include <iterator>
37 #include <vector>
38 #include <set>
39
40 namespace rsg
41 {
42
43 class ValueEntry
44 {
45 public:
46 ValueEntry(const Variable *variable);
~ValueEntry(void)47 ~ValueEntry(void)
48 {
49 }
50
getVariable(void) const51 const Variable *getVariable(void) const
52 {
53 return m_variable;
54 }
55
getValueRange(void) const56 ConstValueRangeAccess getValueRange(void) const
57 {
58 return m_valueRange.asAccess();
59 }
getValueRange(void)60 ValueRangeAccess getValueRange(void)
61 {
62 return m_valueRange.asAccess();
63 }
64
65 private:
66 const Variable *m_variable;
67 ValueRange m_valueRange;
68 };
69
70 // Variable scope manages variable allocation.
71 class VariableScope
72 {
73 public:
74 VariableScope(void);
75 ~VariableScope(void);
76
77 Variable *allocate(const VariableType &type, Variable::Storage storage, const char *name);
78 void declare(Variable *variable); //!< Move from live set to declared set
79 void removeLive(const Variable *variable); //!< Just remove from live set (when migrating to parent).
80
getDeclaredVariables(void) const81 const std::vector<Variable *> &getDeclaredVariables(void) const
82 {
83 return m_declaredVariables;
84 }
85
getLiveVariables(void)86 std::vector<Variable *> &getLiveVariables(void)
87 {
88 return m_liveVariables;
89 }
getLiveVariables(void) const90 const std::vector<Variable *> &getLiveVariables(void) const
91 {
92 return m_liveVariables;
93 }
94
95 private:
96 VariableScope(const VariableScope &other);
97 VariableScope &operator=(const VariableScope &other);
98
99 std::vector<Variable *> m_declaredVariables; //!< Variables declared in this scope. Not available for expressions.
100 std::vector<Variable *>
101 m_liveVariables; //!< Live variables (available for expression) that can be declared in this scope.
102 };
103
104 class ValueScope
105 {
106 public:
107 ValueScope(void);
108 ~ValueScope(void);
109
110 ValueEntry *allocate(const Variable *variable);
111 ValueEntry *findEntry(const Variable *variable) const;
112 void setValue(const Variable *variable, ConstValueRangeAccess value);
113 void removeValue(const Variable *variable);
114
getValues(void)115 std::vector<ValueEntry *> &getValues(void)
116 {
117 return m_entries;
118 }
getValues(void) const119 const std::vector<ValueEntry *> &getValues(void) const
120 {
121 return m_entries;
122 }
123
124 void clear(void);
125
126 private:
127 ValueScope(const ValueScope &other);
128 ValueScope &operator=(const ValueScope &other);
129
130 std::vector<ValueEntry *> m_entries;
131 };
132
133 class ReservedScalars
134 {
135 public:
136 int numScalars;
137
ReservedScalars(void)138 ReservedScalars(void) : numScalars(0)
139 {
140 }
141 };
142
143 // \todo [2011-05-26 pyry] Clean up this a bit, separate const variant.
144 template <typename Item, typename Iterator, class Filter>
145 class FilteredIterator
146 {
147 public:
148 using iterator_category = std::input_iterator_tag;
149 using value_type = Item;
150 using difference_type = std::ptrdiff_t;
151 using pointer = Item *;
152 using reference = Item &;
153
FilteredIterator(Iterator iter,Iterator end,Filter filter)154 FilteredIterator(Iterator iter, Iterator end, Filter filter) : m_iter(iter), m_end(end), m_filter(filter)
155 {
156 }
157
operator +(ptrdiff_t offset) const158 FilteredIterator operator+(ptrdiff_t offset) const
159 {
160 Iterator nextEntry = m_iter;
161 while (offset--)
162 nextEntry = findNext(m_filter, nextEntry, m_end);
163 return FilteredIterator(nextEntry, m_end, m_filter);
164 }
165
operator ++()166 FilteredIterator &operator++()
167 {
168 // Pre-increment
169 m_iter = findNext(m_filter, m_iter, m_end);
170 return *this;
171 }
172
operator ++(int)173 FilteredIterator operator++(int)
174 {
175 // Post-increment
176 FilteredIterator copy = *this;
177 m_iter = findNext(m_filter, m_iter, m_end);
178 return copy;
179 }
180
operator ==(const FilteredIterator & other) const181 bool operator==(const FilteredIterator &other) const
182 {
183 return m_iter == other.m_iter;
184 }
185
operator !=(const FilteredIterator & other) const186 bool operator!=(const FilteredIterator &other) const
187 {
188 return m_iter != other.m_iter;
189 }
190
operator *(void)191 const Item &operator*(void)
192 {
193 DE_ASSERT(m_iter != m_end);
194 DE_ASSERT(m_filter(*m_iter));
195 return *m_iter;
196 }
197
198 private:
findNext(Filter filter,Iterator iter,Iterator end)199 static Iterator findNext(Filter filter, Iterator iter, Iterator end)
200 {
201 do
202 iter++;
203 while (iter != end && !filter(*iter));
204 return iter;
205 }
206
207 Iterator m_iter;
208 Iterator m_end;
209 Filter m_filter;
210 };
211
212 template <class Filter>
213 class ValueEntryIterator
214 : public FilteredIterator<const ValueEntry *, std::vector<const ValueEntry *>::const_iterator, Filter>
215 {
216 public:
ValueEntryIterator(std::vector<const ValueEntry * >::const_iterator begin,std::vector<const ValueEntry * >::const_iterator end,Filter filter)217 ValueEntryIterator(std::vector<const ValueEntry *>::const_iterator begin,
218 std::vector<const ValueEntry *>::const_iterator end, Filter filter)
219 : FilteredIterator<const ValueEntry *, std::vector<const ValueEntry *>::const_iterator, Filter>(begin, end,
220 filter)
221 {
222 }
223 };
224
225 class VariableManager
226 {
227 public:
228 VariableManager(NameAllocator &nameAllocator);
229 ~VariableManager(void);
230
getNumAllocatedScalars(void) const231 int getNumAllocatedScalars(void) const
232 {
233 return m_numAllocatedScalars;
234 }
getNumAllocatedShaderInScalars(void) const235 int getNumAllocatedShaderInScalars(void) const
236 {
237 return m_numAllocatedShaderInScalars;
238 }
getNumAllocatedShaderInVariables(void) const239 int getNumAllocatedShaderInVariables(void) const
240 {
241 return m_numAllocatedShaderInVariables;
242 }
getNumAllocatedUniformScalars(void) const243 int getNumAllocatedUniformScalars(void) const
244 {
245 return m_numAllocatedUniformScalars;
246 }
247
248 void reserve(ReservedScalars &store, int numScalars);
249 void release(ReservedScalars &store);
250
251 Variable *allocate(const VariableType &type);
252 Variable *allocate(const VariableType &type, Variable::Storage storage, const char *name);
253
254 void setStorage(Variable *variable, Variable::Storage storage);
255
256 void setValue(const Variable *variable, ConstValueRangeAccess value);
257 const ValueEntry *getValue(const Variable *variable) const;
258 const ValueEntry *getParentValue(const Variable *variable) const;
259
260 void removeValueFromCurrentScope(const Variable *variable);
261
262 void declareVariable(Variable *variable);
263 bool canDeclareInCurrentScope(const Variable *variable) const;
264 const std::vector<Variable *> &getLiveVariables(void) const;
265
266 void pushVariableScope(VariableScope &scope);
267 void popVariableScope(void);
268
269 void pushValueScope(ValueScope &scope);
270 void popValueScope(void);
271
272 template <class Filter>
273 ValueEntryIterator<Filter> getBegin(Filter filter = Filter()) const;
274
275 template <class Filter>
276 ValueEntryIterator<Filter> getEnd(Filter filter = Filter()) const;
277
278 template <class Filter>
279 bool hasEntry(Filter filter = Filter()) const;
280
281 private:
282 VariableManager(const VariableManager &other);
283 VariableManager &operator=(const VariableManager &other);
284
getCurVariableScope(void)285 VariableScope &getCurVariableScope(void)
286 {
287 return *m_variableScopeStack.back();
288 }
getCurVariableScope(void) const289 const VariableScope &getCurVariableScope(void) const
290 {
291 return *m_variableScopeStack.back();
292 }
293
getCurValueScope(void)294 ValueScope &getCurValueScope(void)
295 {
296 return *m_valueScopeStack.back();
297 }
getCurValueScope(void) const298 const ValueScope &getCurValueScope(void) const
299 {
300 return *m_valueScopeStack.back();
301 }
302
303 std::vector<VariableScope *> m_variableScopeStack;
304 std::vector<ValueScope *> m_valueScopeStack;
305
306 std::vector<const ValueEntry *> m_entryCache; //!< For faster value entry access.
307
308 int m_numAllocatedScalars;
309 int m_numAllocatedShaderInScalars;
310 int m_numAllocatedShaderInVariables;
311 int m_numAllocatedUniformScalars;
312 NameAllocator &m_nameAllocator;
313 };
314
315 template <class Filter>
getBegin(Filter filter) const316 ValueEntryIterator<Filter> VariableManager::getBegin(Filter filter) const
317 {
318 std::vector<const ValueEntry *>::const_iterator first = m_entryCache.begin();
319 while (first != m_entryCache.end() && !filter(*first))
320 first++;
321 return ValueEntryIterator<Filter>(first, m_entryCache.end(), filter);
322 }
323
324 template <class Filter>
getEnd(Filter filter) const325 ValueEntryIterator<Filter> VariableManager::getEnd(Filter filter) const
326 {
327 return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter);
328 }
329
330 template <class Filter>
hasEntry(Filter filter) const331 bool VariableManager::hasEntry(Filter filter) const
332 {
333 for (std::vector<const ValueEntry *>::const_iterator i = m_entryCache.begin(); i != m_entryCache.end(); i++)
334 {
335 if (filter(*i))
336 return true;
337 }
338 return false;
339 }
340
341 // Common filters
342
343 class AnyEntry
344 {
345 public:
346 typedef ValueEntryIterator<AnyEntry> Iterator;
347
operator ()(const ValueEntry * entry) const348 bool operator()(const ValueEntry *entry) const
349 {
350 DE_UNREF(entry);
351 return true;
352 }
353 };
354
355 class IsWritableEntry
356 {
357 public:
operator ()(const ValueEntry * entry) const358 bool operator()(const ValueEntry *entry) const
359 {
360 switch (entry->getVariable()->getStorage())
361 {
362 case Variable::STORAGE_LOCAL:
363 case Variable::STORAGE_SHADER_OUT:
364 case Variable::STORAGE_PARAMETER_IN:
365 case Variable::STORAGE_PARAMETER_OUT:
366 case Variable::STORAGE_PARAMETER_INOUT:
367 return true;
368
369 default:
370 return false;
371 }
372 }
373 };
374
375 template <Variable::Storage Storage>
376 class EntryStorageFilter
377 {
378 public:
379 typedef ValueEntryIterator<EntryStorageFilter<Storage>> Iterator;
380
operator ()(const ValueEntry * entry) const381 bool operator()(const ValueEntry *entry) const
382 {
383 return entry->getVariable()->getStorage() == Storage;
384 }
385 };
386
387 typedef EntryStorageFilter<Variable::STORAGE_LOCAL> LocalEntryFilter;
388 typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN> ShaderInEntryFilter;
389 typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT> ShaderOutEntryFilter;
390
391 } // namespace rsg
392
393 #endif // _RSGVARIABLEMANAGER_HPP
394