Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Added ResumeManager so something can be drawn whilst textures are reloaded #1093

Closed
wants to merge 5 commits into
from

Conversation

Projects
None yet
4 participants
Contributor

Aranda commented Dec 18, 2012

How it works
The textures are now reloaded on a different thread so execution can continue. The AndroidGameWindow._isResuming is set so the optional IResumeManager can be drawn. A default ResumeManager implementation has been provided so users can easily set it up with a custom texture rotating in the middle of the screen.

Motivation
Reloading of textures can take a LONG time. Whilst this occurs the user is presented with a black screen and the music playing. This leads to confusion about whether the game may have crashed. Also, when adding full screen ads to a game, these generally cause the GL context to be lost so when the user dismisses the ad, they are hit with this lengthy texture reload each time.

Added ResumeManager so something can be drawn whilst textures are bei…
…ng reloaded.

*How it works*
The textures are now reloaded on a different thread so execution can continue. The AndroidGameWindow._isResuming is set so the optional IResumeManager can be drawn. A default ResumeManager implementation has been provided so users can easily set it up with a custom texture rotating in the middle of the screen.

*Motivation*
Reloading of textures can take a LONG time. Whilst this occurs the user is presented with a black screen and the music playing. This leads to confusion about whether the game may have crashed. Also, when adding full screen ads to a game, these generally cause the GL context to be lost so when the user dismisses the ad, they are hit with this lengthy texture reload each time.
Contributor

totallyeviljake commented Dec 18, 2012

cool! Thanks Aranda! Note that Microsoft XNA makes extensive use of backing store objects to keep the main image display updated. The problem with Android is that the ContentUnload event is fired when the app goes into the background. I never see this behavior on a windows phone.

Contributor

Aranda commented Dec 18, 2012

You're welcome :)

Note that Microsoft XNA makes extensive use of backing store objects to keep the main image display updated.

Not sure what is meant by 'backing store objects' here... do you mean they're kept in system memory so the gpu memory can be quickly restored? I guess this would be possible on Android too, but I'd worry about running out of memory.

The problem with Android is that the ContentUnload event is fired when the app goes into the background. I never see this behavior on a windows phone.

I've never seen a ContentUnload event... unless you mean ContentManager.Unload? The problem with Android is that the GL context is destroyed every time the game goes into the background meaning textures, shaders and any buffers on the GPU become invalidated. I believe this to be a problem with MonoDroid or OpenTK as I've noticed some games that don't have any waiting period when resuming (Angry Birds Rio is one example). I'm not sure how Windows Phone handles this, but perhaps you are right about the backing store objects.

Contributor

totallyeviljake commented Dec 18, 2012

Hi Aranda, yeah, I cheated and decompiled the graphics source for XNA to see how they did the refresh after the app went into the background.

There is the "ContentLost" event that MG does not implement, but Microsoft has a very deep and robust implementation. In the MSFT world, the backing store of the textures is used to recover from the content lost event. Even in the XNA world of Microsoft, the framebuffer is killed but it handles the resurrection of the app state by using backing store (the off screen pixmap).

Android is far more aggressive about recycling the framebuffer though. As you mention, this is likely a byproduct of OpenTK.

Contributor

totallyeviljake commented Dec 19, 2012

I pulled your changes and tried them in Santa Shooter. Pushed the power button, then pushed again, unlocked, but blank screen. I tried to follow your comment on how to use it, but maybe I did not set the path correctly? I didn't capture the log file from it .. .sorry

Contributor

Aranda commented Dec 19, 2012

Thanks for testing, a log would probably not help. What would help is if you could try to put a break point in ResumeManager.LoadContent and see if it's hit when you switch back to the game after hitting the Home button.

With the path, it has to include "Content/" at the start as well as the extension, ie ".png". This is because it uses TitleContainer.OpenStream() and Texture2D.FromStream(). If people think it's a better idea, I could easily make it use it's own ContentManager instead so you can load compiled Xnb textures using normal paths.

Contributor

totallyeviljake commented Dec 19, 2012

Hey Aranda, if you could add those usage notes to the usage comments, that would be great. I did not have the .png extension and did not include the root "Content" directory path. I will try again ..

Member

Nezz commented Dec 19, 2012

I'd recommend going for own content manager.

Contributor

totallyeviljake commented Dec 19, 2012

haha. oh man. so I fixed the path to my resumer image (maybe?). It's in the project as "Assets/Content/images/resumer.png". In the Resumer contruction, I set the path as "Content/images/resumer.png" so hopefully that's ok. why "haha"? Well, I resumed back on the game play screen and while it was dark (no textures), I can play the game and it is fully functional! Android is so crazy.

Aside: There is only 1 thread for the game, and when anything else happens on the phone, like a notificationfor email, the game stalls while the notification plays. I also found that repeated loading of an asset that does not exist causes the GC to run slightly more often thus causing hiccups in game play.

Contributor

Aranda commented Dec 19, 2012

Hmmm, so if you comment out the setting of the Resume Manager, do the textures load ok again? What if you revert my changes?. Your path seems right. Also, which device is it?

Contributor

totallyeviljake commented Dec 19, 2012

Hi Aranda, no the textures do not display even without your changes. This is on the Galaxy Nexus phone and the SONY eXperia.

Contributor

Aranda commented Dec 19, 2012

Right. That is strange as texture reloading works fine in my Galaxy S2 with the latest develop3d. I wonder if the the issue is related to your game or the specific devices you're using? Can you try a simple test project?

Contributor

Aranda commented Dec 21, 2012

I'd recommend going for own content manager.

As @Nezz suggested, I've switched to using a ContentManager. The usage has been updated too:

#if ANDROID
    this.Window.SetResumer(new ResumeManager(this.Services, 
                                                 spriteBatch, 
                                                 "UI/ResumingTexture",
                                                 1.0f, 0.01f));
#endif      

I've not been able to reproduce your problems @totallyeviljake. Perhaps they are device specific.

Contributor

totallyeviljake commented Dec 21, 2012

hi Aranda, it's all me. I pulled out an old version ot Tiles of India that had your fixes in it and an older version of cocos2d-xna, and it survived the infamous power-button-sleep-mode test. Something in cocos2d-xna's texture cache is causing this. The activity is entirely recycled and goes through the bootstrap sequence when it recovers from the sleep mode.

Contributor

Aranda commented Feb 7, 2013

@mgbot test

Contributor

Aranda commented Feb 7, 2013

Despite the green build, don't merge this PR yet. It's not been extensively tested since merging in the latest changes.

Owner

tomspilman commented Feb 14, 2013

So another complication here. We just applied the branch migration plans:

https://github.com/mono/MonoGame/wiki/Branch-Migration-Strategy

So the develop3d branch will stop being updated and eventually deleted. So that leaves you with a choice here:

  1. Close this PR and resubmit to the develop branch.
  2. Let me merge it with develop3d, but there will be a delay of a few days before it is moved into develop.

Totally your call.

Contributor

Aranda commented Feb 16, 2013

Closing to switch this PR over to the develop branch.

@Aranda Aranda closed this Feb 16, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment