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
6 changed files with 70 additions and 108 deletions

View File

@@ -28,6 +28,7 @@
#if SDL_VIDEO_DRIVER_ANDROID
#include <android/native_window.h>
#include "../core/android/SDL_android.h"
#include "../video/android/SDL_androidvideo.h"
#endif
#include "SDL_sysvideo.h"
@@ -1132,6 +1133,10 @@ SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
EGLSurface *
SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
{
#if SDL_VIDEO_DRIVER_ANDROID
EGLint format_wanted;
EGLint format_got;
#endif
/* max 2 values plus terminator. */
EGLint attribs[3];
int attr = 0;
@@ -1141,24 +1146,18 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
if (SDL_EGL_ChooseConfig(_this) != 0) {
return EGL_NO_SURFACE;
}
#if SDL_VIDEO_DRIVER_ANDROID
{
/* Android docs recommend doing this!
* Ref: http://developer.android.com/reference/android/app/NativeActivity.html
*/
EGLint format;
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
_this->egl_data->egl_config,
EGL_NATIVE_VISUAL_ID, &format);
/* On Android, EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). */
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
_this->egl_data->egl_config,
EGL_NATIVE_VISUAL_ID, &format_wanted);
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) {
#ifdef 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) {
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;
}

View File

@@ -64,7 +64,7 @@ int Android_SurfaceWidth = 0;
int Android_SurfaceHeight = 0;
static int Android_DeviceWidth = 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;
SDL_sem *Android_PauseSem = NULL;
SDL_sem *Android_ResumeSem = NULL;
@@ -194,7 +194,7 @@ Android_VideoInit(_THIS)
return -1;
}
display = SDL_GetDisplay(display_index);
display->orientation = Android_JNI_GetDisplayOrientation();
display->orientation = Android_JNI_GetDisplayOrientation();
SDL_AddDisplayMode(&_this->displays[0], &mode);
@@ -222,16 +222,54 @@ Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi
}
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_SurfaceHeight = surfaceHeight;
Android_DeviceWidth = deviceWidth;
Android_DeviceHeight = deviceHeight;
Android_ScreenFormat = format;
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)
{
/*

View File

@@ -28,7 +28,8 @@
#include "../SDL_sysvideo.h"
/* 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);
/* Private display data */