Graphics module in threads

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
DekuJuice
Prole
Posts: 14
Joined: Mon Nov 24, 2014 9:31 pm

Graphics module in threads

Post by DekuJuice »

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?
User avatar
jojomickymack
Prole
Posts: 45
Joined: Tue Dec 26, 2017 4:52 pm

Re: Graphics module in threads

Post by jojomickymack »

Nope - totally unsafe to do that, here's what'll happen
giphy.gif
giphy.gif (488.78 KiB) Viewed 7392 times
all joking aside, what are you worried about occurring?
User avatar
zorg
Party member
Posts: 3465
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Graphics module in threads

Post by zorg »

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 :3True 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.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Graphics module in threads

Post by raidho36 »

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.
User avatar
jojomickymack
Prole
Posts: 45
Joined: Tue Dec 26, 2017 4:52 pm

Re: Graphics module in threads

Post by jojomickymack »

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.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Graphics module in threads

Post by pgimeno »

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.
This crashes for me with a segfault, despite the extra care taken in not using love.graphics in two threads simultaneously.

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)
thread.lua:

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
It's the love.graphics.draw call within the thread that causes the segfault. Without it, it runs without problems, but without drawing anything, of course.

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().
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Graphics module in threads

Post by Jasoco »

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.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Graphics module in threads

Post by pgimeno »

Jasoco wrote: Wed Mar 21, 2018 5:49 pm 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.
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).
User avatar
BrotSagtMist
Party member
Posts: 657
Joined: Fri Aug 06, 2021 10:30 pm

Re: Graphics module in threads

Post by BrotSagtMist »

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.
Sorry to necrodig this old thread but i just happen to have played with this.
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
User avatar
slime
Solid Snayke
Posts: 3161
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Graphics module in threads

Post by slime »

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
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests