diff options
| author | 2023-04-11 22:03:19 -0700 | |
|---|---|---|
| committer | 2023-06-03 00:05:50 -0700 | |
| commit | 4006468f7368d0afe51be11a466e5b33c62e362d (patch) | |
| tree | ca0294e6f596aa09a05352ad56687a41de60a764 /src/android/app | |
| parent | android: vulkan_debug_callback: Ignore many innocuous errors. (diff) | |
| download | yuzu-4006468f7368d0afe51be11a466e5b33c62e362d.tar.gz yuzu-4006468f7368d0afe51be11a466e5b33c62e362d.tar.xz yuzu-4006468f7368d0afe51be11a466e5b33c62e362d.zip | |
android: video_core: Add support for disk shader cache. (#64)
Diffstat (limited to 'src/android/app')
12 files changed, 258 insertions, 4 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt index 3ab685b9b..1e654777a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt | |||
| @@ -42,6 +42,7 @@ object NativeLibrary { | |||
| 42 | const val Player8Device = 7 | 42 | const val Player8Device = 7 |
| 43 | const val ConsoleDevice = 8 | 43 | const val ConsoleDevice = 8 |
| 44 | 44 | ||
| 45 | @JvmField | ||
| 45 | var sEmulationActivity = WeakReference<EmulationActivity?>(null) | 46 | var sEmulationActivity = WeakReference<EmulationActivity?>(null) |
| 46 | 47 | ||
| 47 | init { | 48 | init { |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress.kt new file mode 100644 index 000000000..9b665c7a0 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress.kt | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.disk_shader_cache | ||
| 5 | |||
| 6 | import org.yuzu.yuzu_emu.NativeLibrary | ||
| 7 | import org.yuzu.yuzu_emu.R | ||
| 8 | import org.yuzu.yuzu_emu.disk_shader_cache.ui.ShaderProgressDialogFragment | ||
| 9 | |||
| 10 | object DiskShaderCacheProgress { | ||
| 11 | val finishLock = Object() | ||
| 12 | private lateinit var fragment: ShaderProgressDialogFragment | ||
| 13 | |||
| 14 | private fun prepareDialog() { | ||
| 15 | val emulationActivity = NativeLibrary.sEmulationActivity.get()!! | ||
| 16 | emulationActivity.runOnUiThread { | ||
| 17 | fragment = ShaderProgressDialogFragment.newInstance( | ||
| 18 | emulationActivity.getString(R.string.loading), | ||
| 19 | emulationActivity.getString(R.string.preparing_shaders) | ||
| 20 | ) | ||
| 21 | fragment.show(emulationActivity.supportFragmentManager, ShaderProgressDialogFragment.TAG) | ||
| 22 | } | ||
| 23 | synchronized(finishLock) { finishLock.wait() } | ||
| 24 | } | ||
| 25 | |||
| 26 | @JvmStatic | ||
| 27 | fun loadProgress(stage: Int, progress: Int, max: Int) { | ||
| 28 | val emulationActivity = NativeLibrary.sEmulationActivity.get() | ||
| 29 | ?: error("[DiskShaderCacheProgress] EmulationActivity not present") | ||
| 30 | |||
| 31 | when (LoadCallbackStage.values()[stage]) { | ||
| 32 | LoadCallbackStage.Prepare -> prepareDialog() | ||
| 33 | LoadCallbackStage.Build -> fragment.onUpdateProgress( | ||
| 34 | emulationActivity.getString(R.string.building_shaders), | ||
| 35 | progress, | ||
| 36 | max | ||
| 37 | ) | ||
| 38 | LoadCallbackStage.Complete -> fragment.dismiss() | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | // Equivalent to VideoCore::LoadCallbackStage | ||
| 43 | enum class LoadCallbackStage { | ||
| 44 | Prepare, Build, Complete | ||
| 45 | } | ||
| 46 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ShaderProgressViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ShaderProgressViewModel.kt new file mode 100644 index 000000000..bf6f0366d --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ShaderProgressViewModel.kt | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.disk_shader_cache | ||
| 5 | |||
| 6 | import androidx.lifecycle.LiveData | ||
| 7 | import androidx.lifecycle.MutableLiveData | ||
| 8 | import androidx.lifecycle.ViewModel | ||
| 9 | |||
| 10 | class ShaderProgressViewModel : ViewModel() { | ||
| 11 | private val _progress = MutableLiveData(0) | ||
| 12 | val progress: LiveData<Int> get() = _progress | ||
| 13 | |||
| 14 | private val _max = MutableLiveData(0) | ||
| 15 | val max: LiveData<Int> get() = _max | ||
| 16 | |||
| 17 | private val _message = MutableLiveData("") | ||
| 18 | val message: LiveData<String> get() = _message | ||
| 19 | |||
| 20 | fun setProgress(progress: Int) { | ||
| 21 | _progress.postValue(progress) | ||
| 22 | } | ||
| 23 | |||
| 24 | fun setMax(max: Int) { | ||
| 25 | _max.postValue(max) | ||
| 26 | } | ||
| 27 | |||
| 28 | fun setMessage(msg: String) { | ||
| 29 | _message.postValue(msg) | ||
| 30 | } | ||
| 31 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ui/ShaderProgressDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ui/ShaderProgressDialogFragment.kt new file mode 100644 index 000000000..2c68c9ac3 --- /dev/null +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ui/ShaderProgressDialogFragment.kt | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | package org.yuzu.yuzu_emu.disk_shader_cache.ui | ||
| 5 | |||
| 6 | import android.app.Dialog | ||
| 7 | import android.os.Bundle | ||
| 8 | import android.view.LayoutInflater | ||
| 9 | import android.view.View | ||
| 10 | import android.view.ViewGroup | ||
| 11 | import androidx.appcompat.app.AlertDialog | ||
| 12 | import androidx.fragment.app.DialogFragment | ||
| 13 | import androidx.lifecycle.ViewModelProvider | ||
| 14 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||
| 15 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding | ||
| 16 | import org.yuzu.yuzu_emu.disk_shader_cache.DiskShaderCacheProgress | ||
| 17 | import org.yuzu.yuzu_emu.disk_shader_cache.ShaderProgressViewModel | ||
| 18 | |||
| 19 | class ShaderProgressDialogFragment : DialogFragment() { | ||
| 20 | private var _binding: DialogProgressBarBinding? = null | ||
| 21 | private val binding get() = _binding!! | ||
| 22 | |||
| 23 | private lateinit var alertDialog: AlertDialog | ||
| 24 | |||
| 25 | private lateinit var shaderProgressViewModel: ShaderProgressViewModel | ||
| 26 | |||
| 27 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { | ||
| 28 | _binding = DialogProgressBarBinding.inflate(layoutInflater) | ||
| 29 | shaderProgressViewModel = | ||
| 30 | ViewModelProvider(requireActivity())[ShaderProgressViewModel::class.java] | ||
| 31 | |||
| 32 | val title = requireArguments().getString(TITLE) | ||
| 33 | val message = requireArguments().getString(MESSAGE) | ||
| 34 | |||
| 35 | isCancelable = false | ||
| 36 | alertDialog = MaterialAlertDialogBuilder(requireActivity()) | ||
| 37 | .setView(binding.root) | ||
| 38 | .setTitle(title) | ||
| 39 | .setMessage(message) | ||
| 40 | .create() | ||
| 41 | return alertDialog | ||
| 42 | } | ||
| 43 | |||
| 44 | override fun onCreateView( | ||
| 45 | inflater: LayoutInflater, | ||
| 46 | container: ViewGroup?, | ||
| 47 | savedInstanceState: Bundle? | ||
| 48 | ): View { | ||
| 49 | return binding.root | ||
| 50 | } | ||
| 51 | |||
| 52 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
| 53 | super.onViewCreated(view, savedInstanceState) | ||
| 54 | shaderProgressViewModel.progress.observe(viewLifecycleOwner) { progress -> | ||
| 55 | binding.progressBar.progress = progress | ||
| 56 | setUpdateText() | ||
| 57 | } | ||
| 58 | shaderProgressViewModel.max.observe(viewLifecycleOwner) { max -> | ||
| 59 | binding.progressBar.max = max | ||
| 60 | setUpdateText() | ||
| 61 | } | ||
| 62 | shaderProgressViewModel.message.observe(viewLifecycleOwner) { msg -> | ||
| 63 | alertDialog.setMessage(msg) | ||
| 64 | } | ||
| 65 | synchronized(DiskShaderCacheProgress.finishLock) { DiskShaderCacheProgress.finishLock.notifyAll() } | ||
| 66 | } | ||
| 67 | |||
| 68 | override fun onDestroyView() { | ||
| 69 | super.onDestroyView() | ||
| 70 | _binding = null | ||
| 71 | } | ||
| 72 | |||
| 73 | fun onUpdateProgress(msg: String, progress: Int, max: Int) { | ||
| 74 | shaderProgressViewModel.setProgress(progress) | ||
| 75 | shaderProgressViewModel.setMax(max) | ||
| 76 | shaderProgressViewModel.setMessage(msg) | ||
| 77 | } | ||
| 78 | |||
| 79 | private fun setUpdateText() { | ||
| 80 | binding.progressText.text = String.format( | ||
| 81 | "%d/%d", | ||
| 82 | shaderProgressViewModel.progress.value, | ||
| 83 | shaderProgressViewModel.max.value | ||
| 84 | ) | ||
| 85 | } | ||
| 86 | |||
| 87 | companion object { | ||
| 88 | const val TAG = "ProgressDialogFragment" | ||
| 89 | const val TITLE = "title" | ||
| 90 | const val MESSAGE = "message" | ||
| 91 | |||
| 92 | fun newInstance(title: String, message: String): ShaderProgressDialogFragment { | ||
| 93 | val frag = ShaderProgressDialogFragment() | ||
| 94 | val args = Bundle() | ||
| 95 | args.putString(TITLE, title) | ||
| 96 | args.putString(MESSAGE, message) | ||
| 97 | frag.arguments = args | ||
| 98 | return frag | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index f04b81335..a137d1c3a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt | |||
| @@ -196,6 +196,8 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) | |||
| 196 | val rendererResolution = rendererSection.getSetting(SettingsFile.KEY_RENDERER_RESOLUTION) | 196 | val rendererResolution = rendererSection.getSetting(SettingsFile.KEY_RENDERER_RESOLUTION) |
| 197 | val rendererAspectRatio = | 197 | val rendererAspectRatio = |
| 198 | rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASPECT_RATIO) | 198 | rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASPECT_RATIO) |
| 199 | val rendererUseDiskShaderCache = | ||
| 200 | rendererSection.getSetting(SettingsFile.KEY_RENDERER_USE_DISK_SHADER_CACHE) | ||
| 199 | val rendererForceMaxClocks = | 201 | val rendererForceMaxClocks = |
| 200 | rendererSection.getSetting(SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK) | 202 | rendererSection.getSetting(SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK) |
| 201 | val rendererAsynchronousShaders = | 203 | val rendererAsynchronousShaders = |
| @@ -252,6 +254,16 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) | |||
| 252 | ) | 254 | ) |
| 253 | add( | 255 | add( |
| 254 | SwitchSetting( | 256 | SwitchSetting( |
| 257 | SettingsFile.KEY_RENDERER_USE_DISK_SHADER_CACHE, | ||
| 258 | Settings.SECTION_RENDERER, | ||
| 259 | rendererUseDiskShaderCache, | ||
| 260 | R.string.use_disk_shader_cache, | ||
| 261 | R.string.use_disk_shader_cache_description, | ||
| 262 | true | ||
| 263 | ) | ||
| 264 | ) | ||
| 265 | add( | ||
| 266 | SwitchSetting( | ||
| 255 | SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK, | 267 | SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK, |
| 256 | Settings.SECTION_RENDERER, | 268 | Settings.SECTION_RENDERER, |
| 257 | rendererForceMaxClocks, | 269 | rendererForceMaxClocks, |
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt index 37ae39fe6..c518d9ba0 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt | |||
| @@ -36,6 +36,7 @@ object SettingsFile { | |||
| 36 | const val KEY_RENDERER_RESOLUTION = "resolution_setup" | 36 | const val KEY_RENDERER_RESOLUTION = "resolution_setup" |
| 37 | const val KEY_RENDERER_ASPECT_RATIO = "aspect_ratio" | 37 | const val KEY_RENDERER_ASPECT_RATIO = "aspect_ratio" |
| 38 | const val KEY_RENDERER_ACCURACY = "gpu_accuracy" | 38 | const val KEY_RENDERER_ACCURACY = "gpu_accuracy" |
| 39 | const val KEY_RENDERER_USE_DISK_SHADER_CACHE = "use_disk_shader_cache" | ||
| 39 | const val KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders" | 40 | const val KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders" |
| 40 | const val KEY_RENDERER_FORCE_MAX_CLOCK = "force_max_clock" | 41 | const val KEY_RENDERER_FORCE_MAX_CLOCK = "force_max_clock" |
| 41 | const val KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit" | 42 | const val KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit" |
diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index d882688f1..0e86dea9e 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp | |||
| @@ -226,10 +226,6 @@ void Config::ReadValues() { | |||
| 226 | ReadSetting("Renderer", Settings::values.bg_green); | 226 | ReadSetting("Renderer", Settings::values.bg_green); |
| 227 | ReadSetting("Renderer", Settings::values.bg_blue); | 227 | ReadSetting("Renderer", Settings::values.bg_blue); |
| 228 | 228 | ||
| 229 | // Disable shader cache by default on Android | ||
| 230 | Settings::values.use_disk_shader_cache = | ||
| 231 | config->GetBoolean("Renderer", "use_disk_shader_cache", false); | ||
| 232 | |||
| 233 | // Enable force_max_clock by default on Android | 229 | // Enable force_max_clock by default on Android |
| 234 | Settings::values.renderer_force_max_clock = | 230 | Settings::values.renderer_force_max_clock = |
| 235 | config->GetBoolean("Renderer", "force_max_clock", true); | 231 | config->GetBoolean("Renderer", "force_max_clock", true); |
diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp index 6291c8652..7edadb94a 100644 --- a/src/android/app/src/main/jni/id_cache.cpp +++ b/src/android/app/src/main/jni/id_cache.cpp | |||
| @@ -3,13 +3,18 @@ | |||
| 3 | 3 | ||
| 4 | #include <jni.h> | 4 | #include <jni.h> |
| 5 | 5 | ||
| 6 | #include "common/assert.h" | ||
| 6 | #include "common/fs/fs_android.h" | 7 | #include "common/fs/fs_android.h" |
| 7 | #include "jni/applets/software_keyboard.h" | 8 | #include "jni/applets/software_keyboard.h" |
| 8 | #include "jni/id_cache.h" | 9 | #include "jni/id_cache.h" |
| 10 | #include "video_core/rasterizer_interface.h" | ||
| 9 | 11 | ||
| 10 | static JavaVM* s_java_vm; | 12 | static JavaVM* s_java_vm; |
| 11 | static jclass s_native_library_class; | 13 | static jclass s_native_library_class; |
| 14 | static jclass s_disk_cache_progress_class; | ||
| 15 | static jclass s_load_callback_stage_class; | ||
| 12 | static jmethodID s_exit_emulation_activity; | 16 | static jmethodID s_exit_emulation_activity; |
| 17 | static jmethodID s_disk_cache_load_progress; | ||
| 13 | 18 | ||
| 14 | static constexpr jint JNI_VERSION = JNI_VERSION_1_6; | 19 | static constexpr jint JNI_VERSION = JNI_VERSION_1_6; |
| 15 | 20 | ||
| @@ -38,10 +43,22 @@ jclass GetNativeLibraryClass() { | |||
| 38 | return s_native_library_class; | 43 | return s_native_library_class; |
| 39 | } | 44 | } |
| 40 | 45 | ||
| 46 | jclass GetDiskCacheProgressClass() { | ||
| 47 | return s_disk_cache_progress_class; | ||
| 48 | } | ||
| 49 | |||
| 50 | jclass GetDiskCacheLoadCallbackStageClass() { | ||
| 51 | return s_load_callback_stage_class; | ||
| 52 | } | ||
| 53 | |||
| 41 | jmethodID GetExitEmulationActivity() { | 54 | jmethodID GetExitEmulationActivity() { |
| 42 | return s_exit_emulation_activity; | 55 | return s_exit_emulation_activity; |
| 43 | } | 56 | } |
| 44 | 57 | ||
| 58 | jmethodID GetDiskCacheLoadProgress() { | ||
| 59 | return s_disk_cache_load_progress; | ||
| 60 | } | ||
| 61 | |||
| 45 | } // namespace IDCache | 62 | } // namespace IDCache |
| 46 | 63 | ||
| 47 | #ifdef __cplusplus | 64 | #ifdef __cplusplus |
| @@ -58,8 +75,16 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { | |||
| 58 | // Initialize Java classes | 75 | // Initialize Java classes |
| 59 | const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary"); | 76 | const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary"); |
| 60 | s_native_library_class = reinterpret_cast<jclass>(env->NewGlobalRef(native_library_class)); | 77 | s_native_library_class = reinterpret_cast<jclass>(env->NewGlobalRef(native_library_class)); |
| 78 | s_disk_cache_progress_class = reinterpret_cast<jclass>(env->NewGlobalRef( | ||
| 79 | env->FindClass("org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress"))); | ||
| 80 | s_load_callback_stage_class = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass( | ||
| 81 | "org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage"))); | ||
| 82 | |||
| 83 | // Initialize methods | ||
| 61 | s_exit_emulation_activity = | 84 | s_exit_emulation_activity = |
| 62 | env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); | 85 | env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); |
| 86 | s_disk_cache_load_progress = | ||
| 87 | env->GetStaticMethodID(s_disk_cache_progress_class, "loadProgress", "(III)V"); | ||
| 63 | 88 | ||
| 64 | // Initialize Android Storage | 89 | // Initialize Android Storage |
| 65 | Common::FS::Android::RegisterCallbacks(env, s_native_library_class); | 90 | Common::FS::Android::RegisterCallbacks(env, s_native_library_class); |
| @@ -79,6 +104,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { | |||
| 79 | // UnInitialize Android Storage | 104 | // UnInitialize Android Storage |
| 80 | Common::FS::Android::UnRegisterCallbacks(); | 105 | Common::FS::Android::UnRegisterCallbacks(); |
| 81 | env->DeleteGlobalRef(s_native_library_class); | 106 | env->DeleteGlobalRef(s_native_library_class); |
| 107 | env->DeleteGlobalRef(s_disk_cache_progress_class); | ||
| 108 | env->DeleteGlobalRef(s_load_callback_stage_class); | ||
| 82 | 109 | ||
| 83 | // UnInitialze applets | 110 | // UnInitialze applets |
| 84 | SoftwareKeyboard::CleanupJNI(env); | 111 | SoftwareKeyboard::CleanupJNI(env); |
diff --git a/src/android/app/src/main/jni/id_cache.h b/src/android/app/src/main/jni/id_cache.h index 2fe07169d..9337cd254 100644 --- a/src/android/app/src/main/jni/id_cache.h +++ b/src/android/app/src/main/jni/id_cache.h | |||
| @@ -2,10 +2,15 @@ | |||
| 2 | 2 | ||
| 3 | #include <jni.h> | 3 | #include <jni.h> |
| 4 | 4 | ||
| 5 | #include "video_core/rasterizer_interface.h" | ||
| 6 | |||
| 5 | namespace IDCache { | 7 | namespace IDCache { |
| 6 | 8 | ||
| 7 | JNIEnv* GetEnvForThread(); | 9 | JNIEnv* GetEnvForThread(); |
| 8 | jclass GetNativeLibraryClass(); | 10 | jclass GetNativeLibraryClass(); |
| 11 | jclass GetDiskCacheProgressClass(); | ||
| 12 | jclass GetDiskCacheLoadCallbackStageClass(); | ||
| 9 | jmethodID GetExitEmulationActivity(); | 13 | jmethodID GetExitEmulationActivity(); |
| 14 | jmethodID GetDiskCacheLoadProgress(); | ||
| 10 | 15 | ||
| 11 | } // namespace IDCache | 16 | } // namespace IDCache |
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 55736bce2..b10c55a45 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | #include "jni/emu_window/emu_window.h" | 51 | #include "jni/emu_window/emu_window.h" |
| 52 | #include "jni/id_cache.h" | 52 | #include "jni/id_cache.h" |
| 53 | #include "video_core/rasterizer_interface.h" | 53 | #include "video_core/rasterizer_interface.h" |
| 54 | #include "video_core/renderer_base.h" | ||
| 54 | 55 | ||
| 55 | namespace { | 56 | namespace { |
| 56 | 57 | ||
| @@ -229,6 +230,15 @@ public: | |||
| 229 | m_is_running = true; | 230 | m_is_running = true; |
| 230 | } | 231 | } |
| 231 | 232 | ||
| 233 | // Load the disk shader cache. | ||
| 234 | if (Settings::values.use_disk_shader_cache.GetValue()) { | ||
| 235 | LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); | ||
| 236 | m_system.Renderer().ReadRasterizer()->LoadDiskResources( | ||
| 237 | m_system.GetApplicationProcessProgramID(), std::stop_token{}, | ||
| 238 | LoadDiskCacheProgress); | ||
| 239 | LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); | ||
| 240 | } | ||
| 241 | |||
| 232 | void(m_system.Run()); | 242 | void(m_system.Run()); |
| 233 | 243 | ||
| 234 | if (m_system.DebuggerEnabled()) { | 244 | if (m_system.DebuggerEnabled()) { |
| @@ -296,6 +306,14 @@ private: | |||
| 296 | } | 306 | } |
| 297 | 307 | ||
| 298 | private: | 308 | private: |
| 309 | static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max) { | ||
| 310 | JNIEnv* env = IDCache::GetEnvForThread(); | ||
| 311 | env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(), | ||
| 312 | IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage), | ||
| 313 | static_cast<jint>(progress), static_cast<jint>(max)); | ||
| 314 | } | ||
| 315 | |||
| 316 | private: | ||
| 299 | static EmulationSession s_instance; | 317 | static EmulationSession s_instance; |
| 300 | 318 | ||
| 301 | // Frontend management | 319 | // Frontend management |
diff --git a/src/android/app/src/main/res/layout/dialog_progress_bar.xml b/src/android/app/src/main/res/layout/dialog_progress_bar.xml index 1dbfd4f7b..d17711a65 100644 --- a/src/android/app/src/main/res/layout/dialog_progress_bar.xml +++ b/src/android/app/src/main/res/layout/dialog_progress_bar.xml | |||
| @@ -12,4 +12,13 @@ | |||
| 12 | android:layout_margin="24dp" | 12 | android:layout_margin="24dp" |
| 13 | app:trackCornerRadius="4dp" /> | 13 | app:trackCornerRadius="4dp" /> |
| 14 | 14 | ||
| 15 | <TextView | ||
| 16 | android:id="@+id/progress_text" | ||
| 17 | android:layout_width="match_parent" | ||
| 18 | android:layout_height="wrap_content" | ||
| 19 | android:layout_marginLeft="24dp" | ||
| 20 | android:layout_marginRight="24dp" | ||
| 21 | android:layout_marginBottom="24dp" | ||
| 22 | android:gravity="end" /> | ||
| 23 | |||
| 15 | </LinearLayout> | 24 | </LinearLayout> |
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 70bff5749..45a9694d4 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml | |||
| @@ -35,6 +35,8 @@ | |||
| 35 | <string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously, which will reduce stutter but may introduce glitches.</string> | 35 | <string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously, which will reduce stutter but may introduce glitches.</string> |
| 36 | <string name="renderer_debug">Enable graphics debugging</string> | 36 | <string name="renderer_debug">Enable graphics debugging</string> |
| 37 | <string name="renderer_debug_description">When checked, the graphics API enters a slower debugging mode.</string> | 37 | <string name="renderer_debug_description">When checked, the graphics API enters a slower debugging mode.</string> |
| 38 | <string name="use_disk_shader_cache">Use disk shader cache</string> | ||
| 39 | <string name="use_disk_shader_cache_description">Reduce stuttering by storing and loading generated shaders to disk.</string> | ||
| 38 | 40 | ||
| 39 | <!-- Audio settings strings --> | 41 | <!-- Audio settings strings --> |
| 40 | <string name="audio_volume">Volume</string> | 42 | <string name="audio_volume">Volume</string> |
| @@ -45,6 +47,7 @@ | |||
| 45 | <string name="ini_saved">Saved settings</string> | 47 | <string name="ini_saved">Saved settings</string> |
| 46 | <string name="gameid_saved">Saved settings for %1$s</string> | 48 | <string name="gameid_saved">Saved settings for %1$s</string> |
| 47 | <string name="error_saving">Error saving %1$s.ini: %2$s</string> | 49 | <string name="error_saving">Error saving %1$s.ini: %2$s</string> |
| 50 | <string name="loading">Loading...</string> | ||
| 48 | 51 | ||
| 49 | <!-- Game Grid Screen--> | 52 | <!-- Game Grid Screen--> |
| 50 | <string name="grid_menu_core_settings">Settings</string> | 53 | <string name="grid_menu_core_settings">Settings</string> |
| @@ -183,4 +186,8 @@ | |||
| 183 | <string name="gamepad_home">Home</string> | 186 | <string name="gamepad_home">Home</string> |
| 184 | <string name="gamepad_screenshot">Screenshot</string> | 187 | <string name="gamepad_screenshot">Screenshot</string> |
| 185 | 188 | ||
| 189 | <!-- Disk shader cache --> | ||
| 190 | <string name="preparing_shaders">Preparing shaders</string> | ||
| 191 | <string name="building_shaders">Building shaders</string> | ||
| 192 | |||
| 186 | </resources> | 193 | </resources> |