android: Properly update emulation surface

Previously the emulation surface wasn't being updated during configuration changes and only during specific view events. This would break input and the screen dimensions after each orientation/aspect ratio change. Now a new surface is provided every time and the display dimensions are updated as needed.
This commit is contained in:
Charles Lombardo 2023-09-17 17:27:31 -04:00
parent e3c546a1ed
commit 32d65fc8de
2 changed files with 11 additions and 25 deletions

View file

@ -15,7 +15,6 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Rational
import android.view.* import android.view.*
import android.widget.TextView import android.widget.TextView
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
@ -287,6 +286,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
updateScreenLayout()
if (emulationActivity?.isInPictureInPictureMode == true) { if (emulationActivity?.isInPictureInPictureMode == true) {
if (binding.drawerLayout.isOpen) { if (binding.drawerLayout.isOpen) {
binding.drawerLayout.close() binding.drawerLayout.close()
@ -394,16 +394,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
private fun updateScreenLayout() { private fun updateScreenLayout() {
binding.surfaceEmulation.setAspectRatio( binding.surfaceEmulation.setAspectRatio(null)
when (IntSetting.RENDERER_ASPECT_RATIO.int) {
0 -> Rational(16, 9)
1 -> Rational(4, 3)
2 -> Rational(21, 9)
3 -> Rational(16, 10)
4 -> null // Stretch
else -> Rational(16, 9)
}
)
emulationActivity?.buildPictureInPictureParams() emulationActivity?.buildPictureInPictureParams()
updateOrientation() updateOrientation()
} }
@ -693,7 +684,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
private class EmulationState(private val gamePath: String) { private class EmulationState(private val gamePath: String) {
private var state: State private var state: State
private var surface: Surface? = null private var surface: Surface? = null
private var runWhenSurfaceIsValid = false
init { init {
// Starting state is stopped. // Starting state is stopped.
@ -751,8 +741,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
// If the surface is set, run now. Otherwise, wait for it to get set. // If the surface is set, run now. Otherwise, wait for it to get set.
if (surface != null) { if (surface != null) {
runWithValidSurface() runWithValidSurface()
} else {
runWhenSurfaceIsValid = true
} }
} }
@ -760,7 +748,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
@Synchronized @Synchronized
fun newSurface(surface: Surface?) { fun newSurface(surface: Surface?) {
this.surface = surface this.surface = surface
if (runWhenSurfaceIsValid) { if (this.surface != null) {
runWithValidSurface() runWithValidSurface()
} }
} }
@ -788,10 +776,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
private fun runWithValidSurface() { private fun runWithValidSurface() {
runWhenSurfaceIsValid = false NativeLibrary.surfaceChanged(surface)
when (state) { when (state) {
State.STOPPED -> { State.STOPPED -> {
NativeLibrary.surfaceChanged(surface)
val emulationThread = Thread({ val emulationThread = Thread({
Log.debug("[EmulationFragment] Starting emulation thread.") Log.debug("[EmulationFragment] Starting emulation thread.")
NativeLibrary.run(gamePath) NativeLibrary.run(gamePath)
@ -801,7 +788,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
State.PAUSED -> { State.PAUSED -> {
Log.debug("[EmulationFragment] Resuming emulation.") Log.debug("[EmulationFragment] Resuming emulation.")
NativeLibrary.surfaceChanged(surface)
NativeLibrary.unpauseEmulation() NativeLibrary.unpauseEmulation()
} }

View file

@ -11,6 +11,12 @@
#include "jni/emu_window/emu_window.h" #include "jni/emu_window/emu_window.h"
void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
m_window_width = ANativeWindow_getWidth(surface);
m_window_height = ANativeWindow_getHeight(surface);
// Ensures that we emulate with the correct aspect ratio.
UpdateCurrentFramebufferLayout(m_window_width, m_window_height);
window_info.render_surface = reinterpret_cast<void*>(surface); window_info.render_surface = reinterpret_cast<void*>(surface);
} }
@ -62,14 +68,8 @@ EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsyste
return; return;
} }
m_window_width = ANativeWindow_getWidth(surface); OnSurfaceChanged(surface);
m_window_height = ANativeWindow_getHeight(surface);
// Ensures that we emulate with the correct aspect ratio.
UpdateCurrentFramebufferLayout(m_window_width, m_window_height);
window_info.type = Core::Frontend::WindowSystemType::Android; window_info.type = Core::Frontend::WindowSystemType::Android;
window_info.render_surface = reinterpret_cast<void*>(surface);
m_input_subsystem->Initialize(); m_input_subsystem->Initialize();
} }