| Summary: | SDL_RenderFillRect crash in specific multithreaded context | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Taiki <taiki> |
| Component: | render | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED INVALID | QA Contact: | Sam Lantinga <slouken> |
| Severity: | critical | ||
| Priority: | P2 | CC: | stsp2 |
| Version: | HG 2.1 | ||
| Hardware: | x86_64 | ||
| OS: | Mac OS X 10.8 | ||
|
Description
Taiki
2013-07-28 11:18:42 UTC
The crash occure in glColor4f. movl %gs:120 %eax change the value of %eax to an adress referenced afterward. The problem seems to be that in the said context, %eax is set to 0x0. My knowledges about OpenGL are way too low to dig futhermore but I can give you as much informations you want about the context... OpenGL has specific rules about multi-threading. When you create a context, you make it active on the thread you want to use it. You can only make it active on one thread at a time. If you don't do this, you'll crash in the way you saw. The SDL renderer is not designed to be multi-threaded and it takes significant work to change that. Most OpenGL drivers enable a whole bunch of locking internally if you start using a context on multiple threads which slows it down, so we haven't bothered. Most people handle this by having the main thread be the graphics thread, and using other threads for simulation, loading and other background tasks that feed data to the main thread for processing. Is there any way to use an other rendering engine on OSX? I'd rather like not having to deal with OpenGL internal for one platform on a software which is not a game... (using opengl seems a little bit an overkill) If you can add a link to a test program (or your actual program) I can see how much work it would be to get it to work the way you expect. The context is a couple thousands lines long on a closed source software so I don't think I can post too much code here... Basically, this was the way I designed it: Initial thread dedicated to this context launched: initialize stuffs, allocate memory and create window. Launch processing thread (T2) then start to handle events. It may have to print things if an event change context (eg: reorder stuffs). T2 is an intermediary thread, it'll launch a tasks in an other thread (T3), print on the window what task is being processing and wait for it to be finished. T3 process stuffs and eventually print its changes to the context on the window. Each access was controlled using mutexes to prevent concurrency access to the GUI. Worked perfectly on Windows (probably because DirectX was used instead of OpenGL), crashed miserably on OSX was T2 first tried to print something (and, sometimes T2 didn't crashed but then T3 did). I'm fixing it using a UI-dedicated thread but I still have to fix a couple of problem related to queuing request. I replaced every call to SDL primitives by functions which set a flag then trigger the UI thread to process its request. Not being able to have something which just work is a bit a pain in the ass but well, I can understand it's OpenGL's fault... Hi, will this problem be solved with a Vulkan renderer? AFAIK only openGL have such problem. I use software renderer in SDL because of that, but it doesn't have the scaling filters, so the quality is very bad. (In reply to Stas Sergeev from comment #6) > Hi, will this problem be solved with a > Vulkan renderer? AFAIK only openGL have > such problem. I use software renderer in > SDL because of that, but it doesn't have > the scaling filters, so the quality is > very bad. No, Vulkan has no multi-threading protection. You typically want to create your window and renderer on the main thread and use that to process events and make graphics calls, and then any other threads would send messages to the main thread to do any actual drawing. I am not a Vulkan expert by any means, but at least this: https://developer.nvidia.com/sites/default/files/akamai/gameworks/blog/munich/mschott_vulkan_multi_threading.pdf seems to be saying that Vulkan is thread-friendly. Is it just my misunderstanding? Yes, to clarify, it's not like Direct3D where you just pass a multi-threaded flag to the initialization and you can start making calls on any thread. You have to specifically design your application and rendering systems with threading in mind and use the correct synchronization mechanisms to make that work. All of that code would be outside of SDL though, so you wouldn't mix using the SDL renderer if you are writing your own low level Vulkan rendering code. (In reply to Sam Lantinga from comment #9) > Yes, to clarify, it's not like Direct3D where you just pass a multi-threaded > flag to the initialization and you can start making calls on any thread. You > have to specifically design your application and rendering systems with > threading in mind and use the correct synchronization mechanisms to make > that work. All of that code would be outside of SDL though, Yes, I know currently SDL only allows you to deal with Vulkan on your own. But is this forever? I was kind of expecting the Vulkan render backend in SDL one day, with all the locking/threading API exported via some SDL wrappers. Especially since Vulkan advertises their multi-threaded support that much, and SDL have only software renderer thread-safe. I won't suppose you can give me a lecture why this isn't possible, but at least some brief clarification or an URL where this was discussed, would help. |