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

Thread-safety? #31

Closed
NukeBird opened this issue Feb 15, 2020 · 1 comment
Closed

Thread-safety? #31

NukeBird opened this issue Feb 15, 2020 · 1 comment

Comments

@NukeBird
Copy link

Is SOIL2 threadsafe? Always?
I would love to use such a library to decode textures in parallel (OpenGL textures will be created in render context after)

jpg/png should be fine, I know stb_image have no problems with it. But what about dds and etc?

@SpartanJ
Copy link
Owner

Hi @NukeBird !
Not really, it's possible to use it in a thread-safe environment but you'll have to manage the OpenGL context manually. I use SOIL2 for loading textures in multiple-threads and works just fine, but I cannot implement the thread-safe code inside SOIL2 since it completely depends on how you want to manage the OpenGL context/s.
If you want to know how to achieve that you can take a look at my implementation: here. The code is kinda complex but the basic idea is something like:

  1. Create a window with one shared GL context (besides your render GL context). With SDL2 this is something like:
SDL_GL_SetAttribute( SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1 );
mGLContext = SDL_GL_CreateContext( mSDLWindow );
mGLContextThread = SDL_GL_CreateContext( mSDLWindow );
  1. Before any SOIL_ call you will need to ensure there's a valid GL context active in the thread you are calling the SOIL_ function, something like:
if ( std::this_thread::get_id() != myOpenGLMainThreadId ) {
     // If the current thread is not the OpenGL main thread we need to activate the GL shared context in the current thread.
     glContextThreadMutex.lock();
     SDL_GL_MakeCurrent( mSDLWindow, mGLContextThread );
}

SOIL_load_OGL_texture(...);

if ( std::this_thread::get_id() != myOpenGLMainThreadId ) {
     // Deactivate the GL shared context.
     SDL_GL_MakeCurrent( mSDLWindow, NULL );
     glContextThreadMutex.unlock();
}

And that's basically it. You just need to ensure that there's an active GL context in your current thread before calling any OpenGL method (and in this case any SOIL2 function). To upload any compressed texture directly to VRAM remember to use the flags for it: SOIL_FLAG_DDS_LOAD_DIRECT|SOIL_FLAG_PVR_LOAD_DIRECT|SOIL_FLAG_ETC1_LOAD_DIRECT.

BTW, one clarification this example is to decode and load the OpenGL texture in other thread, If you want to decode first the image in a secondary thread, use SOIL_load_image or SOIL_load_image_from_memory, and then load the texture in the render thread using: SOIL_create_OGL_texture or SOIL_direct_load_DDS_from_memory (or any of the direct_load functions available).

Regards.

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

2 participants