You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
9.9 KiB
337 lines
9.9 KiB
#ifndef _RSGVARIABLEMANAGER_HPP |
|
#define _RSGVARIABLEMANAGER_HPP |
|
/*------------------------------------------------------------------------- |
|
* drawElements Quality Program Random Shader Generator |
|
* ---------------------------------------------------- |
|
* |
|
* Copyright 2014 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*//*! |
|
* \file |
|
* \brief Variable manager. |
|
* |
|
* Memory management: |
|
* Variable manager owns variable objects until they are either explictly |
|
* removed or moved to currently active scope. After that the ownership |
|
* is transferred to Scope or the object that called removeEntry(). |
|
*//*--------------------------------------------------------------------*/ |
|
|
|
#include "rsgDefs.hpp" |
|
#include "rsgVariable.hpp" |
|
#include "rsgVariableValue.hpp" |
|
#include "rsgNameAllocator.hpp" |
|
|
|
#include <iterator> |
|
#include <vector> |
|
#include <set> |
|
|
|
namespace rsg |
|
{ |
|
|
|
class ValueEntry |
|
{ |
|
public: |
|
ValueEntry (const Variable* variable); |
|
~ValueEntry (void) {} |
|
|
|
const Variable* getVariable (void) const { return m_variable; } |
|
|
|
ConstValueRangeAccess getValueRange (void) const { return m_valueRange.asAccess(); } |
|
ValueRangeAccess getValueRange (void) { return m_valueRange.asAccess(); } |
|
|
|
private: |
|
const Variable* m_variable; |
|
ValueRange m_valueRange; |
|
}; |
|
|
|
// Variable scope manages variable allocation. |
|
class VariableScope |
|
{ |
|
public: |
|
VariableScope (void); |
|
~VariableScope (void); |
|
|
|
Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name); |
|
void declare (Variable* variable); //!< Move from live set to declared set |
|
void removeLive (const Variable* variable); //!< Just remove from live set (when migrating to parent). |
|
|
|
const std::vector<Variable*>& getDeclaredVariables (void) const { return m_declaredVariables; } |
|
|
|
std::vector<Variable*>& getLiveVariables (void) { return m_liveVariables; } |
|
const std::vector<Variable*>& getLiveVariables (void) const { return m_liveVariables; } |
|
|
|
private: |
|
VariableScope (const VariableScope& other); |
|
VariableScope& operator= (const VariableScope& other); |
|
|
|
std::vector<Variable*> m_declaredVariables; //!< Variables declared in this scope. Not available for expressions. |
|
std::vector<Variable*> m_liveVariables; //!< Live variables (available for expression) that can be declared in this scope. |
|
}; |
|
|
|
class ValueScope |
|
{ |
|
public: |
|
ValueScope (void); |
|
~ValueScope (void); |
|
|
|
ValueEntry* allocate (const Variable* variable); |
|
ValueEntry* findEntry (const Variable* variable) const; |
|
void setValue (const Variable* variable, ConstValueRangeAccess value); |
|
void removeValue (const Variable* variable); |
|
|
|
std::vector<ValueEntry*>& getValues (void) { return m_entries; } |
|
const std::vector<ValueEntry*>& getValues (void) const { return m_entries; } |
|
|
|
void clear (void); |
|
|
|
private: |
|
ValueScope (const ValueScope& other); |
|
ValueScope& operator= (const ValueScope& other); |
|
|
|
std::vector<ValueEntry*> m_entries; |
|
}; |
|
|
|
class ReservedScalars |
|
{ |
|
public: |
|
int numScalars; |
|
|
|
ReservedScalars (void) |
|
: numScalars(0) |
|
{ |
|
} |
|
}; |
|
|
|
// \todo [2011-05-26 pyry] Clean up this a bit, separate const variant. |
|
template <typename Item, typename Iterator, class Filter> |
|
class FilteredIterator : public std::iterator<std::input_iterator_tag, Item> |
|
{ |
|
public: |
|
FilteredIterator (Iterator iter, Iterator end, Filter filter) |
|
: m_iter (iter) |
|
, m_end (end) |
|
, m_filter (filter) |
|
{ |
|
} |
|
|
|
FilteredIterator operator+ (ptrdiff_t offset) const |
|
{ |
|
Iterator nextEntry = m_iter; |
|
while (offset--) |
|
nextEntry = findNext(m_filter, nextEntry, m_end); |
|
return FilteredIterator(nextEntry, m_end, m_filter); |
|
} |
|
|
|
FilteredIterator& operator++ () |
|
{ |
|
// Pre-increment |
|
m_iter = findNext(m_filter, m_iter, m_end); |
|
return *this; |
|
} |
|
|
|
FilteredIterator operator++ (int) |
|
{ |
|
// Post-increment |
|
FilteredIterator copy = *this; |
|
m_iter = findNext(m_filter, m_iter, m_end); |
|
return copy; |
|
} |
|
|
|
bool operator== (const FilteredIterator& other) const |
|
{ |
|
return m_iter == other.m_iter; |
|
} |
|
|
|
bool operator!= (const FilteredIterator& other) const |
|
{ |
|
return m_iter != other.m_iter; |
|
} |
|
|
|
const Item& operator* (void) |
|
{ |
|
DE_ASSERT(m_iter != m_end); |
|
DE_ASSERT(m_filter(*m_iter)); |
|
return *m_iter; |
|
} |
|
|
|
private: |
|
static Iterator findNext (Filter filter, Iterator iter, Iterator end) |
|
{ |
|
do |
|
iter++; |
|
while (iter != end && !filter(*iter)); |
|
return iter; |
|
} |
|
|
|
Iterator m_iter; |
|
Iterator m_end; |
|
Filter m_filter; |
|
}; |
|
|
|
template <class Filter> |
|
class ValueEntryIterator : public FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter> |
|
{ |
|
public: |
|
ValueEntryIterator (std::vector<const ValueEntry*>::const_iterator begin, std::vector<const ValueEntry*>::const_iterator end, Filter filter) |
|
: FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>(begin, end, filter) |
|
{ |
|
} |
|
}; |
|
|
|
class VariableManager |
|
{ |
|
public: |
|
VariableManager (NameAllocator& nameAllocator); |
|
~VariableManager (void); |
|
|
|
int getNumAllocatedScalars (void) const { return m_numAllocatedScalars; } |
|
int getNumAllocatedShaderInScalars (void) const { return m_numAllocatedShaderInScalars; } |
|
int getNumAllocatedShaderInVariables(void) const { return m_numAllocatedShaderInVariables; } |
|
int getNumAllocatedUniformScalars (void) const { return m_numAllocatedUniformScalars; } |
|
|
|
void reserve (ReservedScalars& store, int numScalars); |
|
void release (ReservedScalars& store); |
|
|
|
Variable* allocate (const VariableType& type); |
|
Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name); |
|
|
|
void setStorage (Variable* variable, Variable::Storage storage); |
|
|
|
void setValue (const Variable* variable, ConstValueRangeAccess value); |
|
const ValueEntry* getValue (const Variable* variable) const; |
|
const ValueEntry* getParentValue (const Variable* variable) const; |
|
|
|
void removeValueFromCurrentScope (const Variable* variable); |
|
|
|
void declareVariable (Variable* variable); |
|
bool canDeclareInCurrentScope (const Variable* variable) const; |
|
const std::vector<Variable*>& getLiveVariables (void) const; |
|
|
|
void pushVariableScope (VariableScope& scope); |
|
void popVariableScope (void); |
|
|
|
void pushValueScope (ValueScope& scope); |
|
void popValueScope (void); |
|
|
|
template <class Filter> |
|
ValueEntryIterator<Filter> getBegin (Filter filter = Filter()) const; |
|
|
|
template <class Filter> |
|
ValueEntryIterator<Filter> getEnd (Filter filter = Filter()) const; |
|
|
|
template <class Filter> |
|
bool hasEntry (Filter filter = Filter()) const; |
|
|
|
private: |
|
VariableManager (const VariableManager& other); |
|
VariableManager& operator= (const VariableManager& other); |
|
|
|
VariableScope& getCurVariableScope (void) { return *m_variableScopeStack.back(); } |
|
const VariableScope& getCurVariableScope (void) const { return *m_variableScopeStack.back(); } |
|
|
|
ValueScope& getCurValueScope (void) { return *m_valueScopeStack.back(); } |
|
const ValueScope& getCurValueScope (void) const { return *m_valueScopeStack.back(); } |
|
|
|
std::vector<VariableScope*> m_variableScopeStack; |
|
std::vector<ValueScope*> m_valueScopeStack; |
|
|
|
std::vector<const ValueEntry*> m_entryCache; //!< For faster value entry access. |
|
|
|
int m_numAllocatedScalars; |
|
int m_numAllocatedShaderInScalars; |
|
int m_numAllocatedShaderInVariables; |
|
int m_numAllocatedUniformScalars; |
|
NameAllocator& m_nameAllocator; |
|
}; |
|
|
|
template <class Filter> |
|
ValueEntryIterator<Filter> VariableManager::getBegin (Filter filter) const |
|
{ |
|
std::vector<const ValueEntry*>::const_iterator first = m_entryCache.begin(); |
|
while (first != m_entryCache.end() && !filter(*first)) |
|
first++; |
|
return ValueEntryIterator<Filter>(first, m_entryCache.end(), filter); |
|
} |
|
|
|
template <class Filter> |
|
ValueEntryIterator<Filter> VariableManager::getEnd (Filter filter) const |
|
{ |
|
return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter); |
|
} |
|
|
|
template <class Filter> |
|
bool VariableManager::hasEntry (Filter filter) const |
|
{ |
|
for (std::vector<const ValueEntry*>::const_iterator i = m_entryCache.begin(); i != m_entryCache.end(); i++) |
|
{ |
|
if (filter(*i)) |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
// Common filters |
|
|
|
class AnyEntry |
|
{ |
|
public: |
|
typedef ValueEntryIterator<AnyEntry> Iterator; |
|
|
|
bool operator() (const ValueEntry* entry) const |
|
{ |
|
DE_UNREF(entry); |
|
return true; |
|
} |
|
}; |
|
|
|
class IsWritableEntry |
|
{ |
|
public: |
|
bool operator() (const ValueEntry* entry) const |
|
{ |
|
switch (entry->getVariable()->getStorage()) |
|
{ |
|
case Variable::STORAGE_LOCAL: |
|
case Variable::STORAGE_SHADER_OUT: |
|
case Variable::STORAGE_PARAMETER_IN: |
|
case Variable::STORAGE_PARAMETER_OUT: |
|
case Variable::STORAGE_PARAMETER_INOUT: |
|
return true; |
|
|
|
default: |
|
return false; |
|
} |
|
} |
|
}; |
|
|
|
template <Variable::Storage Storage> |
|
class EntryStorageFilter |
|
{ |
|
public: |
|
typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator; |
|
|
|
bool operator() (const ValueEntry* entry) const |
|
{ |
|
return entry->getVariable()->getStorage() == Storage; |
|
} |
|
}; |
|
|
|
typedef EntryStorageFilter<Variable::STORAGE_LOCAL> LocalEntryFilter; |
|
typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN> ShaderInEntryFilter; |
|
typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT> ShaderOutEntryFilter; |
|
|
|
} // rsg |
|
|
|
#endif // _RSGVARIABLEMANAGER_HPP
|
|
|