99#include < utility>
1010
1111#include " impeller/renderer/backend/vulkan/context_vk.h"
12- #include " impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
1312#include " impeller/renderer/backend/vulkan/resource_manager_vk.h"
1413
1514#include " impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep.
@@ -156,6 +155,10 @@ void CommandPoolVK::Destroy() {
156155 collected_buffers_.clear ();
157156}
158157
158+ // Associates a resource with a thread and context.
159+ using CommandPoolMap =
160+ std::unordered_map<uint64_t , std::shared_ptr<CommandPoolVK>>;
161+
159162// CommandPoolVK Lifecycle:
160163// 1. End of frame will reset the command pool (clearing this on a thread).
161164// There will still be references to the command pool from the uncompleted
@@ -166,47 +169,17 @@ void CommandPoolVK::Destroy() {
166169// available for reuse ("recycle").
167170static thread_local std::unique_ptr<CommandPoolMap> tls_command_pool_map;
168171
169- struct WeakThreadLocalData {
170- std::weak_ptr<CommandPoolVK> command_pool;
171- std::weak_ptr<DescriptorPoolVK> descriptor_pool;
172- };
173-
174172// Map each context to a list of all thread-local command pools associated
175173// with that context.
176174static Mutex g_all_pools_map_mutex;
177- static std::unordered_map<const ContextVK*,
178- std::vector<WeakThreadLocalData>> g_all_pools_map
175+ static std::unordered_map<
176+ const ContextVK*,
177+ std::vector<std::weak_ptr<CommandPoolVK>>> g_all_pools_map
179178 IPLR_GUARDED_BY (g_all_pools_map_mutex);
180179
181- std::shared_ptr<DescriptorPoolVK> CommandPoolRecyclerVK::GetDescriptorPool () {
182- const auto & 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 ()) {
189- tls_command_pool_map.reset (new CommandPoolMap ());
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 .descriptor_pool ;
196- }
197-
198- const auto & result =
199- InitializeThreadLocalResources (strong_context, pool_map, hash);
200- if (result.has_value ()) {
201- return result->descriptor_pool ;
202- }
203-
204- return nullptr ;
205- }
206-
207180// TODO(matanlurey): Return a status_or<> instead of nullptr when we have one.
208181std::shared_ptr<CommandPoolVK> CommandPoolRecyclerVK::Get () {
209- const auto & strong_context = context_.lock ();
182+ auto const strong_context = context_.lock ();
210183 if (!strong_context) {
211184 return nullptr ;
212185 }
@@ -219,40 +192,25 @@ std::shared_ptr<CommandPoolVK> CommandPoolRecyclerVK::Get() {
219192 auto const hash = strong_context->GetHash ();
220193 auto const it = pool_map.find (hash);
221194 if (it != pool_map.end ()) {
222- return it->second . command_pool ;
195+ return it->second ;
223196 }
224197
225- const auto & result =
226- InitializeThreadLocalResources (strong_context, pool_map, hash);
227- if (result.has_value ()) {
228- return result->command_pool ;
229- }
230-
231- return nullptr ;
232- }
233-
234- std::optional<ThreadLocalData>
235- CommandPoolRecyclerVK::InitializeThreadLocalResources (
236- const std::shared_ptr<ContextVK>& context,
237- CommandPoolMap& pool_map,
238- uint64_t pool_key) {
198+ // Otherwise, create a new resource and return it.
239199 auto data = Create ();
240200 if (!data || !data->pool ) {
241- return std:: nullopt ;
201+ return nullptr ;
242202 }
243203
244- auto command_pool = std::make_shared<CommandPoolVK>(
204+ auto const resource = std::make_shared<CommandPoolVK>(
245205 std::move (data->pool ), std::move (data->buffers ), context_);
246- auto descriptor_pool = std::make_shared<DescriptorPoolVK>(context_);
206+ pool_map.emplace (hash, resource);
207+
247208 {
248209 Lock all_pools_lock (g_all_pools_map_mutex);
249- g_all_pools_map[context.get ()].push_back (WeakThreadLocalData{
250- .command_pool = command_pool, .descriptor_pool = descriptor_pool});
210+ g_all_pools_map[strong_context.get ()].push_back (resource);
251211 }
252212
253- return pool_map[pool_key] =
254- ThreadLocalData{.command_pool = std::move (command_pool),
255- .descriptor_pool = std::move (descriptor_pool)};
213+ return resource;
256214}
257215
258216// TODO(matanlurey): Return a status_or<> instead of nullopt when we have one.
@@ -335,13 +293,14 @@ void CommandPoolRecyclerVK::DestroyThreadLocalPools(const ContextVK* context) {
335293 Lock all_pools_lock (g_all_pools_map_mutex);
336294 auto found = g_all_pools_map.find (context);
337295 if (found != g_all_pools_map.end ()) {
338- for (auto & [command_pool, desc_pool] : found->second ) {
339- const auto & strong_pool = command_pool.lock ();
340- if (strong_pool) {
341- // Delete all objects held by this pool. The destroyed pool will still
342- // remain in its thread's TLS map until that thread exits.
343- strong_pool->Destroy ();
296+ for (auto & weak_pool : found->second ) {
297+ auto pool = weak_pool.lock ();
298+ if (!pool) {
299+ continue ;
344300 }
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 ();
345304 }
346305 g_all_pools_map.erase (found);
347306 }
0 commit comments