strange behaviour with Animations and OnResume()

Started by neo187, January 30, 2012, 01:53:37 PM

Previous topic - Next topic

neo187

Hi all

Very curious thing happens here. So I am following the exact same structure as the HelloWorld template, whereby the Activity gets backed up in the 'master' field so as to not being re initialised from scratch when the context changes...

Nothing bizarre happens when I start an input activity which leaves the GL context in the background (basically as a widget on top of the game) but if I leave the game completely (say due to a call) and return to it from outside, then all is fine apart from Objects with keyframe animations attached. They become invisible. You can still though turn them to OBJECT_VISIBLE manually and the animation would play as normal, but I just find it curious that everything else returns normally whereas animated objects become invisible....


Is there a reason for this?

EgonOlsen

Yes...the reason has to be in your code... ;) Honestly, i don't see how this should be triggered by the engine. The setVisibility-method simply switches a boolean flag. There are two other locations that set it...one when creating an Object3D (where it's always true) and one when cloning an Object3D (where it is set to the visibility of the master object). Then there's a method in World to set the visibility for all objects...and that's it. I don't see how this should be related to animations in the slightest. There's no connection between the two as far as i can see. Nor have i ever experienced such a behaviour...Alien Runner uses keyframe animations too, and i don't see it behave like that.

Please double check your code and if you are 110% sure that this isn't your fault, i would like to see a test case for this.

neo187

Right, I've narrowed it down.....the culprit seems to be the actual animation indices for animated objects.... I don't quite know how this happens since I am pausing all threads when onPause() is called and I actually reset the tickTime upon resuming... but the animation indices during the pause are somehow being assigned values (i haven't checked the actual values) that make the objects disappear (still .OBJECT_ VISIBLE though).... so using a function that resets all indices to 0 when resuming makes up for the problem....

I don't quite know how this happens as I am sure that I am not animating anything while onPause() but there you go, just in case anyone else may ever encounter this issue...

Thanks Egon for your pointers!

EgonOlsen

It is an engine problem...i just discovered that it happens when you are using animated objects but don't call animate() or touch() after onResume(). In that case, the VBO data seems to be lost. I've no idea why. The driver seems to handle dynamic VBOs different from static ones. Anyway, it's an easy fix and i'll add it to the next version. For now, just call touch() once on all animated objects after a resume...that should actually do the trick.

EgonOlsen

Because it's somehow related and i have to write a little rant: Android's activity management still drives me nuts. It's impossible to understand why it does what and when and the behaviour changes in every damn version. I was used to it destroying the gl context when going into pause/stop. It then triggered an onCreate() when coming back...hence this solution with the static master field and the copy-method.

In Android 4.0, they have finally improved this. It actually survives stop/pause. Even the GLSurfaceView survives and reinitializes itself properly...so far, so good. But while doing so, it calls onSurfaceCreated() once (which is understandable) and onSurfaceChanged() twice with the same gl context. That makes no sense to me. So if you, like i did, rely on onSurfaceChanged() to create the new FrameBuffer, you are doing it twice. So i moved that to onDraw() instead. But it doesn't help either...it calls onSurfaceChanged(), then calls onDraw() forcing everything to be uploaded to the GPU again and then is calls onSurfaceChanged() again with the same context and the same dimensions...WTF? So i ended up detecting if the gl context between the two calls has changed and only create a new FrameBuffer if it has. And i bet that Android 4.x will change that again...

neo187

Lol, that was a quite informative and totally understandable rant.... Things do seem to act randomly at times on the Android... and yes, as a matter of fact the way I was making the objects reappear was by calling .animate(0, ....) on them upon resume... I originally thought that maybe this was linked to the Animation.setCaching method somehow? But never investigated it...

Glad I helped you discover this!