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
40namespace rsg
41{
42
43class ValueEntry
44{
45public:
46							ValueEntry				(const Variable* variable);
47							~ValueEntry				(void) {}
48
49	const Variable*			getVariable				(void) const	{ return m_variable;	}
50
51	ConstValueRangeAccess	getValueRange			(void) const	{ return m_valueRange.asAccess();	}
52	ValueRangeAccess		getValueRange			(void)			{ return m_valueRange.asAccess();	}
53
54private:
55	const Variable*			m_variable;
56	ValueRange				m_valueRange;
57};
58
59// Variable scope manages variable allocation.
60class VariableScope
61{
62public:
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
70	const std::vector<Variable*>&		getDeclaredVariables	(void) const	{ return m_declaredVariables;	}
71
72	std::vector<Variable*>&				getLiveVariables		(void)			{ return m_liveVariables;		}
73	const std::vector<Variable*>&		getLiveVariables		(void) const	{ return m_liveVariables;		}
74
75private:
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
83class ValueScope
84{
85public:
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
94	std::vector<ValueEntry*>&			getValues				(void)			{ return m_entries;	}
95	const std::vector<ValueEntry*>&		getValues				(void) const	{ return m_entries; }
96
97	void								clear					(void);
98
99private:
100										ValueScope				(const ValueScope& other);
101	ValueScope&							operator=				(const ValueScope& other);
102
103	std::vector<ValueEntry*>			m_entries;
104};
105
106class ReservedScalars
107{
108public:
109	int numScalars;
110
111	ReservedScalars (void)
112		: numScalars(0)
113	{
114	}
115};
116
117// \todo [2011-05-26 pyry] Clean up this a bit, separate const variant.
118template <typename Item, typename Iterator, class Filter>
119class FilteredIterator : public std::iterator<std::input_iterator_tag, Item>
120{
121public:
122	FilteredIterator (Iterator iter, Iterator end, Filter filter)
123		: m_iter	(iter)
124		, m_end		(end)
125		, m_filter	(filter)
126	{
127	}
128
129	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
137	FilteredIterator& operator++ ()
138	{
139		// Pre-increment
140		m_iter = findNext(m_filter, m_iter, m_end);
141		return *this;
142	}
143
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
152	bool operator== (const FilteredIterator& other) const
153	{
154		return m_iter == other.m_iter;
155	}
156
157	bool operator!= (const FilteredIterator& other) const
158	{
159		return m_iter != other.m_iter;
160	}
161
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
169private:
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
183template <class Filter>
184class ValueEntryIterator : public FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>
185{
186public:
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
193class VariableManager
194{
195public:
196									VariableManager					(NameAllocator& nameAllocator);
197									~VariableManager				(void);
198
199	int								getNumAllocatedScalars			(void) const { return m_numAllocatedScalars; }
200	int								getNumAllocatedShaderInScalars	(void) const { return m_numAllocatedShaderInScalars; }
201	int								getNumAllocatedShaderInVariables(void) const { return m_numAllocatedShaderInVariables; }
202	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
237private:
238									VariableManager					(const VariableManager& other);
239	VariableManager&				operator=						(const VariableManager& other);
240
241	VariableScope&					getCurVariableScope				(void)			{ return *m_variableScopeStack.back();	}
242	const VariableScope&			getCurVariableScope				(void) const	{ return *m_variableScopeStack.back();	}
243
244	ValueScope&						getCurValueScope				(void)			{ return *m_valueScopeStack.back();	}
245	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
259template <class Filter>
260ValueEntryIterator<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
268template <class Filter>
269ValueEntryIterator<Filter> VariableManager::getEnd (Filter filter) const
270{
271	return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter);
272}
273
274template <class Filter>
275bool 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
287class AnyEntry
288{
289public:
290	typedef ValueEntryIterator<AnyEntry> Iterator;
291
292	bool operator() (const ValueEntry* entry) const
293	{
294		DE_UNREF(entry);
295		return true;
296	}
297};
298
299class IsWritableEntry
300{
301public:
302	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
319template <Variable::Storage Storage>
320class EntryStorageFilter
321{
322public:
323	typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator;
324
325	bool operator() (const ValueEntry* entry) const
326	{
327		return entry->getVariable()->getStorage() == Storage;
328	}
329};
330
331typedef EntryStorageFilter<Variable::STORAGE_LOCAL>			LocalEntryFilter;
332typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN>		ShaderInEntryFilter;
333typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT>	ShaderOutEntryFilter;
334
335} // rsg
336
337#endif // _RSGVARIABLEMANAGER_HPP
338