No more drawing to canvas after canvas:newImageData()

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
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

No more drawing to canvas after canvas:newImageData()

Post by grump »

This code draws one white and one red circle:

Code: Select all

local gfx = love.graphics

function love.draw()
	if not canvas then
		canvas = gfx.newCanvas(512, 512)
		gfx.setCanvas(canvas)

		gfx.setColor(255, 255, 255, 255)
		gfx.circle("fill",  128, 128, 128)

		gfx.setColor(255, 0, 0, 255)
		gfx.circle("fill",  256, 128, 128)

		gfx.setCanvas()
	end

	gfx.setColor(255, 255, 255, 255)
	gfx.draw(canvas)
end
Image

This code does the same thing, except for calling canvas:newImageData() after drawing the first circle:

Code: Select all

local gfx = love.graphics

function love.draw()
	if not canvas then
		canvas = gfx.newCanvas(512, 512)
		gfx.setCanvas(canvas)

		gfx.setColor(255, 255, 255, 255)
		gfx.circle("fill",  128, 128, 128)

		-- only difference is this line
		local img = canvas:newImageData()

		gfx.setColor(255, 0, 0, 255)
		gfx.circle("fill",  256, 128, 128)

		gfx.setCanvas()
	end

	gfx.setColor(255, 255, 255, 255)
	gfx.draw(canvas)
end
Image

The red circle is gone. I can't draw anything to the canvas after I've called newImageData(). Is this a known limitation, or a bug or a problem with my system?

Edit: It's working as expected when switching to another canvas and back to the original:

Code: Select all

local img = canvas:newImageData()
-- set a dummy canvas
gfx.setCanvas(gfx.newCanvas(512, 512))
-- switch back
gfx.setCanvas(canvas)
-- drawing works again
But it has to be an actual canvas object, simply calling gfx.setCanvas() without a canvas doesn't do the trick.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: No more drawing to canvas after canvas:newImageData()

Post by bartbes »

You're not allowed to read from a canvas you're currently writing to, so I presume the same holds for newImageData. Does it work if you move the call to newImageData to after gfx.setCanvas() (4 lines later)?
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: No more drawing to canvas after canvas:newImageData()

Post by grump »

bartbes wrote: Fri Sep 15, 2017 6:37 pm You're not allowed to read from a canvas you're currently writing to
I've considered that, but shouldn't this work:

Code: Select all

gfx.setCanvas()
local img = canvas:newImageData()
gfx.setCanvas(canvas)
-- ...drawing more stuff on the canvas...
Does it work if you move the call to newImageData to after gfx.setCanvas() (4 lines later)?
Yes of course, everything has been drawn at that point and I'm not touching the canvas anymore. But it doesn't give me the ImageData that I want, with only the first circle in it. I want to draw stuff, get a snapshot, draw more stuff.

Edit: after seeing more bizarre behaviour when using Canvas, I switched from Debian 9 AMD64 and tried the same code in Windows 10 AMD64. Everything works as expected in Windows, but fails in Linux. :(
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: No more drawing to canvas after canvas:newImageData()

Post by bartbes »

grump wrote: Fri Sep 15, 2017 6:51 pm I've considered that, but shouldn't this work:

Code: Select all

gfx.setCanvas()
local img = canvas:newImageData()
gfx.setCanvas(canvas)
-- ...drawing more stuff on the canvas...
I'd assume so. Doesn't it?
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: No more drawing to canvas after canvas:newImageData()

Post by Nixola »

It looks like it's a bug they're encountering on Debian 9 (as for their edit). I cannot reproduce this with LÖVE 0.10.2 on Manjaro, 64 bit.
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: No more drawing to canvas after canvas:newImageData()

Post by grump »

Yeah, it's my system. Probably a graphics driver issue.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: No more drawing to canvas after canvas:newImageData()

Post by bartbes »

It's very possible for different graphics drivers to behave differently when you do something you're not allowed to do.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: No more drawing to canvas after canvas:newImageData()

Post by grump »

But the error is still present even when I'm not doing the thing I'm not supposed to do. My example code is just the minimal code that would reproduce the issue. As I have explained, I tried to disable the canvas before calling newImageData, since it seemed the obvious thing to try, but it did not solve the issue.

By the way, if calling newImageData on a currently active Canvas is not allowed, may I suggest to update the documentation to include that fact? I couldn't find any mention of "You're not allowed to read from a canvas you're currently writing to" in the docs.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: No more drawing to canvas after canvas:newImageData()

Post by Nixola »

LÖVE 0.11 actively prevents you from doing it, with a descriptive error message (which, honestly, I was not expecting), so at least there's that.
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: No more drawing to canvas after canvas:newImageData()

Post by grump »

Thanks for the info, Nixola.

Regarding the bug: rendering to Canvas in VMWare is seriously fucked on my system. I've spent the day trying to find the cause of this bug, to no avail. After updating basically everything, and even compiling and installing the latest MESA drivers, the only thing that helped was to disable hardware rendering completely by setting LIBGL_ALWAYS_SOFTWARE=1 on the command line.
Post Reply

Who is online

Users browsing this forum: No registered users and 48 guests