12 changed files with 258 additions and 4 deletions
-
1src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
-
46src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress.kt
-
31src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ShaderProgressViewModel.kt
-
101src/android/app/src/main/java/org/yuzu/yuzu_emu/disk_shader_cache/ui/ShaderProgressDialogFragment.kt
-
12src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
-
1src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
-
4src/android/app/src/main/jni/config.cpp
-
27src/android/app/src/main/jni/id_cache.cpp
-
5src/android/app/src/main/jni/id_cache.h
-
18src/android/app/src/main/jni/native.cpp
-
9src/android/app/src/main/res/layout/dialog_progress_bar.xml
-
7src/android/app/src/main/res/values/strings.xml
@ -0,0 +1,46 @@ |
|||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
package org.yuzu.yuzu_emu.disk_shader_cache |
||||
|
|
||||
|
import org.yuzu.yuzu_emu.NativeLibrary |
||||
|
import org.yuzu.yuzu_emu.R |
||||
|
import org.yuzu.yuzu_emu.disk_shader_cache.ui.ShaderProgressDialogFragment |
||||
|
|
||||
|
object DiskShaderCacheProgress { |
||||
|
val finishLock = Object() |
||||
|
private lateinit var fragment: ShaderProgressDialogFragment |
||||
|
|
||||
|
private fun prepareDialog() { |
||||
|
val emulationActivity = NativeLibrary.sEmulationActivity.get()!! |
||||
|
emulationActivity.runOnUiThread { |
||||
|
fragment = ShaderProgressDialogFragment.newInstance( |
||||
|
emulationActivity.getString(R.string.loading), |
||||
|
emulationActivity.getString(R.string.preparing_shaders) |
||||
|
) |
||||
|
fragment.show(emulationActivity.supportFragmentManager, ShaderProgressDialogFragment.TAG) |
||||
|
} |
||||
|
synchronized(finishLock) { finishLock.wait() } |
||||
|
} |
||||
|
|
||||
|
@JvmStatic |
||||
|
fun loadProgress(stage: Int, progress: Int, max: Int) { |
||||
|
val emulationActivity = NativeLibrary.sEmulationActivity.get() |
||||
|
?: error("[DiskShaderCacheProgress] EmulationActivity not present") |
||||
|
|
||||
|
when (LoadCallbackStage.values()[stage]) { |
||||
|
LoadCallbackStage.Prepare -> prepareDialog() |
||||
|
LoadCallbackStage.Build -> fragment.onUpdateProgress( |
||||
|
emulationActivity.getString(R.string.building_shaders), |
||||
|
progress, |
||||
|
max |
||||
|
) |
||||
|
LoadCallbackStage.Complete -> fragment.dismiss() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Equivalent to VideoCore::LoadCallbackStage |
||||
|
enum class LoadCallbackStage { |
||||
|
Prepare, Build, Complete |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
package org.yuzu.yuzu_emu.disk_shader_cache |
||||
|
|
||||
|
import androidx.lifecycle.LiveData |
||||
|
import androidx.lifecycle.MutableLiveData |
||||
|
import androidx.lifecycle.ViewModel |
||||
|
|
||||
|
class ShaderProgressViewModel : ViewModel() { |
||||
|
private val _progress = MutableLiveData(0) |
||||
|
val progress: LiveData<Int> get() = _progress |
||||
|
|
||||
|
private val _max = MutableLiveData(0) |
||||
|
val max: LiveData<Int> get() = _max |
||||
|
|
||||
|
private val _message = MutableLiveData("") |
||||
|
val message: LiveData<String> get() = _message |
||||
|
|
||||
|
fun setProgress(progress: Int) { |
||||
|
_progress.postValue(progress) |
||||
|
} |
||||
|
|
||||
|
fun setMax(max: Int) { |
||||
|
_max.postValue(max) |
||||
|
} |
||||
|
|
||||
|
fun setMessage(msg: String) { |
||||
|
_message.postValue(msg) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
package org.yuzu.yuzu_emu.disk_shader_cache.ui |
||||
|
|
||||
|
import android.app.Dialog |
||||
|
import android.os.Bundle |
||||
|
import android.view.LayoutInflater |
||||
|
import android.view.View |
||||
|
import android.view.ViewGroup |
||||
|
import androidx.appcompat.app.AlertDialog |
||||
|
import androidx.fragment.app.DialogFragment |
||||
|
import androidx.lifecycle.ViewModelProvider |
||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder |
||||
|
import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding |
||||
|
import org.yuzu.yuzu_emu.disk_shader_cache.DiskShaderCacheProgress |
||||
|
import org.yuzu.yuzu_emu.disk_shader_cache.ShaderProgressViewModel |
||||
|
|
||||
|
class ShaderProgressDialogFragment : DialogFragment() { |
||||
|
private var _binding: DialogProgressBarBinding? = null |
||||
|
private val binding get() = _binding!! |
||||
|
|
||||
|
private lateinit var alertDialog: AlertDialog |
||||
|
|
||||
|
private lateinit var shaderProgressViewModel: ShaderProgressViewModel |
||||
|
|
||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { |
||||
|
_binding = DialogProgressBarBinding.inflate(layoutInflater) |
||||
|
shaderProgressViewModel = |
||||
|
ViewModelProvider(requireActivity())[ShaderProgressViewModel::class.java] |
||||
|
|
||||
|
val title = requireArguments().getString(TITLE) |
||||
|
val message = requireArguments().getString(MESSAGE) |
||||
|
|
||||
|
isCancelable = false |
||||
|
alertDialog = MaterialAlertDialogBuilder(requireActivity()) |
||||
|
.setView(binding.root) |
||||
|
.setTitle(title) |
||||
|
.setMessage(message) |
||||
|
.create() |
||||
|
return alertDialog |
||||
|
} |
||||
|
|
||||
|
override fun onCreateView( |
||||
|
inflater: LayoutInflater, |
||||
|
container: ViewGroup?, |
||||
|
savedInstanceState: Bundle? |
||||
|
): View { |
||||
|
return binding.root |
||||
|
} |
||||
|
|
||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
||||
|
super.onViewCreated(view, savedInstanceState) |
||||
|
shaderProgressViewModel.progress.observe(viewLifecycleOwner) { progress -> |
||||
|
binding.progressBar.progress = progress |
||||
|
setUpdateText() |
||||
|
} |
||||
|
shaderProgressViewModel.max.observe(viewLifecycleOwner) { max -> |
||||
|
binding.progressBar.max = max |
||||
|
setUpdateText() |
||||
|
} |
||||
|
shaderProgressViewModel.message.observe(viewLifecycleOwner) { msg -> |
||||
|
alertDialog.setMessage(msg) |
||||
|
} |
||||
|
synchronized(DiskShaderCacheProgress.finishLock) { DiskShaderCacheProgress.finishLock.notifyAll() } |
||||
|
} |
||||
|
|
||||
|
override fun onDestroyView() { |
||||
|
super.onDestroyView() |
||||
|
_binding = null |
||||
|
} |
||||
|
|
||||
|
fun onUpdateProgress(msg: String, progress: Int, max: Int) { |
||||
|
shaderProgressViewModel.setProgress(progress) |
||||
|
shaderProgressViewModel.setMax(max) |
||||
|
shaderProgressViewModel.setMessage(msg) |
||||
|
} |
||||
|
|
||||
|
private fun setUpdateText() { |
||||
|
binding.progressText.text = String.format( |
||||
|
"%d/%d", |
||||
|
shaderProgressViewModel.progress.value, |
||||
|
shaderProgressViewModel.max.value |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
companion object { |
||||
|
const val TAG = "ProgressDialogFragment" |
||||
|
const val TITLE = "title" |
||||
|
const val MESSAGE = "message" |
||||
|
|
||||
|
fun newInstance(title: String, message: String): ShaderProgressDialogFragment { |
||||
|
val frag = ShaderProgressDialogFragment() |
||||
|
val args = Bundle() |
||||
|
args.putString(TITLE, title) |
||||
|
args.putString(MESSAGE, message) |
||||
|
frag.arguments = args |
||||
|
return frag |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue