| // |
| // Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| // Cache.cpp: Implements a cache for various commonly created objects. |
| |
| #include <limits> |
| |
| #include "common/angleutils.h" |
| #include "common/debug.h" |
| #include "compiler/translator/Cache.h" |
| |
| namespace sh |
| { |
| |
| namespace |
| { |
| |
| class TScopedAllocator : angle::NonCopyable |
| { |
| public: |
| TScopedAllocator(TPoolAllocator *allocator) : mPreviousAllocator(GetGlobalPoolAllocator()) |
| { |
| SetGlobalPoolAllocator(allocator); |
| } |
| ~TScopedAllocator() { SetGlobalPoolAllocator(mPreviousAllocator); } |
| |
| private: |
| TPoolAllocator *mPreviousAllocator; |
| }; |
| |
| } // namespace |
| |
| TCache::TypeKey::TypeKey(TBasicType basicType, |
| TPrecision precision, |
| TQualifier qualifier, |
| unsigned char primarySize, |
| unsigned char secondarySize) |
| { |
| static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small"); |
| |
| const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max(); |
| |
| // TODO: change to static_assert() once we deprecate MSVC 2013 support |
| ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast && |
| "TypeKey::EnumComponentType is too small"); |
| |
| value = 0; |
| components.basicType = static_cast<EnumComponentType>(basicType); |
| components.precision = static_cast<EnumComponentType>(precision); |
| components.qualifier = static_cast<EnumComponentType>(qualifier); |
| components.primarySize = primarySize; |
| components.secondarySize = secondarySize; |
| } |
| |
| TCache *TCache::sCache = nullptr; |
| |
| void TCache::initialize() |
| { |
| if (sCache == nullptr) |
| { |
| sCache = new TCache(); |
| } |
| } |
| |
| void TCache::destroy() |
| { |
| SafeDelete(sCache); |
| } |
| |
| const TType *TCache::getType(TBasicType basicType, |
| TPrecision precision, |
| TQualifier qualifier, |
| unsigned char primarySize, |
| unsigned char secondarySize) |
| { |
| TypeKey key(basicType, precision, qualifier, primarySize, secondarySize); |
| auto it = sCache->mTypes.find(key); |
| if (it != sCache->mTypes.end()) |
| { |
| return it->second; |
| } |
| |
| TScopedAllocator scopedAllocator(&sCache->mAllocator); |
| |
| TType *type = new TType(basicType, precision, qualifier, primarySize, secondarySize); |
| type->realize(); |
| sCache->mTypes.insert(std::make_pair(key, type)); |
| |
| return type; |
| } |
| |
| } // namespace sh |