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
getVariable(void) const49 const Variable* getVariable (void) const { return m_variable; }
50
getValueRange(void) const51 ConstValueRangeAccess getValueRange (void) const { return m_valueRange.asAccess(); }
getValueRange(void)52 ValueRangeAccess getValueRange (void) { return m_valueRange.asAccess(); }
53
54 private:
55 const Variable* m_variable;
56 ValueRange m_valueRange;
57 };
58
59 // Variable scope manages variable allocation.
60 class VariableScope
61 {
62 public:
63 VariableScope (void);
64 ~VariableScope (void);
65
66 Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name);
67 void declare (Variable* variable); //!< Move from live set to declared set
68 void removeLive (const Variable* variable); //!< Just remove from live set (when migrating to parent).
69
getDeclaredVariables(void) const70 const std::vector<Variable*>& getDeclaredVariables (void) const { return m_declaredVariables; }
71
getLiveVariables(void)72 std::vector<Variable*>& getLiveVariables (void) { return m_liveVariables; }
getLiveVariables(void) const73 const std::vector<Variable*>& getLiveVariables (void) const { return m_liveVariables; }
74
75 private:
76 VariableScope (const VariableScope& other);
77 VariableScope& operator= (const VariableScope& other);
78
79 std::vector<Variable*> m_declaredVariables; //!< Variables declared in this scope. Not available for expressions.
80 std::vector<Variable*> m_liveVariables; //!< Live variables (available for expression) that can be declared in this scope.
81 };
82
83 class ValueScope
84 {
85 public:
86 ValueScope (void);
87 ~ValueScope (void);
88
89 ValueEntry* allocate (const Variable* variable);
90 ValueEntry* findEntry (const Variable* variable) const;
91 void setValue (const Variable* variable, ConstValueRangeAccess value);
92 void removeValue (const Variable* variable);
93
getValues(void)94 std::vector<ValueEntry*>& getValues (void) { return m_entries; }
getValues(void) const95 const std::vector<ValueEntry*>& getValues (void) const { return m_entries; }
96
97 void clear (void);
98
99 private:
100 ValueScope (const ValueScope& other);
101 ValueScope& operator= (const ValueScope& other);
102
103 std::vector<ValueEntry*> m_entries;
104 };
105
106 class ReservedScalars
107 {
108 public:
109 int numScalars;
110
ReservedScalars(void)111 ReservedScalars (void)
112 : numScalars(0)
113 {
114 }
115 };
116
117 // \todo [2011-05-26 pyry] Clean up this a bit, separate const variant.
118 template <typename Item, typename Iterator, class Filter>
119 class FilteredIterator
120 {
121 public:
122 using iterator_category = std::input_iterator_tag;
123 using value_type = Item;
124 using difference_type = std::ptrdiff_t;
125 using pointer = Item*;
126 using reference = Item&;
127
FilteredIterator(Iterator iter,Iterator end,Filter filter)128 FilteredIterator (Iterator iter, Iterator end, Filter filter)
129 : m_iter (iter)
130 , m_end (end)
131 , m_filter (filter)
132 {
133 }
134
operator +(ptrdiff_t offset) const135 FilteredIterator operator+ (ptrdiff_t offset) const
136 {
137 Iterator nextEntry = m_iter;
138 while (offset--)
139 nextEntry = findNext(m_filter, nextEntry, m_end);
140 return FilteredIterator(nextEntry, m_end, m_filter);
141 }
142
operator ++()143 FilteredIterator& operator++ ()
144 {
145 // Pre-increment
146 m_iter = findNext(m_filter, m_iter, m_end);
147 return *this;
148 }
149
operator ++(int)150 FilteredIterator operator++ (int)
151 {
152 // Post-increment
153 FilteredIterator copy = *this;
154 m_iter = findNext(m_filter, m_iter, m_end);
155 return copy;
156 }
157
operator ==(const FilteredIterator & other) const158 bool operator== (const FilteredIterator& other) const
159 {
160 return m_iter == other.m_iter;
161 }
162
operator !=(const FilteredIterator & other) const163 bool operator!= (const FilteredIterator& other) const
164 {
165 return m_iter != other.m_iter;
166 }
167
operator *(void)168 const Item& operator* (void)
169 {
170 DE_ASSERT(m_iter != m_end);
171 DE_ASSERT(m_filter(*m_iter));
172 return *m_iter;
173 }
174
175 private:
findNext(Filter filter,Iterator iter,Iterator end)176 static Iterator findNext (Filter filter, Iterator iter, Iterator end)
177 {
178 do
179 iter++;
180 while (iter != end && !filter(*iter));
181 return iter;
182 }
183
184 Iterator m_iter;
185 Iterator m_end;
186 Filter m_filter;
187 };
188
189 template <class Filter>
190 class ValueEntryIterator : public FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>
191 {
192 public:
ValueEntryIterator(std::vector<const ValueEntry * >::const_iterator begin,std::vector<const ValueEntry * >::const_iterator end,Filter filter)193 ValueEntryIterator (std::vector<const ValueEntry*>::const_iterator begin, std::vector<const ValueEntry*>::const_iterator end, Filter filter)
194 : FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>(begin, end, filter)
195 {
196 }
197 };
198
199 class VariableManager
200 {
201 public:
202 VariableManager (NameAllocator& nameAllocator);
203 ~VariableManager (void);
204
getNumAllocatedScalars(void) const205 int getNumAllocatedScalars (void) const { return m_numAllocatedScalars; }
getNumAllocatedShaderInScalars(void) const206 int getNumAllocatedShaderInScalars (void) const { return m_numAllocatedShaderInScalars; }
getNumAllocatedShaderInVariables(void) const207 int getNumAllocatedShaderInVariables(void) const { return m_numAllocatedShaderInVariables; }
getNumAllocatedUniformScalars(void) const208 int getNumAllocatedUniformScalars (void) const { return m_numAllocatedUniformScalars; }
209
210 void reserve (ReservedScalars& store, int numScalars);
211 void release (ReservedScalars& store);
212
213 Variable* allocate (const VariableType& type);
214 Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name);
215
216 void setStorage (Variable* variable, Variable::Storage storage);
217
218 void setValue (const Variable* variable, ConstValueRangeAccess value);
219 const ValueEntry* getValue (const Variable* variable) const;
220 const ValueEntry* getParentValue (const Variable* variable) const;
221
222 void removeValueFromCurrentScope (const Variable* variable);
223
224 void declareVariable (Variable* variable);
225 bool canDeclareInCurrentScope (const Variable* variable) const;
226 const std::vector<Variable*>& getLiveVariables (void) const;
227
228 void pushVariableScope (VariableScope& scope);
229 void popVariableScope (void);
230
231 void pushValueScope (ValueScope& scope);
232 void popValueScope (void);
233
234 template <class Filter>
235 ValueEntryIterator<Filter> getBegin (Filter filter = Filter()) const;
236
237 template <class Filter>
238 ValueEntryIterator<Filter> getEnd (Filter filter = Filter()) const;
239
240 template <class Filter>
241 bool hasEntry (Filter filter = Filter()) const;
242
243 private:
244 VariableManager (const VariableManager& other);
245 VariableManager& operator= (const VariableManager& other);
246
getCurVariableScope(void)247 VariableScope& getCurVariableScope (void) { return *m_variableScopeStack.back(); }
getCurVariableScope(void) const248 const VariableScope& getCurVariableScope (void) const { return *m_variableScopeStack.back(); }
249
getCurValueScope(void)250 ValueScope& getCurValueScope (void) { return *m_valueScopeStack.back(); }
getCurValueScope(void) const251 const ValueScope& getCurValueScope (void) const { return *m_valueScopeStack.back(); }
252
253 std::vector<VariableScope*> m_variableScopeStack;
254 std::vector<ValueScope*> m_valueScopeStack;
255
256 std::vector<const ValueEntry*> m_entryCache; //!< For faster value entry access.
257
258 int m_numAllocatedScalars;
259 int m_numAllocatedShaderInScalars;
260 int m_numAllocatedShaderInVariables;
261 int m_numAllocatedUniformScalars;
262 NameAllocator& m_nameAllocator;
263 };
264
265 template <class Filter>
getBegin(Filter filter) const266 ValueEntryIterator<Filter> VariableManager::getBegin (Filter filter) const
267 {
268 std::vector<const ValueEntry*>::const_iterator first = m_entryCache.begin();
269 while (first != m_entryCache.end() && !filter(*first))
270 first++;
271 return ValueEntryIterator<Filter>(first, m_entryCache.end(), filter);
272 }
273
274 template <class Filter>
getEnd(Filter filter) const275 ValueEntryIterator<Filter> VariableManager::getEnd (Filter filter) const
276 {
277 return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter);
278 }
279
280 template <class Filter>
hasEntry(Filter filter) const281 bool VariableManager::hasEntry (Filter filter) const
282 {
283 for (std::vector<const ValueEntry*>::const_iterator i = m_entryCache.begin(); i != m_entryCache.end(); i++)
284 {
285 if (filter(*i))
286 return true;
287 }
288 return false;
289 }
290
291 // Common filters
292
293 class AnyEntry
294 {
295 public:
296 typedef ValueEntryIterator<AnyEntry> Iterator;
297
operator ()(const ValueEntry * entry) const298 bool operator() (const ValueEntry* entry) const
299 {
300 DE_UNREF(entry);
301 return true;
302 }
303 };
304
305 class IsWritableEntry
306 {
307 public:
operator ()(const ValueEntry * entry) const308 bool operator() (const ValueEntry* entry) const
309 {
310 switch (entry->getVariable()->getStorage())
311 {
312 case Variable::STORAGE_LOCAL:
313 case Variable::STORAGE_SHADER_OUT:
314 case Variable::STORAGE_PARAMETER_IN:
315 case Variable::STORAGE_PARAMETER_OUT:
316 case Variable::STORAGE_PARAMETER_INOUT:
317 return true;
318
319 default:
320 return false;
321 }
322 }
323 };
324
325 template <Variable::Storage Storage>
326 class EntryStorageFilter
327 {
328 public:
329 typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator;
330
operator ()(const ValueEntry * entry) const331 bool operator() (const ValueEntry* entry) const
332 {
333 return entry->getVariable()->getStorage() == Storage;
334 }
335 };
336
337 typedef EntryStorageFilter<Variable::STORAGE_LOCAL> LocalEntryFilter;
338 typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN> ShaderInEntryFilter;
339 typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT> ShaderOutEntryFilter;
340
341 } // rsg
342
343 #endif // _RSGVARIABLEMANAGER_HPP
344