The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Despite using SDL 2.0.4 and, as far as I know, following all the guidelines (e.g. suspending rendering calls when my app is in the background) I'm suffering the old 'black screen on resume' problem. Here is a snippet from logcat, I'm guessing the EGL_BAD_ACCESS errors may be relevant:

Code:
V/SDL     (  972): nativeResume()
I/SDL/APP (  972): SDL_APP_DIDENTERFOREGROUND
D/        (  972): Updating FBO content dimensions 1920x1104
E/libEGL  (  972): eglMakeCurrent:777 error 3002 (EGL_BAD_ACCESS)
D/        (  972): droid_create_context : config id = 10 conf->NativeVisualID=4
D/        (  972): Pixel Format : GGL_PIXEL_FORMAT_RGB_565
I/        (  972): Requested context : GLES 1.1.
E/libEGL  (  972): eglMakeCurrent:777 error 3002 (EGL_BAD_ACCESS)

I'm using OpenGLES (not ES2) and my rendering code is as follows (done this way so the target bitmap is preserved, since it is updated incrementally):

Code:
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, bitmap, NULL, &DestRect);
SDL_RenderPresent(renderer);
SDL_SetRenderTarget(renderer, bitmap);

The app is still running after the resume (for example if it is playing music that still works) but the display is entirely black.

Any ideas?

Richard.
LBandy


Joined: 01 Jan 2013
Posts: 38
I've had the same. You have to manually reupload all images to the GPU, e.g. convert all surfaces to textures when you receive the resume event.
LBandy


Joined: 01 Jan 2013
Posts: 38
I've had the same. You have to manually reupload all images to the GPU, e.g. convert all surfaces to textures when you receive the resume event.
rtrussell


Joined: 10 Feb 2016
Posts: 88
LBandy wrote:
You have to manually reupload all images to the GPU, e.g. convert all surfaces to textures when you receive the resume event.

I don't have any surfaces - only textures!

I've also discovered that if I go back to SDL 2.0.3 everything works fine: it resumes from the background correctly and the black screen problem does not occur.

Richard.
rtrussell


Joined: 10 Feb 2016
Posts: 88
rtrussell wrote:
I've also discovered that if I go back to SDL 2.0.3 everything works

To double-check I downloaded and installed SDL-2.0.4 again from scratch, and the black screen problem came back. So, sadly, it does seem that a change from 2.0.3 to 2.0.4 is responsible. It's a pity, because I particularly wanted to take advantage of the Android Message Box functionality added in 2.0.4.

Richard.
rtrussell


Joined: 10 Feb 2016
Posts: 88
rtrussell wrote:
it does seem that a change from 2.0.3 to 2.0.4 is responsible.

I've been trying to pin down where the significant difference is, but so far without success. I was hoping to make incremental changes from 2.0.3 to 2.0.4 to find out which one introduces the fault, but there are so many dependencies it is proving difficult to make intermediate versions that successfully compile and run. I would welcome suggestions for how to proceed.

Richard.
Android black screen on resume
Eric Wing
Guest

On 2/14/16, rtrussell wrote:
Quote:

rtrussell wrote:
Quote:
it does seem that a change from 2.0.3 to 2.0.4 is responsible.

I've been trying to pin down where the significant difference is, but so far
without success. I was hoping to make incremental changes from 2.0.3 to
2.0.4 to find out which one introduces the fault, but there are so many
dependencies it is proving difficult to make intermediate versions that
successfully compile and run. I would welcome suggestions for how to
proceed.

Richard.



I don't have much in terms of guidance, but only some data points.
I do not have any problems with backgrounding with 2.0.4.
However, I'm using GLES2, not 1.1. But 100% of Android devices support
at least 2.0 by Google's statistics. It looks like you are using the
SDL 2D renderer. I don't see why you need to stay with 1.1.

Additionally, device manufacturer and operating system version may
matter here. Android fragmentation is real. Some devices are much
better than others. OS versions matter a lot too. I've tried 2.0.4
under 4.x and 5.0.2. How many different devices and OS versions have
you tried?

For example, the comment about unloading and reuploading textures is
less needed somewhere in the 3.0 or 4 time frame. I think officially
you still can get hosed, but I haven't heard of any cases recently.)

Have you tried simple test apps to test the backgrounding?
More often than not, I see blank screen bugs the result of other bugs
in the codebase. For example, Android does something stupid and
doesn't reinitialize static and global variables between
quits/relaunches, unless you do something like a force kill or crash
(or Android actually completely killed the process). I've had a lot of
annoying bugs due to the fact that these variables contained the state
from the previous run instead of being reset so the program wouldn't
continue correctly.

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
I don't see why you need to stay with 1.1.

