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