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