I am using GLES 1.1 because I need the 'glLogicOp' functionality (where graphics are AND, OR or XOR plotted). Annoyingly, this functionality was deleted from GLES 2 but it's essential for my application. There seem to be significant changes from 2.0.3 to 2.0.4 in the render/opengles directory so apparently GLES 1.1 is still supported by SDL.

Quote:
How many different devices and OS versions have
you tried?

I've tried it on an Android 5.1 (Lollipop) tablet and an Android 4.2.1 (Jelly Bean) phone. The symptoms are identical: it works perfectly in SDL 2.0.3 but fails in 2.0.4.

Quote:
Have you tried simple test apps to test the backgrounding?

No, but I do intend to try that, if only so I can upload a test case.

Quote:
More often than not, I see blank screen bugs the result of other bugs
in the codebase.

I appreciate that, but it would have to be an obscure bug not to cause any problems with 2.0.3.

I will try to distil my app down to a minimal test case which demonstrates the issue.

Richard.
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
OK, here's a test case to demonstrate the problem. With SDL 2.0.3 it resumes from the background correctly, but with SDL 2.0.4 resuming results in a black screen. The simplest way to test is to tap on the Android 'square' navigation button to put the app into the background, and then tap the app's icon to resume. It would be really helpful if somebody can suggest a way forward to resolve this issue.

