We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3250 - Wrong backbuffer pixel format on Android, keep getting RGB_565
Summary: Wrong backbuffer pixel format on Android, keep getting RGB_565
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: video (show other bugs)
Version: HG 2.1
Hardware: ARM Android (All)
: P2 normal
Assignee: Sylvain
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-01-28 03:48 UTC by Onat Turkcuoglu
Modified: 2019-01-05 21:35 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Onat Turkcuoglu 2016-01-28 03:48:21 UTC
I cannot create a backbuffer with pixel format RGBA_8888 or any other format for that matter on Android.
I tried setting SDL_GL_SetAttribute with many different values, the devices I tested definitely support the pixel format, yet I keep getting the RGB_565 pixel format.
These are the devices I tested on:
Nvidia Shield 2015
LG G Flex 2
Samsung Galaxy S3

This is the log:
V/SDL     (13984): onCreate(): null
V/SDL     (13984): onResume()
V/SDL     (13984): surfaceCreated()
V/SDL     (13984): surfaceChanged()
V/SDL     (13984): pixel format RGB_565
V/SDL     (13984): Window size: 1200x1824
I/SDL     (13984): SDL_Android_Init()
I/SDL     (13984): SDL_Android_Init() finished!
V/SDL     (13984): onWindowFocusChanged(): true
Comment 1 Sylvain 2017-08-12 19:44:22 UTC
I think you need to modify SDLActivity.java to do that : 

public SDLSurface(Context context) {
         super(context);
         getHolder().addCallback(this);
         getHolder().setFormat(PixelFormat.RGBA_8888); // Add this line & set the format there.
Comment 2 Sam Lantinga 2017-08-12 22:27:54 UTC
Sylvain, shouldn't we be taking the surface format from the desired EGL depth?
Comment 3 Sylvain 2017-08-13 13:12:56 UTC
Indeed you're right, it seems enough to set:
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);


After that, the calls to "eglGetConfigAttrib" and "ANativeWindow_setBuffersGeometry" report and use a "format == 1 ".
(https://hg.libsdl.org/SDL/file/f7abcb63e51e/src/video/SDL_egl.c#l726 ).
Which means WINDOW_FORMAT_RGBA_8888. (see the file android/native_window.h)


But, what is strange is that the SDLActivity java function surfaceChanged would still report RGB_565.
https://developer.android.com/reference/android/view/SurfaceHolder.Callback.html#surfaceChanged(android.view.SurfaceHolder,%20int,%20int,%20int)

(for the first call that could make sense (default value), then egl re-configure the java surface, but after some foreground/background, surfaceChanged still reports RGB_565)




Android ndk:  android/native_window.h

 26 /*
 27  * Pixel formats that a window can use.
 28  */
 29 enum {
 30     WINDOW_FORMAT_RGBA_8888          = 1,
 31     WINDOW_FORMAT_RGBX_8888          = 2,
 32     WINDOW_FORMAT_RGB_565            = 4,
 33 };

 88 /*
 89  * Change the format and size of the window buffers.
 90  *
 91  * The width and height control the number of pixels in the buffers, not the
 92  * dimensions of the window on screen.  If these are different than the
 93  * window's physical size, then it buffer will be scaled to match that size
 94  * when compositing it to the screen.
 95  *
 96  * For all of these parameters, if 0 is supplied then the window's base
 97  * value will come back in force.
 98  *
 99  * width and height must be either both zero or both non-zero.
100  *
101  */
102 int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
103
Comment 4 Sylvain 2019-01-02 17:12:40 UTC
I have fixed in: https://hg.libsdl.org/SDL/rev/82f9397db3e7

Once you have the EGL format, it calls "Android_JNI_SetSurfaceViewFormat" to reconfigure the java SurfaceView holder format with it.

(Not much difference, but maybe it's the reason for the black screen on some phone ..)
Comment 5 Sylvain 2019-01-02 17:14:59 UTC
Marked as fixed!
Comment 6 Sylvain 2019-01-04 22:54:21 UTC
A corner from the patch is fixed here: https://hg.libsdl.org/SDL/rev/bedfecf09e71
Test-case:

Set
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);

So that it will trigger a SurfaceView holder reconfiguration after the window is created (eg surfaceDestroyed/Created/Change sequence).

Add a SDL_Delay(500) and start rendering. (This is for the test-case, but it can be considered as loading resources).

- event loop is filled with 

SDL_WINDOWEVENT_ENTER
SDL_WINDOWEVENT_FOCUS_LOST
SDL_WINDOWEVENT_MINIMIZED
SDL_APP_WILL ENTER BACKGROUND
SDL_APP_DID ENTER BACKGROUND
SDL_APP_WILL ENTER FOREGROUND
SDL_APP_DID ENTER FOREGROUND
SDL_WINDOWEVENT_FOCUS_GAINED
SDL_WINDOWEVENT_RESTORED

- The extra surfaceDestroyed/Created/Change is destroying EGL_Surface, Creating a new one, but not doing MakeCurrent.

Application starts polling, and render with no context made current. 
First eglSwapBuffers reports EGL_BAD_SURFACE.

At second polling, it does the pause/resume, hence backup-restore and make current and it renders.

With the patch, backup-restore and make current is done after SDL_APP_DID ENTER BACKGROUND is consumed.
Comment 7 Sylvain 2019-01-05 21:35:10 UTC
Another corner case: https://hg.libsdl.org/SDL/rev/b5f8e6c420c2

Can be triggered by putting the screen off (manually), as soon as the app starts