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:

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)
 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 95 of file command_pool_vk.h.

Constructor & Destructor Documentation

◆ ~CommandPoolRecyclerVK()

impeller::CommandPoolRecyclerVK::~CommandPoolRecyclerVK ( )

Definition at line 232 of file command_pool_vk.cc.

232  {
233  // Ensure all recycled pools are reclaimed before this is destroyed.
234  Dispose();
235 }

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 109 of file command_pool_vk.h.

110  : 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 244 of file command_pool_vk.cc.

244  {
245  // Delete the context's entry in this thread's command pool map.
246  if (tls_command_pool_map.get()) {
247  tls_command_pool_map.get()->erase(context->GetHash());
248  }
249 
250  // Destroy all other thread-local CommandPoolVK instances associated with
251  // this context.
252  Lock all_pools_lock(g_all_pools_map_mutex);
253  auto found = g_all_pools_map.find(context);
254  if (found != g_all_pools_map.end()) {
255  for (auto& weak_pool : found->second) {
256  auto pool = weak_pool.lock();
257  if (!pool) {
258  continue;
259  }
260  // Delete all objects held by this pool. The destroyed pool will still
261  // remain in its thread's TLS map until that thread exits.
262  pool->Destroy();
263  }
264  g_all_pools_map.erase(found);
265  }
266 }

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 237 of file command_pool_vk.cc.

237  {
238  CommandPoolMap* pool_map = tls_command_pool_map.get();
239  if (pool_map) {
240  pool_map->clear();
241  }
242 }

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 144 of file command_pool_vk.cc.

144  {
145  auto const strong_context = context_.lock();
146  if (!strong_context) {
147  return nullptr;
148  }
149 
150  // If there is a resource in used for this thread and context, return it.
151  if (!tls_command_pool_map.get()) {
153  }
154  CommandPoolMap& pool_map = *tls_command_pool_map.get();
155  auto const hash = strong_context->GetHash();
156  auto const it = pool_map.find(hash);
157  if (it != pool_map.end()) {
158  return it->second;
159  }
160 
161  // Otherwise, create a new resource and return it.
162  auto pool = Create();
163  if (!pool) {
164  return nullptr;
165  }
166 
167  auto const resource =
168  std::make_shared<CommandPoolVK>(std::move(*pool), context_);
169  pool_map.emplace(hash, resource);
170 
171  {
172  Lock all_pools_lock(g_all_pools_map_mutex);
173  g_all_pools_map[strong_context.get()].push_back(resource);
174  }
175 
176  return resource;
177 }

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

◆ Reclaim()

void impeller::CommandPoolRecyclerVK::Reclaim ( vk::UniqueCommandPool &&  pool)

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

Parameters
[in]poolThe pool to recycler.

Definition at line 216 of file command_pool_vk.cc.

216  {
217  TRACE_EVENT0("impeller", "ReclaimCommandPool");
218 
219  // Reset the pool on a background thread.
220  auto strong_context = context_.lock();
221  if (!strong_context) {
222  return;
223  }
224  auto device = strong_context->GetDevice();
225  device.resetCommandPool(pool.get());
226 
227  // Move the pool to the recycled list.
228  Lock recycled_lock(recycled_mutex_);
229  recycled_.push_back(std::move(pool));
230 }

The documentation for this class was generated from the following files:
impeller::CommandPoolMap
std::unordered_map< uint64_t, std::shared_ptr< CommandPoolVK > > CommandPoolMap
Definition: command_pool_vk.cc:133
impeller::g_all_pools_map_mutex
static Mutex g_all_pools_map_mutex
Definition: command_pool_vk.cc:138
impeller::CommandPoolRecyclerVK::Dispose
void Dispose()
Clears all recycled command pools to let them be reclaimed.
Definition: command_pool_vk.cc:237
impeller::tls_command_pool_map
FML_THREAD_LOCAL fml::ThreadLocalUniquePtr< CommandPoolMap > tls_command_pool_map
Definition: command_pool_vk.cc:134