1 //
2 // Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Cache.cpp: Implements a cache for various commonly created objects.
8
9 #include <limits>
10
11 #include "common/angleutils.h"
12 #include "common/debug.h"
13 #include "compiler/translator/Cache.h"
14
15 namespace sh
16 {
17
18 namespace
19 {
20
21 class TScopedAllocator : angle::NonCopyable
22 {
23 public:
TScopedAllocator(TPoolAllocator * allocator)24 TScopedAllocator(TPoolAllocator *allocator) : mPreviousAllocator(GetGlobalPoolAllocator())
25 {
26 SetGlobalPoolAllocator(allocator);
27 }
~TScopedAllocator()28 ~TScopedAllocator() { SetGlobalPoolAllocator(mPreviousAllocator); }
29
30 private:
31 TPoolAllocator *mPreviousAllocator;
32 };
33
34 } // namespace
35
TypeKey(TBasicType basicType,TPrecision precision,TQualifier qualifier,unsigned char primarySize,unsigned char secondarySize)36 TCache::TypeKey::TypeKey(TBasicType basicType,
37 TPrecision precision,
38 TQualifier qualifier,
39 unsigned char primarySize,
40 unsigned char secondarySize)
41 {
42 static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small");
43
44 const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
45
46 // TODO: change to static_assert() once we deprecate MSVC 2013 support
47 ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast &&
48 "TypeKey::EnumComponentType is too small");
49
50 value = 0;
51 components.basicType = static_cast<EnumComponentType>(basicType);
52 components.precision = static_cast<EnumComponentType>(precision);
53 components.qualifier = static_cast<EnumComponentType>(qualifier);
54 components.primarySize = primarySize;
55 components.secondarySize = secondarySize;
56 }
57
58 TCache *TCache::sCache = nullptr;
59
TCache()60 TCache::TCache()
61 {
62 }
63
initialize()64 void TCache::initialize()
65 {
66 if (sCache == nullptr)
67 {
68 sCache = new TCache();
69 }
70 }
71
destroy()72 void TCache::destroy()
73 {
74 SafeDelete(sCache);
75 }
76
getType(TBasicType basicType,TPrecision precision,TQualifier qualifier,unsigned char primarySize,unsigned char secondarySize)77 const TType *TCache::getType(TBasicType basicType,
78 TPrecision precision,
79 TQualifier qualifier,
80 unsigned char primarySize,
81 unsigned char secondarySize)
82 {
83 TypeKey key(basicType, precision, qualifier, primarySize, secondarySize);
84 auto it = sCache->mTypes.find(key);
85 if (it != sCache->mTypes.end())
86 {
87 return it->second;
88 }
89
90 TScopedAllocator scopedAllocator(&sCache->mAllocator);
91
92 TType *type = new TType(basicType, precision, qualifier, primarySize, secondarySize);
93 type->realize();
94 sCache->mTypes.insert(std::make_pair(key, type));
95
96 return type;
97 }
98
99 } // namespace sh
100