Fixed bug 3250 - Wrong backbuffer pixel format on Android, keep getting RGB_565 Use the egl format to reconfigure java SurfaceView holder format. If there is a change, it triggers a surfaceDestroyed/Created/Change sequence.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index a58ce34..b4d5c46 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -530,6 +530,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
static final int COMMAND_CHANGE_TITLE = 1;
static final int COMMAND_CHANGE_WINDOW_STYLE = 2;
static final int COMMAND_TEXTEDIT_HIDE = 3;
+ static final int COMMAND_CHANGE_SURFACEVIEW_FORMAT = 4;
static final int COMMAND_SET_KEEP_SCREEN_ON = 5;
protected static final int COMMAND_USER = 0x8000;
@@ -627,6 +628,32 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
}
break;
}
+ case COMMAND_CHANGE_SURFACEVIEW_FORMAT:
+ {
+ int format = ((int)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:
if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
Log.e(TAG, "error handling message, command is " + msg.arg1);
@@ -1032,6 +1059,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
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);
+ return;
+ }
+
// Input
/**
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index dd20a2b..9a3ba2b 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -222,6 +222,7 @@ static jclass mActivityClass;
/* method signatures */
static jmethodID midGetNativeSurface;
+static jmethodID midSetSurfaceViewFormat;
static jmethodID midSetActivityTitle;
static jmethodID midSetWindowStyle;
static jmethodID midSetOrientation;
@@ -327,6 +328,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"getNativeSurface","()Landroid/view/Surface;");
+ midSetSurfaceViewFormat = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+ "setSurfaceViewFormat","(I)V");
midSetActivityTitle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"setActivityTitle","(Ljava/lang/String;)Z");
midSetWindowStyle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
@@ -374,7 +377,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setRelativeMouseEnabled", "(Z)Z");
- if (!midGetNativeSurface ||
+ if (!midGetNativeSurface || !midSetSurfaceViewFormat ||
!midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInputGetInputDeviceIds ||
!midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
!midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
@@ -964,6 +967,26 @@ ANativeWindow* Android_JNI_GetNativeWindow(void)
return anw;
}
+void Android_JNI_SetSurfaceViewFormat(int format)
+{
+ JNIEnv *mEnv = 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;
+ }
+
+ (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetSurfaceViewFormat, new_format);
+}
+
void Android_JNI_SetActivityTitle(const char *title)
{
JNIEnv *mEnv = Android_JNI_GetEnv();
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index b2ff32e..1277a74 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -44,6 +44,7 @@ extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect);
extern void Android_JNI_HideTextInput(void);
extern SDL_bool Android_JNI_IsScreenKeyboardShown(void);
extern ANativeWindow* Android_JNI_GetNativeWindow(void);
+extern void Android_JNI_SetSurfaceViewFormat(int format);
extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);
diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c
index dfaf28e..685c65b 100644
--- a/src/video/SDL_egl.c
+++ b/src/video/SDL_egl.c
@@ -27,6 +27,7 @@
#endif
#if SDL_VIDEO_DRIVER_ANDROID
#include <android/native_window.h>
+#include "../core/android/SDL_android.h"
#endif
#include "SDL_sysvideo.h"
@@ -885,6 +886,10 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
+
+ /* Update SurfaceView holder format.
+ * May triggers a sequence surfaceDestroyed(), surfaceCreated(), surfaceChanged(). */
+ Android_JNI_SetSurfaceViewFormat(format);
}
#endif
if (_this->gl_config.framebuffer_srgb_capable) {