Graphics module in threads
Graphics module in threads
According to the wiki, love.graphics isn't usable from a thread. However, I've found that there's nothing stopping you from requiring the graphics module and calling functions from it. Can I assume it's safe to use as long as I don't do anything that might cause concurrency issues, like drawing to the screen or modifying graphics objects at the same time other threads do so?
- jojomickymack
- Prole
- Posts: 45
- Joined: Tue Dec 26, 2017 4:52 pm
Re: Graphics module in threads
Nope - totally unsafe to do that, here's what'll happen
all joking aside, what are you worried about occurring?- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Graphics module in threads
No, it will most likely either error (hopefully) or crash (hopefully not); it's not about concurrency, rather about the fact that you can only have one thread be a dedicated openGL thread, or something like that.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: Graphics module in threads
In my experience the OpenGL simply fails to render stuff properly if you attempt multithreading. You can however use multiple threads to generate render list data and feed it back to main thread.
- jojomickymack
- Prole
- Posts: 45
- Joined: Tue Dec 26, 2017 4:52 pm
Re: Graphics module in threads
is this an actual problem or a theoretical one? I wonder if it's possible to create a love program that demonstrates the limitation a single graphics thread poses here.
Re: Graphics module in threads
This crashes for me with a segfault, despite the extra care taken in not using love.graphics in two threads simultaneously.jojomickymack wrote: ↑Thu Jan 04, 2018 7:07 pm is this an actual problem or a theoretical one? I wonder if it's possible to create a love program that demonstrates the limitation a single graphics thread poses here.
main.lua:
Code: Select all
local chan = love.thread.getChannel('chan')
local img = love.graphics.newImage('anything.png')
local thread = love.thread.newThread('thread.lua')
love.graphics.clear()
love.run = function() end -- no main loop
thread:start() -- calls to love.graphics within the thread start here
chan:supply(img) -- pass the image to the thread
chan:demand() -- wait for thread to finish
love.graphics.present()
love.timer.sleep(3)
Code: Select all
require 'love.graphics'
local chan = love.thread.getChannel('chan')
local img = chan:demand() -- get the image
love.graphics.draw(img, 0, 0) -- call a love.graphics function
chan:push('done') -- we're done - the main thread can use love.graphics again
I was trying to make an animated loading screen, but short of using coroutines and loading in small chunks, which isn't always possible, I don't see how. Even love.graphics.newImage segfaults, therefore a thread can't even load images that way. At best it can load ImageData so that the main thread can use love.graphics.newImage(imageData) when the loading finishes; not sure whether that's costly for a big number of big images, but I suppose it is.
Edit: The segfault happens in libGL.so.1, within glEnableVertexAttribArray().
- Jasoco
- Inner party member
- Posts: 3726
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Graphics module in threads
Well you'd have to start the new thread and have the main thread wait for the new thread (Which I guess loads everything) to send the "all done!" message back to the main thread. And while you wait you'd draw that loading screen.
Re: Graphics module in threads
The point is that in the thread you can't load images with love.graphics.newImage(). You can load sounds, maps, library files, and so on, but not images, except with love.image.newImageData().
Edit: Also, there's still the problem that the environments are not shared, which makes loading certain kinds of objects more difficult or impossible from a thread. Example of "more difficult": stuff you allocate in FFI memory. You need to use malloc for it to not be garbage-collected, and you need to pass the pointer to the main thread, which isn't exactly a trivial task. Example of "impossible": userdata objects (fortunately it's not likely you need to create one of these that takes long to load).
- BrotSagtMist
- Party member
- Posts: 657
- Joined: Fri Aug 06, 2021 10:30 pm
Re: Graphics module in threads
Sorry to necrodig this old thread but i just happen to have played with this.jojomickymack wrote: ↑Thu Jan 04, 2018 7:07 pm I was trying to make an animated loading screen, but short of using coroutines and loading in small chunks, which isn't always possible, I don't see how. Even love.graphics.newImage segfaults, therefore a thread can't even load images that way.
It looks like calling love.window.setMode from within the thread hands over the graphic stuff to the thread and it magically worked.
So rendering stuff in the thread actually works for me and this could play an animation while the mainthread loads data.
obey
- slime
- Solid Snayke
- Posts: 3161
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Graphics module in threads
It will completely break on different operating systems, please don't do that.
You can load data on other threads and render on the main thread instead, and everything will work fine - for example for Images, usually the most time-consuming part by far is loading the file from your hard drive and decoding it into raw pixels, which love.image.newImageData does. You can then pass the result into love.graphics.newImage on the main thread via Channels.
There are several libraries to make that super simple, e.g.: https://github.com/kikito/love-loader or https://github.com/MikuAuahDark/lily
You can load data on other threads and render on the main thread instead, and everything will work fine - for example for Images, usually the most time-consuming part by far is loading the file from your hard drive and decoding it into raw pixels, which love.image.newImageData does. You can then pass the result into love.graphics.newImage on the main thread via Channels.
There are several libraries to make that super simple, e.g.: https://github.com/kikito/love-loader or https://github.com/MikuAuahDark/lily
Who is online
Users browsing this forum: No registered users and 0 guests