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

Use dispatch_async for -[NSOpenGLContext update] #4242

Merged
merged 1 commit into from Mar 31, 2021

Conversation

Learath2
Copy link
Contributor

Description

I just moved the patch I provided on bugzilla to here, the issue explains why I fixed it like this.
Whether setWindow also should be using an async dispatch is up to discussion but I never got any feedback on that.

Existing Issue(s)

#3680

@slouken
Copy link
Collaborator

slouken commented Mar 29, 2021

@icculus, is this safe to do?

@icculus
Copy link
Collaborator

icculus commented Mar 29, 2021

I think it mostly is, but it also serves as an ongoing cautionary tale to stop using OpenGL on Apple devices, as it continues to get more fragile.

There are places where we will now make two async calls in a row with this patch, though, so don't merge this; I'm going to clean those instances up to make a single async call, just in case.

@icculus icculus added this to the 2.0.16 milestone Mar 30, 2021
@icculus
Copy link
Collaborator

icculus commented Mar 31, 2021

Okay, looking at this closer: setWindow can't be async, even if this would deadlock the app, because this is the core of SDL_GL_MakeCurrent(), and it would be disastrous to return from that function before the setWindow call is definitely complete, as future GL calls from the app would race on what context they apply to, or maybe not apply to anything if the main thread is completely blocked. In such a case, the app will need to redesign to deal with this case (either make the context current earlier in the process, or at least call SDL_PumpEvents() while waiting on the main thread).

The docs for -[NSOpenGLContext update] say this, though:

A multithreaded application must synchronize all threads that access the same drawable object and call update for each thread’s context serially.

...and I'm wondering if the original problem wasn't that it has to be on the main thread, but that we had a case where someone was calling it from two threads at once, and we just needed a mutex instead of a dispatch.

But for now: this patch is fine as-is. But we might want to revisit this later and try to reproduce the original crash that led to the dispatch call being added.

@psi29a
Copy link

psi29a commented Apr 26, 2021

This is great news, resolved our OpenMW crashy-ness. When can we expect a new release? 😄

@icculus
Copy link
Collaborator

icculus commented Apr 27, 2021

When can we expect a new release? 😄

https://github.com/libsdl-org/SDL/milestone/1

@Learath2
Copy link
Contributor Author

...and I'm wondering if the original problem wasn't that it has to be on the main thread, but that we had a case where someone was calling it from two threads at once, and we just needed a mutex instead of a dispatch.

For posterity, I think I was the one that introduced the dispatch with a performSelectorOnMain in the main thread (#3600) and I can confirm it has to happen on the main thread atleast on AppKit shipped with 10.15. There is literally a call to pthread_main_np guarding it.

nikolaykasyanov added a commit to OpenMW/openmw-deps-mac that referenced this pull request May 2, 2021
* Use prerelease version of SDL2 with OpenGL fix

See:
- libsdl-org/SDL#4242
- https://gitlab.com/OpenMW/openmw/-/issues/5939

* Use HTTPS everywhere, update libjpeg's hash

* Improve patch wrapper

- fail immediately if something fails
- silence preflight check completely

* Update boost patch to build against Xcode 11.7
@icculus
Copy link
Collaborator

icculus commented Aug 10, 2022

Heads up everyone, we just changed the default behavior back to dispatch_sync, because async upsets modern macOS, so if you still need async behavior, you should call this once, somewhere near SDL_Init().

SDL_SetHint("SDL_MAC_OPENGL_ASYNC_DISPATCH", "1");

And it will continue to do async updates as before. This is safe to do even if you don't update your SDL to 2.24.0, where this change is being made.

ALSO NOTE that the async behavior can cause crashes in the latest macOS, so you might want to consider reworking your code to deal with this, as there is nothing we can do to mitigate that problem on your behalf if you run into that (but it's possible that you won't, it's a bit of a black box).

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

Successfully merging this pull request may close these issues.

None yet

4 participants