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 2044

Summary: Android : pause/resume (focus gained/lost)
Product: SDL Reporter: Sylvain <sylvain.becker>
Component: *don't know*Assignee: Gabriel Jacobo <gabomdq>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: HG 2.0   
Hardware: ARM   
OS: Android (All)   
Attachments: more detailed logcat
logcat1
logcat2
logcat3
SDLActivity.java modified for exit
AndroidManitfest.xml modified
logcat4
main_bug_pauseresume.c

Description Sylvain 2013-08-16 03:36:23 UTC
Hi,

I try with lastest (August 16th), and the one from August 9th, I believe this is a regression. 
It does not work anymore on Android 2.3.3 (API 10) : both on phone and emulator.
But it works fine on Android 4.2.2.
I am pretty sure it used to work correctly, one or two month ago!

Start the application,  press the home button, then try to reload the application -> only a black screen appear.

The SDL correctly sends the events Focus_Lost, then Focus_Gained.

In logcat, I see, when pressing home : 
------------------------------------

08-16 07:32:17.984  2453  2453 D PhoneWindow: couldn't save which view has focus because the focused view org.libsdl.app.SDLSurface@404f9570 has no id.

08-16 07:32:17.984  1389  1420 I ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.motorola.blur.home/.HomeActivity } from pid 1389

08-16 07:32:17.991  2453  2453 V SDL     : onPause()
08-16 07:32:17.991  2453  2453 E libEGL  : call to OpenGL ES API with no current context (logged once per thread)

08-16 07:32:17.991  2453  2453 V SDL     : nativePause()

08-16 07:32:17.999  2453  2469 E void Appli::lost_focus(): Application Inactive

When resuming :
-------------

08-16 07:32:38.491  1389  1550 I ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=net.jeu.solitaire/.MainActivity } from pid 1499

08-16 07:32:38.507  2453  2453 V SDL     : onResume()
08-16 07:32:38.515  2453  2453 V SDL     : surfaceCreated()
08-16 07:32:38.530  2453  2453 V SDL     : surfaceChanged()
08-16 07:32:38.530  2453  2453 V SDL     : pixel format RGB_565
08-16 07:32:38.530  2453  2453 V SDL     : Window size:480x854
08-16 07:32:38.546  2453  2453 V SDL     : onWindowFocusChanged(): true
08-16 07:32:38.546  2453  2453 V SDL     : nativeResume()
08-16 07:32:38.554  2453  2469 V SDL     : Creating new EGL Surface

08-16 07:32:38.554  2453  2469 E Surface : [Surface] using an invalid surface, identity=33 should be 38

08-16 07:32:38.554  2453  2469 E Surface : [Surface] using an invalid surface, identity=33 should be 38

08-16 07:32:38.554  2453  2469 E SDL     : Old EGL Context doesnt work, trying with a new one

08-16 07:32:38.585  2453  2469 E void Appli::gain_focus(): Application Active



thanks,

Sylvain
Comment 1 Gabriel Jacobo 2013-08-16 10:23:11 UTC
Can you post the whole logcat and mark where you press home and where you go back? I don't see the surfaceDestroyed() message in there, and I'm not sure if it's not happening or you edited it out.

