We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5421

Summary: batching makes sw renderer thread-unsafe
Product: SDL Reporter: Stas Sergeev <stsp2>
Component: renderAssignee: Ryan C. Gordon <icculus>
Status: ASSIGNED --- QA Contact: Sam Lantinga <slouken>
Severity: enhancement    
Priority: P2 CC: amaranth72
Version: HG 2.0   
Hardware: x86_64   
OS: Linux   

Description Stas Sergeev 2020-12-28 02:16:14 UTC
Batching adds a dependency between renderer
and texture. Like this:

#2  0x00007ffff6b05787 in SW_RunCommandQueue (renderer=0x555556827c80, 
    cmd=0x7fff60000ba0, vertices=0x555556c00440, vertsize=<optimized out>)
    at /home/stas/src/SDL/src/render/software/SDL_render_sw.c:714
#3  0x00007ffff6ad8976 in FlushRenderCommands (renderer=0x555556827c80)
    at /home/stas/src/SDL/src/render/SDL_render.c:221
#4  0x00007ffff6ad8a12 in FlushRenderCommandsIfTextureNeeded (
    texture=texture@entry=0x555556b43780)
    at /home/stas/src/SDL/src/render/SDL_render.c:244
#5  0x00007ffff6ada69f in SDL_UpdateTexture_REAL (texture=0x555556b43780, 
    rect=0x7fffa7706a30, pixels=0x5555577e0838, pitch=2880)
    at /home/stas/src/SDL/src/render/SDL_render.c:1572
#6  0x00007ffff6ac5ee2 in SDL_UpdateTexture (a=<optimized out>, 
    b=<optimized out>, c=<optimized out>, d=<optimized out>)

So the call to SDL_UpdateTexture() flushes
the renderer queue (which would be empty w/o
batching I think, at least no crash w/o batching).
If some other thread also does something
with the renderer, you get crash.
So the only work-around is to use a "giant"
lock that covers both texture and renderer.
Thread-safe api should allow a lock per resource
and no implicit dependencies.
Comment 1 Alex Szpakowski 2021-01-01 02:10:07 UTC
All SDL_Render functionality (including objects owned by SDL_Render like textures) is already only meant to be used from the main thread.

See the documentation here: https://wiki.libsdl.org/CategoryRender and here: https://hg.libsdl.org/SDL/file/5bb9c1e57e52/include/SDL_render.h
Comment 2 Stas Sergeev 2021-01-01 02:14:25 UTC
Yes, the current situation is as you say.
I just think it would make sense to locate
and report such occurences so that eventually
there are none, at least in an SW renderer.
Comment 3 Alex Szpakowski 2021-01-01 02:19:00 UTC
Even if all of SDL_Render's code was completely atomic with respect to every API call (which seems like a non-goal in the first place), it still wouldn't make it usable on multiple threads on most platforms, because OpenGL is inherently single-threaded.

If you want increased performance, hardware-accelerated backends as well as other possible optimizations within those backends like draw call batching are the way to go, rather than the extremely complex and costly changes that would be needed to make SDL_Render usable in multiple threads.
Comment 4 Stas Sergeev 2021-01-01 02:39:41 UTC
Yes, I realize that currently only SW
renderer can benefit from threading.
Actually it can benefit quite a lot,
as no other "HW acceleration" than
threading, is possible for SW renderer.
So by disallowing that, you are risking
to make SW renderer completely useless.

Also note that eventually probably (not
sure) SDL may support vulkan as a rendering
back-end, and the problem will re-surface.

As it is, it may be better to consider
this ticket as an RFE.