Android: don't need to set the SurfaceHolder format from java code

It's already set with ANativeWindow_setGeometry, and eventually set/changed also by eglCreateWindowSurface.
 - avoid issues with older device where SurfaceView cycle create/changed/destroy appears broken:
   calling create/changed/changed, and leading to "deuqueBuffer failed at server side, error: -19", with black screen.
 - re-read the format after egl window surface is created, to report the correct one (sometimes, changed from RGBA8888 to RGB24)
This commit is contained in:
Sylvain 2021-04-22 18:06:17 +02:00
parent 8e3ec34d34
commit 98a966d1c2
No known key found for this signature in database
GPG Key ID: 5F87E02E5BC0939E
6 changed files with 70 additions and 108 deletions

View File

@ -605,7 +605,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
static final int COMMAND_CHANGE_TITLE = 1; static final int COMMAND_CHANGE_TITLE = 1;
static final int COMMAND_CHANGE_WINDOW_STYLE = 2; static final int COMMAND_CHANGE_WINDOW_STYLE = 2;
static final int COMMAND_TEXTEDIT_HIDE = 3; static final int COMMAND_TEXTEDIT_HIDE = 3;
static final int COMMAND_CHANGE_SURFACEVIEW_FORMAT = 4;
static final int COMMAND_SET_KEEP_SCREEN_ON = 5; static final int COMMAND_SET_KEEP_SCREEN_ON = 5;
protected static final int COMMAND_USER = 0x8000; protected static final int COMMAND_USER = 0x8000;
@ -703,32 +702,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
} }
break; break;
} }
case COMMAND_CHANGE_SURFACEVIEW_FORMAT:
{
int format = (Integer) msg.obj;
int pf;
if (SDLActivity.mSurface == null) {
return;
}
SurfaceHolder holder = SDLActivity.mSurface.getHolder();
if (holder == null) {
return;
}
if (format == 1) {
pf = PixelFormat.RGBA_8888;
} else if (format == 2) {
pf = PixelFormat.RGBX_8888;
} else {
pf = PixelFormat.RGB_565;
}
holder.setFormat(pf);
break;
}
default: default:
if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) { if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
Log.e(TAG, "error handling message, command is " + msg.arg1); Log.e(TAG, "error handling message, command is " + msg.arg1);
@ -812,7 +785,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
public static native void nativeResume(); public static native void nativeResume();
public static native void nativeFocusChanged(boolean hasFocus); public static native void nativeFocusChanged(boolean hasFocus);
public static native void onNativeDropFile(String filename); public static native void onNativeDropFile(String filename);
public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, int format, float rate); public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate);
public static native void onNativeResize(); public static native void onNativeResize();
public static native void onNativeKeyDown(int keycode); public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode); public static native void onNativeKeyUp(int keycode);
@ -1218,13 +1191,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return SDLActivity.mSurface.getNativeSurface(); return SDLActivity.mSurface.getNativeSurface();
} }
/**
* This method is called by SDL using JNI.
*/
public static void setSurfaceViewFormat(int format) {
mSingleton.sendCommand(COMMAND_CHANGE_SURFACEVIEW_FORMAT, format);
}
// Input // Input
/** /**
@ -1796,30 +1762,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
return; return;
} }
int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
switch (format) {
case PixelFormat.RGBA_8888:
Log.v("SDL", "pixel format RGBA_8888");
sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
break;
case PixelFormat.RGBX_8888:
Log.v("SDL", "pixel format RGBX_8888");
sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
break;
case PixelFormat.RGB_565:
Log.v("SDL", "pixel format RGB_565");
sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
break;
case PixelFormat.RGB_888:
Log.v("SDL", "pixel format RGB_888");
// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
break;
default:
Log.v("SDL", "pixel format unknown " + format);
break;
}
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
int nDeviceWidth = width; int nDeviceWidth = width;
@ -1842,7 +1784,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
Log.v("SDL", "Window size: " + width + "x" + height); Log.v("SDL", "Window size: " + width + "x" + height);
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight); Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate()); SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, mDisplay.getRefreshRate());
SDLActivity.onNativeResize(); SDLActivity.onNativeResize();
// Prevent a screen distortion glitch, // Prevent a screen distortion glitch,

View File

@ -79,7 +79,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
JNIEnv *env, jclass jcls, JNIEnv *env, jclass jcls,
jint surfaceWidth, jint surfaceHeight, jint surfaceWidth, jint surfaceHeight,
jint deviceWidth, jint deviceHeight, jint format, jfloat rate); jint deviceWidth, jint deviceHeight, jfloat rate);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
JNIEnv *env, jclass cls); JNIEnv *env, jclass cls);
@ -168,7 +168,7 @@ static JNINativeMethod SDLActivity_tab[] = {
{ "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) }, { "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
{ "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) }, { "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) },
{ "onNativeDropFile", "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) }, { "onNativeDropFile", "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) },
{ "nativeSetScreenResolution", "(IIIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) }, { "nativeSetScreenResolution", "(IIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) },
{ "onNativeResize", "()V", SDL_JAVA_INTERFACE(onNativeResize) }, { "onNativeResize", "()V", SDL_JAVA_INTERFACE(onNativeResize) },
{ "onNativeSurfaceCreated", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) }, { "onNativeSurfaceCreated", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) },
{ "onNativeSurfaceChanged", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) }, { "onNativeSurfaceChanged", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) },
@ -318,7 +318,6 @@ static jmethodID midSetActivityTitle;
static jmethodID midSetCustomCursor; static jmethodID midSetCustomCursor;
static jmethodID midSetOrientation; static jmethodID midSetOrientation;
static jmethodID midSetRelativeMouseEnabled; static jmethodID midSetRelativeMouseEnabled;
static jmethodID midSetSurfaceViewFormat;
static jmethodID midSetSystemCursor; static jmethodID midSetSystemCursor;
static jmethodID midSetWindowStyle; static jmethodID midSetWindowStyle;
static jmethodID midShouldMinimizeOnFocusLoss; static jmethodID midShouldMinimizeOnFocusLoss;
@ -598,7 +597,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setCustomCursor", "(I)Z"); midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setCustomCursor", "(I)Z");
midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass, "setOrientation","(IIZLjava/lang/String;)V"); midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass, "setOrientation","(IIZLjava/lang/String;)V");
midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass, "setRelativeMouseEnabled", "(Z)Z"); midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass, "setRelativeMouseEnabled", "(Z)Z");
midSetSurfaceViewFormat = (*env)->GetStaticMethodID(env, mActivityClass, "setSurfaceViewFormat","(I)V");
midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setSystemCursor", "(I)Z"); midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setSystemCursor", "(I)Z");
midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass, "setWindowStyle","(Z)V"); midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass, "setWindowStyle","(Z)V");
midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass, "shouldMinimizeOnFocusLoss","()Z"); midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass, "shouldMinimizeOnFocusLoss","()Z");
@ -629,7 +627,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
!midSetCustomCursor || !midSetCustomCursor ||
!midSetOrientation || !midSetOrientation ||
!midSetRelativeMouseEnabled || !midSetRelativeMouseEnabled ||
!midSetSurfaceViewFormat ||
!midSetSystemCursor || !midSetSystemCursor ||
!midSetWindowStyle || !midSetWindowStyle ||
!midShouldMinimizeOnFocusLoss || !midShouldMinimizeOnFocusLoss ||
@ -845,11 +842,11 @@ retry:
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
JNIEnv *env, jclass jcls, JNIEnv *env, jclass jcls,
jint surfaceWidth, jint surfaceHeight, jint surfaceWidth, jint surfaceHeight,
jint deviceWidth, jint deviceHeight, jint format, jfloat rate) jint deviceWidth, jint deviceHeight, jfloat rate)
{ {
SDL_LockMutex(Android_ActivityMutex); SDL_LockMutex(Android_ActivityMutex);
Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate); Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, rate);
SDL_UnlockMutex(Android_ActivityMutex); SDL_UnlockMutex(Android_ActivityMutex);
} }
@ -1384,26 +1381,6 @@ ANativeWindow* Android_JNI_GetNativeWindow(void)
return anw; return anw;
} }
void Android_JNI_SetSurfaceViewFormat(int format)
{
JNIEnv *env = Android_JNI_GetEnv();
int new_format = 0;
/* Format from android/native_window.h,
* convert to temporary arbitrary values,
* then to java PixelFormat */
if (format == WINDOW_FORMAT_RGBA_8888) {
new_format = 1;
} else if (format == WINDOW_FORMAT_RGBX_8888) {
new_format = 2;
} else if (format == WINDOW_FORMAT_RGB_565) {
/* Default */
new_format = 0;
}
(*env)->CallStaticVoidMethod(env, mActivityClass, midSetSurfaceViewFormat, new_format);
}
void Android_JNI_SetActivityTitle(const char *title) void Android_JNI_SetActivityTitle(const char *title)
{ {
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();

View File

@ -47,7 +47,6 @@ extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect);
extern void Android_JNI_HideTextInput(void); extern void Android_JNI_HideTextInput(void);
extern SDL_bool Android_JNI_IsScreenKeyboardShown(void); extern SDL_bool Android_JNI_IsScreenKeyboardShown(void);
extern ANativeWindow* Android_JNI_GetNativeWindow(void); extern ANativeWindow* Android_JNI_GetNativeWindow(void);
extern void Android_JNI_SetSurfaceViewFormat(int format);
extern SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void); extern SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void);
extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi); extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);

