| Flutter Impeller |

Public Member Functions | Static Public Attributes | List of all members
impeller::DescriptorPoolRecyclerVK Class Referencefinal

Creates and manages the lifecycle of |vk::DescriptorPoolVK| objects. More...

`#include <descriptor_pool_vk.h>`

Inheritance diagram for impeller::DescriptorPoolRecyclerVK:

## Public Member Functions
| ~DescriptorPoolRecyclerVK ()=default
| DescriptorPoolRecyclerVK (std::weak_ptr< ContextVK > context)
| Creates a recycler for the given |ContextVK|. More...
DescriptorPoolAndSize | Get (uint32_t minimum_capacity)
| Gets a descriptor pool with at least [minimum_capacity] sampler and slots. More...
void | Reclaim (vk::UniqueDescriptorPool &&pool, uint32_t allocated_capacity)
| Returns the descriptor pool to be reset on a background thread. More...

## Static Public Attributes
static constexpr size_t | kMaxRecycledPools = 32u
| The maximum number of descriptor pools this recycler will hold onto. More...

## Detailed Description

Creates and manages the lifecycle of |vk::DescriptorPoolVK| objects.

To make descriptor pool recycling more effective, the number of requusted descriptor slots is rounded up the nearest power of two. This also makes determining whether a recycled pool has sufficient slots easier as only a single number comparison is required.

We round up to a minimum of 64 as the smallest power of two to reduce the range of potential allocations to approximately: 64, 128, 256, 512, 1024, 2048, 4096. Beyond this size applications will have far too many drawing commands to render correctly. We also limit the number of cached descriptor pools to 32, which is somewhat arbitrarily chosen, but given 2-ish frames in flight is about 16 descriptors pools per frame which is extremely generous.

Definition at line 67 of file descriptor_pool_vk.h.

## Constructor & Destructor Documentation

## ◆ ~DescriptorPoolRecyclerVK()

impeller::DescriptorPoolRecyclerVK::~DescriptorPoolRecyclerVK | ( |  | ) |
| default

## ◆ DescriptorPoolRecyclerVK()

impeller::DescriptorPoolRecyclerVK::DescriptorPoolRecyclerVK | ( | std::weak_ptr< ContextVK > | context | ) |
| inline explicit

Creates a recycler for the given |ContextVK|.

Parameters

  [in] | context | The context to create the recycler for.

Definition at line 78 of file descriptor_pool_vk.h.

79 : context_(std::move(context)) {}

## Member Function Documentation

## ◆ Get()

DescriptorPoolAndSize impeller::DescriptorPoolRecyclerVK::Get | ( | uint32_t | minimum_capacity | ) |

Gets a descriptor pool with at least [minimum_capacity] sampler and slots.

This may create a new descriptor pool if no existing pools had the necessary capacity.

Definition at line 158 of file descriptor_pool_vk.cc.

158 {
159 // See note on DescriptorPoolRecyclerVK doc comment.
160 auto rounded_capacity =
161 std::max(Allocation::NextPowerOfTwoSize(minimum_capacity), 64u);
162
163 // Recycle a pool with a matching minumum capcity if it is available.
164 auto recycled_pool = Reuse(rounded_capacity);
165 if (recycled_pool.has_value()) {
166 return std::move(recycled_pool.value());
167 }
168 return Create(rounded_capacity);
169 }

References impeller::Allocation::NextPowerOfTwoSize().

## ◆ Reclaim()

void impeller::DescriptorPoolRecyclerVK::Reclaim | ( | vk::UniqueDescriptorPool && | pool,
|  | uint32_t | allocated_capacity
| ) |  |

Returns the descriptor pool to be reset on a background thread.

Parameters

  [in] | pool | The pool to recycler.

Definition at line 117 of file descriptor_pool_vk.cc.

118 {
119 // Reset the pool on a background thread.
120 auto strong_context = context_.lock();
121 if (!strong_context) {
122 return;
123 }
124 auto device = strong_context->GetDevice();
125 device.resetDescriptorPool(pool.get());
126
127 // Move the pool to the recycled list.
128 Lock recycled_lock(recycled_mutex_);
129
130 if (recycled_.size() < kMaxRecycledPools) {
131 recycled_.push_back(std::make_pair(std::move(pool), allocated_capacity));
132 return;
133 }
134
135 // If recycled has exceeded the max size of 32, then we need to remove a pool
136 // from the list. If we were to drop this pool, then there is a risk that
137 // the list of recycled descriptor pools could fill up with descriptors that
138 // are too small to reuse. This would lead to all subsequent descriptor
139 // allocations no longer being recycled. Instead, we pick the first
140 // descriptor pool with a smaller capacity than the reseting pool to drop.
141 // This may result in us dropping the current pool instead.
142 std::optional<size_t> selected_index = std::nullopt;
143 for (auto i = 0u; i < recycled_.size(); i++) {
144 const auto& [_, capacity] = recycled_[i];
145 if (capacity < allocated_capacity) {
146 selected_index = i;
147 break;
148 }
149 }
150 if (selected_index.has_value()) {
151 recycled_[selected_index.value()] =
152 std::make_pair(std::move(pool), allocated_capacity);
153 }
154 // If selected index has no value, then no pools had a smaller capacity than
155 // this one and we drop it instead.
156 }

References kMaxRecycledPools.

## Member Data Documentation

## ◆ kMaxRecycledPools

constexpr size_t impeller::DescriptorPoolRecyclerVK::kMaxRecycledPools = 32u
| static constexpr

The maximum number of descriptor pools this recycler will hold onto.

Definition at line 73 of file descriptor_pool_vk.h.

Referenced by Reclaim().

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

- impeller/renderer/backend/vulkan/descriptor_pool_vk.h
- impeller/renderer/backend/vulkan/descriptor_pool_vk.cc

impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:41
impeller::DescriptorPoolRecyclerVK::kMaxRecycledPools
static constexpr size_t kMaxRecycledPools
The maximum number of descriptor pools this recycler will hold onto.
Definition: descriptor_pool_vk.h:73