| Flutter Impeller |

resource_manager_vk.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_RESOURCE_MANAGER_VK_H_
6 #define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_RESOURCE_MANAGER_VK_H_
7
8 #include <condition_variable>
9 #include <memory>
10 #include <mutex>
11 #include <thread>
12 #include <vector>
13
14 namespace impeller {
15
16 //------------------------------------------------------------------------------
17 /// @brief A resource that may be reclaimed by a |ResourceManagerVK|.
18 ///
19 /// To create a resource, use `UniqueResourceVKT` to create a unique handle:
20 ///
21 /// auto resource = UniqueResourceVKT<SomeResource>(resource_manager);
22 ///
23 /// @see |ResourceManagerVK::Reclaim|.
24 class ResourceVK {
25 public:
26 virtual ~ResourceVK() = default;
27 };
28
29 //------------------------------------------------------------------------------
30 /// @brief A resource manager controls how resources are allocated and
31 /// reclaimed.
32 ///
33 /// Reclaimed resources are collected in a batch on a separate
34 /// thread. In the future, the resource manager may allow resource
35 /// pooling/reuse, delaying reclamation past frame workloads, etc...
36 ///
37 class ResourceManagerVK final
38 : public std::enable_shared_from_this<ResourceManagerVK> {
39 public:
40 //----------------------------------------------------------------------------
41 /// @brief Creates a shared resource manager (a dedicated thread).
42 ///
43 /// Upon creation, a thread is spawned which will collect resources as they
44 /// are reclaimed (passed to `Reclaim`). The thread will exit when the
45 /// resource manager is destroyed.
46 ///
47 /// @note Only one |ResourceManagerVK| should be created per Vulkan
48 /// context, but that contract is not enforced by this method.
49 ///
50 /// @return A resource manager if one could be created.
51 ///
52 static std::shared_ptr<ResourceManagerVK> Create();
53
54 //----------------------------------------------------------------------------
55 /// @brief Mark a resource as being reclaimable.
56 ///
57 /// The resource will be reset at some point in the future.
58 ///
59 /// @param[in] resource The resource to reclaim.
60 ///
61 /// @note Despite being a public API, this method cannot be invoked
62 /// directly. Instead, use `UniqueResourceVKT` to create a unique
63 /// handle to a resource, which will call this method.
64 void Reclaim(std::unique_ptr<ResourceVK> resource);
65
66 //----------------------------------------------------------------------------
67 /// @brief Destroys the resource manager.
68 ///
69 /// The resource manager will stop collecting resources and will be destroyed
70 /// when all references to it are dropped.
71 ~ResourceManagerVK();
72
73 private:
74 using Reclaimables = std::vector<std::unique_ptr<ResourceVK>>;
75
76 ResourceManagerVK();
77 std::mutex reclaimables_mutex_;
78 std::condition_variable reclaimables_cv_;
79 Reclaimables reclaimables_;
80 bool should_exit_ = false;
81 // This should be initialized last since it references the other instance
82 // variables.
83 std::thread waiter_;
84
85 //----------------------------------------------------------------------------
86 /// @brief Starts the resource manager thread.
87 ///
88 /// This method is called implicitly by `Create`.
89 void Start();
90
91 //----------------------------------------------------------------------------
92 /// @brief Terminates the resource manager thread.
93 ///
94 /// Any resources given to the resource manager post termination will be
95 /// collected when the resource manager is collected.
96 void Terminate();
97
98 ResourceManagerVK(const ResourceManagerVK&) = delete;
99
100 ResourceManagerVK& operator=(const ResourceManagerVK&) = delete;
101 };
102
103 //------------------------------------------------------------------------------
104 /// @brief An internal type that is used to move a resource reference.
105 ///
106 /// Do not use directly, use `UniqueResourceVKT` instead.
107 ///
108 /// @tparam ResourceType_ The type of the resource.
109 ///
110 /// @see |UniqueResourceVKT|.
111 template <class ResourceType_>
112 class ResourceVKT : public ResourceVK {
113 public:
114 using ResourceType = ResourceType_;
115
116 /// @brief Construct a resource from a move-constructible resource.
117 ///
118 /// @param[in] resource The resource to move.
119 explicit ResourceVKT(ResourceType&& resource)
120 : resource_(std::move(resource)) {}
121
122 /// @brief Returns a pointer to the resource.
123 const ResourceType* Get() const { return &resource_; }
124
125 private:
126 // Prevents subclassing, use `UniqueResourceVKT`.
127 ResourceVKT() = default;
128
129 ResourceType resource_;
130
131 ResourceVKT(const ResourceVKT&) = delete;
132
133 ResourceVKT& operator=(const ResourceVKT&) = delete;
134 };
135
136 //------------------------------------------------------------------------------
137 /// @brief A unique handle to a resource which will be reclaimed by the
138 /// specified resource manager.
139 ///
140 /// @tparam ResourceType_ A move-constructible resource type.
141 ///
142 template <class ResourceType_>
143 class UniqueResourceVKT final {
144 public:
145 using ResourceType = ResourceType_;
146
147 /// @brief Construct a unique resource handle belonging to a manager.
148 ///
149 /// Initially the handle is empty, and can be populated by calling `Swap`.
150 ///
151 /// @param[in] resource_manager The resource manager.
152 explicit UniqueResourceVKT(std::weak_ptr<ResourceManagerVK> resource_manager)
153 : resource_manager_(std::move(resource_manager)) {}
154
155 /// @brief Construct a unique resource handle belonging to a manager.
156 ///
157 /// Initially the handle is populated with the specified resource, but can
158 /// be replaced (reclaiming the old resource) by calling `Swap`.
159 ///
160 /// @param[in] resource_manager The resource manager.
161 /// @param[in] resource The resource to move.
162 explicit UniqueResourceVKT(std::weak_ptr<ResourceManagerVK> resource_manager,
163 ResourceType&& resource)
164 : resource_manager_(std::move(resource_manager)),
165 resource_(
166 std::make_unique<ResourceVKT<ResourceType>>(std::move(resource))) {}
167
168 ~UniqueResourceVKT() { Reset(); }
169
170 /// @brief Returns a pointer to the resource.
171 const ResourceType* operator->() const {
172 // If this would segfault, fail with a nicer error message.
173 FML_CHECK(resource_) << "UniqueResourceVKT was reclaimed.";
174
175 return resource_.get()->Get();
176 }
177
178 /// @brief Reclaims the existing resource, if any, and replaces it.
179 ///
180 /// @param[in] other The (new) resource to move.
181 void Swap(ResourceType&& other) {
182 Reset();
183 resource_ = std::make_unique<ResourceVKT<ResourceType>>(std::move(other));
184 }
185
186 /// @brief Reclaims the existing resource, if any.
187 void Reset() {
188 if (!resource_) {
189 return;
190 }
191 // If there is a manager, ask it to reclaim the resource. If there isn't a
192 // manager (because the manager has been destroyed), just drop it on the
193 // floor here.
194 if (auto manager = resource_manager_.lock()) {
195 manager->Reclaim(std::move(resource_));
196 }
197 resource_.reset();
198 }
199
200 private:
201 std::weak_ptr<ResourceManagerVK> resource_manager_;
202 std::unique_ptr<ResourceVKT<ResourceType>> resource_;
203
204 UniqueResourceVKT(const UniqueResourceVKT&) = delete;
205
206 UniqueResourceVKT& operator=(const UniqueResourceVKT&) = delete;
207 };
208
209 } // namespace impeller
210
211 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_RESOURCE_MANAGER_VK_H_
impeller::ResourceManagerVK::Create
static std::shared_ptr< ResourceManagerVK > Create()
Creates a shared resource manager (a dedicated thread).
Definition: resource_manager_vk.cc:14
impeller::ResourceManagerVK
A resource manager controls how resources are allocated and reclaimed.
Definition: resource_manager_vk.h:37
impeller::UniqueResourceVKT
A unique handle to a resource which will be reclaimed by the specified resource manager.
Definition: resource_manager_vk.h:143
impeller::ResourceVKT
An internal type that is used to move a resource reference.
Definition: resource_manager_vk.h:112
impeller::UniqueResourceVKT::Swap
void Swap(ResourceType &&other)
Reclaims the existing resource, if any, and replaces it.
Definition: resource_manager_vk.h:181
impeller::ResourceVKT::ResourceType
ResourceType_ ResourceType
Definition: resource_manager_vk.h:114
impeller::ResourceManagerVK::Reclaim
void Reclaim(std::unique_ptr< ResourceVK > resource)
Mark a resource as being reclaimable.
Definition: resource_manager_vk.cc:75
impeller::ResourceVK
A resource that may be reclaimed by a |ResourceManagerVK|.
Definition: resource_manager_vk.h:24
impeller::ResourceVKT::Get
const ResourceType * Get() const
Returns a pointer to the resource.
Definition: resource_manager_vk.h:123
impeller::UniqueResourceVKT::~UniqueResourceVKT
~UniqueResourceVKT()
Definition: resource_manager_vk.h:168
impeller::UniqueResourceVKT::UniqueResourceVKT
UniqueResourceVKT(std::weak_ptr< ResourceManagerVK > resource_manager)
Construct a unique resource handle belonging to a manager.
Definition: resource_manager_vk.h:152
impeller::ResourceVKT::ResourceVKT
ResourceVKT(ResourceType &&resource)
Construct a resource from a move-constructible resource.
Definition: resource_manager_vk.h:119
impeller::UniqueResourceVKT::operator->
const ResourceType * operator->() const
Returns a pointer to the resource.
Definition: resource_manager_vk.h:171
impeller::ResourceVK::~ResourceVK
virtual ~ResourceVK()=default
std
Definition: comparable.h:95
impeller::UniqueResourceVKT< ImageResource >::ResourceType
ImageResource ResourceType
Definition: resource_manager_vk.h:145
impeller::ResourceManagerVK::~ResourceManagerVK
~ResourceManagerVK()
Destroys the resource manager.
Definition: resource_manager_vk.cc:25
impeller::UniqueResourceVKT::UniqueResourceVKT
UniqueResourceVKT(std::weak_ptr< ResourceManagerVK > resource_manager, ResourceType &&resource)
Construct a unique resource handle belonging to a manager.
Definition: resource_manager_vk.h:162
impeller
Definition: allocation.cc:12
impeller::UniqueResourceVKT::Reset
void Reset()
Reclaims the existing resource, if any.
Definition: resource_manager_vk.h:187