MonoGame.Extended icon indicating copy to clipboard operation
MonoGame.Extended copied to clipboard

ShapeExtensions (FillRectangle) texture disposed in android when app is not foreground

Open NebulaSleuth opened this issue 3 years ago • 1 comments

Sometimes the texture created for ShapeExtensions gets disposed when the application is pushed to the background. When the app comes back to the foreground, the shapes no longer draw properly (all black).

I can't find any method to clear the internal 1x1 texture to force it to regenerate it.

NebulaSleuth avatar Jun 14 '22 16:06 NebulaSleuth

It happens when the app on Android is not on the foreground, where the user is actively interacting with the app. The android activity may stop but the application is still running so dalvik (the android vm) will clear memory and the memory it clears may be the texture you wanted to keep alive.

You could run the https://square.github.io/leakcanary/ to see the leaks in action.

MonoGame should be preventing this by default for it's android port. I am pretty sure this is a issue internally to MonoGame since I reviewed the MonoGame.Extended source just to see if this would happen to me and

        private static Texture2D GetTexture(SpriteBatch spriteBatch)
        {
            if (_whitePixelTexture == null)
            {
                _whitePixelTexture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
                _whitePixelTexture.SetData(new[] { Color.White });
                spriteBatch.Disposing += (sender, args) =>
                {
                    _whitePixelTexture?.Dispose();
                    _whitePixelTexture = null;
                };
            }

            return _whitePixelTexture;
        }

shows that FillRectangle always calls that method resulting in a null check for _whitePixelTexture in which the _whitePixelTexture is then created again.

I should note, I don't use MonoGame. I use the fork which is preferable for me considering the 600+ issues in the MonoGame repo.

captkirk88 avatar Aug 18 '24 12:08 captkirk88

I attempted to reproduce this issue using MonoGame 3.8.4.1 and MonoGame.Extended 5.1.1.

Steps taken:

  1. Created a new MonoGame Android application
  2. Used _spriteBatch.FillRectangle to draw a rectangle
  3. Debugged the application using an Android emulator
  4. While the application was running, pressed the home button, waited several seconds, then returned to the application

I was unable to reproduce the bug with these steps. However, it's possible that the texture could be disposed if the application remains in the background long enough for Android to reclaim resources. This could trigger a GraphicsDeviceReset event when resuming, which would dispose graphics resources including the cached white pixel texture.

As a defensive measure, I've added an IsDisposed check to the GetTexture method in PR #1041. This ensures the texture is recreated if it has been disposed for any reason.

I'm closing this issue with PR #1041, as I'm unable to reproduce it and both MonoGame and MonoGame.Extended have gone through several version updates since the issue was reported.

If this PR doesn't resolve the issue and you're able to provide a minimal reproduction repository or detailed steps to reproduce, please open a new issue and we'll reinvestigate.

AristurtleDev avatar Oct 23 '25 05:10 AristurtleDev