Flutter Impeller
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< CommandPoolVKGet ()
 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 }
void Dispose()
Clears all recycled command pools to let them be reclaimed.

References Dispose().

◆ CommandPoolRecyclerVK()

impeller::CommandPoolRecyclerVK::CommandPoolRecyclerVK ( std::weak_ptr< ContextVK context)
inlineexplicit

Creates a recycler for the given |ContextVK|.

Parameters
[in]contextThe 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]contextThe 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 }
static Mutex g_all_pools_map_mutex
static thread_local std::unique_ptr< CommandPoolMap > tls_command_pool_map

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 }
std::unordered_map< uint64_t, std::shared_ptr< CommandPoolVK > > CommandPoolMap

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()) {
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 }
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:67

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]poolThe pool to recycle.
[in]should_trimwhether 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: