xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/metal/mtl_library_cache.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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> &macros,
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> &macros,
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> &macros,
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