diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 777b3a0ecc..5b6f4c50cd 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -951,6 +951,8 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv int old_w = g_display.pixel_xres; int old_h = g_display.pixel_yres; + int old_dp_w = g_display.dp_xres; + int old_dp_h = g_display.dp_yres; // pixel_*res is the backbuffer resolution. backbuffer_format = format; @@ -973,7 +975,9 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv display_dpi, dpi_x, dpi_y, display_scale_x, display_scale_y, g_display.dpi_scale_x, g_display.dpi_scale_y, g_display.dp_xres, g_display.dp_yres); if (new_size || rotated) { - INFO_LOG(Log::G3D, "%s detected (previously %d,%d) - calling NativeResized()", new_size ? "Size change" : "Rotation change", old_w, old_h); + // Note that a density change moves the dp size while the pixel size stays put. + INFO_LOG(Log::G3D, "%s detected (previously %dx%d px, %dx%d dp) - calling NativeResized()", + new_size ? "Size change" : "Rotation change", old_w, old_h, old_dp_w, old_dp_h); NativeResized(); } else { INFO_LOG(Log::G3D, "NativeApp::backbufferResize: Size didn't change."); diff --git a/android/src/org/ppsspp/ppsspp/NativeSurfaceManager.java b/android/src/org/ppsspp/ppsspp/NativeSurfaceManager.java index 1a48843a17..5227de6e7a 100644 --- a/android/src/org/ppsspp/ppsspp/NativeSurfaceManager.java +++ b/android/src/org/ppsspp/ppsspp/NativeSurfaceManager.java @@ -20,6 +20,13 @@ public class NativeSurfaceManager implements SurfaceHolder.Callback { // The fixed surface size we last asked for, or 0,0 for "size from layout". private final Point desiredSize = new Point(); + // What we last told the native side about the surface, and the density we told it with. + // A density change has to re-report it, see densityChanged(). + private int reportedWidth; + private int reportedHeight; + private int reportedFormat; + private float reportedDensityDpi; + public NativeSurfaceManager(final PpssppActivity a) { activity = a; } @@ -86,18 +93,40 @@ public class NativeSurfaceManager implements SurfaceHolder.Callback { } } - NativeApp.backbufferResize(width, height, format, activity.getWindowManager().getDefaultDisplay().getRotation()); + reportSurfaceSize(width, height, format); activity.notifySurface(holder.getSurface()); } @Override public void surfaceDestroyed(SurfaceHolder holder) { activity.notifySurface(null); + reportedWidth = 0; + reportedHeight = 0; // Autosize the next created surface. holder.setSizeFromLayout(); } + private void reportSurfaceSize(int width, int height, int format) { + reportedWidth = width; + reportedHeight = height; + reportedFormat = format; + reportedDensityDpi = densityDpi; + NativeApp.backbufferResize(width, height, format, activity.getWindowManager().getDefaultDisplay().getRotation()); + } + + // A density change rescales the UI but leaves the surface size alone, so no surfaceChanged + // follows it to carry the new density to the native side - the DPI is only recalculated in + // backbufferResize. Re-report the surface we already have, or the UI keeps the old scale + // until the next real resize. Call after updateDisplayMeasurements has picked up the change. + public void densityChanged() { + if (reportedWidth <= 0 || densityDpi == reportedDensityDpi) { + return; + } + Log.i(TAG, "Density is now " + densityDpi + ", re-reporting surface " + reportedWidth + "x" + reportedHeight); + reportSurfaceSize(reportedWidth, reportedHeight, reportedFormat); + } + public void updateDisplayMeasurements() { Display display = activity.getWindowManager().getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index d1c1ce07a0..a8b159faf3 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -1075,7 +1075,10 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList // The surface size change that comes with it is what actually updates the native side, except // for this, which the native side was told once at init. Changes on fold/unfold. NativeApp.sendMessageFromJava("smallestScreenWidthDp", String.valueOf(newConfig.smallestScreenWidthDp)); + // This re-measures the display, so the density check below sees the new value. updateSystemUiVisibility(); + // A density change doesn't resize the surface, so it needs separate handling. + surfaceManager.densityChanged(); } @Override