blob: 07cc5b244b23034cd272f384577310b971014bb2 [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
Jamie Madill45bcc782016-11-07 13:58:48 -050015namespace sh
16{
17
Dmitry Skiba01971112015-07-10 14:54:00 -040018namespace
19{
20
21class TScopedAllocator : angle::NonCopyable
22{
23 public:
Jamie Madilld7b1ab52016-12-12 14:42:19 -050024 TScopedAllocator(TPoolAllocator *allocator) : mPreviousAllocator(GetGlobalPoolAllocator())
Dmitry Skiba01971112015-07-10 14:54:00 -040025 {
26 SetGlobalPoolAllocator(allocator);
27 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -050028 ~TScopedAllocator() { SetGlobalPoolAllocator(mPreviousAllocator); }
Dmitry Skiba01971112015-07-10 14:54:00 -040029
30 private:
31 TPoolAllocator *mPreviousAllocator;
32};
33
34} // namespace
35
36TCache::TypeKey::TypeKey(TBasicType basicType,
37 TPrecision precision,
38 TQualifier qualifier,
39 unsigned char primarySize,
40 unsigned char secondarySize)
41{
Jamie Madilld7b1ab52016-12-12 14:42:19 -050042 static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small");
Dmitry Skiba01971112015-07-10 14:54:00 -040043
44 const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();
Dmitry Skiba01971112015-07-10 14:54:00 -040045
46 // TODO: change to static_assert() once we deprecate MSVC 2013 support
Jamie Madilld7b1ab52016-12-12 14:42:19 -050047 ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast &&
Dmitry Skiba01971112015-07-10 14:54:00 -040048 "TypeKey::EnumComponentType is too small");
49
Jamie Madilld7b1ab52016-12-12 14:42:19 -050050 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;
Dmitry Skiba01971112015-07-10 14:54:00 -040055 components.secondarySize = secondarySize;
56}
57
58TCache *TCache::sCache = nullptr;
59
60void TCache::initialize()
61{
62 if (sCache == nullptr)
63 {
64 sCache = new TCache();
65 }
66}
67
68void TCache::destroy()
69{
70 SafeDelete(sCache);
71}
72
73const TType *TCache::getType(TBasicType basicType,
74 TPrecision precision,
75 TQualifier qualifier,
76 unsigned char primarySize,
77 unsigned char secondarySize)
78{
Jamie Madilld7b1ab52016-12-12 14:42:19 -050079 TypeKey key(basicType, precision, qualifier, primarySize, secondarySize);
Dmitry Skiba01971112015-07-10 14:54:00 -040080 auto it = sCache->mTypes.find(key);
81 if (it != sCache->mTypes.end())
82 {
83 return it->second;
84 }
85
86 TScopedAllocator scopedAllocator(&sCache->mAllocator);
87
Jamie Madilld7b1ab52016-12-12 14:42:19 -050088 TType *type = new TType(basicType, precision, qualifier, primarySize, secondarySize);
Dmitry Skiba01971112015-07-10 14:54:00 -040089 type->realize();
90 sCache->mTypes.insert(std::make_pair(key, type));
91
92 return type;
93}
Jamie Madill45bcc782016-11-07 13:58:48 -050094
95} // namespace sh