[NativeLibrary] do not release surface in SurfaceDestroyed when VR (surface is managed by swapchain)

This commit is contained in:
amwatson 2024-03-19 14:12:22 -05:00
parent ef1946abf1
commit dd65871f15
4 changed files with 27 additions and 9 deletions

View file

@ -124,7 +124,7 @@ object NativeLibrary {
external fun run(path: String)
// Surface Handling
external fun surfaceChanged(surf: Surface)
external fun surfaceChanged(surf: Surface, shouldReleaseSurface: Boolean)
external fun surfaceDestroyed()
external fun doFrame()

View file

@ -67,7 +67,7 @@ import org.citra.citra_emu.utils.EmulationLifecycleUtil
import org.citra.citra_emu.utils.Log
import org.citra.citra_emu.utils.ViewUtils
import org.citra.citra_emu.viewmodel.EmulationViewModel
import org.citra.citra_emu.vr.VrActivity
import org.citra.citra_emu.vr.utils.VRUtils
class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback {
private val preferences: SharedPreferences
@ -165,7 +165,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
return
}
if (activity !is VrActivity) {
if (!VRUtils.isVR(activity)) {
Log.debug("[EmulationFragment] non-VR mode: adding surface callback");
binding.surfaceEmulation.holder.addCallback(this)
} else {
@ -420,7 +420,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
fun surfaceCreated(surface : Surface) {
Log.debug("[EmulationFragment] Surface created");
emulationState.newSurface(surface)
emulationState.newSurface(surface, VRUtils.isVR(emulationActivity))
}
private fun togglePause() {
@ -873,7 +873,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
Log.debug("[EmulationFragment] Surface changed. Resolution: " + width + "x" + height)
emulationState.newSurface(holder.surface)
emulationState.newSurface(holder.surface, !VRUtils.isVR(emulationActivity))
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
@ -924,6 +924,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
private class EmulationState(private val gamePath: String) {
private var state: State
private var surface: Surface? = null
private var isVrSurface : Boolean = false;
init {
// Starting state is stopped.
@ -999,8 +1000,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
// Surface callbacks
@Synchronized
fun newSurface(surface: Surface?) {
fun newSurface(surface: Surface?, isVrSurface: Boolean) {
this.surface = surface
this.isVrSurface = isVrSurface
if (this.surface != null) {
runWithValidSurface()
}
@ -1012,6 +1014,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
Log.warning("[EmulationFragment] clearSurface called, but surface already null.")
} else {
surface = null
isVrSurface = false
Log.debug("[EmulationFragment] Surface destroyed.")
when (state) {
State.RUNNING -> {
@ -1031,7 +1034,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
}
private fun runWithValidSurface() {
NativeLibrary.surfaceChanged(surface!!)
NativeLibrary.surfaceChanged(surface!!, isVrSurface)
when (state) {
State.STOPPED -> {
Thread({

View file

@ -1,9 +1,11 @@
package org.citra.citra_emu.vr.utils
import android.app.Activity
import android.view.KeyEvent
import org.citra.citra_emu.NativeLibrary
import org.citra.citra_emu.R
import org.citra.citra_emu.features.settings.model.Settings
import org.citra.citra_emu.vr.VrActivity
object VRUtils {
val hMDType: Int
@ -81,6 +83,11 @@ object VRUtils {
}
}
@JvmStatic
fun isVR(mainActivity: Activity?) : Boolean {
return mainActivity is VrActivity
}
const val PREF_RELEASE_VERSION_NAME_LAUNCH_CURRENT = "VR_ReleaseVersionName_LaunchCurrent"
const val PREF_RELEASE_VERSION_NAME_LAUNCH_PREV = "VR_ReleaseVersionName_LaunchPrev"
}

View file

@ -67,6 +67,10 @@
namespace {
ANativeWindow* s_surf;
// VR-SPECIFIC:
// false when using VR mode, as the surface is allocated by the OpenXR swapchain.
// True otherwise.
bool s_should_release_surface = true;
std::shared_ptr<Common::DynamicLibrary> vulkan_library{};
std::unique_ptr<EmuWindow_Android> window;
@ -290,8 +294,9 @@ extern "C" {
void Java_org_citra_citra_1emu_NativeLibrary_surfaceChanged(JNIEnv* env,
[[maybe_unused]] jobject obj,
jobject surf) {
jobject surf, jboolean should_release_surface) {
s_surf = ANativeWindow_fromSurface(env, surf);
s_should_release_surface = should_release_surface;
if (window) {
window->OnSurfaceChanged(s_surf);
@ -307,7 +312,10 @@ void Java_org_citra_citra_1emu_NativeLibrary_surfaceChanged(JNIEnv* env,
void Java_org_citra_citra_1emu_NativeLibrary_surfaceDestroyed([[maybe_unused]] JNIEnv* env,
[[maybe_unused]] jobject obj) {
ANativeWindow_release(s_surf);
if (s_should_release_surface) {
ANativeWindow_release(s_surf);
}
s_surf = nullptr;
if (window) {
window->OnSurfaceChanged(s_surf);