Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
16namespace 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|.
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///
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.
74
75 private:
76 using Reclaimables = std::vector<std::unique_ptr<ResourceVK>>;
77
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|.
113template <class ResourceType_>
114class 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///
144template <class ResourceType_>
145class 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
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_
A resource manager controls how resources are allocated and reclaimed.
static std::shared_ptr< ResourceManagerVK > Create()
Creates a shared resource manager (a dedicated thread).
void Reclaim(std::unique_ptr< ResourceVK > resource)
Mark a resource as being reclaimable.
~ResourceManagerVK()
Destroys the resource manager.
An internal type that is used to move a resource reference.
ResourceVKT(ResourceType &&resource)
Construct a resource from a move-constructible resource.
const ResourceType * Get() const
Returns a pointer to the resource.
A resource that may be reclaimed by a |ResourceManagerVK|.
virtual ~ResourceVK()=default
A unique handle to a resource which will be reclaimed by the specified resource manager.
void Reset()
Reclaims the existing resource, if any.
const ResourceType * operator->() const
Returns a pointer to the resource.
void Swap(ResourceType &&other)
Reclaims the existing resource, if any, and replaces it.
UniqueResourceVKT(std::weak_ptr< ResourceManagerVK > resource_manager)
Construct a unique resource handle belonging to a manager.
UniqueResourceVKT(std::weak_ptr< ResourceManagerVK > resource_manager, ResourceType &&resource)
Construct a unique resource handle belonging to a manager.
#define FML_CHECK(condition)
Definition logging.h:85
Definition ref_ptr.h:256