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

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

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

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

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

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

◆ Destroy()

void impeller::CommandPoolVK::Destroy ( )

Delete all Vulkan objects in this command pool.

Definition at line 142 of file command_pool_vk.cc.

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

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