aboutsummaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/jni/native.cpp63
-rw-r--r--src/android/app/src/main/jni/native.h6
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;
};