fix(SDL): Tab out crashing game

This commit is contained in:
tomikun
2026-07-08 13:35:12 +08:00
parent d8a195640a
commit a31b594db5
2 changed files with 41 additions and 13 deletions

View File

@@ -146,6 +146,8 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
public void surfaceCreated(@NonNull SurfaceHolder holder) {
if(isCalled) {
JREUtils.setupBridgeWindow(mNativeSurface);
if (sdlEnabled) SDLSurface.setNativeSurface(mNativeSurface);
refreshSize(true);
return;
}
isCalled = true;
@@ -155,6 +157,9 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
// Don't use the scaled resolution, SDL doesn't work like that, it'll render offscreen instead.
// The first two args go unused, you can put any garbage in em.
if (sdlEnabled) SDLActivity.getSDLSurface().surfaceChanged(holder, format, Tools.currentDisplayMetrics.widthPixels, Tools.currentDisplayMetrics.heightPixels);
refreshSize();
}
@@ -167,6 +172,7 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
window, it appears to automatically release the associated ANativeWindow. This
can cause a crash if not handled.
*/
if (sdlEnabled) SDLActivity.getSDLSurface().surfaceDestroyed(holder);
}
});
@@ -185,6 +191,7 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
setupSDL(getContext(), mNativeSurface, (ViewGroup) getParent());
if(isCalled) {
JREUtils.setupBridgeWindow(mNativeSurface);
if (sdlEnabled) SDLSurface.setNativeSurface(mNativeSurface);
return;
}
isCalled = true;
@@ -194,6 +201,9 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
// Don't use the scaled resolution, SDL doesn't work like that, it'll render offscreen instead.
// The first two args go unused, you can put any garbage in em.
if (sdlEnabled) SDLActivity.getSDLSurface().surfaceChanged(null, 0, Tools.currentDisplayMetrics.widthPixels, Tools.currentDisplayMetrics.heightPixels);
refreshSize();
}
@@ -204,6 +214,7 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
into a floating window. Subsequent turns to floating window no longer trigger
recreation. Tabbing out and in does not trigger recreation.
*/
if (sdlEnabled) SDLActivity.getSDLSurface().surfaceDestroyed(null);
return true;
}
@@ -424,14 +435,23 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
post(this::refreshSize);
return;
}
// Use the width and height of the View instead of display dimensions to avoid
// getting squiched/stretched due to inconsistencies between the layout and
// screen dimensions.
int newWidth = Tools.getDisplayFriendlyRes(getWidth(), LauncherPreferences.PREF_SCALE_FACTOR);
int newHeight = Tools.getDisplayFriendlyRes(getHeight(), LauncherPreferences.PREF_SCALE_FACTOR);
if (newHeight < 1 || newWidth < 1) {
Log.e("MGLSurface", String.format("Impossible resolution : %dx%d", newWidth, newHeight));
return;
int newWidth;
int newHeight;
if (sdlEnabled) {
// We don't support windows that aren't stretched to fullscreen, but SDL has a different
// way of handling changing res, that is via SDL_SetRenderLogicalPresentation
newWidth = getWidth();
newHeight = getHeight();
} else {
// Use the width and height of the View instead of display dimensions to avoid
// getting squiched/stretched due to inconsistencies between the layout and
// screen dimensions.
newWidth = Tools.getDisplayFriendlyRes(getWidth(), LauncherPreferences.PREF_SCALE_FACTOR);
newHeight = Tools.getDisplayFriendlyRes(getHeight(), LauncherPreferences.PREF_SCALE_FACTOR);
if (newHeight < 1 || newWidth < 1) {
Log.e("MGLSurface", String.format("Impossible resolution : %dx%d", newWidth, newHeight));
return;
}
}
windowWidth = newWidth;
windowHeight = newHeight;
@@ -452,7 +472,6 @@ public class MinecraftGLSurface extends View implements GrabListener, DirectGame
}
CallbackBridge.sendUpdateWindowSize(windowWidth, windowHeight);
}
private void realStart(Surface surface){

View File

@@ -31,6 +31,7 @@ import android.view.WindowManager;
import android.view.ScaleGestureDetector;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
/**
SDLSurface. This is what we draw on, so we need to know when it's created
@@ -78,9 +79,14 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
setOnGenericMotionListener(SDLActivity.getMotionListener());
// Some arbitrary defaults to avoid a potential division by zero
mWidth = 1.0f;
mHeight = 1.0f;
// // Some arbitrary defaults to avoid a potential division by zero
// mWidth = 1.0f;
// mHeight = 1.0f;
// These values are used in calculating the position of inputs. SDL's scaling is independent
// of those, it only cares about the actual native surface resolution. Logical rendering
// resolution is set via SDL_SetRenderLogicalPresentation, not here.
mWidth = Tools.currentDisplayMetrics.widthPixels;
mHeight = Tools.currentDisplayMetrics.heightPixels;
mIsSurfaceReady = false;
}
@@ -105,6 +111,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
public static void setNativeSurface(Surface nativeSurface) {
mNativeSurface = nativeSurface;
SDLActivity.getSDLSurface().surfaceCreated(null);
}
// Called when we have a valid drawing surface
@@ -162,7 +169,9 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
// In case we're waiting on a size change after going fullscreen, send a notification.
SDLActivity.getContext().notifyAll();
}
// We must always be full screen because SDL uses a different mechanism for downscaling.
// TODO: Add resolution slider support for SDL via SDL_SetRenderLogicalPresentation
LauncherPreferences.PREF_SCALE_FACTOR = 1f;
Log.v("SDL", "Window size: " + width + "x" + height);
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, density, mDisplay.getRefreshRate());