//
// 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_
