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 2774

Summary: Android: screen distorted in Landscape after background/foreground
Product: SDL Reporter: Sylvain <sylvain.becker>
Component: *don't know*Assignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: gabomdq
Version: 2.0.3   
Hardware: ARM   
OS: Android (All)   
Attachments: video of the bug
testsprite2 starts in landscape
testsprite2 in landscape, after background/foreground
discard surfaceChanged
discard surfaceChanged v2

Description Sylvain 2014-11-01 15:22:11 UTC
Created attachment 1922 [details]
video of the bug

With a Landscape application.
Going to background with Home Key, then foreground.
The screen is distorted.

This has been reported by Samsung. It happens on S5 and Samsung Alpha, see the video attached.

I have captured the following logcat: 

V/SDL     (20549): onResume()
V/SDL     (20549): surfaceCreated()
V/SDL     (20549): surfaceChanged()
V/SDL     (20549): pixel format RGB_565
V/SDL     (20549): Window size:1920x1080
I/SDL     (20549): SDL_Android_Init()
I/SDL     (20549): SDL_Android_Init() finished!
V/SDL     (20549): SDL audio: opening device
V/SDL     (20549): SDL audio: wanted stereo 16-bit 22.05kHz, 256 frames buffer
V/SDL     (20549): SDL audio: got stereo 16-bit 22.05kHz, 1764 frames buffer
V/SDL     (20549): onWindowFocusChanged(): true
V/SDL     (20549): onWindowFocusChanged(): false
V/SDL     (20549): onPause()
V/SDL     (20549): nativePause()
V/SDL     (20549): surfaceDestroyed()

Background / Foreground

V/SDL     (20549): onResume()
V/SDL     (20549): surfaceCreated()
V/SDL     (20549): surfaceChanged()
V/SDL     (20549): pixel format RGB_565
V/SDL     (20549): Window size:1080x1920
V/SDL     (20549): surfaceChanged()
V/SDL     (20549): pixel format RGB_565
V/SDL     (20549): Window size:1920x1080
V/SDL     (20549): onWindowFocusChanged(): true
V/SDL     (20549): nativeResume()



This seems to be related to the fact that I have in "AndroidManifest.xml": 
android:configChanges="..."
Because of the fields: "orientation" and also "screenSize".


The following patch works (in Java_org_libsdl_app_SDLActivity_onNativeSurfaceChanged):

diff -r 741700a12835 src/core/android/SDL_android.c

--- a/src/core/android/SDL_android.c	Fri Oct 24 11:53:34 2014 +0200
+++ b/src/core/android/SDL_android.c	Sat Nov 01 15:33:52 2014 +0100
@@ -224,6 +224,18 @@
         }
         data->native_window = Android_JNI_GetNativeWindow();
         data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
+    } else {
+
+        SDL_EGL_MakeCurrent(_this, NULL, NULL);
+        SDL_EGL_DestroySurface(_this, data->egl_surface);
+
+        if(data->native_window) {
+            ANativeWindow_release(data->native_window);
+        }
+
+        data->native_window = Android_JNI_GetNativeWindow();
+        data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
+ 
     }

And also a shorter version works:

+        SDL_EGL_MakeCurrent(_this, NULL, NULL);
+        SDL_EGL_DestroySurface(_this, data->egl_surface);
+        data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);


I looked deeper into "SDL_EGL_CreateSurface" and I tried this, but it did not work:

+        data->native_window = Android_JNI_GetNativeWindow();
+        ANativeWindow_setBuffersGeometry(data->native_window,
+          ANativeWindow_getWidth(data->native_window),
+          ANativeWindow_getHeight(data->native_window),
+          ANativeWindow_getFormat(data->native_window));
Comment 1 Sylvain 2014-11-02 10:31:59 UTC
Some update: 

It works if I remove this line from my application: 
  
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);

So, it seems to be also related to the choice of the EGL configuration.


I have tried testgles2 and testsprite2. Both have this issue.
Provided that: 
- set the landscape mode
- comment out all the SDL_GL_SetAttribute in "SDL_test_common.c"
- add SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
Comment 2 Sylvain 2014-11-04 18:35:21 UTC
Created attachment 1923 [details]
testsprite2 starts in landscape
Comment 3 Sylvain 2014-11-04 18:36:11 UTC
Created attachment 1924 [details]
testsprite2 in landscape, after background/foreground
Comment 4 Sylvain 2014-11-04 18:42:04 UTC
I have just attached two screen shots of testsprite2 :
- when it starts
- after background/foreground

the screen is distorted : 
- stretched
- shifter to the right


About the video. Notice it has garbage on the left part of the screen. Because I don't do a "RenderClear" before writing each frame.
Comment 5 Sylvain 2014-11-04 18:45:14 UTC
I have played with the egl configs, by hardcoding the config no to load. 

They all works when it starts! (no red screen ...)

25% of them have this is issue of landscape-background-foreground.
With (so far) no apparent reason.
Comment 6 Sylvain 2014-11-14 15:27:48 UTC
Please ignore the above patch. It adds some problem when going back to the application from the lock-screen.


I have looked for another way to solve the issue. Discarding the "surfaceChanged" call, based on the "requestedOrientation" and the new Orientation. It seems to be better.


On my failing test case, the first "surfaceChanged()" is discarded. Sometimes the "focusChanged()" might appear between the two "surfaceChanged()", while the surface is not yet ready. Thus, discarding also the "nativeResume()".

So, for robustness, a call to "nativeResume()" is added at the end of "surfaceChanged()". 

Let me know about the following patch.
Comment 7 Sylvain 2014-11-14 15:30:02 UTC
Created attachment 1932 [details]
discard surfaceChanged

discard surfaceChanged base on orientation.
Comment 8 Sam Lantinga 2014-11-29 22:47:19 UTC
Gabriel, can you look at this patch and see if it's good for 2.0.4?

Thanks!
Comment 9 Sylvain 2014-11-30 07:07:18 UTC
Created attachment 1946 [details]
discard surfaceChanged v2
Comment 10 Sylvain 2014-11-30 07:23:42 UTC
Some update: 

1/ First I tried, to discard the surface using the current orientation (rather than width / heigh). -> that solve the issue sometimes, but not always.

2/ Samsung Certification now accepts my application that were previously failing. 

3/ I personally now owns a Samsung S5, and was able to solve the issue on my side.

4/ I now use the patch and get no complaints from my users. (but I admit, nobody seemed to be complaining before neither...).

5/ I have added a v2 because of a new smart-phone called "Black Berry Passport" that has a square screen of 1440x1440. This screen has a "status bar" so the resolution is in fact : 1440x1308. (as reported by "surfaceChanged").

Problem is: the portrait resolution is in fact a Landscape!

So the "v1" patch is always discarding the "surface" of BlackBerry Passport. Which is terribly bad. 


Hence, I added the "v2" patch not to discard the surface when aspect ratio is < 1.20. (BB 1440/1308 is : 1.1009). Which seems fair.
Comment 11 Sam Lantinga 2015-06-17 05:17:21 UTC
Fixed, thanks!
https://hg.libsdl.org/SDL/rev/a1b920bc870d