Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onSurfaceChanged called twice

I'm creating an Android application using openGL ES, and I have following problem:

When I minimize the application, then reopen it, onSurfaceChanged in my GLSurfaceView.Renderer is called 2 times.

I have the following code in onSurfaceChanged (and similar code in onSurfaceCreated,onDrawFrame):

Log.e("onSurfaceChanged",Integer.toString(width)+" "+Integer.toString(height));

So I get the following log:

onSurfaceCreated
onSurfaceChanged 480 800
onDrawFrame
onSurfaceChanged 480 800
onDrawFrame
onDrawFrame
onDrawFrame
onDrawFrame
onDrawFrame
onDrawFrame
(...)

When I minimize, change screen orientation from portrait to landscape, then reopen, onSurfaceChanged is called 3 times. And the log is:

onSurfaceCreated
onSurfaceChanged 480 800
onDrawFrame
onSurfaceChanged 480 800
onDrawFrame
onDrawFrame
onDrawFrame
onSurfaceChanged 800 480
onDrawFrame
onDrawFrame
onDrawFrame
onDrawFrame
onDrawFrame
onDrawFrame
(...)

My question: is this a bug? In my application or is an Android bug? There is a way to onSurfaceChanged being called just once? (because in onSurfaceCreated I'm executing code that slow down the application)

Thanks in advance

like image 479
Andrew Avatar asked Sep 29 '22 01:09

Andrew


1 Answers

It's not a bug. Personally I don't do much on onSurfaceChanged in my class which inherits from GLSurfaceView. I only set the viewport according to the new resolution and save the current resolution dimensions to a variable.

OpenGL assets such as textures don't need to be recreated at onSurfaceChanged, instead choose the right place on the ActivityCycle to create and destroy your OpenGL assets.

I am running my game on several platforms such as Android, Amazon Fire TV and OUYA. What I found that works on all these platforms is to destroy the GL assets on onPause, onStop and onRestart but I also keep a flag to see if the assets are already destroyed so I won't destroy it twice in a raw.

I create the OpenGL assets at onCreate, onRestart and onResume(also using a flag to not create it twice). If you don't want the game to lose it's state while pausing you will have to serialize the game state and write it to a file and load it later when you resume.

Hope this helps.

Again, you can't really predict how many onSurfaceCreated you will receive especially that it might behave differently on different devices. However, you can always trust the ActivityCycle to behave as described by Google.

like image 59
user1097185 Avatar answered Oct 06 '22 02:10

user1097185