#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 #include #include 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& getDeclaredVariables (void) const { return m_declaredVariables; } std::vector& getLiveVariables (void) { return m_liveVariables; } const std::vector& getLiveVariables (void) const { return m_liveVariables; } private: VariableScope (const VariableScope& other); VariableScope& operator= (const VariableScope& other); std::vector m_declaredVariables; //!< Variables declared in this scope. Not available for expressions. std::vector 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& getValues (void) { return m_entries; } const std::vector& getValues (void) const { return m_entries; } void clear (void); private: ValueScope (const ValueScope& other); ValueScope& operator= (const ValueScope& other); std::vector 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 class FilteredIterator { public: using iterator_category = std::input_iterator_tag; using value_type = Item; using difference_type = std::ptrdiff_t; using pointer = Item*; using reference = Item&; 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 ValueEntryIterator : public FilteredIterator::const_iterator, Filter> { public: ValueEntryIterator (std::vector::const_iterator begin, std::vector::const_iterator end, Filter filter) : FilteredIterator::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& getLiveVariables (void) const; void pushVariableScope (VariableScope& scope); void popVariableScope (void); void pushValueScope (ValueScope& scope); void popValueScope (void); template ValueEntryIterator getBegin (Filter filter = Filter()) const; template ValueEntryIterator getEnd (Filter filter = Filter()) const; template 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 m_variableScopeStack; std::vector m_valueScopeStack; std::vector m_entryCache; //!< For faster value entry access. int m_numAllocatedScalars; int m_numAllocatedShaderInScalars; int m_numAllocatedShaderInVariables; int m_numAllocatedUniformScalars; NameAllocator& m_nameAllocator; }; template ValueEntryIterator VariableManager::getBegin (Filter filter) const { std::vector::const_iterator first = m_entryCache.begin(); while (first != m_entryCache.end() && !filter(*first)) first++; return ValueEntryIterator(first, m_entryCache.end(), filter); } template ValueEntryIterator VariableManager::getEnd (Filter filter) const { return ValueEntryIterator(m_entryCache.end(), m_entryCache.end(), filter); } template bool VariableManager::hasEntry (Filter filter) const { for (std::vector::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 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 class EntryStorageFilter { public: typedef ValueEntryIterator > Iterator; bool operator() (const ValueEntry* entry) const { return entry->getVariable()->getStorage() == Storage; } }; typedef EntryStorageFilter LocalEntryFilter; typedef EntryStorageFilter ShaderInEntryFilter; typedef EntryStorageFilter ShaderOutEntryFilter; } // rsg #endif // _RSGVARIABLEMANAGER_HPP