Also, I'm trying this with the emulator and I do get the surfaceDestroyed() message, but it crashes on eglMakeCurrent when resuming, it's hard to tell if this is a emulator bug (very likely, I can't get OpenGL ES2 to work at all), and I don't have a API 10 device.
Comment 2 Sylvain 2013-08-16 10:45:39 UTC
Created attachment 1289 [details]
more detailed logcat
Comment 3 Sylvain 2013-08-16 10:46:55 UTC
Hi,

Ok several answers :
I have the SurfaceDestroyed message on hardware devices : both on my 2.3.3 Android Phones (where the Pause/Resume doesnt work).
and on my 4.2.2 phone (where the Pause/Resume do work!)

On my emulators ... it always crashes (from API_10 to 17) ... and I do get the SurfaceDestroyed message. (always same APK !).
In fact, I cannot say if "pause/resume" works on emulator, because emulator now always crashes.


Attached is the more detailed logcat.

thanks,

Sylvain
Comment 4 Gabriel Jacobo 2013-08-16 14:01:42 UTC
Can you try this patch: http://bugzilla.libsdl.org/attachment.cgi?id=1290 from bug #2037 ?

It solves the emulator crashes and pauses/resumes properly for me on and API 10 environment and it seems to work fine with my Android 4.3 phone
Comment 5 Sylvain 2013-08-18 19:08:10 UTC
Hello,

I have just tried the patch...which apply with no problem.
I compiled and used the same APK for all.

on Device android 4.2.2 : (logcat1.txt)
- start, but resume won't work (black screen).

on Device android 2.3.3 :
- start, but resume won't work (black screen).

On emulator API_10  : (logcat3.txt)
- it does not even start. Crash when loading

D/libEGL  ( 1061): loaded /system/lib/egl/libGLES_android.so
D/gralloc_goldfish( 1061): Emulator without GPU emulation detected.
E/libEGL  ( 1061): called unimplemented OpenGL ES API

Maybe I need to configure the emulator which I dont know yet how to do.

I puts the logcats ...


Thanks,

Sylvain
Comment 6 Sylvain 2013-08-18 19:09:33 UTC
Created attachment 1292 [details]
logcat1
Comment 7 Sylvain 2013-08-18 19:09:59 UTC
Created attachment 1293 [details]
logcat2
Comment 8 Sylvain 2013-08-18 19:10:26 UTC
Created attachment 1294 [details]
logcat3
Comment 9 Gabriel Jacobo 2013-08-18 22:36:10 UTC
Do you have perhaps a custom Java SDLActivity class? Either that or an AndroidManifest.xml difference is all I can think of...

Output for adb logcat | grep 'SDL\|EGL'

4.3, OpenGL ES 1.x http://pastebin.com/fdPZfYTv
4.3, OpenGL ES 2.x http://pastebin.com/gvmXGZs9 (I threw in a lock by power button, screen rotate, etc just to be sure)


The emulator on 2.3.3, OpenGL ES 1, sometimes works, sometimes crashes on eglMakeCurrent when switching to home, tough eglMakeCurrent is called with valid parameters, it has all the appearance of an implementation error. The emulator with Android 4.1, works perfectly, both with ES 1 and 2, GPU hw acceleration.

Thanks for your help in figuring this out!
Comment 10 Sylvain 2013-08-19 06:35:06 UTC
Hello,
 
My AndroidManifest.xml is a little bit modified (see in attachement).

I have a few modificaions on the SDL_Activity class:
If the call to "nativeInit" returns, then I call the "finish" method for the application to exit (see in attachement).

I have also a subclass of SDL_Activity, which calls setRequestOrientation in the onCreate Method.

I have to add that I compile with the NDK-r9 and that I modified the project.properties file to target android-18

thanks,

Sylvain
Comment 11 Sylvain 2013-08-19 06:35:54 UTC
Created attachment 1296 [details]
SDLActivity.java modified for exit
Comment 12 Sylvain 2013-08-19 06:36:33 UTC
Created attachment 1297 [details]
AndroidManitfest.xml modified
Comment 13 Gabriel Jacobo 2013-08-19 12:30:50 UTC
There's something off with the files you provided, in android:configChanges you have "screenSize" and "smallestScreenSize", which were added in API Level 13 [1]. If I try to use that manifest file as is I get an error from ant:

> error: Error: String types not allowed (at 'configChanges' ....

Removing those two settings, using your SDLActivity.java, it all seems to work fine. Can you double check? 


1. http://developer.android.com/guide/topics/manifest/activity-element.html
Comment 14 Sylvain 2013-08-19 13:13:37 UTC
Can you tell me : 
- which ndk you use
- which api level you use (build.properties) to compile

I will double-check soon ...
Comment 15 Gabriel Jacobo 2013-08-19 13:30:25 UTC
I use target=android-10 in project.properties. NDK is r8d
Comment 16 Sylvain 2013-08-19 17:45:20 UTC
Well I couldn't make it work : 
- I dowgraded the ndk to ndk-r8b (not r8d)
- put back the API level to API_10 (build.properties and AndroidManifest.xml)
- remove my almost dummy subclass ...
- remove the screenSize and smallestScreenSize from Manifest.

I still get a black screen after resume to application.

see logcat4.txt, I get lots of messages : 

W/Adreno200-EGLSUB( 5640): <DequeueBuffer:483>: dequeue native buffer fail: No such device
W/Adreno200-ES20( 5640): <core_glFinish:25>: GL_OUT_OF_MEMORY
W/Adreno200-EGL( 5640): <qeglDrvAPI_eglSwapBuffers:3453>: EGL_BAD_SURFACE

I tried on a 4.2.2 android phone.

Maybe my app is not doing the right stuff, but this is basic :
I detect the lost_focus with SDL_WINDOWEVENT_FOCUS_LOST.
and gain focus with SDL_WINDOWEVENT_FOCUS_GAINED.

Which are correctly received.
Lost_focus doesn't do much.
As soon as I get the Gain Focus, I start to recreate all the SDL_Texture for the next renderered frame. (I dont recreate the windows nor the renderer)


Thanks,

Sylvain
Comment 17 Sylvain 2013-08-19 17:45:44 UTC
Created attachment 1298 [details]
logcat4
Comment 18 Gabriel Jacobo 2013-08-19 18:22:40 UTC
Why do you re create the textures? If the GL Context is preserved (which is the case 99% of the time), the textures remain valid. I wonder if that's the problem here.
Comment 19 Sylvain 2013-08-19 19:58:47 UTC
Ok that was it. 
So your patch works correctly on my two phones : 2.3.3 and 4.2.2.
both with API_10+NDK-r8b and with API_18+NDK-r9.

It seems to me that re-creating all the textures should not be a problem.
Maybe something uneffecient, but it should not make this bad_surface error.

I also tried to re-create always the textures during the normal use. So the app behave slowly, but it did not crash or black screen. So there might be a problem with this full deletion/creation textures when it occurs just after the resume. ... don't if that helps.

You talk about the 99% ... but for the 1% ...
How could I check if the GL context is valid of not?! What should be done, when it's not valid then?

BTW, on emulator API_10, I still get this error : 
I/SDL     (  366): SDL_Android_Init()
I/SDL     (  366): SDL_Android_Init() finished!
D/libEGL  (  366): egl.cfg not found, using default config
D/libEGL  (  366): loaded /system/lib/egl/libGLES_android.so
E/libEGL  (  366): called unimplemented OpenGL ES API
If you know how can I configure this, I would appreciate !

...

I also have retried back without the patch, but _with_ my internal modifications (of not recreating all the textures). And there was actually a bug of resume on 2.3.3. So your patch is _actually_ fixing something !


Can you explain a little bit the patch ? is this going to be merged on the trunk or is it an old version ?

thanks,

Sylvain
Comment 20 Gabriel Jacobo 2013-08-19 20:04:12 UTC
I just commited that patch, see the mailing list for details.

If the context is no longer valid, we need to send the app a message. That's in the TODO list as far as I know. On the upside, it should only happen in old devices, and I've never seen it happen :)

The central question now is why your code to re create the textures doesn't work, that's worth investigating, do you care to post your code here? Thanks!
Comment 21 Sylvain 2013-08-19 20:11:11 UTC
Thanks I saw the mailinglist for the explanation !

I cannot really publish the code ... I will make a minimal app for that.
Comment 22 Sylvain 2013-08-19 22:42:19 UTC
Created attachment 1299 [details]
main_bug_pauseresume.c
Comment 23 Sylvain 2013-08-19 22:49:00 UTC
So here's a simplification of the issue.

The function is only doing : 

while (1) { 
 "poll events" 
 destroy texture
 create texture
 blit texture
 present frame
}

The black screen happen when going to home, then resuming.
the poll events does nothing but lets you exit by pressing back.

There is some king of timing I guess, see the "poll events":
If I only pick one event, then I dont get the issue. (function pollEvent())
If I pick alls the current event, I do get the issue ! (function pollEventS())

Thanks,

Sylvain
Comment 24 Gabriel Jacobo 2013-08-22 13:14:51 UTC
Looking at your example, you are doing stuff in your loop right after polling. When the app loses focus, the Android event loop marks itself for pausing and releases the GL context, but pauses on the next iteration! So, you are doing at least one round with the GL context unset.
You have to listen for SDL_WINDOWEVENT_FOCUS_LOST / SDL_WINDOWEVENT_FOCUS_GAINED, and avoid rendering (and specially creating textures) if the GL context is not active.

Marking as fixed, feel free to reopen or file another bug if you spot a different problem. Thanks for your feedback!
Comment 25 Sylvain 2013-08-24 10:02:04 UTC
Ok. this is ok for me!
Not creating texture, while the application is unfocused, is fine !

One more question :
you said in old device, the GL context could be broken when resuming ?
then what should the application do ? re-create all the textures ? recreate also the renderer ?

thanks