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 disableFastMath, 30 bool usesInvariance); 31 AutoObjCPtr<id<MTLLibrary>> getOrCompileShaderLibrary( 32 DisplayMtl *displayMtl, 33 const std::shared_ptr<const std::string> &source, 34 const std::map<std::string, std::string> ¯os, 35 bool disableFastMath, 36 bool usesInvariance, 37 AutoObjCPtr<NSError *> *errorOut); 38 39 private: 40 struct LibraryKey 41 { 42 LibraryKey() = default; 43 LibraryKey(const std::shared_ptr<const std::string> &source, 44 const std::map<std::string, std::string> ¯os, 45 bool disableFastMath, 46 bool usesInvariance); 47 48 std::shared_ptr<const std::string> source; 49 std::map<std::string, std::string> macros; 50 bool disableFastMath; 51 bool usesInvariance; 52 53 bool operator==(const LibraryKey &other) const; 54 }; 55 56 struct LibraryKeyHasher 57 { 58 // Hash function 59 size_t operator()(const LibraryKey &k) const; 60 61 // Comparison 62 bool operator()(const LibraryKey &a, const LibraryKey &b) const; 63 }; 64 65 struct LibraryCacheEntry : angle::NonCopyable 66 { 67 LibraryCacheEntry() = default; 68 ~LibraryCacheEntry(); 69 LibraryCacheEntry(LibraryCacheEntry &&moveFrom); 70 71 // library can only go from the null -> not null state. It is safe to check if the library 72 // already exists without locking. 73 AutoObjCPtr<id<MTLLibrary>> library; 74 75 // Lock for this specific library to avoid multiple threads compiling the same shader at 76 // once. 77 std::mutex lock; 78 }; 79 80 LibraryCacheEntry &getCacheEntry(LibraryKey &&key); 81 82 static constexpr unsigned int kMaxCachedLibraries = 128; 83 84 // The cache tries to clean up this many states at once. 85 static constexpr unsigned int kGCLimit = 32; 86 87 // Lock for searching and adding new entries to the cache 88 std::mutex mCacheLock; 89 90 using CacheMap = angle::base::HashingMRUCache<LibraryKey, LibraryCacheEntry, LibraryKeyHasher>; 91 CacheMap mCache; 92 }; 93 94 } // namespace mtl 95 } // namespace rx 96 97 #endif // LIBANGLE_RENDERER_METAL_MTL_LIBRARY_CACHE_H_ 98