libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.67k stars 1.79k forks source link

Can the 2D renderer be made thread safe? #11159

Open icculus opened 2 hours ago

icculus commented 2 hours ago

So #11150 brings up something that keeps coming up, and that's the requirement that the 2D renderer run on the main thread.

Part of the problem is that this causes problems, but also part of the problem is sometimes it doesn't, depending on the platform, so people keep doing it.

I thought I'd start an issue to talk about this and see if we can find a reasonable way to remove this requirement. It's totally possible we won't be able to do that, to be clear.

But I think it might be worth exploring a few questions:

I'm going to tweak testsprite.c to do its rendering in a background thread and see what blows up and where. It's not the most dramatic use of the API; there are no texture uploads after startup, no ReadPixels, etc, but it's a good start.

I'll report back.

slouken commented 1 hour ago

I think the most common use case is creating a renderer and doing all rendering/texture operations and presenting in a separate thread . The second case is creating a renderer on the main thread, doing rendering/texture operations off the main thread, and presenting on the main thread. Note that we have SDL_HINT_RENDER_DIRECT3D_THREADSAFE to accommodate the second case for D3D9 and D3D11.

slouken commented 1 hour ago

Also, by definition, it might appear to work most of the time and blow up sometimes or with certain operations.

thatcosmonaut commented 1 hour ago

I will say that this is a pain for Render GPU. The intention in a modern explicit API is that the command buffer is only accessed from one thread, and certain operations cannot be interleaved. We'll have to put locks everywhere and even single threaded applications will have to pay for the overhead.

slouken commented 1 hour ago

I will say that this is a pain for Render GPU. The intention in a modern explicit API is that the command buffer is only accessed from one thread, and certain operations cannot be interleaved. We'll have to put locks everywhere and even single threaded applications will have to pay for the overhead.

Our intent is not to make the GPU renderer completely multi-threaded, it's to understand the natural limitations of threading and renderers on the various platforms. We won't be making the kinds of changes you're anticipating, we just want to see if there's an off-main thread case that makes sense and can be officially supported. And if not, well, we'll note that clearly in the renderer documentation, along with any caveats, and call it a day.

thatcosmonaut commented 1 hour ago

In that case the two common cases you mentioned should be fine as far as GPU is concerned - the first one will definitely already work, and the second one will probably already work.