Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
command_pool_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_COMMAND_POOL_VK_H_
6#define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_COMMAND_POOL_VK_H_
7
8#include <memory>
9#include <optional>
10#include <utility>
11
14#include "impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep.
15#include "vulkan/vulkan_handles.hpp"
16
17namespace impeller {
18
19class ContextVK;
20class CommandPoolRecyclerVK;
21
22//------------------------------------------------------------------------------
23/// @brief Manages the lifecycle of a single |vk::CommandPool|.
24///
25/// A |vk::CommandPool| is expensive to create and reset. This class manages
26/// the lifecycle of a single |vk::CommandPool| by returning to the origin
27/// (|CommandPoolRecyclerVK|) when it is destroyed to be reused.
28///
29/// @warning This class is not thread-safe.
30///
31/// @see |CommandPoolRecyclerVK|
32class CommandPoolVK final {
33 public:
35
36 /// @brief Creates a resource that manages the life of a command pool.
37 ///
38 /// @param[in] pool The command pool to manage.
39 /// @param[in] buffers Zero or more command buffers in an initial state.
40 /// @param[in] recycler The context that will be notified on destruction.
41 CommandPoolVK(vk::UniqueCommandPool pool,
42 std::vector<vk::UniqueCommandBuffer>&& buffers,
43 std::weak_ptr<ContextVK> context,
44 std::weak_ptr<DeviceHolderVK> device_holder)
45 : pool_(std::move(pool)),
46 unused_command_buffers_(std::move(buffers)),
47 context_(std::move(context)),
48 device_holder_(std::move(device_holder)) {}
49
50 /// @brief Creates and returns a new |vk::CommandBuffer|.
51 ///
52 /// @return Always returns a new |vk::CommandBuffer|, but if for any
53 /// reason a valid command buffer could not be created, it will be
54 /// a `{}` default instance (i.e. while being torn down).
55 vk::UniqueCommandBuffer CreateCommandBuffer();
56
57 /// @brief Collects the given |vk::CommandBuffer| to be retained.
58 ///
59 /// @param[in] buffer The |vk::CommandBuffer| to collect.
60 ///
61 /// @see |GarbageCollectBuffersIfAble|
62 void CollectCommandBuffer(vk::UniqueCommandBuffer&& buffer);
63
64 private:
66
67 /// @brief Delete all Vulkan objects in this command pool.
68 void Destroy();
69
70 CommandPoolVK(const CommandPoolVK&) = delete;
71
72 CommandPoolVK& operator=(const CommandPoolVK&) = delete;
73
74 Mutex pool_mutex_;
75 vk::UniqueCommandPool pool_ IPLR_GUARDED_BY(pool_mutex_);
76 std::vector<vk::UniqueCommandBuffer> unused_command_buffers_;
77 std::weak_ptr<ContextVK> context_;
78 std::weak_ptr<DeviceHolderVK> device_holder_;
79
80 // Used to retain a reference on these until the pool is reset.
81 std::vector<vk::UniqueCommandBuffer> collected_buffers_
82 IPLR_GUARDED_BY(pool_mutex_);
83};
84
85//------------------------------------------------------------------------------
86/// @brief Creates and manages the lifecycle of |vk::CommandPool| objects.
87///
88/// A |vk::CommandPool| is expensive to create and reset. This class manages
89/// the lifecycle of |vk::CommandPool| objects by creating and recycling them;
90/// or in other words, a pool for command pools.
91///
92/// A single instance should be created per |ContextVK|.
93///
94/// Every "frame", a single |CommandPoolResourceVk| is made available for each
95/// thread that calls |Get|. After calling |Dispose|, the current thread's pool
96/// is moved to a background thread, reset, and made available for the next time
97/// |Get| is called and needs to create a command pool.
98///
99/// Commands in the command pool are not necessarily done executing when the
100/// pool is recycled, when all references are dropped to the pool, they are
101/// reset and returned to the pool of available pools.
102///
103/// @note This class is thread-safe.
104///
105/// @see |vk::CommandPoolResourceVk|
106/// @see |ContextVK|
107/// @see
108/// https://arm-software.github.io/vulkan_best_practice_for_mobile_developers/samples/performance/command_buffer_usage/command_buffer_usage_tutorial.html
110 : public std::enable_shared_from_this<CommandPoolRecyclerVK> {
111 public:
112 /// A unique command pool and zero or more recycled command buffers.
114 vk::UniqueCommandPool pool;
115 std::vector<vk::UniqueCommandBuffer> buffers;
116 };
117
118 /// @brief Clean up resources held by all per-thread command pools
119 /// associated with the context.
121
122 /// @brief Creates a recycler for the given |ContextVK|.
123 ///
124 /// @param[in] context The context to create the recycler for.
125 explicit CommandPoolRecyclerVK(const std::shared_ptr<ContextVK>& context);
126
127 /// @brief Gets a command pool for the current thread.
128 ///
129 /// @warning Returns a |nullptr| if a pool could not be created.
130 std::shared_ptr<CommandPoolVK> Get();
131
132 /// @brief Returns a command pool to be reset on a background thread.
133 ///
134 /// @param[in] pool The pool to recycle.
135 /// @param[in] should_trim whether to trim command pool memory before
136 /// reseting.
137 void Reclaim(vk::UniqueCommandPool&& pool,
138 std::vector<vk::UniqueCommandBuffer>&& buffers,
139 bool should_trim = false);
140
141 /// @brief Clears this context's thread-local command pool.
142 void Dispose();
143
144 // Visible for testing.
145 static int GetGlobalPoolCount(const ContextVK& context);
146
147 private:
148 std::weak_ptr<ContextVK> context_;
149 uint64_t context_hash_;
150
151 Mutex recycled_mutex_;
152 std::vector<RecycledData> recycled_ IPLR_GUARDED_BY(recycled_mutex_);
153
154 /// @brief Creates a new |vk::CommandPool|.
155 ///
156 /// @returns Returns a |std::nullopt| if a pool could not be created.
157 std::optional<CommandPoolRecyclerVK::RecycledData> Create();
158
159 /// @brief Reuses a recycled |RecycledData|, if available.
160 ///
161 /// @returns Returns a |std::nullopt| if a pool was not available.
162 std::optional<RecycledData> Reuse();
163
165
166 CommandPoolRecyclerVK& operator=(const CommandPoolRecyclerVK&) = delete;
167};
168
169} // namespace impeller
170
171#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_COMMAND_POOL_VK_H_
Creates and manages the lifecycle of |vk::CommandPool| objects.
void Dispose()
Clears this context's thread-local command pool.
static int GetGlobalPoolCount(const ContextVK &context)
std::shared_ptr< CommandPoolVK > Get()
Gets a command pool for the current thread.
void DestroyThreadLocalPools()
Clean up resources held by all per-thread command pools associated with the context.
void Reclaim(vk::UniqueCommandPool &&pool, std::vector< vk::UniqueCommandBuffer > &&buffers, bool should_trim=false)
Returns a command pool to be reset on a background thread.
Manages the lifecycle of a single |vk::CommandPool|.
CommandPoolVK(vk::UniqueCommandPool pool, std::vector< vk::UniqueCommandBuffer > &&buffers, std::weak_ptr< ContextVK > context, std::weak_ptr< DeviceHolderVK > device_holder)
Creates a resource that manages the life of a command pool.
void CollectCommandBuffer(vk::UniqueCommandBuffer &&buffer)
Collects the given |vk::CommandBuffer| to be retained.
vk::UniqueCommandBuffer CreateCommandBuffer()
Creates and returns a new |vk::CommandBuffer|.
Definition ref_ptr.h:261
A unique command pool and zero or more recycled command buffers.
std::vector< vk::UniqueCommandBuffer > buffers
#define IPLR_GUARDED_BY(x)