Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tabbing in/out of SDL2 app really quick leads to visible texture corruption #3221

Closed
SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Closed

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: HG 2.0
Reported for operating system, platform: Android (All), ARM

Comments on the original bug report:

On 2019-04-04 14:21:00 +0000, Ellie wrote:

Created attachment 3729
Texture corruption that happens when tabbing in/out often & fast enough

If you write a test SDL2 android app that uses:

  1. Only SDL_Renderer in accelerated mode with SDL_Texture (no direct OpenGL access)

  2. ... and does nothing special on app pause & resume, especially not dump/recreate the renderer

  3. ... redraws its SDL_Textures continuously and has a bunch of them

Then if you tab in/out of the app quickly enough and often enough, it appears that suddenly a big bunch of the textures suffers major corruption! (see attached screenshot) I have also noticed once this happens the CPU-side seems to be fine (no misbehaving that would make me guess system memory corruption, no crashes) but suddenly rectangles are sometimes the wrong color, or elements are plain missing even of new textures, so on the GPU side something big seems to have broken down

Since this is quite central to an app working correctly when it runs a little longer and the user has it in the background and tabs in/out, it would be neat if that could be fixed

On 2019-04-04 14:22:30 +0000, Ellie wrote:

Sorry I forgot to specify, I've tested hg revision a34ab2e5ddcf. However, I've also seen this happen on 2.0.9 stable so it doesn't seem to be a recent regression

On 2019-04-04 16:02:46 +0000, Ellie wrote:

Another detail I forgot: I set to SDL_ANDROID_BLOCK_ON_PAUSE to 0, so that may also be needed to reproduce this

On 2019-04-04 18:05:39 +0000, Sylvain wrote:

This is one of the reason of block_on_pause, you can't use the opengles context while you're in background. As soon as you enter pause state, you shouldn't use the sdl renderer, and resume when you go back into foreground.

On 2019-04-04 18:09:06 +0000, Ellie wrote:

Interesting, that extends to all non-drawing actions like SDL_CreateTexture or SDL_DestroyTexture as well I assume? The garbage collector could actually trigger SDL_DestroyTexture while things are in background, so maybe that is the cause. Very interesting! I'll dive into things, seems like this is likely to be my own mistake then

On 2019-04-05 02:46:27 +0000, Ellie wrote:

Yup, I refactored my destructor to not call SDL_DestroyTexture but queue up the deletions and clean them in a safe spot when in foreground, and now the problem is gone. So this was my own fault / caused by accessing SDL_Renderer while in background

thanks for the help!

On 2019-04-05 15:11:41 +0000, Sam Lantinga wrote:

Sylvain, is there any way we can do this internally inside SDL? This seems like a reasonable thing that we could protect against.

On 2019-04-05 15:13:47 +0000, Ellie wrote:

For what it's worth, it was 99% SDL_DestroyTexture at fault, and I fixed it by manually delaying it with an internal queue until a point where I know the context is safe to use.

It would be admittedly really cool if SDL2 just did that internally without requiring me to do it, but I understand if that is too complex to do

On 2019-04-05 20:09:07 +0000, Sylvain wrote:

Created attachment 3730
patch test modified version of block_on_pause=0

Not sure if this make sense and even if this is possible to be really robust with this. They are also probably differences between devices and android versions.

BTW, it's still possible to use block_on_pause=1, and have another thread that still run in bg.

But, I may see an issue in the non_blocking event loop:
It doesn't acknowledge that the app has read the event SDL_WILL_ENTER_BACKGROUND before actually doing the egl context backup.
It receives the java pause and immediately backup the context.
SDL_WILL_ENTER_BACKGROUND should be a warning that the context will be backed up, then, on the next pollEvent, the context is actually backed-up

Here's a modified version of block_on_pause=0. It became more similar to block_on_pause=1, but totally un-tested. To be tried ...

On 2019-04-05 20:20:59 +0000, Ellie wrote:

I did speak too soon and I am still seeing corruption, just way more rarely.

And indeed, when getting SDL_WILLENTERBACKGROUND I do still touch the context in many cases, so that could be part of the reason :-O I am still trying to figure out what causes it. But there isn't much else in my code that could be it at this point since I gated all the drawing and texture creation/destruction operations with a global access lock

On 2019-04-12 21:19:13 +0000, Sylvain wrote:

Created attachment 3748
test-case

I've pushed the fix:
https://hg.libsdl.org/SDL/rev/f6c7e5e03f60

And here's a test-case to see it. Without that fix, it remains black after background/foreground.

In non-blocking mode:

  • we wait that the user application fetch SDL_APP_DIDENTERBACKGROUND before backup-ing the context.

So that it's the same behavior as for the blocking mode.

On 2019-04-14 23:40:37 +0000, Ellie wrote:

I've tested with rev. f6c7e5e03f60 for a while (no additional patches) and so far everything looks fine, even when tabbing out during the occasional hangs. Thanks once more for the great work!

I'll still test further to be more certain this time, but it seems like the new wait for SDL_APPDIDENTERBACKGROUND fetch fixed it!

On 2019-04-17 02:38:30 +0000, Sam Lantinga wrote:

It looks like this is fixed, thanks guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant