summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/compiler/translator/Cache.cpp
blob: 094e3ff577ef006a6191949db18a9b3371b57887 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// 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