Android: Re-report the surface when the display density changes

Now that density is in configChanges, a density change no longer recreates
the activity - but it also doesn't resize the surface, so no surfaceChanged
follows it. The DPI is only recalculated in backbufferResize, so the UI kept
the old scale until the next real resize or a trip through the background.

Re-report the surface we already have when the density has moved. The native
side needs no change: Recalculate() already returns true when the dp size
changes, which a density change does on its own.

Also make the log line say which size changed, since the pixel size now stays
put in this case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01152igCdjTNhT29qvphPyPC
This commit is contained in:
Henrik RydgårdandClaude Opus 5 committed 2026-10-08 21:51:35 +02:00
1 parent 114512774d
commit a2869a47cd
3 files changed
+38 -2

No files matched your search

+5 -1
View File
@@ -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.");
@@ -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();
@@ -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