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 : public std::iterator<std::input_iterator_tag, Item>
120 {
121 public:
FilteredIterator(Iterator iter,Iterator end,Filter filter)122 FilteredIterator (Iterator iter, Iterator end, Filter filter)
123 : m_iter (iter)
124 , m_end (end)
125 , m_filter (filter)
126 {
127 }
128
operator +(ptrdiff_t offset) const129 FilteredIterator operator+ (ptrdiff_t offset) const
130 {
131 Iterator nextEntry = m_iter;
132 while (offset--)
133 nextEntry = findNext(m_filter, nextEntry, m_end);
134 return FilteredIterator(nextEntry, m_end, m_filter);
135 }
136
operator ++()137 FilteredIterator& operator++ ()
138 {
139 // Pre-increment
140 m_iter = findNext(m_filter, m_iter, m_end);
141 return *this;
142 }
143
operator ++(int)144 FilteredIterator operator++ (int)
145 {
146 // Post-increment
147 FilteredIterator copy = *this;
148 m_iter = findNext(m_filter, m_iter, m_end);
149 return copy;
150 }
151
operator ==(const FilteredIterator & other) const152 bool operator== (const FilteredIterator& other) const
153 {
154 return m_iter == other.m_iter;
155 }
156
operator !=(const FilteredIterator & other) const157 bool operator!= (const FilteredIterator& other) const
158 {
159 return m_iter != other.m_iter;
160 }
161
operator *(void)162 const Item& operator* (void)
163 {
164 DE_ASSERT(m_iter != m_end);
165 DE_ASSERT(m_filter(*m_iter));
166 return *m_iter;
167 }
168
169 private:
findNext(Filter filter,Iterator iter,Iterator end)170 static Iterator findNext (Filter filter, Iterator iter, Iterator end)
171 {
172 do
173 iter++;
174 while (iter != end && !filter(*iter));
175 return iter;
176 }
177
178 Iterator m_iter;
179 Iterator m_end;
180 Filter m_filter;
181 };
182
183 template <class Filter>
184 class ValueEntryIterator : public FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>
185 {
186 public:
ValueEntryIterator(std::vector<const ValueEntry * >::const_iterator begin,std::vector<const ValueEntry * >::const_iterator end,Filter filter)187 ValueEntryIterator (std::vector<const ValueEntry*>::const_iterator begin, std::vector<const ValueEntry*>::const_iterator end, Filter filter)
188 : FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>(begin, end, filter)
189 {
190 }
191 };
192
193 class VariableManager
194 {
195 public:
196 VariableManager (NameAllocator& nameAllocator);
197 ~VariableManager (void);
198
getNumAllocatedScalars(void) const199 int getNumAllocatedScalars (void) const { return m_numAllocatedScalars; }
getNumAllocatedShaderInScalars(void) const200 int getNumAllocatedShaderInScalars (void) const { return m_numAllocatedShaderInScalars; }
getNumAllocatedShaderInVariables(void) const201 int getNumAllocatedShaderInVariables(void) const { return m_numAllocatedShaderInVariables; }
getNumAllocatedUniformScalars(void) const202 int getNumAllocatedUniformScalars (void) const { return m_numAllocatedUniformScalars; }
203
204 void reserve (ReservedScalars& store, int numScalars);
205 void release (ReservedScalars& store);
206
207 Variable* allocate (const VariableType& type);
208 Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name);
209
210 void setStorage (Variable* variable, Variable::Storage storage);
211
212 void setValue (const Variable* variable, ConstValueRangeAccess value);
213 const ValueEntry* getValue (const Variable* variable) const;
214 const ValueEntry* getParentValue (const Variable* variable) const;
215
216 void removeValueFromCurrentScope (const Variable* variable);
217
218 void declareVariable (Variable* variable);
219 bool canDeclareInCurrentScope (const Variable* variable) const;
220 const std::vector<Variable*>& getLiveVariables (void) const;
221
222 void pushVariableScope (VariableScope& scope);
223 void popVariableScope (void);
224
225 void pushValueScope (ValueScope& scope);
226 void popValueScope (void);
227
228 template <class Filter>
229 ValueEntryIterator<Filter> getBegin (Filter filter = Filter()) const;
230
231 template <class Filter>
232 ValueEntryIterator<Filter> getEnd (Filter filter = Filter()) const;
233
234 template <class Filter>
235 bool hasEntry (Filter filter = Filter()) const;
236
237 private:
238 VariableManager (const VariableManager& other);
239 VariableManager& operator= (const VariableManager& other);
240
getCurVariableScope(void)241 VariableScope& getCurVariableScope (void) { return *m_variableScopeStack.back(); }
getCurVariableScope(void) const242 const VariableScope& getCurVariableScope (void) const { return *m_variableScopeStack.back(); }
243
getCurValueScope(void)244 ValueScope& getCurValueScope (void) { return *m_valueScopeStack.back(); }
getCurValueScope(void) const245 const ValueScope& getCurValueScope (void) const { return *m_valueScopeStack.back(); }
246
247 std::vector<VariableScope*> m_variableScopeStack;
248 std::vector<ValueScope*> m_valueScopeStack;
249
250 std::vector<const ValueEntry*> m_entryCache; //!< For faster value entry access.
251
252 int m_numAllocatedScalars;
253 int m_numAllocatedShaderInScalars;
254 int m_numAllocatedShaderInVariables;
255 int m_numAllocatedUniformScalars;
256 NameAllocator& m_nameAllocator;
257 };
258
259 template <class Filter>
getBegin(Filter filter) const260 ValueEntryIterator<Filter> VariableManager::getBegin (Filter filter) const
261 {
262 std::vector<const ValueEntry*>::const_iterator first = m_entryCache.begin();
263 while (first != m_entryCache.end() && !filter(*first))
264 first++;
265 return ValueEntryIterator<Filter>(first, m_entryCache.end(), filter);
266 }
267
268 template <class Filter>
getEnd(Filter filter) const269 ValueEntryIterator<Filter> VariableManager::getEnd (Filter filter) const
270 {
271 return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter);
272 }
273
274 template <class Filter>
hasEntry(Filter filter) const275 bool VariableManager::hasEntry (Filter filter) const
276 {
277 for (std::vector<const ValueEntry*>::const_iterator i = m_entryCache.begin(); i != m_entryCache.end(); i++)
278 {
279 if (filter(*i))
280 return true;
281 }
282 return false;
283 }
284
285 // Common filters
286
287 class AnyEntry
288 {
289 public:
290 typedef ValueEntryIterator<AnyEntry> Iterator;
291
operator ()(const ValueEntry * entry) const292 bool operator() (const ValueEntry* entry) const
293 {
294 DE_UNREF(entry);
295 return true;
296 }
297 };
298
299 class IsWritableEntry
300 {
301 public:
operator ()(const ValueEntry * entry) const302 bool operator() (const ValueEntry* entry) const
303 {
304 switch (entry->getVariable()->getStorage())
305 {
306 case Variable::STORAGE_LOCAL:
307 case Variable::STORAGE_SHADER_OUT:
308 case Variable::STORAGE_PARAMETER_IN:
309 case Variable::STORAGE_PARAMETER_OUT:
310 case Variable::STORAGE_PARAMETER_INOUT:
311 return true;
312
313 default:
314 return false;
315 }
316 }
317 };
318
319 template <Variable::Storage Storage>
320 class EntryStorageFilter
321 {
322 public:
323 typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator;
324
operator ()(const ValueEntry * entry) const325 bool operator() (const ValueEntry* entry) const
326 {
327 return entry->getVariable()->getStorage() == Storage;
328 }
329 };
330
331 typedef EntryStorageFilter<Variable::STORAGE_LOCAL> LocalEntryFilter;
332 typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN> ShaderInEntryFilter;
333 typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT> ShaderOutEntryFilter;
334
335 } // rsg
336
337 #endif // _RSGVARIABLEMANAGER_HPP
338