I’ve faced a strange issue in my monogame (3.1) windows phone 8 app. When app is deactivated and then activated all textures become black. This happened also after the lock screen (UserIdleDetectionMode is enabled).
I’ve checked GraphicsDevice.IsDisposed, GraphicsDevice.IsContentLost, GraphicsDevice.ResourcesLost but everything looks ok. I’ve implemented reload of all my textures on Activated and Unobscured events, but full texture reload takes too much time. In the same time on Marketplace I see monogame apps easily handling desactivate-activate. Moreover, the same app for windows phone 7 written on xna, restores very quickly. What do I do wrong with monogame? My app is based on monogame WP8 template.
Just have found out that all textures which loaded via Content.Load(…) are restored very quickly. But all my textures are written by a hand: I load a file from TileContainer, unpack it, read its data with ImageTools, create Texture2D and set its pixels with loaded data. Jpeg files also are rendered to RenderTarget2D as BGR565 to consume space. Moreover I widely use RenderTarget2D for rendering text labels with shadows, sprite runtime compositions and so on. So it looks like that Monogame just don’t want to restore images loaded not by Content.Load. Continue investigating…
Sadly that is normal behaviour for Windows Phone 8. The DirectX graphics context is lost every time the game is deactivated and all textures and shaders have to be reloaded. This behaviour was probably chosen to save memory without having to close the app.
Android has the same behaviour, so this is not a WP8-only problem.
Thank you for quick answer!
Regarding to DirectX context - all direct games I’ve tried on WP8 so far are restored perfectly after the lock screen. Even huge games like Asphalt 7. So this is not DirectX problem.
Btw, I’ve checked Rum Run also - it restores very quickly.
Please tell how do you restore textures loaded by Content.Load(…)? All textures loaded this way are restored perfectly. But my textures (loaded manually from png and jpg files using Image Tools) do not. Unfortunately I can’t move to Content.Load() because there are a lot of textures with compositions in my game.
And also how can I programmatically check whether textures become black or not? I can get pixels and check their color, but this must be not the best method.
What MonoGame currently does is that it stores a list of content managers. Each content manager stores an internal list of assets. If the device context is lost, each asset of each content manager is reloaded by calling an internal function similar in functionality to calling Content.Load. So basically all assets are reloaded from the ground up.
This was okay for Rum Run since it managed to load within a few seconds, but in case of SongArc we had to add a silverlight “Loading…” screen because loading took longer with that game.
I suspect that big titles like Asphalt 7 have an option to opt-out of the context loss (something like setPreserveEGLContextOnPause on Android) and that’s how they can resume quickly.
As far as I know there is no way to see if a texture has been lost, other than checking the “_texture” field, but that’s private. You will get a graphics device reset event if it happens, so you can just listen to that (or the game activated) and recreate your programmatical textures.
Yes, currently I listen to GraphicsDevice.DeviceReset event, but I have to actually reload the whole game each time.
On Android however I almost never lose textures, but out engine is written in java and dealing directly with opengl.
Ok, if there is nothing left, can you please tell how do you add “Loading” message in SongArc? Is it on the same game page but unvisible? I’ve tried to place unvisible textbox and on DeviceReset call
Thanks.
I’ve just made it this way: on DeviceReset load simple texture with “Loading” string and show it, then in delayed call after 0.2 sec calling the rest resuming code.
And still my game restores longer than if I’d use Content.Load<>. It looks like your xnb loading code is just faster than ImageTools png and jpg loading.
Is there a way to load Texture2D from xnb (XNA Texture) with MonoGame but without Content Manager?
I’d like to, but XNA architecture is kinda high-level, and it makes impossible to use it for porting purposes. We already have big cross-plafrorm 2d engine with games, loaders, messages, gui, etc. It is ported to several languages/platforms, one of them was wp7/XNA, and Texture2d.FromStream was one of the key methods. But after MSFT killed XNA, they suggested us to make our apps available for wp8 and win8, usign MonoGame.
Anyway thank you for your answers!
Update
Btw, just have made manual load from uncompressed xnb files - restoring takes about 1-2 seconds! So for wp8 I’ll use uncompressed textures, that’s much better than jpegs/pngs.