Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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

void DestroyThreadLocalPools ()
 Clean up resources held by all per-thread command pools associated with the context.
 
 CommandPoolRecyclerVK (const std::shared_ptr< ContextVK > &context)
 Creates a recycler for the given |ContextVK|.
 
std::shared_ptr< CommandPoolVKGet ()
 Gets a command pool for the current thread.
 
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.
 
void Dispose ()
 Clears this context's thread-local command pool.
 

Static Public Member Functions

static int GetGlobalPoolCount (const ContextVK &context)
 

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

Constructor & Destructor Documentation

◆ CommandPoolRecyclerVK()

impeller::CommandPoolRecyclerVK::CommandPoolRecyclerVK ( const std::shared_ptr< ContextVK > &  context)
explicit

Creates a recycler for the given |ContextVK|.

Parameters
[in]contextThe context to create the recycler for.

Definition at line 191 of file command_pool_vk.cc.

193 : context_(context), context_hash_(context->GetHash()) {}

Member Function Documentation

◆ DestroyThreadLocalPools()

void impeller::CommandPoolRecyclerVK::DestroyThreadLocalPools ( )

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

Definition at line 320 of file command_pool_vk.cc.

320 {
321 // Delete the context's entry in this thread's command pool map.
322 if (tls_command_pool_map.get()) {
323 tls_command_pool_map.get()->erase(context_hash_);
324 }
325
326 // Destroy all other thread-local CommandPoolVK instances associated with
327 // this context.
328 Lock all_pools_lock(g_all_pools_map_mutex);
329 auto found = g_all_pools_map.find(context_hash_);
330 if (found != g_all_pools_map.end()) {
331 for (auto& [thread_id, weak_pool] : found->second) {
332 auto pool = weak_pool.lock();
333 if (!pool) {
334 continue;
335 }
336 // Delete all objects held by this pool. The destroyed pool will still
337 // remain in its thread's TLS map until that thread exits.
338 pool->Destroy();
339 }
340 g_all_pools_map.erase(found);
341 }
342}
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, and impeller::tls_command_pool_map.

◆ Dispose()

void impeller::CommandPoolRecyclerVK::Dispose ( )

Clears this context's thread-local command pool.

Definition at line 305 of file command_pool_vk.cc.

305 {
306 CommandPoolMap* pool_map = tls_command_pool_map.get();
307 if (pool_map) {
308 pool_map->erase(context_hash_);
309 }
310
311 {
312 Lock all_pools_lock(g_all_pools_map_mutex);
313 auto found = g_all_pools_map.find(context_hash_);
314 if (found != g_all_pools_map.end()) {
315 found->second.erase(std::this_thread::get_id());
316 }
317 }
318}
std::unordered_map< uint64_t, std::shared_ptr< CommandPoolVK > > CommandPoolMap

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

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

204 {
205 auto const strong_context = context_.lock();
206 if (!strong_context) {
207 return nullptr;
208 }
209
210 // If there is a resource in used for this thread and context, return it.
211 if (!tls_command_pool_map.get()) {
213 }
214 CommandPoolMap& pool_map = *tls_command_pool_map.get();
215 auto const it = pool_map.find(context_hash_);
216 if (it != pool_map.end()) {
217 return it->second;
218 }
219
220 // Otherwise, create a new resource and return it.
221 auto data = Create();
222 if (!data || !data->pool) {
223 return nullptr;
224 }
225
226 auto const resource = std::make_shared<CommandPoolVK>(
227 std::move(data->pool), std::move(data->buffers), context_,
228 strong_context->GetDeviceHolder());
229 pool_map.emplace(context_hash_, resource);
230
231 {
232 Lock all_pools_lock(g_all_pools_map_mutex);
233 g_all_pools_map[context_hash_][std::this_thread::get_id()] = resource;
234 }
235
236 return resource;
237}
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36

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

◆ GetGlobalPoolCount()

int impeller::CommandPoolRecyclerVK::GetGlobalPoolCount ( const ContextVK context)
static

Definition at line 197 of file command_pool_vk.cc.

197 {
198 Lock all_pools_lock(g_all_pools_map_mutex);
199 auto it = g_all_pools_map.find(context.GetHash());
200 return it != g_all_pools_map.end() ? it->second.size() : 0;
201}

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

Referenced by impeller::testing::TEST(), and flutter::testing::TEST().

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

282 {
283 // Reset the pool on a background thread.
284 auto strong_context = context_.lock();
285 if (!strong_context) {
286 return;
287 }
288 auto device = strong_context->GetDevice();
289 vk::CommandPoolResetFlags flags;
290 if (should_trim) {
291 buffers.clear();
292 flags = vk::CommandPoolResetFlagBits::eReleaseResources;
293 }
294 const auto result = device.resetCommandPool(pool.get(), flags);
295 if (result != vk::Result::eSuccess) {
296 VALIDATION_LOG << "Could not reset command pool: " << vk::to_string(result);
297 }
298
299 // Move the pool to the recycled list.
300 Lock recycled_lock(recycled_mutex_);
301 recycled_.push_back(
302 RecycledData{.pool = std::move(pool), .buffers = std::move(buffers)});
303}
VkDevice device
Definition main.cc:69
#define VALIDATION_LOG
Definition validation.h:91

References device, impeller::CommandPoolRecyclerVK::RecycledData::pool, and VALIDATION_LOG.


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