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); 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 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 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 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 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 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 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: 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 169 private: 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: 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 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 237 private: 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 259 template <class Filter> 260 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> 269 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> 275 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 292 bool operator() (const ValueEntry* entry) const 293 { 294 DE_UNREF(entry); 295 return true; 296 } 297 }; 298 299 class IsWritableEntry 300 { 301 public: 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 319 template <Variable::Storage Storage> 320 class EntryStorageFilter 321 { 322 public: 323 typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator; 324 325 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