SDL_UpdateTexture crash when called from another thread... |
pik33
|
.. in Linux, but not in Windows.
I wrote a program (a smple SID player) with Lazarus/Freepascal (you can download it here: http://eksperymenty.edu.pl/index.php/en/sid-player/2-uncategorised/23-a-nostalgic-sid-player ). The program works like this: it initializes SDL in the main thread, then it starts another thread, which then do all display things in the loop while the main program opens files, and does the rest of needed things. The thread code looks like this:
In Windows all works as expected. In Linux (Mint, x64, Nvidia 760) I got segmentation fault when using proprietary Nvidia driver or simply nothing (the SDL window with garbage copied from the background) when using Nouveau. Then I disabled the thread and added this screen refreshing stuff to the main loop. Then it worked. Some things are of course broken, because this screen refreshing thing was supposed to run in parallel with the rest of the program, but I have a screen looking as expected. So the obvious solution is to rewrite all the code, to make screen refresh in the main loop and the rest SDL unrelated things in another thread(s). This needs a lot of work. Is there any solution to make this thread run or is it simply impossible in Linux to do this and I have to rewrite the code? |
|||||||||||||
|
SDL_UpdateTexture crash when called from another thread... |
Jared Maddox
Guest
|
<snip>
Graphical adapter code should only be expected to work on the main thread. Ths is true for all platforms. Some platforms will allow it to work in more situations (Windows uses COM to convert multi-threaded to single-threaded, X11 can operate fully multi-threaded in cross-network configurations, etc.), but the only situation that you can count on is running from the main thread. Thus, if you want multi-threaded behavior you should leave graphics in the main thread, and push everything else into another thread, instead of the other way around. It might also be the case that you aren't updating the event queue properly, but I think this is a driver issue. Cram the bulk of the "main loop" code into a function, put a minimalist "main loop" into the TRetro.Execute function (you need it to update the events queue), and swap the positions of the functions. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
KubaBrt
|
on windows you are using propably d3d driver, and you can update texture from another thread, on linux you are using Opengl for sure. In OpenGL you can access your texture only from thread where your GlContext was created. OpenGl doesnt allow to access textures from different thread.
For example on windows change your renderer to OpenGl and i asume your application will crash too as linux. If you have to access opengl textures in another thread some option is to change driver to OpenGl ES2 and use OES_EGL_image_external texture type, according to this documentation: https://www.khronos.org/registry/gles/extensions/OES/OES_EGL_image_external.txt, opengl es2 extensions allow you to work with textures from another thread. But SDl2 doesnt support image_external by default you have to change some renderer code directly in sdl2 which isn't too easy. So, i think you should change your architecture and access textures in render thread. |
|||||||||||
|
Problem solved. |
pik33
|
Solved.
The solution was simple: moving sdl_init, sdl_quit and all the rest of SDL initialization stuff from the main therad to the screen refreshing thread. Now all SDL calls are called from the same thread and it works with OpenGL renderer too. |
|||||||||||
|