Browse Source

chore: DRY up pause and capture, debug resume

pull/3651/head
xXJSONDeruloXx 7 days ago
parent
commit
3a391e5730
No known key found for this signature in database GPG Key ID: 629F3E618E280D7F
  1. 91
      src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt

91
src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt

@ -739,10 +739,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (emulationState.isPaused) {
resumeEmulationFromUi()
} else {
emulationState.pause()
updatePauseMenuEntry(true)
capturePausedFrameFromCore()
updatePausedFrameVisibility()
pauseEmulationAndCaptureFrame()
}
binding.inGameMenu.requestFocus()
true
@ -1208,6 +1205,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
private fun pauseEmulationAndCaptureFrame() {
emulationState.pause()
updatePauseMenuEntry(true)
capturePausedFrameFromCore()
updatePausedFrameVisibility()
}
private fun capturePausedFrameFromCore() {
lifecycleScope.launch(Dispatchers.Default) {
val frameData = NativeLibrary.getAppletCaptureBuffer()
@ -1243,28 +1247,18 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
private fun updatePausedFrameVisibility() {
val b = _binding ?: return
val shouldShowPaused = this::emulationState.isInitialized && emulationState.isPaused
b.pausedIcon.setVisible(shouldShowPaused)
if (!shouldShowPaused) {
b.pausedFrameImage.setVisible(false)
b.pausedFrameImage.setImageDrawable(null)
return
}
val showPausedUi = this::emulationState.isInitialized && emulationState.isPaused
b.pausedIcon.setVisible(showPausedUi)
val bitmap = pausedFrameBitmap ?: run {
b.pausedFrameImage.setVisible(false)
b.pausedFrameImage.setImageDrawable(null)
return
}
val bitmap = if (showPausedUi) pausedFrameBitmap else null
b.pausedFrameImage.setImageBitmap(bitmap)
b.pausedFrameImage.setVisible(true)
b.pausedFrameImage.setVisible(bitmap != null)
}
private fun resumeEmulationFromUi() {
clearPausedFrame()
emulationState.run(false, explicitResume = true)
updatePauseMenuEntry(false)
emulationState.resume()
updatePauseMenuEntry(emulationState.isPaused)
updatePausedFrameVisibility()
}
@ -1369,11 +1363,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
override fun onPause() {
if (this::emulationState.isInitialized) {
if (emulationState.isRunning && emulationActivity?.isInPictureInPictureMode != true) {
emulationState.pause()
updatePauseMenuEntry(true)
capturePausedFrameFromCore()
pauseEmulationAndCaptureFrame()
} else {
updatePausedFrameVisibility()
}
updatePausedFrameVisibility()
}
super.onPause()
}
@ -2159,11 +2152,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
@Synchronized
fun run(
isActivityRecreated: Boolean,
programIndex: Int = 0,
explicitResume: Boolean = false
) {
fun run(isActivityRecreated: Boolean, programIndex: Int = 0) {
if (isActivityRecreated) {
if (NativeLibrary.isRunning()) {
state = State.PAUSED
@ -2174,8 +2163,30 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
// If the surface is set, run now. Otherwise, wait for it to get set.
if (surface != null) {
runWithValidSurface(programIndex, explicitResume)
runWithValidSurface(programIndex)
}
}
@Synchronized
fun resume() {
if (state != State.PAUSED) {
Log.warning("[EmulationFragment] Resume called while emulation is not paused.")
return
}
if (!emulationCanStart.invoke()) {
return
}
val currentSurface = surface
if (currentSurface == null || !currentSurface.isValid) {
Log.debug("[EmulationFragment] Resume requested with invalid surface.")
return
}
NativeLibrary.surfaceChanged(currentSurface)
Log.debug("[EmulationFragment] Resuming emulation.")
NativeLibrary.unpauseEmulation()
NativeLibrary.playTimeManagerStart()
state = State.RUNNING
}
@Synchronized
@ -2235,7 +2246,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
private fun runWithValidSurface(programIndex: Int = 0, explicitResume: Boolean = false) {
private fun runWithValidSurface(programIndex: Int = 0) {
if (!emulationCanStart.invoke()) {
return
}
@ -2253,26 +2264,18 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
NativeLibrary.run(gamePath, programIndex, true)
}, "NativeEmulation")
emulationThread.start()
state = State.RUNNING
}
State.PAUSED -> {
if (!explicitResume) {
Log.debug(
"[EmulationFragment] Surface restored while emulation paused; " +
"deferring native surface update until explicit resume."
)
return
}
NativeLibrary.surfaceChanged(currentSurface)
Log.debug("[EmulationFragment] Resuming emulation.")
NativeLibrary.unpauseEmulation()
NativeLibrary.playTimeManagerStart()
Log.debug(
"[EmulationFragment] Surface restored while emulation paused; " +
"waiting for explicit resume."
)
}
else -> Log.debug("[EmulationFragment] Bug, run called while already running.")
}
state = State.RUNNING
}
private enum class State {

Loading…
Cancel
Save