• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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