From 0b28c198f7bf529d294742a7fe9bcde6b577b795 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 20 Aug 2026 13:02:29 +1000 Subject: [PATCH] FullscreenUI: Remove shared_ptr usage --- src/core/fullscreenui.cpp | 4 +- src/core/fullscreenui_game_list.cpp | 2 +- src/core/fullscreenui_widgets.cpp | 89 ++++++++++++++--------------- src/core/fullscreenui_widgets.h | 10 ++-- 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/core/fullscreenui.cpp b/src/core/fullscreenui.cpp index 1fde2962a..5076ba754 100644 --- a/src/core/fullscreenui.cpp +++ b/src/core/fullscreenui.cpp @@ -2316,7 +2316,7 @@ void FullscreenUI::DrawResumeStateSelector() TextAlignedMultiLine(0.5f, IMSTR_START_END(sick)); ImGui::PopFont(); - const GPUTexture* image = entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get(); + const GPUTexture* image = entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture(); const float image_height = LayoutScale(400.0f); const float image_width = image_height * (static_cast(image->GetWidth()) / static_cast(image->GetHeight())); @@ -2324,7 +2324,7 @@ void FullscreenUI::DrawResumeStateSelector() ImVec2((ImGui::GetCurrentWindow()->WorkRect.GetWidth() - image_width) * 0.5f, LayoutScale(20.0f))); const ImRect image_bb(pos, pos + ImVec2(image_width, image_height)); ImGui::GetWindowDrawList()->AddImage( - static_cast(entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get()), + static_cast(entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture()), image_bb.Min, image_bb.Max, ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), ImGui::GetColorU32(IM_COL32(255, 255, 255, 255))); diff --git a/src/core/fullscreenui_game_list.cpp b/src/core/fullscreenui_game_list.cpp index d34b30468..f506059b4 100644 --- a/src/core/fullscreenui_game_list.cpp +++ b/src/core/fullscreenui_game_list.cpp @@ -1161,7 +1161,7 @@ GPUTexture* FullscreenUI::GetGameListCoverTrophy(const GameList::Entry* entry, c static_cast(trophy_size.x), static_cast(trophy_size.y)); // don't draw the placeholder, it's way too large - return (texture == GetPlaceholderTexture().get()) ? nullptr : texture; + return (texture == GetPlaceholderTexture()) ? nullptr : texture; } std::string_view FullscreenUI::GetKeyForGameListEntry(const GameList::Entry* entry) diff --git a/src/core/fullscreenui_widgets.cpp b/src/core/fullscreenui_widgets.cpp index 11984ab72..1778aa623 100644 --- a/src/core/fullscreenui_widgets.cpp +++ b/src/core/fullscreenui_widgets.cpp @@ -87,11 +87,11 @@ enum class SplitWindowFocusChange : u8 static std::optional LoadTextureImage(std::string_view path, u32 svg_width, u32 svg_height); static std::optional LoadTextureImage(std::string_view filename, std::span buffer, u32 svg_width, u32 svg_height); -static std::shared_ptr UploadTexture(std::string_view path, const Image& image); +static std::unique_ptr UploadTexture(std::string_view path, const Image& image); static void QueueTextureUploadFromBuffer(std::string_view filename, const std::span& buffer, std::string&& insert_name, u32 svg_width, u32 svg_height, bool use_task_for_decode); -static std::shared_ptr LoadTexture(std::string_view path, std::string_view name, u32 svg_width, +static std::unique_ptr LoadTexture(std::string_view path, std::string_view name, u32 svg_width, u32 svg_height); static GPUTexture* LookupCachedTextureAsync(std::string_view path, std::string_view name, u32 svg_width, u32 svg_height); @@ -495,8 +495,8 @@ struct WidgetsState ImVec2 horizontal_menu_button_size = {}; - LRUCache> texture_cache{128, true}; - std::shared_ptr placeholder_texture; + LRUCache texture_cache{128, true}; + std::unique_ptr placeholder_texture; std::deque> texture_upload_queue; std::vector> texture_recycle_queue; @@ -732,9 +732,9 @@ GPUPipeline* FullscreenUI::GetPresentCopyPipeline() return s_state.present_copy_pipeline.get(); } -const std::shared_ptr& FullscreenUI::GetPlaceholderTexture() +GPUTexture* FullscreenUI::GetPlaceholderTexture() { - return s_state.placeholder_texture; + return s_state.placeholder_texture.get(); } std::optional FullscreenUI::LoadTextureImage(std::string_view path, u32 svg_width, u32 svg_height) @@ -831,7 +831,7 @@ std::optional FullscreenUI::LoadTextureImage(std::string_view filename, s return image; } -std::shared_ptr FullscreenUI::UploadTexture(std::string_view path, const Image& image) +std::unique_ptr FullscreenUI::UploadTexture(std::string_view path, const Image& image) { Error error; std::unique_ptr texture = @@ -843,7 +843,7 @@ std::shared_ptr FullscreenUI::UploadTexture(std::string_view path, c } DEV_LOG("Uploaded texture resource '{}' ({}x{})", path, image.GetWidth(), image.GetHeight()); - return std::shared_ptr(texture.release(), GPUDevice::PooledTextureDeleter()); + return texture; } void FullscreenUI::QueueTextureUploadFromBuffer(std::string_view filename, const std::span& buffer, @@ -873,7 +873,7 @@ void FullscreenUI::QueueTextureUploadFromBuffer(std::string_view filename, const s_state.texture_upload_queue.emplace_back(std::move(insert_name), std::move(image.value())); } -std::shared_ptr FullscreenUI::LoadTexture(std::string_view path, std::string_view name, u32 svg_width, +std::unique_ptr FullscreenUI::LoadTexture(std::string_view path, std::string_view name, u32 svg_width, u32 svg_height) { if (HTTPCache::IsHTTPURL(path)) @@ -900,11 +900,7 @@ std::shared_ptr FullscreenUI::LoadTexture(std::string_view path, std { const std::optional image = LoadTextureImage(filename, result.value().cspan(), svg_width, svg_height); if (image.has_value()) - { - std::shared_ptr ret = UploadTexture(path, image.value()); - if (ret) - return ret; - } + return UploadTexture(path, image.value()); } break; @@ -923,31 +919,27 @@ std::shared_ptr FullscreenUI::LoadTexture(std::string_view path, std DefaultCaseIsUnreachable(); } - return s_state.placeholder_texture; + return nullptr; } std::optional image(LoadTextureImage(path, svg_width, svg_height)); if (image.has_value()) - { - std::shared_ptr ret(UploadTexture(path, image.value())); - if (ret) - return ret; - } + return UploadTexture(path, image.value()); - return s_state.placeholder_texture; + return nullptr; } -std::shared_ptr FullscreenUI::LoadTexture(std::string_view name) +std::unique_ptr FullscreenUI::LoadTexture(std::string_view name) { return LoadTexture(name, {}, 0, 0); } -std::shared_ptr FullscreenUI::LoadTexture(std::string_view path, std::string_view name) +std::unique_ptr FullscreenUI::LoadTexture(std::string_view path, std::string_view name) { return LoadTexture(path, name, 0, 0); } -std::shared_ptr FullscreenUI::LoadTexture(std::string_view name, u32 svg_width, u32 svg_height) +std::unique_ptr FullscreenUI::LoadTexture(std::string_view name, u32 svg_width, u32 svg_height) { // ignore size hints if it's not needed, don't duplicate if (!TextureNeedsSVGDimensions(name)) @@ -957,15 +949,16 @@ std::shared_ptr FullscreenUI::LoadTexture(std::string_view name, u32 return LoadTexture(name, wh_name, svg_width, svg_height); } -std::shared_ptr FullscreenUI::LoadTexture(std::string_view name, const ImVec2& size) +std::unique_ptr FullscreenUI::LoadTexture(std::string_view name, const ImVec2& size) { return LoadTexture(name, name, static_cast(size.x), static_cast(size.y)); } GPUTexture* FullscreenUI::FindCachedTexture(std::string_view name) { - std::shared_ptr* tex_ptr = s_state.texture_cache.Lookup(name); - return tex_ptr ? tex_ptr->get() : nullptr; + // We want to return the placeholder if it's currently async loading. + GPUTexture** tex_ptr = s_state.texture_cache.Lookup(name); + return !tex_ptr ? nullptr : (*tex_ptr ? *tex_ptr : s_state.placeholder_texture.get()); } GPUTexture* FullscreenUI::FindCachedTexture(std::string_view name, u32 svg_width, u32 svg_height) @@ -975,8 +968,8 @@ GPUTexture* FullscreenUI::FindCachedTexture(std::string_view name, u32 svg_width return FindCachedTexture(name); const SmallString wh_name = SmallString::from_format("{}#{}x{}", name, svg_width, svg_height); - std::shared_ptr* tex_ptr = s_state.texture_cache.Lookup(wh_name.view()); - return tex_ptr ? tex_ptr->get() : nullptr; + GPUTexture** tex_ptr = s_state.texture_cache.Lookup(wh_name.view()); + return !tex_ptr ? nullptr : (*tex_ptr ? *tex_ptr : s_state.placeholder_texture.get()); } GPUTexture* FullscreenUI::FindCachedTexture(std::string_view name, const ImVec2& size) @@ -991,14 +984,15 @@ GPUTexture* FullscreenUI::GetCachedTexture(std::string_view name) GPUTexture* FullscreenUI::GetCachedTexture(std::string_view path, std::string_view name) { - std::shared_ptr* tex_ptr = s_state.texture_cache.Lookup(name); + GPUTexture** tex_ptr = s_state.texture_cache.Lookup(name); if (!tex_ptr) { - std::shared_ptr tex = LoadTexture(path); - tex_ptr = s_state.texture_cache.Insert(std::string(name), std::move(tex)); + std::unique_ptr tex = LoadTexture(path); + if (tex) + tex_ptr = s_state.texture_cache.Insert(std::string(name), tex.release()); } - return tex_ptr->get(); + return tex_ptr ? *tex_ptr : s_state.placeholder_texture.get(); } GPUTexture* FullscreenUI::GetCachedTexture(std::string_view name, u32 svg_width, u32 svg_height) @@ -1008,14 +1002,15 @@ GPUTexture* FullscreenUI::GetCachedTexture(std::string_view name, u32 svg_width, return GetCachedTexture(name); const SmallString wh_name = SmallString::from_format("{}#{}x{}", name, svg_width, svg_height); - std::shared_ptr* tex_ptr = s_state.texture_cache.Lookup(wh_name.view()); + GPUTexture** tex_ptr = s_state.texture_cache.Lookup(wh_name.view()); if (!tex_ptr) { - std::shared_ptr tex = LoadTexture(name, svg_width, svg_height); - tex_ptr = s_state.texture_cache.Insert(std::string(wh_name.view()), std::move(tex)); + std::unique_ptr tex = LoadTexture(name, svg_width, svg_height); + if (tex) + tex_ptr = s_state.texture_cache.Insert(std::string(wh_name.view()), tex.release()); } - return tex_ptr->get(); + return tex_ptr ? *tex_ptr : s_state.placeholder_texture.get(); } GPUTexture* FullscreenUI::GetCachedTexture(std::string_view name, const ImVec2& size) @@ -1027,12 +1022,12 @@ GPUTexture* FullscreenUI::LookupCachedTextureAsync(std::string_view path, std::s u32 svg_height) { const std::string_view lookup_name = name.empty() ? path : name; - std::shared_ptr* tex_ptr = s_state.texture_cache.Lookup(lookup_name); + GPUTexture** tex_ptr = s_state.texture_cache.Lookup(lookup_name); if (tex_ptr) - return tex_ptr->get(); + return *tex_ptr ? *tex_ptr : s_state.placeholder_texture.get(); - // insert the placeholder - tex_ptr = s_state.texture_cache.Insert(std::string(lookup_name), s_state.placeholder_texture); + // insert the placeholder so the load won't insert if it's already evicted + s_state.texture_cache.Insert(std::string(lookup_name), nullptr); // queue load Host::QueueAsyncTask([path = std::string(path), name = std::string(name), svg_width, svg_height]() mutable { @@ -1078,7 +1073,7 @@ GPUTexture* FullscreenUI::LookupCachedTextureAsync(std::string_view path, std::s } }); - return tex_ptr->get(); + return s_state.placeholder_texture.get(); } GPUTexture* FullscreenUI::GetCachedTextureAsync(std::string_view name) @@ -1127,9 +1122,13 @@ void FullscreenUI::UploadAsyncTextures() s_state.texture_upload_queue.pop_front(); lock.unlock(); - std::shared_ptr tex = UploadTexture(it.first.c_str(), it.second); - if (tex) - s_state.texture_cache.Insert(std::move(it.first), std::move(tex)); + // did it get evicted in the meantime? if so, don't bother uploading it + GPUTexture** tex_ptr = s_state.texture_cache.Lookup(it.first); + if (tex_ptr && !*tex_ptr) + { + std::unique_ptr tex = UploadTexture(it.first.c_str(), it.second); + *tex_ptr = *s_state.texture_cache.Insert(std::move(it.first), tex.release()); + } lock.lock(); } diff --git a/src/core/fullscreenui_widgets.h b/src/core/fullscreenui_widgets.h index 56ea770af..8fab461c5 100644 --- a/src/core/fullscreenui_widgets.h +++ b/src/core/fullscreenui_widgets.h @@ -256,11 +256,11 @@ void SetFont(ImFont* ui_font); bool UpdateLayoutScale(); /// Texture cache. -const std::shared_ptr& GetPlaceholderTexture(); -std::shared_ptr LoadTexture(std::string_view path); -std::shared_ptr LoadTexture(std::string_view path, std::string_view name); -std::shared_ptr LoadTexture(std::string_view path, u32 svg_width, u32 svg_height); -std::shared_ptr LoadTexture(std::string_view path, const ImVec2& size); +GPUTexture* GetPlaceholderTexture(); +std::unique_ptr LoadTexture(std::string_view path); +std::unique_ptr LoadTexture(std::string_view path, std::string_view name); +std::unique_ptr LoadTexture(std::string_view path, u32 svg_width, u32 svg_height); +std::unique_ptr LoadTexture(std::string_view path, const ImVec2& size); GPUTexture* FindCachedTexture(std::string_view name); GPUTexture* FindCachedTexture(std::string_view name, u32 svg_width, u32 svg_height); GPUTexture* FindCachedTexture(std::string_view name, const ImVec2& size);