Hi!
I'm wondering how data is marshalled between threads in Love2D. At example, can I load image on side thread, then construct set of quads over it, then pack them into sprite batch (according to level layout), and finally pass all this stuff to main thread in a single message? Will Love2D properly resolve multiple links to single userdata object in such a message?
Thanks!
love.thread data marshalling
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: love.thread data marshalling
love.thread admits numbers, strings, booleans, and userdata. You can't send/receive any other stuff. This includes tables and functions - you can't pass them around. In other words, there is zero "state sharing" - you can pass values, but not references (or reference containers).
However, you can load a ImageData from the disk on a different thread and pass it, no problem. You may find an example in my love-loader lib.
You can't, but for a very specific reason - you can't use any function from love.graphics inside a thread. The love.graphics library makes it fail (at least in 0.7.2) on the 'require'.target.san wrote:At example, can I load image on side thread, then construct set of quads over it, then pack them into sprite batch (according to level layout), and finally pass all this stuff to main thread in a single message?
However, you can load a ImageData from the disk on a different thread and pass it, no problem. You may find an example in my love-loader lib.
When I write def I mean function.
Re: love.thread data marshalling
To extend kikito:
It is possible to do something like that, but you have to be very careful what you call and when. The OpenGL calls used in the graphics module are not protected by any locks and will make it burn horribly if you call them at inappropriate times. Some platforms also restrict the OpenGL calls to the thread where the context was created (The "main" thread if you don't disable it in love.conf and create the window elsewhere). That's why there's the warning on the wiki.
LÖVE userdatas are shared across threads if you pass them through with a message. They also don't have any locks and you should use the message system to signal when a thread is allowed to access it. A big problem is the image loading library which is not thread-safe. Make sure you use love.image.newImageData not at the same time in different threads (This is fixed with locks in 0.8.0, it'll be safe to call it anytime).
Back to the graphics module. Many of the functions use OpenGL and as explained they should not be used in different threads. This includes love.graphics.newImage which loads the decoded raw image data into the graphics memory. You can, however, use love.image.newImageData in the other thread to offload the decoding process and then pass the ImageData back.
Quads do not use any OpenGL calls, you can create them in any thread.
The love.graphics.newSpriteBatch function does use OpenGL. There are the undocumented functions lock and unlock that will bind and release the SpriteBatch data to RAM, making it technically possible to add stuff from another thread. BUT! They're undocumented because they cause issues if used improperly. There should be no other OpenGL operation involving buffers between lock and unlock or data may get corrupted (also fixed in 0.8.0). This makes it kind of useless for offloading.
That would leave us with image decoding and quad creation in the thread.
Here's an example how it could look like in LÖVE 0.7.2, though I do use lock und unlock incorrectly in this. It should work if ported to 0.8.0. Until then, it's better to avoid lock/unlock.
It is possible to do something like that, but you have to be very careful what you call and when. The OpenGL calls used in the graphics module are not protected by any locks and will make it burn horribly if you call them at inappropriate times. Some platforms also restrict the OpenGL calls to the thread where the context was created (The "main" thread if you don't disable it in love.conf and create the window elsewhere). That's why there's the warning on the wiki.
LÖVE userdatas are shared across threads if you pass them through with a message. They also don't have any locks and you should use the message system to signal when a thread is allowed to access it. A big problem is the image loading library which is not thread-safe. Make sure you use love.image.newImageData not at the same time in different threads (This is fixed with locks in 0.8.0, it'll be safe to call it anytime).
Back to the graphics module. Many of the functions use OpenGL and as explained they should not be used in different threads. This includes love.graphics.newImage which loads the decoded raw image data into the graphics memory. You can, however, use love.image.newImageData in the other thread to offload the decoding process and then pass the ImageData back.
Quads do not use any OpenGL calls, you can create them in any thread.
The love.graphics.newSpriteBatch function does use OpenGL. There are the undocumented functions lock and unlock that will bind and release the SpriteBatch data to RAM, making it technically possible to add stuff from another thread. BUT! They're undocumented because they cause issues if used improperly. There should be no other OpenGL operation involving buffers between lock and unlock or data may get corrupted (also fixed in 0.8.0). This makes it kind of useless for offloading.
That would leave us with image decoding and quad creation in the thread.
Here's an example how it could look like in LÖVE 0.7.2, though I do use lock und unlock incorrectly in this. It should work if ported to 0.8.0. Until then, it's better to avoid lock/unlock.
Shallow indentations.
Who is online
Users browsing this forum: No registered users and 2 guests