blob: d936e6a4aeec66c66ae9b4203c61c9480b68563b [file] [log] [blame]
//
// Copyright 2023 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.
//
// mtl_library_cache.h:
// Defines classes for caching of mtl libraries
//
#ifndef LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_
#define LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_
#include "libANGLE/renderer/metal/mtl_utils.h"
#include <type_traits>
namespace rx
{
namespace mtl
{
class LibraryCache : angle::NonCopyable
{
public:
LibraryCache();
angle::ObjCPtr<id<MTLLibrary>> get(const std::shared_ptr<const std::string> &source,
const std::map<std::string, std::string> &macros,
bool disableFastMath,
bool usesInvariance);
angle::ObjCPtr<id<MTLLibrary>> getOrCompileShaderLibrary(
DisplayMtl *displayMtl,
const std::shared_ptr<const std::string> &source,
const std::map<std::string, std::string> &macros,
bool disableFastMath,
bool usesInvariance,
angle::ObjCPtr<NSError> *errorOut);
private:
struct LibraryKey
{
LibraryKey() = default;
LibraryKey(const std::shared_ptr<const std::string> &source,
const std::map<std::string, std::string> &macros,
bool disableFastMath,
bool usesInvariance);
std::shared_ptr<const std::string> source;
std::map<std::string, std::string> macros;
bool disableFastMath;
bool usesInvariance;
bool operator==(const LibraryKey &other) const;
};
struct LibraryKeyHasher
{
// Hash function
size_t operator()(const LibraryKey &k) const;
// Comparison
bool operator()(const LibraryKey &a, const LibraryKey &b) const;
};
struct LibraryCacheEntry : angle::NonCopyable
{
LibraryCacheEntry() = default;
~LibraryCacheEntry();
LibraryCacheEntry(LibraryCacheEntry &&moveFrom);
// library can only go from the null -> not null state. It is safe to check if the library
// already exists without locking.
angle::ObjCPtr<id<MTLLibrary>> library;
// Lock for this specific library to avoid multiple threads compiling the same shader at
// once.
std::mutex lock;
};
LibraryCacheEntry &getCacheEntry(LibraryKey &&key);
static constexpr unsigned int kMaxCachedLibraries = 128;
// The cache tries to clean up this many states at once.
static constexpr unsigned int kGCLimit = 32;
// Lock for searching and adding new entries to the cache
std::mutex mCacheLock;
using CacheMap = angle::base::HashingMRUCache<LibraryKey, LibraryCacheEntry, LibraryKeyHasher>;
CacheMap mCache;
};
} // namespace mtl
} // namespace rx
#endif // LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_