View File

@ -28,6 +28,7 @@
#if SDL_VIDEO_DRIVER_ANDROID #if SDL_VIDEO_DRIVER_ANDROID
#include <android/native_window.h> #include <android/native_window.h>
#include "../core/android/SDL_android.h" #include "../core/android/SDL_android.h"
#include "../video/android/SDL_androidvideo.h"
#endif #endif
#include "SDL_sysvideo.h" #include "SDL_sysvideo.h"
@ -1132,6 +1133,10 @@ SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
EGLSurface * EGLSurface *
SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
{ {
#if SDL_VIDEO_DRIVER_ANDROID
EGLint format_wanted;
EGLint format_got;
#endif
/* max 2 values plus terminator. */ /* max 2 values plus terminator. */
EGLint attribs[3]; EGLint attribs[3];
int attr = 0; int attr = 0;
@ -1141,24 +1146,18 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
if (SDL_EGL_ChooseConfig(_this) != 0) { if (SDL_EGL_ChooseConfig(_this) != 0) {
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
#if SDL_VIDEO_DRIVER_ANDROID #if SDL_VIDEO_DRIVER_ANDROID
{ /* On Android, EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
/* Android docs recommend doing this! * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). */
* Ref: http://developer.android.com/reference/android/app/NativeActivity.html _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
*/ _this->egl_data->egl_config,
EGLint format; EGL_NATIVE_VISUAL_ID, &format_wanted);
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
_this->egl_data->egl_config,
EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(nw, 0, 0, format); /* Format based on selected egl config. */
ANativeWindow_setBuffersGeometry(nw, 0, 0, format_wanted);
#endif
/* Update SurfaceView holder format.
* May triggers a sequence surfaceDestroyed(), surfaceCreated(), surfaceChanged(). */
Android_JNI_SetSurfaceViewFormat(format);
}
#endif
if (_this->gl_config.framebuffer_srgb_capable) { if (_this->gl_config.framebuffer_srgb_capable) {
#ifdef EGL_KHR_gl_colorspace #ifdef EGL_KHR_gl_colorspace
if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) { if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) {
@ -1181,6 +1180,12 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
if (surface == EGL_NO_SURFACE) { if (surface == EGL_NO_SURFACE) {
SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface"); SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
} }
#if SDL_VIDEO_DRIVER_ANDROID
format_got = ANativeWindow_getFormat(nw);
Android_SetFormat(format_wanted, format_got);
#endif
return surface; return surface;
} }

View File

@ -64,7 +64,7 @@ int Android_SurfaceWidth = 0;
int Android_SurfaceHeight = 0; int Android_SurfaceHeight = 0;
static int Android_DeviceWidth = 0; static int Android_DeviceWidth = 0;
static int Android_DeviceHeight = 0; static int Android_DeviceHeight = 0;
static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN; static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; /* Default SurfaceView format, in case this is queried before being filled */
static int Android_ScreenRate = 0; static int Android_ScreenRate = 0;
SDL_sem *Android_PauseSem = NULL; SDL_sem *Android_PauseSem = NULL;
SDL_sem *Android_ResumeSem = NULL; SDL_sem *Android_ResumeSem = NULL;
@ -194,7 +194,7 @@ Android_VideoInit(_THIS)
return -1; return -1;
} }
display = SDL_GetDisplay(display_index); display = SDL_GetDisplay(display_index);
display->orientation = Android_JNI_GetDisplayOrientation(); display->orientation = Android_JNI_GetDisplayOrientation();
SDL_AddDisplayMode(&_this->displays[0], &mode); SDL_AddDisplayMode(&_this->displays[0], &mode);
@ -222,16 +222,54 @@ Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi
} }
void void
Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate) Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate)
{ {
Android_SurfaceWidth = surfaceWidth; Android_SurfaceWidth = surfaceWidth;
Android_SurfaceHeight = surfaceHeight; Android_SurfaceHeight = surfaceHeight;
Android_DeviceWidth = deviceWidth; Android_DeviceWidth = deviceWidth;
Android_DeviceHeight = deviceHeight; Android_DeviceHeight = deviceHeight;
Android_ScreenFormat = format;
Android_ScreenRate = (int)rate; Android_ScreenRate = (int)rate;
} }
static
Uint32 format_to_pixelFormat(int format) {
Uint32 pf;
if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { /* 1 */
pf = SDL_PIXELFORMAT_RGBA8888;
} else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { /* 2 */
pf = SDL_PIXELFORMAT_RGBX8888;
} else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { /* 3 */
pf = SDL_PIXELFORMAT_RGB24;
} else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { /* 4*/
pf = SDL_PIXELFORMAT_RGB565;
} else if (format == 5) {
pf = SDL_PIXELFORMAT_BGRA8888;
} else if (format == 6) {
pf = SDL_PIXELFORMAT_RGBA5551;
} else if (format == 7) {
pf = SDL_PIXELFORMAT_RGBA4444;
} else {
pf = SDL_PIXELFORMAT_UNKNOWN;
}
return pf;
}
void
Android_SetFormat(int format_wanted, int format_got)
{
Uint32 pf_wanted;
Uint32 pf_got;
pf_wanted = format_to_pixelFormat(format_wanted);
pf_got = format_to_pixelFormat(format_got);
Android_ScreenFormat = pf_got;
SDL_Log("pixel format wanted %s (%d), got %s (%d)",
SDL_GetPixelFormatName(pf_wanted), format_wanted,
SDL_GetPixelFormatName(pf_got), format_got);
}
void Android_SendResize(SDL_Window *window) void Android_SendResize(SDL_Window *window)
{ {
/* /*

View File

@ -28,7 +28,8 @@
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
/* Called by the JNI layer when the screen changes size or format */ /* Called by the JNI layer when the screen changes size or format */
extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate); extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate);
extern void Android_SetFormat(int format_wanted, int format_got);
extern void Android_SendResize(SDL_Window *window); extern void Android_SendResize(SDL_Window *window);
/* Private display data */ /* Private display data */