blob: 09c5be41b5674b90af71e2e22dad6f94f5ac86e2 [file] [log] [blame]
Dmitry Skiba01971112015-07-10 14:54:00 -04001//
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
15namespace
16{
17
18class TScopedAllocator : angle::NonCopyable
19{
20 public:
21 TScopedAllocator(TPoolAllocator *allocator)
22 : mPreviousAllocator(GetGlobalPoolAllocator())
23 {
24 SetGlobalPoolAllocator(allocator);
25 }
26 ~TScopedAllocator()
27 {
28 SetGlobalPoolAllocator(mPreviousAllocator);
29 }
30
31 private:
32 TPoolAllocator *mPreviousAllocator;
33};
34
35} // namespace
36
37TCache::TypeKey::TypeKey(TBasicType basicType,
38 TPrecision precision,
39 TQualifier qualifier,
40 unsigned char primarySize,
41 unsigned char secondarySize)
42{
43 static_assert(sizeof(components) <= sizeof(value),
44 "TypeKey::value is too small");
45
46 const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
Dmitry Skiba01971112015-07-10 14:54:00 -040047
48 // TODO: change to static_assert() once we deprecate MSVC 2013 support
49 ASSERT(MaxEnumValue >= EbtLast &&
50 MaxEnumValue >= EbpLast &&
51 MaxEnumValue >= EvqLast &&
52 "TypeKey::EnumComponentType is too small");
53
54 value = 0;
55 components.basicType = static_cast<EnumComponentType>(basicType);
56 components.precision = static_cast<EnumComponentType>(precision);
57 components.qualifier = static_cast<EnumComponentType>(qualifier);
58 components.primarySize = primarySize;
59 components.secondarySize = secondarySize;
60}
61
62TCache *TCache::sCache = nullptr;
63
64void TCache::initialize()
65{
66 if (sCache == nullptr)
67 {
68 sCache = new TCache();
69 }
70}
71
72void TCache::destroy()
73{
74 SafeDelete(sCache);
75}
76
77const 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,
84 primarySize, secondarySize);
85 auto it = sCache->mTypes.find(key);
86 if (it != sCache->mTypes.end())
87 {
88 return it->second;
89 }
90
91 TScopedAllocator scopedAllocator(&sCache->mAllocator);
92
93 TType *type = new TType(basicType, precision, qualifier,
94 primarySize, secondarySize);
95 type->realize();
96 sCache->mTypes.insert(std::make_pair(key, type));
97
98 return type;
99}