Fixed bug 3250 - Wrong backbuffer pixel format on Android, keep getting RGB_565
authorSylvain Becker <sylvain.becker@gmail.com>
Wed, 02 Jan 2019 18:06:33 +0100
changeset 1249382f9397db3e7
parent 12492 fe136f38ab71
child 12494 6053ab61996a
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.
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
src/core/android/SDL_android.c
src/core/android/SDL_android.h
src/video/SDL_egl.c
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Wed Jan 02 17:41:33 2019 +0100
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Wed Jan 02 18:06:33 2019 +0100
     1.3 @@ -530,6 +530,7 @@
     1.4      static final int COMMAND_CHANGE_TITLE = 1;
     1.5      static final int COMMAND_CHANGE_WINDOW_STYLE = 2;
     1.6      static final int COMMAND_TEXTEDIT_HIDE = 3;
     1.7 +    static final int COMMAND_CHANGE_SURFACEVIEW_FORMAT = 4;
     1.8      static final int COMMAND_SET_KEEP_SCREEN_ON = 5;
     1.9  
    1.10      protected static final int COMMAND_USER = 0x8000;
    1.11 @@ -627,6 +628,32 @@
    1.12                  }
    1.13                  break;
    1.14              }
    1.15 +            case COMMAND_CHANGE_SURFACEVIEW_FORMAT:
    1.16 +            {
    1.17 +                int format = ((int)msg.obj);
    1.18 +                int pf;
    1.19 +
    1.20 +                if (SDLActivity.mSurface == null) {
    1.21 +                    return;
    1.22 +                }
    1.23 +
    1.24 +                SurfaceHolder holder = SDLActivity.mSurface.getHolder();
    1.25 +                if (holder == null) {
    1.26 +                    return;
    1.27 +                }
    1.28 +
    1.29 +                if (format == 1) {
    1.30 +                    pf = PixelFormat.RGBA_8888;
    1.31 +                } else if (format == 2) {
    1.32 +                    pf = PixelFormat.RGBX_8888;
    1.33 +                } else {
    1.34 +                    pf = PixelFormat.RGB_565;
    1.35 +                }
    1.36 +
    1.37 +                holder.setFormat(pf);
    1.38 +
    1.39 +                break;
    1.40 +            }
    1.41              default:
    1.42                  if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
    1.43                      Log.e(TAG, "error handling message, command is " + msg.arg1);
    1.44 @@ -1032,6 +1059,14 @@
    1.45          return SDLActivity.mSurface.getNativeSurface();
    1.46      }
    1.47  
    1.48 +    /**
    1.49 +     * This method is called by SDL using JNI.
    1.50 +     */
    1.51 +    public static void setSurfaceViewFormat(int format) {
    1.52 +        mSingleton.sendCommand(COMMAND_CHANGE_SURFACEVIEW_FORMAT, format);
    1.53 +        return;
    1.54 +    }
    1.55 +
    1.56      // Input
    1.57  
    1.58      /**
     2.1 --- a/src/core/android/SDL_android.c	Wed Jan 02 17:41:33 2019 +0100
     2.2 +++ b/src/core/android/SDL_android.c	Wed Jan 02 18:06:33 2019 +0100
     2.3 @@ -222,6 +222,7 @@
     2.4  
     2.5  /* method signatures */
     2.6  static jmethodID midGetNativeSurface;
     2.7 +static jmethodID midSetSurfaceViewFormat;
     2.8  static jmethodID midSetActivityTitle;
     2.9  static jmethodID midSetWindowStyle;
    2.10  static jmethodID midSetOrientation;
    2.11 @@ -327,6 +328,8 @@
    2.12  
    2.13      midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    2.14                                  "getNativeSurface","()Landroid/view/Surface;");
    2.15 +    midSetSurfaceViewFormat = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    2.16 +                                "setSurfaceViewFormat","(I)V");
    2.17      midSetActivityTitle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    2.18                                  "setActivityTitle","(Ljava/lang/String;)Z");
    2.19      midSetWindowStyle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
    2.20 @@ -374,7 +377,7 @@
    2.21      midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setRelativeMouseEnabled", "(Z)Z");
    2.22  
    2.23  
    2.24 -    if (!midGetNativeSurface ||
    2.25 +    if (!midGetNativeSurface || !midSetSurfaceViewFormat ||
    2.26         !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInputGetInputDeviceIds ||
    2.27         !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
    2.28         !midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
    2.29 @@ -964,6 +967,26 @@
    2.30      return anw;
    2.31  }
    2.32  
    2.33 +void Android_JNI_SetSurfaceViewFormat(int format)
    2.34 +{
    2.35 +    JNIEnv *mEnv = Android_JNI_GetEnv();
    2.36 +    int new_format = 0;
    2.37 +
    2.38 +    /* Format from android/native_window.h,
    2.39 +     * convert to temporary arbitrary values,
    2.40 +     * then to java PixelFormat */
    2.41 +    if (format == WINDOW_FORMAT_RGBA_8888) {
    2.42 +        new_format = 1;
    2.43 +    } else if (format == WINDOW_FORMAT_RGBX_8888) {
    2.44 +        new_format = 2;
    2.45 +    } else if (format == WINDOW_FORMAT_RGB_565) {
    2.46 +        /* Default */
    2.47 +        new_format = 0;
    2.48 +    }
    2.49 +
    2.50 +    (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetSurfaceViewFormat, new_format);
    2.51 +}
    2.52 +
    2.53  void Android_JNI_SetActivityTitle(const char *title)
    2.54  {
    2.55      JNIEnv *mEnv = Android_JNI_GetEnv();
     3.1 --- a/src/core/android/SDL_android.h	Wed Jan 02 17:41:33 2019 +0100
     3.2 +++ b/src/core/android/SDL_android.h	Wed Jan 02 18:06:33 2019 +0100
     3.3 @@ -44,6 +44,7 @@
     3.4  extern void Android_JNI_HideTextInput(void);
     3.5  extern SDL_bool Android_JNI_IsScreenKeyboardShown(void);
     3.6  extern ANativeWindow* Android_JNI_GetNativeWindow(void);
     3.7 +extern void Android_JNI_SetSurfaceViewFormat(int format);
     3.8  
     3.9  extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);
    3.10  
     4.1 --- a/src/video/SDL_egl.c	Wed Jan 02 17:41:33 2019 +0100
     4.2 +++ b/src/video/SDL_egl.c	Wed Jan 02 18:06:33 2019 +0100
     4.3 @@ -27,6 +27,7 @@
     4.4  #endif
     4.5  #if SDL_VIDEO_DRIVER_ANDROID
     4.6  #include <android/native_window.h>
     4.7 +#include "../core/android/SDL_android.h"
     4.8  #endif
     4.9  
    4.10  #include "SDL_sysvideo.h"
    4.11 @@ -885,6 +886,10 @@
    4.12                                              EGL_NATIVE_VISUAL_ID, &format);
    4.13  
    4.14          ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
    4.15 +
    4.16 +        /* Update SurfaceView holder format.
    4.17 +         * May triggers a sequence surfaceDestroyed(), surfaceCreated(), surfaceChanged(). */
    4.18 +        Android_JNI_SetSurfaceViewFormat(format);
    4.19      }
    4.20  #endif    
    4.21      if (_this->gl_config.framebuffer_srgb_capable) {