Edit

kc3-lang/angle/src/libANGLE/BlobCache.h

Branch :

  • Show log

    Commit

  • Author : Amy Liu
    Date : 2021-03-26 17:38:21
    Hash : 95935176
    Message : Handle the compression of big pipeline cache. Big pipeline cache will cost much time to compress. Regarding the perfomance, handle the compression of big pipeline cache in this way: 1)Return when the pipeline cache data is larger than 10M. 2)Use worker thread to complete compression. Bug: angleproject:4722 Change-Id: I62eb69d8c46729261f0502af01450ec301c258f3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2788169 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/libANGLE/BlobCache.h
  • //
    // 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
    {
    
    bool CompressBlobCacheData(const size_t cacheSize,
                               const uint8_t *cacheData,
                               angle::MemoryBuffer *compressedData);
    bool DecompressBlobCacheData(const uint8_t *compressedData,
                                 const size_t compressedSize,
                                 angle::MemoryBuffer *uncompressedData);
    
    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,
                                  size_t *bufferSizeOut);
    
        // 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>;
    
        std::mutex mBlobCacheMutex;
        angle::SizedMRUCache<BlobCache::Key, CacheEntry> mBlobCache;
    
        EGLSetBlobFuncANDROID mSetBlobFunc;
        EGLGetBlobFuncANDROID mGetBlobFunc;
    };
    
    }  // namespace egl
    
    #endif  // LIBANGLE_MEMORY_PROGRAM_CACHE_H_