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 {