testcase.c:
Code:
/******************************************************************\
* Testcase to demonstrate problem with SDL 2.0.4 on Android GLES 1 *
\******************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include "SDL.h"

#define GL_COLOR_LOGIC_OP 0x0BF2
#define GL_XOR 0x1506
#define SCREEN_WIDTH  640
#define SCREEN_HEIGHT 500
#define IDLE 2
#define PACER 20

void (*glEnable)  (int) ;
void (*glLogicOp) (int) ;
void (*glDisable) (int) ;

static int bkgnd = 0 ;

int myEventFilter(void* userdata, SDL_Event* pev)
{
   switch (pev->type)
   {
      case SDL_APP_WILLENTERBACKGROUND:
      bkgnd = 1 ;
      break ;

      case SDL_APP_WILLENTERFOREGROUND:
      bkgnd = 0 ;
      break ;
   }
   return 0 ;
}

int main(int argc, char* argv[])
{
int running = 1 ;
int sizex, sizey ;
SDL_Event ev ;
SDL_Window *myWindow ;
SDL_Renderer *myRenderer ;
SDL_Rect myRect ;

if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER |
             SDL_INIT_EVENTS | SDL_INIT_JOYSTICK) != 0)
{
   SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
             "Testcase", SDL_GetError(), NULL) ;
   return 1;
}

#ifdef __ANDROID__
   SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengles") ;
   SDL_SetHint (SDL_HINT_RENDER_SCALE_QUALITY, "linear") ;
#else
   SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengl") ;
   SDL_SetHint (SDL_HINT_RENDER_SCALE_QUALITY, "linear") ;
#endif

myWindow = SDL_CreateWindow("BBCSDL",  SDL_WINDOWPOS_CENTERED,  SDL_WINDOWPOS_CENTERED,
                  SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE) ;
if (myWindow == NULL)
{
   SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
             "Testcase", SDL_GetError(), NULL) ;
   SDL_Quit() ;
   return 5;
}

SDL_GetWindowSize (myWindow, &sizex, &sizey) ; // Window may not be the requested size

myRenderer = SDL_CreateRenderer(myWindow, -1, SDL_RENDERER_ACCELERATED |SDL_RENDERER_PRESENTVSYNC) ;
if (myRenderer == NULL)
{
   SDL_DestroyWindow(myWindow) ;
   SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
             "Testcase", SDL_GetError(), NULL) ;
   SDL_Quit() ;
   return 6;
}

if (!SDL_RenderTargetSupported(myRenderer))
{
   SDL_DestroyWindow(myWindow) ;
   SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
             "Testcase", "Render targets not supported", NULL) ;
   SDL_Quit() ;
   return 7;
}

SDL_SetRenderTarget(myRenderer, SDL_CreateTexture(myRenderer, SDL_PIXELFORMAT_ARGB8888,
                            SDL_TEXTUREACCESS_TARGET, sizex, sizey)) ;

#ifdef __ANDROID__
   glLogicOp = (void *) dlsym (-1, "glLogicOp") ;
   glEnable  = (void *) dlsym (-1, "glEnable") ;
   glDisable = (void *) dlsym (-1, "glDisable") ;
#else
   glLogicOp = SDL_GL_GetProcAddress("glLogicOp") ;
   glEnable  = SDL_GL_GetProcAddress("glEnable") ;
   glDisable = SDL_GL_GetProcAddress("glDisable") ;
#endif

glEnable(GL_COLOR_LOGIC_OP) ;
glLogicOp(GL_XOR) ;
SDL_SetRenderDrawColor(myRenderer, 0, 0, 255, 255) ;
SDL_RenderFillRect(myRenderer, NULL) ;
myRect.x = 0 ;
myRect.y = 0 ;
myRect.w = sizex / 2 ;
myRect.h = sizey ;
SDL_SetRenderDrawColor(myRenderer, 255, 0, 255, 255) ;
SDL_RenderFillRect(myRenderer, &myRect) ;
myRect.x = 0 ;
myRect.y = 0 ;
myRect.w = sizex ;
myRect.h = sizey / 2 ;
SDL_SetRenderDrawColor(myRenderer, 255, 255, 255, 255) ;
SDL_RenderFillRect(myRenderer, &myRect) ;
glDisable(GL_COLOR_LOGIC_OP) ;

SDL_AddEventWatch(myEventFilter, 0) ;

// Main loop:
while (running)
{
   static unsigned int zoom = 32768 ;
   static int offsetx, offsety ;
   unsigned int lastpaint ;
   unsigned int now = SDL_GetTicks () ;
   float scale = (float)(zoom) / 32768.0 ; // must be float

   if (((now >= (lastpaint + PACER)) || (now < lastpaint)) && !bkgnd)
   {
      int winx, winy ;
      SDL_Rect DestRect ;
      SDL_Texture *bitmap = SDL_GetRenderTarget (myRenderer) ;
      SDL_GetWindowSize (myWindow, &winx, &winy) ;

      DestRect.x = -offsetx * scale ;
      DestRect.y = -offsety * scale ;
      DestRect.w = sizex * scale ;
      DestRect.h = sizey * scale ;
      DestRect.x += (winx - DestRect.w) >> 1 ;

      SDL_SetRenderTarget(myRenderer, NULL) ;
      SDL_SetRenderDrawColor (myRenderer, 0, 0, 0, 255) ;
      SDL_RenderClear (myRenderer) ;
      SDL_RenderCopy(myRenderer, bitmap, NULL, &DestRect) ;
      SDL_RenderPresent(myRenderer) ;
      SDL_SetRenderTarget(myRenderer, bitmap) ;

      lastpaint = SDL_GetTicks() ; // wraps around after 50 days
   }

   SDL_PumpEvents () ;
   if (SDL_PeepEvents(&ev, 1, SDL_GETEVENT, 0, SDL_USEREVENT-1))
      switch (ev.type)
      {
         static float panx, pany ;

         case SDL_QUIT:
            running = 0 ;
            break ;

         case SDL_MULTIGESTURE :
                           if (fabs(ev.mgesture.dDist) > 0.002)
               zoom = zoom * (1.0 + ev.mgesture.dDist) /
                                                 (1.0 - ev.mgesture.dDist) ;

            if (fabs(ev.mgesture.x - panx) < 0.05)
               offsetx -= sizex * (ev.mgesture.x - panx) / scale ;

            if (fabs(ev.mgesture.y - pany) < 0.05)
               offsety -= sizey * (ev.mgesture.y - pany) / scale ;
   
            panx = ev.mgesture.x ;
            pany = ev.mgesture.y ;
            break ;
      }

   else
      SDL_Delay (IDLE) ;

}

SDL_DestroyRenderer(myRenderer) ;
SDL_DestroyWindow(myWindow) ;
SDL_Quit() ;

exit(0) ;
}


AndroidManifest.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Replace org.libsdl.app with the identifier of your game below, e.g.
     com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.rtrussell.testcase"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="auto">

    <!-- Create a Java class extending SDLActivity and place it in a
         directory under src matching the package, e.g.
            src/com/gamemaker/game/MyGame.java

         then replace "SDLActivity" with the name of your class (e.g. "MyGame")
         in the XML below.

         An example Java class can be found in README-android.txt
    -->
    <application android:label="@string/app_name"
                 android:icon="@drawable/ic_launcher"
                 android:allowBackup="true"
                 android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
                 android:hardwareAccelerated="true" >
        <activity android:name="TestCase"
                  android:label="@string/app_name"
                  android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
                  >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <!-- Android 2.3.3 -->
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="15" />

    <!-- OpenGL ES 2.0 -->
    <!-- uses-feature android:glEsVersion="0x00020000" -->

    <!-- Allow writing to external storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>


Richard.
Android black screen on resume
Eric Wing
Guest

On 3/25/16, rtrussell wrote:
Quote:
OK, here's a test case to demonstrate the problem. With SDL 2.0.3 it
resumes from the background correctly, but with SDL 2.0.4 resuming results
in a black screen. The simplest way to test is to tap on the Android
'square' navigation button to put the app into the background, and then tap
the app's icon to resume. It would be really helpful if somebody can
suggest a way forward to resolve this issue.

Out of curiosity, did you test OpenGLES 2 in this case to show there
is a difference between it and 1.1?

Also, I see static/global variables in your example. That has a code
smell for Android because Android doesn't always reinitialize your
static/global variables on quit/relaunch (because Android is stupid).
This means when you are repeating you testing, your global/statics
might not be set to what you think they are and are carrying garbage
values from the prior run.

Finally, I posted these in another thread for Android troubleshooting,
but they might reveal something. Here are some apks I made. They use
SDL's 2D renderer (defaults) and 2.0.4. As far as I know, they
background and resume correctly. Try running these and see if you see
a blank screen problem.

http://blurrrsdk.com/tempdownload/BlurrrBinaries/FlappyBlurrr/FlappyBlurrrC.apk
http://blurrrsdk.com/tempdownload/BlurrrBinaries/FlappyBlurrr/FlappyBlurrrJavaScript.apk
http://blurrrsdk.com/tempdownload/BlurrrBinaries/FlappyBlurrr/FlappyBlurrrLua.apk
http://blurrrsdk.com/tempdownload/BlurrrBinaries/FlappyBlurrr/FlappyBlurrrSwift.apk

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
Out of curiosity, did you test OpenGLES 2 in this case to show there
is a difference between it and 1.1?

Yes, GLES2 resumes correctly (but I can't use it). The problem only affects GLES 1.1.

Quote:
This means when you are repeating you testing, your global/statics
might not be set to what you think they are and are carrying garbage
values from the prior run.

The only globals/statics are ordinary C variables that are stored on the heap. They are preserved through a suspend/resume.

Quote:
I posted these in another thread for Android troubleshooting,
but they might reveal something... They use SDL's 2D renderer (defaults)

The default renderer will be GLES 2 on my devices, so running your apps here won't reveal anything I'm afraid. What might be informative is if you can add the opengles hint to your code and then see whether they still resume correctly for you using GLES 1.1.

Richard.
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
rtrussell wrote:
What might be informative is if you can add the opengles hint to your code and then see whether they still resume correctly for you using GLES 1.1.

Eric, are you able to do that test? If you find SDL 2.0.4 with GLES 1.1 does resume correctly for you it would give me an avenue to explore, otherwise I'm all out of ideas for how to progress this. Although I can cope with using 2.0.3 at the moment it's not very satisfactory, and if a fix isn't forthcoming I'm not going to be able to take advantage of future SDL upgrades.

Richard.
Android black screen on resume
Eric Wing
Guest

On 3/30/16, rtrussell wrote:
Quote:

rtrussell wrote:
Quote:
What might be informative is if you can add the opengles hint to your code
and then see whether they still resume correctly for you using GLES 1.1.

Eric, are you able to do that test? If you find SDL 2.0.4 with GLES 1.1
does resume correctly for you it would give me an avenue to explore,
otherwise I'm all out of ideas for how to progress this. Although I can
cope with using 2.0.3 at the moment it's not very satisfactory, and if a fix
isn't forthcoming I'm not going to be able to take advantage of future SDL
upgrades.

I tried to reproduce, but I'm not seeing the problem.

I added SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengles"); right before
my SDL_CreateWindow call in my FlappyBlurrr example. I'm on SDL 2.0.4
(plus a couple of weeks).

Running Nexus 7 2013, Android 5.0.2.

Tried suspending by hitting the circle button and also the square
button. Both resumed with no problems. Also swapped to another SDL
program and back; no problem there either.

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
I tried to reproduce, but I'm not seeing the problem.

Interesting. Is the source available for me to compare with mine?

Any chance of you making a GLES 1.1 APK available for download so I can confirm I don't see the problem on my devices?

Quote:
I'm on SDL 2.0.4 (plus a couple of weeks).

Do you think the "plus a couple of weeks" could be significant?

Richard.
Android black screen on resume
Eric Wing
Guest

On 3/31/16, rtrussell wrote:
Quote:

Eric Wing wrote:
Quote:
I tried to reproduce, but I'm not seeing the problem.

Interesting. Is the source available for me to compare with mine?


I haven't formally announced this repo, as it is part of my SDK
examples. But whatever.
https://bitbucket.org/ewing/flappyblurrrc

Though I highly recommend using the full SDK. It makes actually trying
things so much easier. I have an early access program going on right
now.
https://blurrrsdk.com

Quote:
Any chance of you making a GLES 1.1 APK available for download so I can
confirm I don't see the problem on my devices?
Here you go.
http://playcontrol.net/tempdownload/BlurrrBinaries/FlappyBlurrrC_es11.apk


Quote:
Quote:
I'm on SDL 2.0.4 (plus a couple of weeks).
Do you think the "plus a couple of weeks" could be significant?

I wouldn't think so, but here's my branch. It merges a few patches I
have. I don't think they are relevant to your situation, but you can
sift through it.
https://bitbucket.org/ewing/blurrrsdl

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Android black screen on resume
Eric Wing
Guest

Quote:
I wouldn't think so, but here's my branch.
https://bitbucket.org/ewing/blurrrsdl

Sorry, wrong link. This is the correct link:
https://bitbucket.org/blurrr/sdl
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88

Progress, of sorts. I've confirmed that your APK runs correctly here, so it's not something specific to my devices. Comparing your code with mine, the most significant difference is that I am using a separate texture as my render target:

Code:
SDL_SetRenderTarget(myRenderer, myTexture) ;

If, as an experiment, I convert my testcase to use the default render target (which means rendering my graphic every frame, rather than just once) then it does resume correctly. So it would seem that the difference between 2.0.3 and 2.0.4 is specifically affecting the case when a separate texture is used as the render target.

Is it possible that my target texture is being destroyed by the suspend/resume in 2.0.4 but not in 2.0.3?

Richard.
Android black screen on resume
Michael Labbé
Guest

Guys,
In reproducing the black screen bug, you are not discerning between onPause() and onDestroy() in the Android lifecycle.

By default, SDL2 (both 2.0.3 and 2.0.4) freezes the application when it goes into the background with onPause(). When it resumes, very few resources need to be recreated since you are un-suspending a process.

When onDestroy() is called, application resources are destroyed and need to be recreated.

Unless overridden by developer settings, it is non-deterministic when onDestroy() is being called, so trying to reproduce black screen bugs without knowing whether it has or not is a waste of time.

In developer options, you can select “Do not keep activities” which will force onDestroy() on backgrounding. However, it is called as soon as onPause() is called, overriding any asynchronous events such as writing saves to a cloud or whatever, so it is not the same as testing the true lifecycle of an Android app.

But at any rate, this “it works for me”, “it does not work for me”, needs to take into account the fact that onDestroy() may or may not be getting called, invalidating all your tests.

The resume code path for SDL2 is very different if onDestroy() was called while or during the application backgrounding.
Michael Labbé
Quote:
On Mar 31, 2016, at 10:13 AM, rtrussell wrote:
Eric Wing wrote:Here you go.http://playcontrol.net/tempdownload/BlurrrBinaries/FlappyBlurrrC_es11.apk
Progress, of sorts. I've confirmed that your APK runs correctly here, so it's not something specific to my devices. Comparing your code with mine, the most significant difference is that I am using a separate texture as my render target:Code:SDL_SetRenderTarget(myRenderer, myTexture) ;
If, as an experiment, I convert my testcase to use the default render target (which means rendering my graphic every frame, rather than just once) then it doesresume correctly. So it would seem that the difference between 2.0.3 and 2.0.4 is specifically affecting the case when a separate texture is used as the render target.Is it possible that my target texture is being destroyed by the suspend/resume in 2.0.4 but not in 2.0.3?Richard.
_______________________________________________SDL mailinghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Android black screen on resume
Eric Wing
Guest

On 3/31/16, rtrussell wrote:
Quote:

Eric Wing wrote:

Progress, of sorts. I've confirmed that your APK runs correctly here, so
it's not something specific to my devices. Comparing your code with mine,
the most significant difference is that I am using a separate texture as my
render target:


Code:
SDL_SetRenderTarget(myRenderer, myTexture) ;


If, as an experiment, I convert my testcase to use the default render target
(which means rendering my graphic every frame, rather than just once) then
it does resume correctly. So it would seem that the difference between
2.0.3 and 2.0.4 is specifically affecting the case when a separate texture
is used as the render target.

Is it possible that my target texture is being destroyed by the
suspend/resume in 2.0.4 but not in 2.0.3?

Richard.


FYI, FlappyBlurrr does use render to texture (change the target) to
render things like some of the text (particularly for the Game Over
panel).
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Michael Labbé wrote:
But at any rate, this “it works for me”, “it does not work for me”, needs to take into account the fact that onDestroy() may or may not be getting called, invalidating all your tests.

I do not understand how, in a practical sense, you want me to "take it into account". SDL is designed to isolate the application programmer from this kind of OS-specific detail. All I observe is a program that always works correctly in 2.0.3 but always fails in 2.0.4. I don't see any other variability that might suggest onDestroy() is sometimes being called and sometimes not.

Richard.
Android black screen on resume
Eric Wing
Guest

On 3/31/16, Michael Labbé wrote:
Quote:
Guys,

In reproducing the black screen bug, you are not discerning between
onPause() and onDestroy() in the Android lifecycle.

By default, SDL2 (both 2.0.3 and 2.0.4) freezes the application when it goes
into the background with onPause(). When it resumes, very few resources
need to be recreated since you are un-suspending a process.

When onDestroy() is called, application resources are destroyed and need to
be recreated.

Unless overridden by developer settings, it is non-deterministic when
onDestroy() is being called, so trying to reproduce black screen bugs
without knowing whether it has or not is a waste of time.

In developer options, you can select “Do not keep activities” which will
force onDestroy() on backgrounding. However, it is called as soon as
onPause() is called, overriding any asynchronous events such as writing
saves to a cloud or whatever, so it is not the same as testing the true
lifecycle of an Android app.

But at any rate, this “it works for me”, “it does not work for me”, needs to
take into account the fact that onDestroy() may or may not be getting
called, invalidating all your tests.

The resume code path for SDL2 is very different if onDestroy() was called
while or during the application backgrounding.

Michael Labbé


So my Flappy Blurrr example does properly distinguish and handle
onPause vs. onDestroy(). And this was what I was alluding to earlier
when I warned about his use of global/static variables in his sample
code because these are the things that will screw you up if you don't
use them properly and fail to distinguish between these two events.

However in practice, just for quick suspend/resume testing (hitting
Square) in a small test app, Android isn't that wildly random for
testing just the suspend/resume part. I don't think I've ever seen it
call onDestroy just toggling with that button, nor should it since
Android users would be really annoyed their apps completely restart
the very first time they hit Square/Circle. (Though I still find it
incredible that Android still makes the default behavior to restart
your app on an orientation change. I used to get tons of misdirected
confusion/blame/hate from developers about that at a previous job.)

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
FYI, FlappyBlurrr does use render to texture (change the target) to
render things like some of the text (particularly for the Game Over
panel).

However (and correct me if I'm wrong) I don't think you rely on the target texture retaining its contents through a suspend/resume in quite the same way as I do. If I've understood your code correctly, everything is rendered from scratch on every frame. In my testcase however I render the background just once during the startup phase of the program; it doesn't get rendered every frame, just copied from a texture. This technique works fine on all platforms, using SDL 2.0.3.

This is the essence of what my code does every frame, note that nothing is 'rendered' as such:

Code:
      myTexture = SDL_GetRenderTarget(myRenderer) ;
      SDL_SetRenderTarget(myRenderer, NULL) ;
      SDL_RenderClear(myRenderer) ;
      SDL_RenderCopy(myRenderer, myTexture, NULL, NULL) ;
      SDL_RenderPresent(myRenderer) ; 
      SDL_SetRenderTarget(myRenderer, myTexture) ;

Richard.
Android black screen on resume
Alex Szpakowski
Guest

Does your code respond to SDL_RENDER_TARGETS_RESET and SDL_RENDER_DEVICE_RESET events?
Quote:
On Mar 31, 2016, at 6:47 PM, rtrussell wrote:
Eric Wing wrote:FYI, FlappyBlurrr does use render to texture (change the target) torender things like some of the text (particularly for the Game Overpanel).
However (and correct me if I'm wrong) I don't think you rely on the target texture retaining its contents through a suspend/resume in quite the same way as I do. If I've understood your code correctly, everything is rendered from scratch on every frame. In my testcase however I render the background just once during the startup phase of the program; it doesn't get rendered every frame, just copied from a texture. This technique works fine on all platforms, using SDL 2.0.3.

Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Alex Szpakowski wrote:
Does your code respond to SDL_RENDER_TARGETS_RESET and SDL_RENDER_DEVICE_RESET events?

No, and it doesn't seem to be necessary with SDL 2.0.3. If you are suggesting that in SDL 2.0.4 the render target may be reset when in 2.0.3 it wasn't, I'm probably screwed (I can't recreate the contents of the target texture on demand, it's not stored anywhere else)!

Richard.
Android black screen on resume
Alex Szpakowski
Guest

It was always necessary on Android as far as I know. The OS tends to destroy the OpenGL context behind the app’s back.
Quote:
On Mar 31, 2016, at 7:03 PM, rtrussell wrote:
Alex Szpakowski wrote:Does your code respond to SDL_RENDER_TARGETS_RESET and SDL_RENDER_DEVICE_RESET events?
No, and it doesn't seem to be necessary with SDL 2.0.3. If you are suggesting that in SDL 2.0.4 the render target may be reset when in 2.0.3 it wasn't, I'm probably screwed (I can't recreate the contents of the target texture on demand, it's not stored anywhere else)!Richard.
_______________________________________________SDL mailinghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Alex Szpakowski wrote:
It was always necessary on Android as far as I know.

I've read that too, but I've seen no evidence of the OpenGL context being destroyed on a suspend/resume when using SDL 2.0.3 on Android. My assumption is that if this is going to happen it will be as the result of an onDestroy(), which as Eric commented would not be expected on a simple suspend/resume (for example using the square button). In my application (a programming language) I would expect a black screen after an onDestroy(); it would then be the responsibility of the user's program to decide what to do.

Richard.
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
rtrussell wrote:
So it would seem that the difference between 2.0.3 and 2.0.4 is specifically affecting the case when a separate texture is used as the render target.

This is definitely key to the issue. If I deselect my target texture as soon as I've rendered the background (rather than leaving it selected as the render target most of the time) then the suspend/resume works correctly in 2.0.4. So it's looking as though what matters is whether the texture is selected as the render target when the resume happens: if it is I get a black screen, if it isn't I don't. Why should that have changed since 2.0.3?

I tried deselecting the texture in my SDL_APP_WILLENTERBACKGROUND handler and reselecting it in my SDL_APP_DIDENTERFOREGROUND handler, reasoning that this ought to have the same effect. But it doesn't: I still get a black screen. It's almost as though the resume hasn't fully completed when the DIDENTERFOREGROUND event is triggered; is that possible?

At least I can feel I'm homing in on the problem.

Richard.
Android black screen on resume
Eric Wing
Guest

On 3/31/16, rtrussell wrote:
Quote:

Eric Wing wrote:
Quote:
FYI, FlappyBlurrr does use render to texture (change the target) to
render things like some of the text (particularly for the Game Over
panel).

However (and correct me if I'm wrong) I don't think you rely on the target
texture retaining its contents through a suspend/resume in quite the same
way as I do. If I've understood your code correctly, everything is rendered
from scratch on every frame. In my testcase however I render the background
just once during the startup phase of the program; it doesn't get rendered
every frame, just copied from a texture. This technique works fine on all
platforms, using SDL 2.0.3.


Actually, there are some things that rely on the textures persisting
in the code. This is kind of a bug, however I've done a lot of testing
and it only is a problem for Direct3D when I toggle fullscreen modes.
OpenGL on all the platforms I've tested on seem to handle this okay.

I didn't know about the SDL_RENDER_TARGETS_RESET and
SDL_RENDER_DEVICE_RESET events, but these sound perfect for handling
the Direct3D fullscreen toggle case.

But for your problem, this might rule out this line of reasoning.

Also, while the Android documentation warns the OpenGL context can be
destroyed out from under you, I don't think this actually happens in
the real world any more because it was such a pain for developers and
actually having reliable apps in the market place (I forgot what
Android version, but pretty confident it was done by 4.0). I think
that clause was left in to cover their butts because they never like
to guarantee anything actually works in Android. (Though if anybody
knows of real device models and Android versions that still have this
problem, I'd like to know. I already scattered notes about There
might be a manifest setting or API thing to request this mode.
(Already forgot all the details, ) But again, for your case of
toggling the Square/Circle, I don't think losing the OpenGL context is
the actual problem. (And Flappy Blurrr doesn't jump through any
special hoops to handle this and this is working for you.)

But there could be a multitude of other differences. NDK version, NDK
target API, SDK version, SDK api version, toolchain version, how you
and I built SDL (I used my CMake patch/fork) and against which
settings of theses, which compiler version/chain you used,
optimization levels, AndroidManifest settings and so forth. I've seen
little things like this make all the difference sometimes with bugs.
There was another thread here that had a thread deadlock problem or
something, and simply updating to the lastest NDK made the problem
disappear.

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Android black screen on resume
Eric Wing
Guest

One more thing, I feel remiss in not pointing out that all we actually
established with my build is I added
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles"); We don't have any
proof it actually triggered 1.1 mode. I honestly would not have
guessed that SDL would force 1.1 mode with that hint. Why not OpenGL
ES 2.0 or 3.0?

-Eric
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
We don't have any proof it actually triggered 1.1 mode.

Not in your case, I admit, but in my testcase (and in my app) I perform 'exclusive-or' plotting which won't work otherwise. If it's easy for you to build my testcase from the source I listed (and with your toolchain I guess it should be) you can confirm that GLES 1.1 is being used by checking that the display looks like this (possibly upside-down, which is another known bug in SDL/GLES 1.1!):



I realise that it's in the nature of a 'hint' that nothing is guaranteed, but since my app relies on the 'logical' plotting modes it's that or nothing as far as I am concerned!

If I'm right in concluding from my experiments that SDL 2.0.4/GLES 1.1 is causing the target texture to be destroyed on a suspend/resume, there isn't a fully satisfactory workaround. I can attempt to keep the texture deselected most of the time, and I'm sure that will help, but inevitably it must be selected as the render target some of the time. Given the asynchronous nature of a suspend/resume it's bound to happen occasionally when the texture is selected, and then I'm stuck.

It seems to me (in the absence of an unequivocal statement of what should happen) that since 2.0.3 always seems to preserve the texture through a suspend/resume, and since 2.0.4 with GLES 2 also seems to preserve the texture, that the issue with 2.0.4 and GLES 1.1 is indeed most probably a bug in SDL. Unfortunately, given the relatively uncommon circumstances, I can have little confidence that it's going to be fixed, and that's a worry for me.

Richard.
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
But there could be a multitude of other differences. NDK version, NDK
target API, SDK version, SDK api version, toolchain version, how you
and I built SDL (I used my CMake patch/fork) and against which
settings of theses, which compiler version/chain you used,
optimization levels, AndroidManifest settings and so forth.

Right. Now, if I could only persuade you to build my testcase using your toolchain we could eliminate (or confirm) that possibility at a stroke! Is there some inducement I could provide that might have the desired effect? I would be happy to make a small monetary contribution, if you don't consider that too sordid!

Richard.
Android black screen on resume
slvn


Joined: 06 Oct 2012
Posts: 88
Hello Richard, 

I tried your test-case, thanks for providing it !



1) first I got some noise, so I believe the "GL_COLOR_LOGIC_OP" should be done after the "SDL_RenderFillRect"...


2) I can reproduce it on my android device :
   As you said, it appears that when using opengles2 it resumes correctly, but when using opengles it resumes as black.


3) ... Found out there was no need of the gl calls to produce the black screen on resume.


4)  This seems to happen when changing the renderer target, with a call to "SDL_SetRenderTarget".


 In the opengles leaf function (in "src/render/opengles/SDL_render_gles.c"), it appears there is a call to "GLES_ActivateRenderer" in "GLES_SetRenderTarget", which is not present in opengles2.
 when commenting out this "GLES_ActivateRenderer", it seems to resume fine.


Hope it helps ...



Cheers,


Sylvain















On 1 April 2016 at 14:03, rtrussell wrote:
Quote:



Eric Wing wrote:

But there could be a multitude of other differences. NDK version, NDK
target API, SDK version, SDK api version, toolchain version, how you
and I built SDL (I used my CMake patch/fork) and against which
settings of theses, which compiler version/chain you used,
optimization levels, AndroidManifest settings and so forth.



Right. Now, if I could only persuade you to build my testcase using your toolchain we could eliminate (or confirm) that possibility at a stroke! Is there some inducement I could provide that might have the desired effect? I would be happy to make a small monetary contribution, if you don't consider that too sordid!

Richard.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




--
Sylvain Becker
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
slvn wrote:
Hope it helps ...

This is marvellous, thank you so much. I will investigate all your suggestions.

Richard.
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
slvn wrote:
when commenting out this "GLES_ActivateRenderer", it seems to resume fine.

Well, I'm flabbergasted! Making that change seems not only to have completely fixed the issue in my testcase, but in my main app as well! It's such a non-obvious (to me) change too: I would never have expected the problem to be in SetRenderTarget (which has always appeared to work correctly), and the call to ActivateRenderer looks so 'deliberate' I'm surprised that it apparently works so well without it. Goodness knows how you managed to figure it out.

I can't thank you enough.

Richard.
Android black screen on resume
Eric Wing
Guest

On 4/1/16, rtrussell wrote:
Quote:

slvn wrote:
Quote:
when commenting out this "GLES_ActivateRenderer", it seems to resume
fine.

Well, I'm flabbergasted! Making that change seems not only to have
completely fixed the issue in my testcase, but in my main app as well! It's
such a non-obvious (to me) change too: I would never have expected the
problem to be in SetRenderTarget (which has always appeared to work
correctly), and the call to ActivateRenderer looks so 'deliberate' I'm
surprised that it apparently works so well without it. Goodness knows how
you managed to figure it out.

I can't thank you enough.

Richard.

Sorry, I didn't back to your thread sooner. But it sounds like it's solved!
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: Android black screen on resume
rtrussell


Joined: 10 Feb 2016
Posts: 88
Eric Wing wrote:
it sounds like it's solved!

The issue with my app seems to be fixed, but presumably before Sylvain's modification can find its way into SDL 2.0.5 somebody needs to do a more detailed investigation to confirm that it has no unwanted side-effects. Do I need to report it formally as a bug, or submit a patch, to initiate that?

Richard.
Android black screen on resume
Eric Wing
Guest

On 4/1/16, rtrussell wrote:
Quote:

Eric Wing wrote:
Quote:
it sounds like it's solved!

The issue with my app seems to be fixed, but presumably before Sylvain's
modification can find its way into SDL 2.0.5 somebody needs to do a more
detailed investigation to confirm that it has no unwanted side-effects. Do
I need to report it formally as a bug, or submit a patch, to initiate that?


Richard.


Yes, you should file a formal bug and include a patch.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org