| Flutter Impeller |

Classes | Public Member Functions | Static Public Member Functions | List of all members
impeller::CommandPoolRecyclerVK Class Referencefinal

Creates and manages the lifecycle of |vk::CommandPool| objects. More...

`#include <command_pool_vk.h>`

Inheritance diagram for impeller::CommandPoolRecyclerVK:

## Classes
struct | RecycledData
| A unique command pool and zero or more recycled command buffers. More...

## Public Member Functions
| ~CommandPoolRecyclerVK ()
| CommandPoolRecyclerVK (std::weak_ptr< ContextVK > context)
| Creates a recycler for the given |ContextVK|. More...
std::shared_ptr< CommandPoolVK > | Get ()
| Gets a command pool for the current thread. More...
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. More...
void | Dispose ()
| Clears all recycled command pools to let them be reclaimed. More...

## Static Public Member Functions
static void | DestroyThreadLocalPools (const ContextVK *context)
| Clean up resources held by all per-thread command pools associated with the given context. More...

## Detailed Description

Creates and manages the lifecycle of |vk::CommandPool| objects.

A |vk::CommandPool| is expensive to create and reset. This class manages the lifecycle of |vk::CommandPool| objects by creating and recycling them; or in other words, a pool for command pools.

A single instance should be created per |ContextVK|.

Every "frame", a single |CommandPoolResourceVk| is made available for each thread that calls |Get|. After calling |Dispose|, the current thread's pool is moved to a background thread, reset, and made available for the next time |Get| is called and needs to create a command pool.

Commands in the command pool are not necessarily done executing when the pool is recycled, when all references are dropped to the pool, they are reset and returned to the pool of available pools.

Note
  This class is thread-safe.

See also
  |vk::CommandPoolResourceVk|
  |ContextVK|
  https://arm-software.github.io/vulkan_best_practice_for_mobile_developers/samples/performance/command_buffer_usage/command_buffer_usage_tutorial.html

Definition at line 103 of file command_pool_vk.h.

## Constructor & Destructor Documentation

## ◆ ~CommandPoolRecyclerVK()

impeller::CommandPoolRecyclerVK::~CommandPoolRecyclerVK | ( |  | ) |

Definition at line 278 of file command_pool_vk.cc.

278 {
279 // Ensure all recycled pools are reclaimed before this is destroyed.
280 Dispose();
281 }
impeller::CommandPoolRecyclerVK::Dispose
void Dispose()
Clears all recycled command pools to let them be reclaimed.
Definition: command_pool_vk.cc:283

References Dispose().

## ◆ CommandPoolRecyclerVK()

impeller::CommandPoolRecyclerVK::CommandPoolRecyclerVK | ( | std::weak_ptr< ContextVK > | context | ) |
| inline explicit

Creates a recycler for the given |ContextVK|.

Parameters

  [in] | context | The context to create the recycler for.

Definition at line 123 of file command_pool_vk.h.

124 : context_(std::move(context)) {}

## Member Function Documentation

## ◆ DestroyThreadLocalPools()

void impeller::CommandPoolRecyclerVK::DestroyThreadLocalPools | ( | const ContextVK * | context | ) |
| static

Clean up resources held by all per-thread command pools associated with the given context.

Parameters

  [in] | context | The context.

Definition at line 290 of file command_pool_vk.cc.

290 {
291 // Delete the context's entry in this thread's command pool map.
292 if (tls_command_pool_map.get()) {
293 tls_command_pool_map.get()->erase(context->GetHash());
294 }
295
296 // Destroy all other thread-local CommandPoolVK instances associated with
297 // this context.
298 Lock all_pools_lock(g_all_pools_map_mutex);
299 auto found = g_all_pools_map.find(context);
300 if (found != g_all_pools_map.end()) {
301 for (auto& weak_pool : found->second) {
302 auto pool = weak_pool.lock();
303 if (!pool) {
304 continue;
305 }
306 // Delete all objects held by this pool. The destroyed pool will still
307 // remain in its thread's TLS map until that thread exits.
308 pool->Destroy();
309 }
310 g_all_pools_map.erase(found);
311 }
312 }
impeller::g_all_pools_map_mutex
static Mutex g_all_pools_map_mutex
Definition: command_pool_vk.cc:172
impeller::tls_command_pool_map
static thread_local std::unique_ptr< CommandPoolMap > tls_command_pool_map
Definition: command_pool_vk.cc:168

