Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/libANGLE/BlobCache.h
1693 views
1
//
2
// Copyright 2018 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
// BlobCache: Stores compiled and linked programs in memory so they don't
7
// always have to be re-compiled. Can be used in conjunction with the platform
8
// layer to warm up the cache from disk.
9
10
#ifndef LIBANGLE_BLOB_CACHE_H_
11
#define LIBANGLE_BLOB_CACHE_H_
12
13
#include <array>
14
#include <cstring>
15
16
#include <anglebase/sha1.h>
17
#include "common/MemoryBuffer.h"
18
#include "common/hash_utils.h"
19
#include "libANGLE/Error.h"
20
#include "libANGLE/SizedMRUCache.h"
21
22
namespace gl
23
{
24
class Context;
25
} // namespace gl
26
27
namespace egl
28
{
29
// 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for
30
// simplicity and efficiency.
31
static constexpr size_t kBlobCacheKeyLength = angle::base::kSHA1Length;
32
using BlobCacheKey = std::array<uint8_t, kBlobCacheKeyLength>;
33
} // namespace egl
34
35
namespace std
36
{
37
template <>
38
struct hash<egl::BlobCacheKey>
39
{
40
// Simple routine to hash four ints.
41
size_t operator()(const egl::BlobCacheKey &key) const
42
{
43
return angle::ComputeGenericHash(key.data(), key.size());
44
}
45
};
46
} // namespace std
47
48
namespace egl
49
{
50
51
bool CompressBlobCacheData(const size_t cacheSize,
52
const uint8_t *cacheData,
53
angle::MemoryBuffer *compressedData);
54
bool DecompressBlobCacheData(const uint8_t *compressedData,
55
const size_t compressedSize,
56
angle::MemoryBuffer *uncompressedData);
57
58
class BlobCache final : angle::NonCopyable
59
{
60
public:
61
// 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for
62
// simplicity and efficiency.
63
static constexpr size_t kKeyLength = kBlobCacheKeyLength;
64
using Key = BlobCacheKey;
65
class Value
66
{
67
public:
68
Value() : mPtr(nullptr), mSize(0) {}
69
Value(const uint8_t *ptr, size_t sz) : mPtr(ptr), mSize(sz) {}
70
71
// A very basic struct to hold the pointer and size together. The objects of this class
72
// don't own the memory.
73
const uint8_t *data() { return mPtr; }
74
size_t size() { return mSize; }
75
76
const uint8_t &operator[](size_t pos) const
77
{
78
ASSERT(pos < mSize);
79
return mPtr[pos];
80
}
81
82
private:
83
const uint8_t *mPtr;
84
size_t mSize;
85
};
86
enum class CacheSource
87
{
88
Memory,
89
Disk,
90
};
91
92
explicit BlobCache(size_t maxCacheSizeBytes);
93
~BlobCache();
94
95
// Store a key-blob pair in the cache. If application callbacks are set, the application cache
96
// will be used. Otherwise the value is cached in this object.
97
void put(const BlobCache::Key &key, angle::MemoryBuffer &&value);
98
99
// Store a key-blob pair in the application cache, only if application callbacks are set.
100
void putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value);
101
102
// Store a key-blob pair in the cache without making callbacks to the application. This is used
103
// to repopulate this object's cache on startup without generating callback calls.
104
void populate(const BlobCache::Key &key,
105
angle::MemoryBuffer &&value,
106
CacheSource source = CacheSource::Disk);
107
108
// Check if the cache contains the blob corresponding to this key. If application callbacks are
109
// set, those will be used. Otherwise they key is looked up in this object's cache.
110
ANGLE_NO_DISCARD bool get(angle::ScratchBuffer *scratchBuffer,
111
const BlobCache::Key &key,
112
BlobCache::Value *valueOut,
113
size_t *bufferSizeOut);
114
115
// For querying the contents of the cache.
116
ANGLE_NO_DISCARD bool getAt(size_t index,
117
const BlobCache::Key **keyOut,
118
BlobCache::Value *valueOut);
119
120
// Evict a blob from the binary cache.
121
void remove(const BlobCache::Key &key);
122
123
// Empty the cache.
124
void clear() { mBlobCache.clear(); }
125
126
// Resize the cache. Discards current contents.
127
void resize(size_t maxCacheSizeBytes) { mBlobCache.resize(maxCacheSizeBytes); }
128
129
// Returns the number of entries in the cache.
130
size_t entryCount() const { return mBlobCache.entryCount(); }
131
132
// Reduces the current cache size and returns the number of bytes freed.
133
size_t trim(size_t limit) { return mBlobCache.shrinkToSize(limit); }
134
135
// Returns the current cache size in bytes.
136
size_t size() const { return mBlobCache.size(); }
137
138
// Returns whether the cache is empty
139
bool empty() const { return mBlobCache.empty(); }
140
141
// Returns the maximum cache size in bytes.
142
size_t maxSize() const { return mBlobCache.maxSize(); }
143
144
void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
145
146
bool areBlobCacheFuncsSet() const;
147
148
bool isCachingEnabled() const { return areBlobCacheFuncsSet() || maxSize() > 0; }
149
150
private:
151
// This internal cache is used only if the application is not providing caching callbacks
152
using CacheEntry = std::pair<angle::MemoryBuffer, CacheSource>;
153
154
std::mutex mBlobCacheMutex;
155
angle::SizedMRUCache<BlobCache::Key, CacheEntry> mBlobCache;
156
157
EGLSetBlobFuncANDROID mSetBlobFunc;
158
EGLGetBlobFuncANDROID mGetBlobFunc;
159
};
160
161
} // namespace egl
162
163
#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_
164
165