diff options
Diffstat (limited to 'src/android')
| -rw-r--r-- | src/android/app/src/main/jni/native.cpp | 63 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/native.h | 6 |
2 files changed, 65 insertions, 4 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 4d0c39f5c7..e8e9f0a14b 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -76,6 +76,7 @@ extern "C" { #include "core/frontend/applets/software_keyboard.h" #include "core/frontend/applets/web_browser.h" #include "common/android/applets/web_browser.h" +#include "core/file_sys/common_funcs.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/frontend/applets.h" #include "core/hle/service/filesystem/filesystem.h" @@ -311,11 +312,23 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string ConfigureFilesystemProvider(filepath); // Load the ROM. + const u64 previous_program_id = + program_index != 0 && m_next_program_id.load() > + static_cast<u64>(Service::AM::AppletProgramId::MaxProgramId) + ? m_next_program_id.load() + : 0; + Service::AM::FrontendAppletParameters params{ + .program_id = previous_program_id, .applet_id = static_cast<Service::AM::AppletId>(m_applet_id), .launch_type = frontend_initiated ? Service::AM::LaunchType::FrontendInitiated : Service::AM::LaunchType::ApplicationInitiated, .program_index = static_cast<s32>(program_index), + .previous_program_index = + previous_program_id != 0 + ? static_cast<s32>(previous_program_id - + FileSys::GetBaseTitleID(previous_program_id)) + : -1, }; m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params); @@ -328,8 +341,12 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string m_system.GetCpuManager().OnGpuReady(); m_system.RegisterExitCallback([&] { HaltEmulation(); }); + m_system.RegisterApplicationChangedCallback( + [&](u64 changed_program_id) { RequestDiskShaderCacheReload(changed_program_id); }); + // Register an ExecuteProgram callback such that Core can execute a sub-program m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) { + m_next_program_id = m_system.GetApplicationProcessProgramID(); m_next_program_index = program_index_; EmulationSession::GetInstance().HaltEmulation(); }); @@ -407,20 +424,58 @@ void EmulationSession::RunEmulation() { } while (true) { + std::optional<u64> reload_title; { [[maybe_unused]] std::unique_lock lock(m_mutex); - if (m_cv.wait_for(lock, std::chrono::milliseconds(800), - [&]() { return !m_is_running; })) { - // Emulation halted. - break; + if (m_cv.wait_for(lock, std::chrono::milliseconds(800), [&]() { + return !m_is_running || m_pending_shader_cache_title.has_value(); + })) { + if (!m_is_running) { + break; + } + reload_title = std::exchange(m_pending_shader_cache_title, std::nullopt); } } + + if (reload_title.has_value()) + ReloadDiskShaderCache(*reload_title); } // Reset current applet ID. m_applet_id = static_cast<int>(Service::AM::AppletId::Application); } +void EmulationSession::RequestDiskShaderCacheReload(u64 program_id) { + { + std::scoped_lock lock(m_mutex); + m_pending_shader_cache_title = program_id; + } + m_cv.notify_one(); +} + +void EmulationSession::ReloadDiskShaderCache(u64 program_id) { + if (!Settings::values.use_disk_shader_cache.GetValue()) + return; + + LOG_INFO(Frontend, "Reloading disk shader cache for {:016X}", program_id); + + const bool was_paused = m_is_paused; + + m_system.Pause(); + m_system.GPU().WaitForIdle(); + m_system.GPU().ObtainContext(); + + LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); + m_system.Renderer().ReadRasterizer()->LoadDiskResources(program_id, std::stop_token{}, + LoadDiskCacheProgress); + LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); + + m_system.GPU().ReleaseContext(); + + if (!was_paused) + m_system.Run(); +} + Common::Android::SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() { return m_software_keyboard; } diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index 6b171d5a66..5794660bbd 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -4,6 +4,8 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <optional> + #include <android/native_window_jni.h> #include "common/android/applets/software_keyboard.h" #include "core/core.h" @@ -44,6 +46,7 @@ public: void HaltEmulation(); void RunEmulation(); void ShutdownEmulation(); + void RequestDiskShaderCacheReload(u64 program_id); const Core::PerfStatsResults& PerfStats(); int ShadersBuilding(); @@ -65,6 +68,7 @@ private: static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max); static void OnEmulationStopped(Core::SystemResultStatus result); static void ChangeProgram(std::size_t program_index); + void ReloadDiskShaderCache(u64 program_id); private: // Window management @@ -83,6 +87,7 @@ private: Common::Android::SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider; int m_applet_id{1}; + std::optional<u64> m_pending_shader_cache_title; // GPU driver parameters std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; @@ -93,4 +98,5 @@ private: // Program index for next boot std::atomic<s32> m_next_program_index = -1; + std::atomic<u64> m_next_program_id = 0; }; |
