summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/BlobCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/BlobCache.h')
-rw-r--r--gfx/angle/checkout/src/libANGLE/BlobCache.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/BlobCache.h b/gfx/angle/checkout/src/libANGLE/BlobCache.h
new file mode 100644
index 0000000000..eec906dadc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/BlobCache.h
@@ -0,0 +1,153 @@
+//
+// Copyright 2018 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.
+//
+// BlobCache: Stores compiled and linked programs in memory so they don't
+// always have to be re-compiled. Can be used in conjunction with the platform
+// layer to warm up the cache from disk.
+
+#ifndef LIBANGLE_BLOB_CACHE_H_
+#define LIBANGLE_BLOB_CACHE_H_
+
+#include <array>
+#include <cstring>
+
+#include <anglebase/sha1.h>
+#include "common/MemoryBuffer.h"
+#include "common/hash_utils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/SizedMRUCache.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+// 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for
+// simplicity and efficiency.
+static constexpr size_t kBlobCacheKeyLength = angle::base::kSHA1Length;
+using BlobCacheKey = std::array<uint8_t, kBlobCacheKeyLength>;
+} // namespace egl
+
+namespace std
+{
+template <>
+struct hash<egl::BlobCacheKey>
+{
+ // Simple routine to hash four ints.
+ size_t operator()(const egl::BlobCacheKey &key) const
+ {
+ return angle::ComputeGenericHash(key.data(), key.size());
+ }
+};
+} // namespace std
+
+namespace egl
+{
+
+class BlobCache final : angle::NonCopyable
+{
+ public:
+ // 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for
+ // simplicity and efficiency.
+ static constexpr size_t kKeyLength = kBlobCacheKeyLength;
+ using Key = BlobCacheKey;
+ class Value
+ {
+ public:
+ Value() : mPtr(nullptr), mSize(0) {}
+ Value(const uint8_t *ptr, size_t sz) : mPtr(ptr), mSize(sz) {}
+
+ // A very basic struct to hold the pointer and size together. The objects of this class
+ // don't own the memory.
+ const uint8_t *data() { return mPtr; }
+ size_t size() { return mSize; }
+
+ const uint8_t &operator[](size_t pos) const
+ {
+ ASSERT(pos < mSize);
+ return mPtr[pos];
+ }
+
+ private:
+ const uint8_t *mPtr;
+ size_t mSize;
+ };
+ enum class CacheSource
+ {
+ Memory,
+ Disk,
+ };
+
+ explicit BlobCache(size_t maxCacheSizeBytes);
+ ~BlobCache();
+
+ // Store a key-blob pair in the cache. If application callbacks are set, the application cache
+ // will be used. Otherwise the value is cached in this object.
+ void put(const BlobCache::Key &key, angle::MemoryBuffer &&value);
+
+ // Store a key-blob pair in the application cache, only if application callbacks are set.
+ void putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value);
+
+ // Store a key-blob pair in the cache without making callbacks to the application. This is used
+ // to repopulate this object's cache on startup without generating callback calls.
+ void populate(const BlobCache::Key &key,
+ angle::MemoryBuffer &&value,
+ CacheSource source = CacheSource::Disk);
+
+ // Check if the cache contains the blob corresponding to this key. If application callbacks are
+ // set, those will be used. Otherwise they key is looked up in this object's cache.
+ ANGLE_NO_DISCARD bool get(angle::ScratchBuffer *scratchBuffer,
+ const BlobCache::Key &key,
+ BlobCache::Value *valueOut);
+
+ // For querying the contents of the cache.
+ ANGLE_NO_DISCARD bool getAt(size_t index,
+ const BlobCache::Key **keyOut,
+ BlobCache::Value *valueOut);
+
+ // Evict a blob from the binary cache.
+ void remove(const BlobCache::Key &key);
+
+ // Empty the cache.
+ void clear() { mBlobCache.clear(); }
+
+ // Resize the cache. Discards current contents.
+ void resize(size_t maxCacheSizeBytes) { mBlobCache.resize(maxCacheSizeBytes); }
+
+ // Returns the number of entries in the cache.
+ size_t entryCount() const { return mBlobCache.entryCount(); }
+
+ // Reduces the current cache size and returns the number of bytes freed.
+ size_t trim(size_t limit) { return mBlobCache.shrinkToSize(limit); }
+
+ // Returns the current cache size in bytes.
+ size_t size() const { return mBlobCache.size(); }
+
+ // Returns whether the cache is empty
+ bool empty() const { return mBlobCache.empty(); }
+
+ // Returns the maximum cache size in bytes.
+ size_t maxSize() const { return mBlobCache.maxSize(); }
+
+ void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+
+ bool areBlobCacheFuncsSet() const;
+
+ bool isCachingEnabled() const { return areBlobCacheFuncsSet() || maxSize() > 0; }
+
+ private:
+ // This internal cache is used only if the application is not providing caching callbacks
+ using CacheEntry = std::pair<angle::MemoryBuffer, CacheSource>;
+ angle::SizedMRUCache<BlobCache::Key, CacheEntry> mBlobCache;
+
+ EGLSetBlobFuncANDROID mSetBlobFunc;
+ EGLGetBlobFuncANDROID mGetBlobFunc;
+};
+
+} // namespace egl
+
+#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_