Loading images in a thread

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
mike
Administrator
Posts: 364
Joined: Mon Feb 04, 2008 5:24 pm

Loading images in a thread

Post by mike »

Hey guys, I'm trying to separate my image loading into a separate thread to show a nice loading screen (and perhaps be able to do some background loading at some point, whatevs). However, when I run it on my Mac (OSX Lion) I get a cryptic error:

Code: Select all

Bus error: 10
WTF? I googled the error and it seems to be a mac error related to child processes and OSX Lion, but I tried running the code on my windows computer (Windows 7) and it spits out a completely white image. What the hell am I doing wrong? :x

main.lua

Code: Select all

function love.load()
	image = nil
	thread = love.thread.newThread("load", "load.lua")
	thread:start()
	thread:send("path", "image.png")
end

function love.draw()
	if image then
		love.graphics.draw(image, 0, 0)
	end
end

function love.update(dt)
	local receive = thread:receive("image")
	local error = thread:receive("error")

	if receive then
		image = receive
	elseif error then
		print(error)
	end
end
load.lua

Code: Select all

require "love.graphics"
require "love.image"
require "love.filesystem"

local thread = love.thread.getThread()
local path = nil

while path == nil do
	path = thread:receive("path")
end

local image = love.graphics.newImage(path)

thread:send("image", image)
I've attached a .love file if that helps.
Attachments
image-load-thread.love
(118.69 KiB) Downloaded 954 times
Now posting IN STEREO (where available)
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Loading images in a thread

Post by Boolsheet »

There's a warning on the wiki that you should not use the graphics module in threads. love.graphics.newImage tries to upload the image to the GPU, but only the main thread is allowed to do that. Use love.image.newImageData to load the data and pass that back to the main thread.

In 0.7.2 the image module has some threading problems. Don't access the functions or ImageDatas with multiple threads at the same time.

Code: Select all

function love.load()
	image = nil
	thread = love.thread.newThread("load", "load.lua")
	thread:start()
	thread:send("path", "image.png")
end

function love.draw()
	if image then
		love.graphics.draw(image, 0, 0)
	end
end

function love.update(dt)
	local receive = thread:receive("image")
	local error = thread:receive("error")

	if receive then
		image = love.graphics.newImage(receive)
	elseif error then
		print(error)
	end
end

Code: Select all

require "love.filesystem"
require "love.image"

local thread = love.thread.getThread()
local path = nil

while path == nil do
	path = thread:receive("path")
end

local image = love.image.newImageData(path)

thread:send("image", image)
Shallow indentations.
User avatar
mike
Administrator
Posts: 364
Joined: Mon Feb 04, 2008 5:24 pm

Re: Loading images in a thread

Post by mike »

Aha, awesome. I clearly didn't RTFM. Slightly related question: is this the best way to load resources (audio/images) in a separate thread?
Now posting IN STEREO (where available)
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: Loading images in a thread

Post by Taehl »

In my opinion, threads are so limited and temperamental that I'd suggest just using coroutines. Load one image (or sound or whatever) per frame (or per n frames, depending on how you want to affect your framerate). Not quite the same, but close enough, and with less hassle.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Loading images in a thread

Post by Boolsheet »

It's more or less the only way to load resources in a separate thread.
I mean, it's up to you how the thread knows what to load and when. Once you have the ImageData or Source you can pass their reference back and forth between threads wherever it's needed.

I have some experience with images in threads, but don't know about audio. Perhaps someone else knows if there's some catch.
Shallow indentations.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Loading images in a thread

Post by bartbes »

I am looking forward to alternatives that would allow us to do more with threads, 0.10.0 has been mentioned as complete-backend-overhaul-release-time-thingy-at-this-point-Im-just-making-the-word-longer.
User avatar
kraftman
Party member
Posts: 277
Joined: Sat May 14, 2011 10:18 am

Re: Loading images in a thread

Post by kraftman »

out of interest, what images are you loading that are taking long enough to need a loading screen? Ive only really had lag on startup when actually generating a large image and populating it with mapPixel/setPixel
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 7 guests