0

OK, so the title is a little confusing, granted. I'll try to explain in a little more detail.

I have a splashscreen which is basically a simple / static loading graphic which is displayed as a 'dialog' over my GLSurfaceView.

I load all my GLTextures in onSurfaceChanged and everythnig is great.

In my onPause() lifecycle method, I have the following

myGLView.setVisibility(View.GONE);

and in onResume() I have

myGLView.setVisibility(View.VISIBLE);

Now, if the user presses the 'home' key while the loading dialog is still being displayed, then what happens is that the app goes into the background and the following are called (while the app is in the background).

  • onSurfaceCreated - then
  • onSurfaceChanged - then
  • onDrawFrame called once before GLSurfaceView halts

The problem is that when it hits onDrawFrame, my game very briefly appears on the screen (we're talking a fraction of a second).

How can I stop this happening?

I have a work around which is based on an answer to a very similar question that I posted earlier, and that is the use of a boolean to determine if my app is in the foreground or background, so in onDrawFrame I would have something like this:

public void onDrawFrame(GL10 gl) {

    if (isAppInForeground){

        //Main loop code here

    }

}

The only thing is that this adds another (unnecessary?) check to my main loop even when the app is running. It seems OK to do this during parts of the app that aren't performance intensive (like during set-up etc) but not sure about the main-loop.

Is there a more elegant way to resolve this?

Edit

OK, the above suggestion (using the boolean value in onDrawFrame) doesn't cure the issue. I still get a flickering (although not my app's screen, just a blank screen).

Have done a whole days worth of and I'm not sure if this is simply a bug with Android in general or maybe a problem with Kit Kat 4.4.4 or even a problem with the Nexus 10? (I have no other devices to test on though at the moment). Here is what I've found.....

If I use myView.onPause();, I don't get this strange flickering effect, however, the GL Context is then lost which is what I'm trying to avoid (and I'm targeting old Android versions so can't use setPreserveEGLContextOnPause(true);

If I remove everything from my onDrawFrame, and even if I make my GL Viewport 0,0 in size, I still get this flickering (but now again, it's just a blank screen that shows for a fraction of a second, rather than my app!!).

The result is the same whether I use View.GONE or View.Invisible.

If I don't call either setVisibility(View.xxxxx) or onPause(); then again, I don't get this flickering. I would leave it at that, but not calling these gives other problems.

Even if I set the view to Gone or Invisible and then set it to null in onPause(), it still exhibits the problem! I've no idea how this can be.

Oh and I should point out that this problem is intermittent. Sometimes it works just great.

Again, would appreciate some ideas

Zippy
  • 3,826
  • 5
  • 43
  • 96
  • If you made that same check within your onSurfaceCreated or onSurfaceChanged can you keep the onDraw from being called? Then you wouldn't have this extra minor check in your onDraw but in a much less intensive location. – Jay Snayder Jul 28 '14 at 16:25
  • That would be ideal @JaySnayder, unfortunately, I have no idea if this is possible or not!! :-( Actually, I implemented my check in the renderer and it does stop the game flicking up on the screen, however, there is still a glitch of some sort that appears, I've no idea where it's coming from. – Zippy Jul 28 '14 at 20:27

1 Answers1

0

If you call setRenderMode(RENDERMODE_WHEN_DIRTY), then your draw method will only be invoked after you call requestRender(). You can call requestRender() from any thread.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Hi @faddden, unfortunately I've already tried it. I still get the this 'flickering' effect. It only happens sometimes. It looks like it's just when the GLSurfaceView is initially being set up. If you set visibility to GONE or INVISIBLE, it does still call onDrawFrame if the app is in the background & it visibly shows up on screen for a fleeting moment. If you don't call setVisibility, you don't get this visual glitch. I've also tried removing everything from onDrawFrame, and I still get a completely blank screen, again, for a fleeting moment at some point during the GLSurfaceView setup. – Zippy Jul 29 '14 at 15:52
  • Just put some log statements in my **onDrawFrame** method and can confirm that this method *does* get called at least once without explicitly calling it (I guess after initial setup). – Zippy Jul 29 '14 at 16:02
  • Next thought: if you glClear(0,0,0,0), i.e. *transparent* black, there shouldn't be anything to see. I shoudl point out that the SurfaceView's *surface* is relatively independent of the SurfaceView's *view*; attempting to control the behavior of the surface by calling view methods isn't likely to do what you want. Attempting to preserve the EGL context will likely lead to sadness with GLSurfaceView; you should be ready to reconstruct that after it gets yanked out from under you. – fadden Jul 29 '14 at 16:10
  • Yeah I'm attempting to replicate Chris Pruetts' approach to context preservation, I'm looking for quick re-launch so I don't want to be loading all of my textures every time the user does something! However, apart from this it works perfectly. I really can't understand how others deal with this. I've tried the glClear but no difference unfortunately, the only thing that works so far is simply to not change the visibility of the view! – Zippy Jul 29 '14 at 16:27