1 // 2 // Copyright 2023 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 // mtl_library_cache.h: 7 // Defines classes for caching of mtl libraries 8 // 9 10 #ifndef LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_ 11 #define LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_ 12 13 #include "libANGLE/renderer/metal/mtl_utils.h" 14 15 #include <type_traits> 16 17 namespace rx 18 { 19 namespace mtl 20 { 21 22 class LibraryCache : angle::NonCopyable 23 { 24 public: 25 LibraryCache(); 26 27 AutoObjCPtr<id<MTLLibrary>> get(const std::shared_ptr<const std::string> &source, 28 const std::map<std::string, std::string> ¯os, 29 bool enableFastMath); 30 AutoObjCPtr<id<MTLLibrary>> getOrCompileShaderLibrary( 31 ContextMtl *context, 32 const std::shared_ptr<const std::string> &source, 33 const std::map<std::string, std::string> ¯os, 34 bool enableFastMath, 35 AutoObjCPtr<NSError *> *errorOut); 36 37 private: 38 struct LibraryKey 39 { 40 LibraryKey() = default; 41 LibraryKey(const std::shared_ptr<const std::string> &source, 42 const std::map<std::string, std::string> ¯os, 43 bool enableFastMath); 44 45 std::shared_ptr<const std::string> source; 46 std::map<std::string, std::string> macros; 47 bool enableFastMath; 48 49 bool operator==(const LibraryKey &other) const; 50 }; 51 52 struct LibraryKeyHasher 53 { 54 // Hash function 55 size_t operator()(const LibraryKey &k) const; 56 57 // Comparison 58 bool operator()(const LibraryKey &a, const LibraryKey &b) const; 59 }; 60 61 struct LibraryCacheEntry : angle::NonCopyable 62 { 63 LibraryCacheEntry() = default; 64 ~LibraryCacheEntry(); 65 LibraryCacheEntry(LibraryCacheEntry &&moveFrom); 66 67 // library can only go from the null -> not null state. It is safe to check if the library 68 // already exists without locking. 69 AutoObjCPtr<id<MTLLibrary>> library; 70 71 // Lock for this specific library to avoid multiple threads compiling the same shader at 72 // once. 73 std::mutex lock; 74 }; 75 76 LibraryCacheEntry &getCacheEntry(LibraryKey &&key); 77 78 static constexpr unsigned int kMaxCachedLibraries = 128; 79 80 // The cache tries to clean up this many states at once. 81 static constexpr unsigned int kGCLimit = 32; 82 83 // Lock for searching and adding new entries to the cache 84 std::mutex mCacheLock; 85 86 using CacheMap = angle::base::HashingMRUCache<LibraryKey, LibraryCacheEntry, LibraryKeyHasher>; 87 CacheMap mCache; 88 }; 89 90 } // namespace mtl 91 } // namespace rx 92 93 #endif // LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_ 94