diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp
index ab2d522120..0bc223ee09 100644
--- a/UI/NativeApp.cpp
+++ b/UI/NativeApp.cpp
@@ -1345,7 +1345,9 @@ void NativeFrame(GraphicsContext *graphicsContext) {
g_screenManager->resized();
// TODO: Move this to the GraphicsContext objects for each backend.
-#if !PPSSPP_PLATFORM(WINDOWS) && !defined(ANDROID)
+ // (Android used to be left out here, since every size change there was a full graphics restart,
+ // and DeviceRestore covers it. Rotation and window resizing are in-place now.)
+#if !PPSSPP_PLATFORM(WINDOWS)
PSP_CoreParameter().pixelWidth = g_display.pixel_xres;
PSP_CoreParameter().pixelHeight = g_display.pixel_yres;
System_PostUIMessage(UIMessage::GPU_DISPLAY_RESIZED);
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index cb83fc8004..f715a4c4da 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -53,7 +53,7 @@
inputPlayers = new ArrayList<>();
@@ -898,10 +901,15 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
return;
}
+ if (renderLoopRunning) {
+ Log.i(TAG, "startRenderLoopThread: already running, surface changed in place");
+ return;
+ }
+
Log.w(TAG, "startRenderLoopThread: Starting thread");
applyFrameRate(mSurface, 60.0f);
- runRenderLoop(mSurface);
+ renderLoopRunning = runRenderLoop(mSurface);
}
private synchronized void joinRenderLoopThread() {
@@ -915,6 +923,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
// This will wait until the thread has exited.
Log.i(TAG, "requestExitRenderLoop");
requestExitRenderLoop();
+ renderLoopRunning = false;
}
void setupSystemUiCallback() {
@@ -1085,7 +1094,8 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- Log.i(TAG, "onConfigurationChanged");
+ Log.i(TAG, "onConfigurationChanged: orientation=" + newConfig.orientation + " density=" + newConfig.densityDpi
+ + " screen=" + newConfig.screenWidthDp + "x" + newConfig.screenHeightDp + "dp");
if (m_hasNoNativeBinary) {
return;
}
diff --git a/android/src/org/ppsspp/ppsspp/SizeManager.java b/android/src/org/ppsspp/ppsspp/SizeManager.java
index 7e730cb594..585a2b9d0b 100644
--- a/android/src/org/ppsspp/ppsspp/SizeManager.java
+++ b/android/src/org/ppsspp/ppsspp/SizeManager.java
@@ -110,9 +110,31 @@ public class SizeManager implements SurfaceHolder.Callback {
Log.i(TAG, "Surface changed. Resolution: " + width + "x" + height + " Format: " + format);
// The window size might have changed (immersive mode, native fullscreen on some devices)
- NativeApp.backbufferResize(width, height, format);
updateDisplayMeasurements();
+ // A rotation or a window resize no longer recreates the activity, so a fixed-size (hardware scaled)
+ // surface has to be re-fixed here for the new display size and aspect. The fixed size is what the
+ // surface will report, so only do it when it doesn't already match, or this would loop.
+ if (!holder.isCreating()) {
+ Point newDesired = new Point();
+ getDesiredBackbufferSize(newDesired);
+ boolean fixed = desiredSize.x > 0 && desiredSize.y > 0;
+ boolean wantFixed = newDesired.x > 0 && newDesired.y > 0;
+ if (wantFixed && (newDesired.x != width || newDesired.y != height)) {
+ Log.i(TAG, "Display changed, re-fixing surface size to " + newDesired.x + " x " + newDesired.y);
+ desiredSize.set(newDesired.x, newDesired.y);
+ holder.setFixedSize(newDesired.x, newDesired.y);
+ return; // Another surfaceChanged is coming, with the new size.
+ } else if (!wantFixed && fixed) {
+ Log.i(TAG, "Display changed, surface no longer needs a fixed size");
+ desiredSize.set(0, 0);
+ holder.setSizeFromLayout();
+ return;
+ }
+ }
+
+ NativeApp.backbufferResize(width, height, format, activity.getWindowManager().getDefaultDisplay().getRotation());
+
if (!paused) {
activity.notifySurface(holder.getSurface());
} else {