Flutter Impeller
impeller::CommandPoolVK Class Referencefinal

Manages the lifecycle of a single |vk::CommandPool|. More...

#include <command_pool_vk.h>

Public Member Functions

 ~CommandPoolVK ()
 
 CommandPoolVK (vk::UniqueCommandPool pool, std::vector< vk::UniqueCommandBuffer > &&buffers, std::weak_ptr< ContextVK > &context)
 Creates a resource that manages the life of a command pool. More...
 
vk::UniqueCommandBuffer CreateCommandBuffer ()
 Creates and returns a new |vk::CommandBuffer|. More...
 
void CollectCommandBuffer (vk::UniqueCommandBuffer &&buffer)
 Collects the given |vk::CommandBuffer| to be retained. More...
 
void Destroy ()
 Delete all Vulkan objects in this command pool. More...
 

Detailed Description

Manages the lifecycle of a single |vk::CommandPool|.

A |vk::CommandPool| is expensive to create and reset. This class manages the lifecycle of a single |vk::CommandPool| by returning to the origin (|CommandPoolRecyclerVK|) when it is destroyed to be reused.

Warning
This class is not thread-safe.
See also
|CommandPoolRecyclerVK|

Definition at line 31 of file command_pool_vk.h.

Constructor & Destructor Documentation

◆ ~CommandPoolVK()

impeller::CommandPoolVK::~CommandPoolVK ( )

Definition at line 72 of file command_pool_vk.cc.

72  {
73  if (!pool_) {
74  return;
75  }
76 
77  auto const context = context_.lock();
78  if (!context) {
79  return;
80  }
81  auto const recycler = context->GetCommandPoolRecycler();
82  if (!recycler) {
83  return;
84  }
85  // Any unused command buffers are added to the set of used command buffers.
86  // both will be reset to the initial state when the pool is reset.
87  size_t unused_count = unused_command_buffers_.size();
88  for (auto i = 0u; i < unused_command_buffers_.size(); i++) {
89  collected_buffers_.push_back(std::move(unused_command_buffers_[i]));
90  }
91  unused_command_buffers_.clear();
92 
93  auto reset_pool_when_dropped = BackgroundCommandPoolVK(
94  std::move(pool_), std::move(collected_buffers_), unused_count, recycler);
95 
96  UniqueResourceVKT<BackgroundCommandPoolVK> pool(
97  context->GetResourceManager(), std::move(reset_pool_when_dropped));
98 }

◆ CommandPoolVK()

impeller::CommandPoolVK::CommandPoolVK ( vk::UniqueCommandPool  pool,
std::vector< vk::UniqueCommandBuffer > &&  buffers,
std::weak_ptr< ContextVK > &  context 
)
inline

Creates a resource that manages the life of a command pool.

Parameters
[in]poolThe command pool to manage.
[in]buffersZero or more command buffers in an initial state.
[in]recyclerThe context that will be notified on destruction.

Definition at line 40 of file command_pool_vk.h.

43  : pool_(std::move(pool)),
44  unused_command_buffers_(std::move(buffers)),
45  context_(context) {}

Member Function Documentation

◆ CollectCommandBuffer()

void impeller::CommandPoolVK::CollectCommandBuffer ( vk::UniqueCommandBuffer &&  buffer)

Collects the given |vk::CommandBuffer| to be retained.

Parameters
[in]bufferThe |vk::CommandBuffer| to collect.
See also
|GarbageCollectBuffersIfAble|

Definition at line 129 of file command_pool_vk.cc.

129  {
130  Lock lock(pool_mutex_);
131  if (!pool_) {
132  // If the command pool has already been destroyed, then its buffers have
133  // already been freed.
134  buffer.release();
135  return;
136  }
137  collected_buffers_.push_back(std::move(buffer));
138 }

◆ CreateCommandBuffer()

vk::UniqueCommandBuffer impeller::CommandPoolVK::CreateCommandBuffer ( )

Creates and returns a new |vk::CommandBuffer|.

Returns
Always returns a new |vk::CommandBuffer|, but if for any reason a valid command buffer could not be created, it will be a {} default instance (i.e. while being torn down).

Definition at line 101 of file command_pool_vk.cc.

101  {
102  auto const context = context_.lock();
103  if (!context) {
104  return {};
105  }
106 
107  Lock lock(pool_mutex_);
108  if (!pool_) {
109  return {};
110  }
111  if (!unused_command_buffers_.empty()) {
112  vk::UniqueCommandBuffer buffer = std::move(unused_command_buffers_.back());
113  unused_command_buffers_.pop_back();
114  return buffer;
115  }
116 
117  auto const device = context->GetDevice();
118  vk::CommandBufferAllocateInfo info;
119  info.setCommandPool(pool_.get());
120  info.setCommandBufferCount(1u);
121  info.setLevel(vk::CommandBufferLevel::ePrimary);
122  auto [result, buffers] = device.allocateCommandBuffersUnique(info);
123  if (result != vk::Result::eSuccess) {
124  return {};
125  }
126  return std::move(buffers[0]);
127 }

◆ Destroy()

void impeller::CommandPoolVK::Destroy ( )

Delete all Vulkan objects in this command pool.

Definition at line 140 of file command_pool_vk.cc.

140  {
141  Lock lock(pool_mutex_);
142  pool_.reset();
143 
144  // When the command pool is destroyed, all of its command buffers are freed.
145  // Handles allocated from that pool are now invalid and must be discarded.
146  for (auto& buffer : collected_buffers_) {
147  buffer.release();
148  }
149  for (auto& buffer : unused_command_buffers_) {
150  buffer.release();
151  }
152  unused_command_buffers_.clear();
153  collected_buffers_.clear();
154 }

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