References impeller::g_all_pools_map_mutex, impeller::ContextVK::GetHash(), and impeller::tls_command_pool_map.

Referenced by impeller::ContextVK::~ContextVK().

## ◆ Dispose()

void impeller::CommandPoolRecyclerVK::Dispose | ( |  | ) |

Clears all recycled command pools to let them be reclaimed.

Definition at line 283 of file command_pool_vk.cc.

283 {
284 CommandPoolMap* pool_map = tls_command_pool_map.get();
285 if (pool_map) {
286 pool_map->clear();
287 }
288 }
impeller::CommandPoolMap
std::unordered_map< uint64_t, std::shared_ptr< CommandPoolVK > > CommandPoolMap
Definition: command_pool_vk.cc:158

References impeller::tls_command_pool_map.

Referenced by ~CommandPoolRecyclerVK().

## ◆ Get()

std::shared_ptr< CommandPoolVK > impeller::CommandPoolRecyclerVK::Get | ( |  | ) |

Gets a command pool for the current thread.

Warning
  Returns a |nullptr| if a pool could not be created.

Definition at line 179 of file command_pool_vk.cc.

179 {
180 auto const strong_context = context_.lock();
181 if (!strong_context) {
182 return nullptr;
183 }
184
185 // If there is a resource in used for this thread and context, return it.
186 if (!tls_command_pool_map.get()) {
187 tls_command_pool_map.reset(new CommandPoolMap());
188 }
189 CommandPoolMap& pool_map = *tls_command_pool_map.get();
190 auto const hash = strong_context->GetHash();
191 auto const it = pool_map.find(hash);
192 if (it != pool_map.end()) {
193 return it->second;
194 }
195
196 // Otherwise, create a new resource and return it.
197 auto data = Create();
198 if (!data || !data->pool) {
199 return nullptr;
200 }
201
202 auto const resource = std::make_shared<CommandPoolVK>(
203 std::move(data->pool), std::move(data->buffers), context_);
204 pool_map.emplace(hash, resource);
205
206 {
207 Lock all_pools_lock(g_all_pools_map_mutex);
208 g_all_pools_map[strong_context.get()].push_back(resource);
209 }
210
211 return resource;
212 }
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:64

References data, impeller::g_all_pools_map_mutex, and impeller::tls_command_pool_map.

## ◆ Reclaim()

void impeller::CommandPoolRecyclerVK::Reclaim | ( | vk::UniqueCommandPool && | pool,
|  | std::vector< vk::UniqueCommandBuffer > && | buffers,
|  | bool | should_trim = `false`
| ) |  |

Returns a command pool to be reset on a background thread.

Parameters

  [in] | pool | The pool to recycle.
  [in] | should_trim | whether to trim command pool memory before reseting.

Definition at line 254 of file command_pool_vk.cc.

257 {
258 // Reset the pool on a background thread.
259 auto strong_context = context_.lock();
260 if (!strong_context) {
261 return;
262 }
263 auto device = strong_context->GetDevice();
264 if (should_trim) {
265 buffers.clear();
266 device.resetCommandPool(pool.get(),
267 vk::CommandPoolResetFlagBits::eReleaseResources);
268 } else {
269 device.resetCommandPool(pool.get(), {});
270 }
271
272 // Move the pool to the recycled list.
273 Lock recycled_lock(recycled_mutex_);
274 recycled_.push_back(
275 RecycledData{.pool = std::move(pool), .buffers = std::move(buffers)});
276 }

References impeller::CommandPoolRecyclerVK::RecycledData::pool.

The documentation for this class was generated from the following files:

- impeller/renderer/backend/vulkan/command_pool_vk.h
- impeller/renderer/backend/vulkan/command_pool_vk.cc