diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp index f66d805354..5ecb783f99 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" -#include "Emu/RSX/GSRender.h" +#include "Emu/RSX/Overlays/overlays.h" #include "cellSysutil.h" #include "cellMsgDialog.h" @@ -75,24 +75,21 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptr()) + if (auto manager = fxm::get()) { - if (auto dlg = rsxthr->shell_open_message_dialog()) + manager->create()->show(msgString.get_ptr(), _type, [callback, userData](s32 status) { - dlg->show(msgString.get_ptr(), _type, [callback, userData](s32 status) + if (callback) { - if (callback) + sysutil_register_cb([=](ppu_thread& ppu) -> s32 { - sysutil_register_cb([=](ppu_thread& ppu) -> s32 - { - callback(ppu, status, userData); - return CELL_OK; - }); - } - }); + callback(ppu, status, userData); + return CELL_OK; + }); + } + }); - return CELL_OK; - } + return CELL_OK; } const auto dlg = fxm::import(Emu.GetCallbacks().get_msg_dialog); @@ -237,9 +234,9 @@ s32 cellMsgDialogClose(f32 delay) extern u64 get_system_time(); const u64 wait_until = get_system_time() + static_cast(std::max(delay, 0.0f) * 1000); - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (auto dlg = rsxthr->shell_get_current_dialog()) + if (auto dlg = manager->get()) { thread_ctrl::spawn("cellMsgDialogClose() Thread", [=] { @@ -248,7 +245,7 @@ s32 cellMsgDialogClose(f32 delay) if (Emu.IsStopped()) return; - if (rsxthr->shell_get_current_dialog() != dlg) + if (manager->get() != dlg) return; std::this_thread::sleep_for(1ms); @@ -287,10 +284,11 @@ s32 cellMsgDialogAbort() { cellSysutil.warning("cellMsgDialogAbort()"); - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (rsxthr->shell_close_dialog()) + if (auto dlg = manager->get()) { + dlg->close(); return CELL_OK; } } @@ -320,12 +318,11 @@ s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::cptr msgStrin return CELL_MSGDIALOG_ERROR_PARAM; } - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (auto dlg2 = rsxthr->shell_get_current_dialog()) + if (auto dlg = manager->get()) { - if (auto casted = dynamic_cast(dlg2)) - return casted->progress_bar_set_message(progressBarIndex, msgString.get_ptr()); + return dlg->progress_bar_set_message(progressBarIndex, msgString.get_ptr()); } } @@ -353,12 +350,11 @@ s32 cellMsgDialogProgressBarReset(u32 progressBarIndex) { cellSysutil.warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex); - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (auto dlg2 = rsxthr->shell_get_current_dialog()) + if (auto dlg = manager->get()) { - if (auto casted = dynamic_cast(dlg2)) - return casted->progress_bar_reset(progressBarIndex); + return dlg->progress_bar_reset(progressBarIndex); } } @@ -386,12 +382,11 @@ s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta) { cellSysutil.warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta); - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (auto dlg2 = rsxthr->shell_get_current_dialog()) + if (auto dlg = manager->get()) { - if (auto casted = dynamic_cast(dlg2)) - return casted->progress_bar_increment(progressBarIndex, (f32)delta); + return dlg->progress_bar_increment(progressBarIndex, (f32)delta); } } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 61fdd998fd..ee13c470f9 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -847,7 +847,7 @@ void GLGSRender::on_init_thread() type.disable_cancel = true; type.progress_bar_count = 1; - dlg = owner->shell_open_message_dialog(); + dlg = fxm::get()->create(); dlg->show("Loading precompiled shaders from disk...", type, [](s32 status) { if (status != CELL_OK) @@ -1113,15 +1113,18 @@ void GLGSRender::load_program(const gl::vertex_upload_info& upload_info) //Notify the user with HUD notification if (g_cfg.misc.show_shader_compilation_hint) { - if (!m_custom_ui) + if (m_overlay_manager) { - //Create notification but do not draw it at this time. No need to spam flip requests - m_custom_ui = std::make_unique(); - } - else if (auto casted = dynamic_cast(m_custom_ui.get())) - { - //Probe the notification - casted->touch(); + if (auto dlg = m_overlay_manager->get()) + { + //Extend duration + dlg->touch(); + } + else + { + //Create dialog but do not show immediately + m_overlay_manager->create(); + } } } } @@ -1461,11 +1464,28 @@ void GLGSRender::flip(int buffer) } } - if (m_custom_ui) + if (m_overlay_manager) { - gl::screen.bind(); - glViewport(0, 0, m_frame->client_width(), m_frame->client_height()); - m_ui_renderer.run(m_frame->client_width(), m_frame->client_height(), 0, *m_custom_ui.get()); + if (m_overlay_manager->has_dirty()) + { + for (const auto& uid : m_overlay_manager->get_dirty()) + { + m_ui_renderer.remove_temp_resources(uid); + } + + m_overlay_manager->clear_dirty(); + } + + if (m_overlay_manager->has_visible()) + { + gl::screen.bind(); + glViewport(0, 0, m_frame->client_width(), m_frame->client_height()); + + for (const auto& view : m_overlay_manager->get_views()) + { + m_ui_renderer.run(m_frame->client_width(), m_frame->client_height(), 0, *view.get()); + } + } } if (g_cfg.video.overlay) @@ -1582,12 +1602,7 @@ void GLGSRender::do_local_task(bool /*idle*/) m_gl_texture_cache.do_update(); } - if (m_overlay_cleanup_requests.size()) - { - m_ui_renderer.remove_temp_resources(); - m_overlay_cleanup_requests.clear(); - } - else if (m_custom_ui) + if (m_overlay_manager) { if (!in_begin_end && native_ui_flip_request.load()) { @@ -1673,9 +1688,3 @@ void GLGSRender::discard_occlusion_query(rsx::reports::occlusion_query_info* que glEndQuery(GL_ANY_SAMPLES_PASSED); } } - -void GLGSRender::shell_do_cleanup() -{ - //TODO: Key cleanup requests with UID to identify resources to remove - m_overlay_cleanup_requests.push_back(0); -} diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 3af4c03874..b28b56c288 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -313,8 +313,6 @@ private: gl::ui_overlay_renderer m_ui_renderer; gl::video_out_calibration_pass m_video_output_pass; - std::vector m_overlay_cleanup_requests; - shared_mutex queue_guard; std::list work_queue; @@ -391,6 +389,4 @@ protected: std::array, 4> copy_render_targets_to_memory() override; std::array, 2> copy_depth_stencil_buffer_to_memory() override; - - void shell_do_cleanup() override; }; diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 29e0015ddd..08c18df486 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -2,7 +2,7 @@ #include "stdafx.h" #include "GLHelpers.h" -#include "../overlays.h" +#include "../Overlays/overlays.h" extern u64 get_system_time(); @@ -327,7 +327,7 @@ namespace gl { u32 num_elements = 0; std::vector> resources; - std::unordered_map> temp_image_cache; + std::unordered_map>> temp_image_cache; std::unordered_map> temp_view_cache; std::unordered_map> font_cache; std::unordered_map> view_cache; @@ -392,7 +392,7 @@ namespace gl }; } - gl::texture_view* load_simple_image(rsx::overlays::image_info* desc, bool temp_resource) + gl::texture_view* load_simple_image(rsx::overlays::image_info* desc, bool temp_resource, u32 owner_uid) { auto tex = std::make_unique(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, GL_RGBA8); tex->copy_from(desc->data, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8); @@ -409,7 +409,7 @@ namespace gl else { u64 key = (u64)desc; - temp_image_cache[key] = std::move(tex); + temp_image_cache[key] = std::move(std::make_pair(owner_uid, std::move(tex))); temp_view_cache[key] = std::move(view); } @@ -425,7 +425,7 @@ namespace gl for (const auto &res : configuration.texture_raw_data) { - load_simple_image(res.get(), false); + load_simple_image(res.get(), false, UINT32_MAX); } configuration.free_resources(); @@ -439,9 +439,22 @@ namespace gl overlay_pass::destroy(); } - void remove_temp_resources() + void remove_temp_resources(u64 key) { - temp_image_cache.clear(); + std::vector keys_to_remove; + for (auto It = temp_image_cache.begin(); It != temp_image_cache.end(); ++It) + { + if (It->second.first == key) + { + keys_to_remove.push_back(It->first); + } + } + + for (const auto& _key : keys_to_remove) + { + temp_image_cache.erase(_key); + temp_view_cache.erase(_key); + } } gl::texture_view* find_font(rsx::overlays::font *font) @@ -465,7 +478,7 @@ namespace gl return result; } - gl::texture_view* find_temp_image(rsx::overlays::image_info *desc) + gl::texture_view* find_temp_image(rsx::overlays::image_info *desc, u32 owner_uid) { auto key = (u64)desc; auto cached = temp_view_cache.find(key); @@ -475,7 +488,7 @@ namespace gl } else { - return load_simple_image(desc, true); + return load_simple_image(desc, true, owner_uid); } } @@ -535,7 +548,7 @@ namespace gl } case rsx::overlays::image_resource_id::raw_image: { - glBindTexture(GL_TEXTURE_2D, find_temp_image((rsx::overlays::image_info*)cmd.first.external_data_ref)->id()); + glBindTexture(GL_TEXTURE_2D, find_temp_image((rsx::overlays::image_info*)cmd.first.external_data_ref, ui.uid)->id()); break; } case rsx::overlays::image_resource_id::font_file: diff --git a/rpcs3/Emu/RSX/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h similarity index 100% rename from rpcs3/Emu/RSX/overlay_controls.h rename to rpcs3/Emu/RSX/Overlays/overlay_controls.h diff --git a/rpcs3/Emu/RSX/overlays.cpp b/rpcs3/Emu/RSX/Overlays/overlays.cpp similarity index 80% rename from rpcs3/Emu/RSX/overlays.cpp rename to rpcs3/Emu/RSX/Overlays/overlays.cpp index d95af226db..a0470929c2 100644 --- a/rpcs3/Emu/RSX/overlays.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlays.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "overlays.h" -#include "GSRender.h" +#include "../GSRender.h" namespace rsx { @@ -13,8 +13,8 @@ namespace rsx { //Force unload exit = true; - if (auto rsxthr = fxm::get()) - rsxthr->shell_close_dialog(); + if (auto manager = fxm::get()) + manager->remove(uid); if (on_close) on_close(return_code); diff --git a/rpcs3/Emu/RSX/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h similarity index 87% rename from rpcs3/Emu/RSX/overlays.h rename to rpcs3/Emu/RSX/Overlays/overlays.h index 602b9cb313..fae7ce41d5 100644 --- a/rpcs3/Emu/RSX/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -1,8 +1,8 @@ #pragma once #include "overlay_controls.h" -#include "../../Utilities/Thread.h" -#include "../Io/PadHandler.h" +#include "../../../Utilities/Thread.h" +#include "../../Io/PadHandler.h" #include "Emu/Memory/vm.h" #include "Emu/IdManager.h" #include "pad_thread.h" @@ -43,6 +43,9 @@ namespace rsx cross }; + u32 uid = UINT32_MAX; + u32 type_index = UINT32_MAX; + u16 virtual_width = 1280; u16 virtual_height = 720; @@ -161,6 +164,137 @@ namespace rsx } }; + class display_manager + { + private: + atomic_t m_uid_ctr { 0u }; + std::vector> m_iface_list; + std::vector m_uids_to_clean; + + public: + display_manager() {} + ~display_manager() {} + + template + T* add(std::unique_ptr& entry, bool remove_existing = true) + { + T* e = entry.get(); + e->uid = m_uid_ctr.fetch_add(1); + e->type_index = id_manager::typeinfo::get_index(); + + if (remove_existing) + { + for (auto It = m_iface_list.begin(); It != m_iface_list.end(); It++) + { + if (It->get()->type_index == e->type_index) + { + // Replace + m_uids_to_clean.push_back(It->get()->uid); + It->reset(e); + entry.reset(); + return e; + } + } + } + + m_iface_list.push_back(std::move(entry)); + return e; + } + + template + T* create(Args&&... args) + { + std::unique_ptr object = std::make_unique(std::forward(args)...); + return add(object); + } + + bool remove(u32 uid) + { + for (auto It = m_iface_list.begin(); It != m_iface_list.end(); It++) + { + const auto e = It->get(); + if (e->uid == uid) + { + m_iface_list.erase(It); + m_uids_to_clean.push_back(uid); + return true; + } + } + + return false; + } + + template + bool remove() + { + const auto type_id = id_manager::typeinfo::get_index(); + for (auto It = m_iface_list.begin(); It != m_iface_list.end();) + { + if (It->get()->type_index == type_id) + { + It = m_iface_list.erase(It); + } + else + { + ++It; + } + } + } + + // True if any visible elements to draw exist + bool has_visible() const + { + return !m_iface_list.empty(); + } + + // True if any elements have been deleted but their resources may not have been cleaned up + bool has_dirty() const + { + return !m_uids_to_clean.empty(); + } + + const std::vector>& get_views() const + { + return m_iface_list; + } + + const std::vector& get_dirty() const + { + return m_uids_to_clean; + } + + void clear_dirty() + { + m_uids_to_clean.clear(); + } + + user_interface* get(u32 uid) const + { + for (const auto& iface : m_iface_list) + { + if (iface->uid == uid) + return iface.get(); + } + + return nullptr; + } + + template + T* get() const + { + const auto type_id = id_manager::typeinfo::get_index(); + for (const auto& iface : m_iface_list) + { + if (iface->type_index == type_id) + { + return static_cast(iface.get()); + } + } + + return nullptr; + } + }; + struct fps_display : user_interface { label m_display; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 36c22575f0..3ba49bebed 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -344,6 +344,11 @@ namespace rsx void thread::on_task() { + if (supports_native_ui) + { + m_overlay_manager = fxm::make_always(); + } + on_init_thread(); reset(); @@ -2344,69 +2349,6 @@ namespace rsx return performance_counters.approximate_load; } - //TODO: Move these helpers into a better class dedicated to shell interface handling (use idm?) - //They are not dependent on rsx at all - rsx::overlays::save_dialog* thread::shell_open_save_dialog() - { - if (supports_native_ui) - { - auto ptr = new rsx::overlays::save_dialog(); - m_custom_ui.reset(ptr); - return ptr; - } - else - { - return nullptr; - } - } - - rsx::overlays::message_dialog* thread::shell_open_message_dialog() - { - if (supports_native_ui) - { - auto ptr = new rsx::overlays::message_dialog(); - m_custom_ui.reset(ptr); - return ptr; - } - else - { - return nullptr; - } - } - - rsx::overlays::trophy_notification* thread::shell_open_trophy_notification() - { - if (supports_native_ui) - { - auto ptr = new rsx::overlays::trophy_notification(); - m_custom_ui.reset(ptr); - return ptr; - } - else - { - return nullptr; - } - } - - rsx::overlays::user_interface* thread::shell_get_current_dialog() - { - //TODO: Only get dialog type interfaces - return m_custom_ui.get(); - } - - bool thread::shell_close_dialog() - { - //TODO: Only get dialog type interfaces - if (m_custom_ui) - { - m_invalidated_ui = std::move(m_custom_ui); - shell_do_cleanup(); - return true; - } - - return false; - } - namespace reports { void ZCULL_control::set_enabled(class ::rsx::thread* ptimer, bool state) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 511aae4247..73a0c7d315 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -12,7 +12,7 @@ #include "RSXFragmentProgram.h" #include "rsx_methods.h" #include "rsx_utils.h" -#include "overlays.h" +#include "Overlays/overlays.h" #include #include "Utilities/Thread.h" @@ -294,7 +294,7 @@ namespace rsx rsx::gcm_framebuffer_info m_depth_surface_info; bool framebuffer_status_valid = false; - std::unique_ptr m_custom_ui; + std::shared_ptr m_overlay_manager; std::unique_ptr m_invalidated_ui; public: @@ -571,14 +571,5 @@ namespace rsx //Get RSX approximate load in % u32 get_load(); - - //HLE vsh stuff - //TODO: Move into a separate helper - virtual rsx::overlays::save_dialog* shell_open_save_dialog(); - virtual rsx::overlays::message_dialog* shell_open_message_dialog(); - virtual rsx::overlays::trophy_notification* shell_open_trophy_notification(); - virtual rsx::overlays::user_interface* shell_get_current_dialog(); - virtual bool shell_close_dialog(); - virtual void shell_do_cleanup(){} }; } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index be2e54b4e1..ff88ed2d90 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1587,7 +1587,7 @@ void VKGSRender::on_init_thread() type.disable_cancel = true; type.progress_bar_count = 1; - dlg = owner->shell_open_message_dialog(); + dlg = fxm::get()->create(); dlg->show("Loading precompiled shaders from disk...", type, [](s32 status) { if (status != CELL_OK) @@ -2026,6 +2026,16 @@ void VKGSRender::process_swap_request(frame_context_t *ctx, bool free_resources) m_text_writer->reset_descriptors(); } + if (m_overlay_manager && m_overlay_manager->has_dirty()) + { + for (const auto& uid : m_overlay_manager->get_dirty()) + { + m_ui_renderer->remove_temp_resources(uid); + } + + m_overlay_manager->clear_dirty(); + } + m_attachment_clear_pass->free_resources(); m_depth_converter->free_resources(); m_depth_scaler->free_resources(); @@ -2166,14 +2176,7 @@ void VKGSRender::do_local_task(bool /*idle*/) #endif - //TODO: Guard this - if (m_overlay_cleanup_requests.size()) - { - flush_command_queue(true); - m_ui_renderer->remove_temp_resources(); - m_overlay_cleanup_requests.clear(); - } - else if (m_custom_ui) + if (m_overlay_manager) { if (!in_begin_end && native_ui_flip_request.load()) { @@ -2356,15 +2359,18 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info) //Notify the user with HUD notification if (g_cfg.misc.show_shader_compilation_hint) { - if (!m_custom_ui) + if (m_overlay_manager) { - //Create notification but do not draw it at this time. No need to spam flip requests - m_custom_ui = std::make_unique(); - } - else if (auto casted = dynamic_cast(m_custom_ui.get())) - { - //Probe the notification - casted->touch(); + if (auto dlg = m_overlay_manager->get()) + { + //Extend duration + dlg->touch(); + } + else + { + //Create dialog but do not show immediately + m_overlay_manager->create(); + } } } } @@ -3174,7 +3180,8 @@ void VKGSRender::flip(int buffer) std::unique_ptr direct_fbo; std::vector> swap_image_view; - if (g_cfg.video.overlay || m_custom_ui) + const bool has_overlay = (m_overlay_manager && m_overlay_manager->has_visible()); + if (g_cfg.video.overlay || has_overlay) { //Change the image layout whilst setting up a dependency on waiting for the blit op to finish before we start writing VkImageSubresourceRange subres = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; @@ -3212,9 +3219,12 @@ void VKGSRender::flip(int buffer) direct_fbo.reset(new vk::framebuffer_holder(*m_device, single_target_pass, m_client_width, m_client_height, std::move(swap_image_view))); } - if (m_custom_ui) + if (has_overlay) { - m_ui_renderer->run(*m_current_command_buffer, direct_fbo->width(), direct_fbo->height(), direct_fbo.get(), single_target_pass, m_texture_upload_buffer_ring_info, *m_custom_ui); + for (const auto& view : m_overlay_manager->get_views()) + { + m_ui_renderer->run(*m_current_command_buffer, direct_fbo->width(), direct_fbo->height(), direct_fbo.get(), single_target_pass, m_texture_upload_buffer_ring_info, *view.get()); + } } if (g_cfg.video.overlay) @@ -3433,10 +3443,4 @@ void VKGSRender::discard_occlusion_query(rsx::reports::occlusion_query_info* que m_occlusion_query_pool.reset_queries(*m_current_command_buffer, data.indices); m_occlusion_map.erase(query->driver_handle); -} - -void VKGSRender::shell_do_cleanup() -{ - //TODO: Guard this - m_overlay_cleanup_requests.push_back(0); -} +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 364d891210..dc28f89613 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -365,8 +365,6 @@ private: //Vertex layout rsx::vertex_input_layout m_vertex_layout; - std::vector m_overlay_cleanup_requests; - #if !defined(_WIN32) && defined(HAVE_VULKAN) Display *m_display_handle = nullptr; #endif @@ -428,6 +426,4 @@ protected: bool on_access_violation(u32 address, bool is_writing) override; void on_notify_memory_unmapped(u32 address_base, u32 size) override; - - void shell_do_cleanup() override; }; diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index b523e22a41..0f8c7436c4 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -4,7 +4,7 @@ #include "VKFragmentProgram.h" #include "VKRenderTargets.h" -#include "../overlays.h" +#include "../Overlays/overlays.h" namespace vk { @@ -417,7 +417,7 @@ namespace vk std::vector> resources; std::unordered_map> font_cache; std::unordered_map> view_cache; - std::vector> temp_image_cache; + std::unordered_map>> temp_image_cache; std::unordered_map> temp_view_cache; ui_overlay_renderer() @@ -491,7 +491,7 @@ namespace vk } vk::image_view* upload_simple_texture(vk::render_device &dev, vk::command_buffer &cmd, - vk::vk_data_heap& upload_heap, u64 key, int w, int h, bool font, bool temp, void *pixel_src) + vk::vk_data_heap& upload_heap, u64 key, int w, int h, bool font, bool temp, void *pixel_src, u32 owner_uid) { const VkFormat format = (font) ? VK_FORMAT_R8_UNORM : VK_FORMAT_B8G8R8A8_UNORM; const u32 pitch = (font) ? w : w * 4; @@ -543,7 +543,7 @@ namespace vk else if (!temp) resources.push_back(std::move(tex)); else - temp_image_cache.push_back(std::move(tex)); + temp_image_cache[key] = std::move(std::make_pair(owner_uid, std::move(tex))); return result; } @@ -559,7 +559,7 @@ namespace vk u64 storage_key = 1; for (const auto &res : configuration.texture_raw_data) { - upload_simple_texture(dev, cmd, upload_heap, storage_key++, res->w, res->h, false, false, res->data); + upload_simple_texture(dev, cmd, upload_heap, storage_key++, res->w, res->h, false, false, res->data, UINT32_MAX); } configuration.free_resources(); @@ -577,10 +577,22 @@ namespace vk overlay_pass::destroy(); } - void remove_temp_resources() + void remove_temp_resources(u32 key) { - temp_image_cache.clear(); - temp_view_cache.clear(); + std::vector keys_to_remove; + for (auto It = temp_image_cache.begin(); It != temp_image_cache.end(); ++It) + { + if (It->second.first == key) + { + keys_to_remove.push_back(It->first); + } + } + + for (const auto& _key : keys_to_remove) + { + temp_image_cache.erase(_key); + temp_view_cache.erase(_key); + } } vk::image_view* find_font(rsx::overlays::font *font, vk::command_buffer &cmd, vk::vk_data_heap &upload_heap) @@ -591,17 +603,19 @@ namespace vk return found->second.get(); //Create font file - return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, font->width, font->height, true, false, font->glyph_data.data()); + return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, font->width, font->height, + true, false, font->glyph_data.data(), UINT32_MAX); } - vk::image_view* find_temp_image(rsx::overlays::image_info *desc, vk::command_buffer &cmd, vk::vk_data_heap &upload_heap) + vk::image_view* find_temp_image(rsx::overlays::image_info *desc, vk::command_buffer &cmd, vk::vk_data_heap &upload_heap, u32 owner_uid) { u64 key = (u64)desc; auto found = temp_view_cache.find(key); if (found != temp_view_cache.end()) return found->second.get(); - return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, desc->w, desc->h, false, true, desc->data); + return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, desc->w, desc->h, + false, true, desc->data, owner_uid); } void update_uniforms(vk::glsl::program* /*program*/) override @@ -674,7 +688,7 @@ namespace vk src = find_font(command.first.font_ref, cmd, upload_heap)->value; break; case rsx::overlays::image_resource_id::raw_image: - src = find_temp_image((rsx::overlays::image_info*)command.first.external_data_ref, cmd, upload_heap)->value; + src = find_temp_image((rsx::overlays::image_info*)command.first.external_data_ref, cmd, upload_heap, ui.uid)->value; break; default: src = view_cache[command.first.texture_ref]->value; diff --git a/rpcs3/Emu/RSX/rsx_utils.cpp b/rpcs3/Emu/RSX/rsx_utils.cpp index 92aff462f0..b1bc398293 100644 --- a/rpcs3/Emu/RSX/rsx_utils.cpp +++ b/rpcs3/Emu/RSX/rsx_utils.cpp @@ -3,7 +3,7 @@ #include "rsx_methods.h" #include "Emu/RSX/GCM.h" #include "Common/BufferUtils.h" -#include "overlays.h" +#include "Overlays/overlays.h" #include "Utilities/sysinfo.h" extern "C" diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 80363d4dea..e1156e9bfe 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -294,7 +294,7 @@ NotUsing - + @@ -530,8 +530,8 @@ - - + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 8e88528908..a7fd8fb7ea 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -66,6 +66,9 @@ {3f233c0b-4ee1-4c02-963f-0109d3d9c705} + + {7536c5ad-d58f-40a7-96db-74d959fa4c02} + @@ -734,9 +737,6 @@ Emu\Io - - Emu\GPU\RSX - Emu\Cell\lv2 @@ -746,6 +746,9 @@ Emu\GPU\RSX\Capture + + Emu\GPU\RSX\Overlays + @@ -1402,12 +1405,6 @@ Emu\Cell\lv2 - - Emu\GPU\RSX - - - Emu\GPU\RSX - Emu\Cell\lv2 @@ -1441,5 +1438,11 @@ Emu\GPU\RSX\Capture + + Emu\GPU\RSX\Overlays + + + Emu\GPU\RSX\Overlays + \ No newline at end of file diff --git a/rpcs3/rpcs3qt/save_data_dialog.cpp b/rpcs3/rpcs3qt/save_data_dialog.cpp index eb014fc24e..cb1cd7014f 100644 --- a/rpcs3/rpcs3qt/save_data_dialog.cpp +++ b/rpcs3/rpcs3qt/save_data_dialog.cpp @@ -2,19 +2,16 @@ #include "save_data_list_dialog.h" #include -#include +#include s32 save_data_dialog::ShowSaveDataList(std::vector& save_entries, s32 focused, u32 op, vm::ptr listSet) { //TODO: Install native shell as an Emu callback - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (auto native_dlg = rsxthr->shell_open_save_dialog()) - { - auto result = native_dlg->show(save_entries, op, listSet); - if (result != rsx::overlays::user_interface::selection_code::error) - return result; - } + auto result = manager->create()->show(save_entries, op, listSet); + if (result != rsx::overlays::user_interface::selection_code::error) + return result; } //Fall back to front-end GUI diff --git a/rpcs3/rpcs3qt/trophy_notification_helper.cpp b/rpcs3/rpcs3qt/trophy_notification_helper.cpp index afd54b387e..9ae7016a6f 100644 --- a/rpcs3/rpcs3qt/trophy_notification_helper.cpp +++ b/rpcs3/rpcs3qt/trophy_notification_helper.cpp @@ -3,16 +3,13 @@ #include "trophy_notification_frame.h" #include "../Emu/System.h" -#include "../Emu/RSX/GSRender.h" +#include "../Emu/RSX/Overlays/overlays.h" s32 trophy_notification_helper::ShowTrophyNotification(const SceNpTrophyDetails& trophy, const std::vector& trophy_icon_buffer) { - if (auto rsxthr = fxm::get()) + if (auto manager = fxm::get()) { - if (auto dlg = rsxthr->shell_open_trophy_notification()) - { - return dlg->show(trophy, trophy_icon_buffer); - } + return manager->create()->show(trophy, trophy_icon_buffer); } Emu.CallAfter([=]