Flutter Engine
The Flutter Engine
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< CommandPoolVKGet ()
 Gets a command pool for the current thread. More...
 
void Reclaim (vk::UniqueCommandPool &&pool, std::vector< vk::UniqueCommandBuffer > &&buffers)
 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 273 of file command_pool_vk.cc.

273 {
274 // Ensure all recycled pools are reclaimed before this is destroyed.
275 Dispose();
276}
void Dispose()
Clears all recycled command pools to let them be reclaimed.

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

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

◆ Dispose()

void impeller::CommandPoolRecyclerVK::Dispose ( )

Clears all recycled command pools to let them be reclaimed.

Definition at line 278 of file command_pool_vk.cc.

278 {
279 CommandPoolMap* pool_map = tls_command_pool_map.get();
280 if (pool_map) {
281 pool_map->clear();
282 }
283}
std::unordered_map< uint64_t, std::shared_ptr< CommandPoolVK > > CommandPoolMap

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

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

◆ Reclaim()

void impeller::CommandPoolRecyclerVK::Reclaim ( vk::UniqueCommandPool &&  pool,
std::vector< vk::UniqueCommandBuffer > &&  buffers 
)

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

Parameters
[in]poolThe pool to recycler.

Definition at line 256 of file command_pool_vk.cc.

258 {
259 // Reset the pool on a background thread.
260 auto strong_context = context_.lock();
261 if (!strong_context) {
262 return;
263 }
264 auto device = strong_context->GetDevice();
265 device.resetCommandPool(pool.get());
266
267 // Move the pool to the recycled list.
268 Lock recycled_lock(recycled_mutex_);
269 recycled_.push_back(
270 RecycledData{.pool = std::move(pool), .buffers = std::move(buffers)});
271}
VkDevice device
Definition: main.cc:53

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