mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-06-01 12:15:03 -06:00
android: Allow deleting per title disk shader cache (#2032)
This commit is contained in:
parent
5983a23d38
commit
0fc3d692b9
@ -258,6 +258,9 @@ object NativeLibrary {
|
|||||||
|
|
||||||
external fun nativeFileExists(path: String): Boolean
|
external fun nativeFileExists(path: String): Boolean
|
||||||
|
|
||||||
|
external fun deleteOpenGLShaderCache(titleId: Long)
|
||||||
|
external fun deleteVulkanShaderCache(titleId: Long)
|
||||||
|
|
||||||
private var coreErrorAlertResult = false
|
private var coreErrorAlertResult = false
|
||||||
private val coreErrorAlertLock = Object()
|
private val coreErrorAlertLock = Object()
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import androidx.recyclerview.widget.DiffUtil
|
|||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
@ -514,6 +515,63 @@ class GameAdapter(
|
|||||||
showUninstallContextMenu(it, game, bottomSheetDialog)
|
showUninstallContextMenu(it, game, bottomSheetDialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bottomSheetView.findViewById<MaterialButton>(R.id.delete_cache).setOnClickListener {
|
||||||
|
val options = arrayOf(context.getString(R.string.vulkan), context.getString(R.string.opengles))
|
||||||
|
var selectedIndex = -1
|
||||||
|
val dialog = MaterialAlertDialogBuilder(context)
|
||||||
|
.setTitle(R.string.delete_cache_select_backend)
|
||||||
|
.setSingleChoiceItems(options, -1) { dialog, which ->
|
||||||
|
selectedIndex = which
|
||||||
|
}
|
||||||
|
.setPositiveButton(android.R.string.ok) {_, _ ->
|
||||||
|
val progToast = Toast.makeText(
|
||||||
|
CitraApplication.appContext,
|
||||||
|
R.string.deleting_shader_cache,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
)
|
||||||
|
progToast.show()
|
||||||
|
|
||||||
|
activity.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
|
||||||
|
when (selectedIndex) {
|
||||||
|
0 -> {
|
||||||
|
NativeLibrary.deleteVulkanShaderCache(game.titleId)
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
NativeLibrary.deleteOpenGLShaderCache(game.titleId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
activity.runOnUiThread {
|
||||||
|
progToast.cancel()
|
||||||
|
Toast.makeText(
|
||||||
|
CitraApplication.appContext,
|
||||||
|
R.string.shader_cache_deleted,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
.create()
|
||||||
|
|
||||||
|
dialog.setOnShowListener {
|
||||||
|
val positiveButton = dialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE)
|
||||||
|
|
||||||
|
positiveButton.isEnabled = false
|
||||||
|
|
||||||
|
val listView = dialog.listView
|
||||||
|
listView.setOnItemClickListener { _, _, position, _ ->
|
||||||
|
selectedIndex = position
|
||||||
|
positiveButton.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
val bottomSheetBehavior = bottomSheetDialog.getBehavior()
|
val bottomSheetBehavior = bottomSheetDialog.getBehavior()
|
||||||
bottomSheetBehavior.skipCollapsed = true
|
bottomSheetBehavior.skipCollapsed = true
|
||||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
|
|||||||
@ -1130,4 +1130,44 @@ jboolean Java_org_citra_citra_1emu_NativeLibrary_nativeFileExists(JNIEnv* env, j
|
|||||||
return FileUtil::Exists(path);
|
return FileUtil::Exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
void Java_org_citra_citra_1emu_NativeLibrary_deleteOpenGLShaderCache(JNIEnv* env, jobject obj,
|
||||||
|
jlong title_id) {
|
||||||
|
for (const std::string_view cache_type : {"separable", "conventional"}) {
|
||||||
|
const std::string path =
|
||||||
|
fmt::format("{}opengl/precompiled/{}/{:016X}.bin",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir), cache_type, title_id);
|
||||||
|
LOG_INFO(Frontend, "Deleting shader file: {}", path);
|
||||||
|
FileUtil::Delete(path);
|
||||||
|
}
|
||||||
|
const std::string path =
|
||||||
|
fmt::format("{}opengl/transferable/{:016X}.bin",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir), title_id);
|
||||||
|
LOG_INFO(Frontend, "Deleting shader file: {}", path);
|
||||||
|
FileUtil::Delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_citra_citra_1emu_NativeLibrary_deleteVulkanShaderCache(JNIEnv* env, jobject obj,
|
||||||
|
jlong title_id) {
|
||||||
|
for (const std::string_view cache_type : {"vs", "fs", "gs", "pl"}) {
|
||||||
|
const std::string path =
|
||||||
|
fmt::format("{}vulkan/transferable/{:016X}_{}.vkch",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir), title_id, cache_type);
|
||||||
|
LOG_INFO(Frontend, "Deleting shader file: {}", path);
|
||||||
|
FileUtil::Delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileUtil::ForeachDirectoryEntry(
|
||||||
|
nullptr,
|
||||||
|
fmt::format("{}vulkan/pipeline", FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)),
|
||||||
|
[title_id]([[maybe_unused]] u64* num_entries_out, const std::string& directory,
|
||||||
|
const std::string& virtual_name) {
|
||||||
|
if (virtual_name.starts_with(fmt::format("{:016X}", title_id))) {
|
||||||
|
std::string path = directory + DIR_SEP + virtual_name;
|
||||||
|
LOG_INFO(Frontend, "Deleting shader file: {}", path);
|
||||||
|
FileUtil::Delete(path);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
@ -161,7 +161,7 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/game_button_tray"
|
android:id="@+id/horizontal_layout_2"
|
||||||
style="@style/ThemeOverlay.Material3.Button.IconButton.Filled.Tonal"
|
style="@style/ThemeOverlay.Material3.Button.IconButton.Filled.Tonal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -199,19 +199,24 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/compress_tray"
|
android:id="@+id/horizontal_layout_3"
|
||||||
style="@style/ThemeOverlay.Material3.Button.IconButton.Filled.Tonal"
|
style="@style/ThemeOverlay.Material3.Button.IconButton.Filled.Tonal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:gravity="start|center"
|
android:gravity="start|center"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/game_button_tray">
|
app:layout_constraintTop_toBottomOf="@+id/horizontal_layout_2">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/delete_cache"
|
||||||
|
style="@style/Widget.Material3.Button.TonalButton.Icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@string/delete_shader_cache"
|
||||||
|
android:text="@string/delete_shader_cache" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@ -586,6 +586,10 @@
|
|||||||
<!-- Disk Shader Cache -->
|
<!-- Disk Shader Cache -->
|
||||||
<string name="preparing_shaders">Preparing Shaders</string>
|
<string name="preparing_shaders">Preparing Shaders</string>
|
||||||
<string name="building_shaders">Building %s</string>
|
<string name="building_shaders">Building %s</string>
|
||||||
|
<string name="delete_shader_cache">Delete Shader Cache</string>
|
||||||
|
<string name="delete_cache_select_backend">Select which graphics API to delete the shader cache</string>
|
||||||
|
<string name="deleting_shader_cache">Deleting shader cache for title, please wait…</string>
|
||||||
|
<string name="shader_cache_deleted">Shader cache deleted</string>
|
||||||
|
|
||||||
<!-- About Game Dialog -->
|
<!-- About Game Dialog -->
|
||||||
<string name="play">Play</string>
|
<string name="play">Play</string>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user