[solved] flickering when not redrawing every frame

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.
Bananicorn
Prole
Posts: 37
Joined: Thu Apr 12, 2018 9:59 am

[solved] flickering when not redrawing every frame

Post by Bananicorn »

Hey Lövers :)
To preface this: I know ways to work around this, like using a canvas to store the entire screen and drawing that each time, setting the BackgroundColor to this color, or simply redrawing the background every time, but that's not what I'm asking - I'm wondering why Löve behaves as it does in this case :)

Love version: 11.1

And I'm probably trying to abuse the engine again, but I'm hoping someone can clear this up for me :)
If roll my own love.run function, remove the love.graphics.clear call and fill the screen with a single color, once in love.load,
then that should consistently until something is drawn over it, right?
Problem is, on my system (be it natively or in wine), my static background flickers like hell... (Arch linux, but otherwise Löve games run perfectly fine)

Here's the code (.love file in the attachments)

Code: Select all

local lg = love.graphics

function love.load ()
	--initial drawing of the background
	lg.setColor(.5,.5,0,1)
	lg.rectangle("fill",0,0,lg.getWidth(),lg.getHeight())
end

function love.draw ()
	--just to show that everything which is drawn every frame, is actually also redrawn.
	lg.setColor(1,0,0,1)
	lg.rectangle("fill", 10,10,100,100)
end

function love.update (dt)
	if love.keyboard.isDown("escape") then
		love.event.quit()
	end
end

function love.run()
	if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
	if love.timer then love.timer.step() end
	local dt = 0
	return function()
		if love.event then
			love.event.pump()
			for name, a,b,c,d,e,f in love.event.poll() do
				if name == "quit" then
					if not love.quit or not love.quit() then
						return a or 0
					end
				end
				love.handlers[name](a,b,c,d,e,f)
			end
		end
		if love.timer then dt = love.timer.step() end
		if love.update then love.update(dt) end
		if lg and lg.isActive() then
			--love.graphics.clear is omitted to be able to keep the background across frames
			if love.draw then love.draw() end
			lg.present()
		end

		if love.timer then love.timer.sleep(0.001) end
	end
end
Edit: added .love file, whoops^^
Attachments
perf_test_2.love
(1.1 KiB) Downloaded 75 times
Last edited by Bananicorn on Wed Dec 19, 2018 5:28 pm, edited 2 times in total.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: flickering when not redrawing every frame

Post by grump »

You forgot to attach the love file.
Bananicorn wrote: Wed Dec 19, 2018 3:55 pm if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
Huh, I didn't know about love.arg. It's not even documented, but seems handy. Thank you for posting this :)
Bananicorn
Prole
Posts: 37
Joined: Thu Apr 12, 2018 9:59 am

Re: flickering when not redrawing every frame

Post by Bananicorn »

grump wrote: Wed Dec 19, 2018 4:08 pm You forgot to attach the love file.
Bananicorn wrote: Wed Dec 19, 2018 3:55 pm if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
Huh, I didn't know about love.arg. It's not even documented, but seems handy. Thank you for posting this :)
Thanks for pointing that out - I could've sworn I attached it - but, well... I didn't :P
Also, that's just part of the standard love.run function, which you can find here (cool stuff!)
https://love2d.org/wiki/love.run
And I didn't wanna remove it for that example, so you can still just quit the test with esc (because that flickering is terrible)
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: flickering when not redrawing every frame

Post by grump »

I believe the flickering is caused by double buffering. Back buffer gets filled with the rectangle, but front buffer remains black. It alternates between filled and black background with each buffer flip when present is called.

Here is a workaround:

Code: Select all

function love.load ()
	--initial drawing of the background
	lg.setColor(.5,.5,0,1)
	lg.rectangle("fill",0,0,lg.getWidth(),lg.getHeight()) -- back buffer
	lg.present()
	lg.rectangle("fill",0,0,lg.getWidth(),lg.getHeight()) -- front buffer
end
Now both back and front buffer are filled with the rectangle. Maybe you should do it even three times, to make it sure it doesn't flicker when triple buffering is enabled in the driver.
User avatar
slime
Solid Snayke
Posts: 3131
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: flickering when not redrawing every frame

Post by slime »

Even if you do that to account for double/triple buffering, the window manager may trash the contents of the window's frame buffers at any time (for example if you move another window over the LÖVE window, and then move it away).

It's much more robust to just draw to a Canvas and then redraw that every frame, as you said.
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: flickering when not redrawing every frame

Post by zorg »

The assumption i have is that the backbuffer is only colored that barf brown once, but it's at least double buffered, so it flickers between that and black; if you didn't color it anything, it might not flicker bc both of them might be set to black by default;

then again, you can't query how many of these there are on the opengl end, nor can you programmatically check, so it's pointless to not have clear defined.

Edit: ninjad by both of them above.
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.
Bananicorn
Prole
Posts: 37
Joined: Thu Apr 12, 2018 9:59 am

Re: flickering when not redrawing every frame

Post by Bananicorn »

slime wrote: Wed Dec 19, 2018 4:34 pm Even if you do that to account for double/triple buffering, the window manager may trash the contents of the window's frame buffers at any time (for example if you move another window over the LÖVE window, and then move it away).

It's much more robust to just draw to a Canvas and then redraw that every frame, as you said.
In the end I was just looking for ways to squeeze out a few more frames by foregoing the clear function and just painting over the parts which need to be cleared with the background color (premature optimization may be the root of all evil, but it's also hella fun :P)

My initial thought for doing this was to just use the game's regular screen as the buffer, but I guess that's not the way to go^^
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: [solved] flickering when not redrawing every frame

Post by pgimeno »

If the canvas overwrites the whole screen, you don't need to call clear, so in a sense, that method allows you that optimization. And I don't know for sure, but maybe blending method "replace" is faster than the others.
Bananicorn wrote: Wed Dec 19, 2018 5:27 pm(premature optimization may be the root of all evil, but it's also hella fun :P)
I agree it's fun, and I don't agree it's the root of all evil :) http://ubiquity.acm.org/article.cfm?id=1513451
Bananicorn
Prole
Posts: 37
Joined: Thu Apr 12, 2018 9:59 am

Re: [solved] flickering when not redrawing every frame

Post by Bananicorn »

pgimeno wrote: Wed Dec 19, 2018 6:39 pm If the canvas overwrites the whole screen, you don't need to call clear, so in a sense, that method allows you that optimization. And I don't know for sure, but maybe blending method "replace" is faster than the others.
Bananicorn wrote: Wed Dec 19, 2018 5:27 pm(premature optimization may be the root of all evil, but it's also hella fun :P)
I agree it's fun, and I don't agree it's the root of all evil :) http://ubiquity.acm.org/article.cfm?id=1513451
Oh, I'm sorry, absolutes are always bad ;)
I actually agree with you, I was quoting that a bit tongue-in-cheek (which text doesn't convey at all, oops)
And thanks for the article, really interesting read!
As for the blend method replace - I really can't tell... I tried it with a benchmark of mine, with vsync off, but It doesn't make more than a few frames difference, if at all (on top of ~720).

I'll attach the .love file I've been testing this with to this reply - though who knows how it'll look on your machine, it's hacky stuff (mostly badly working around the double buffer issue mentioned by most people in this thread), which will probably never work, but I like messing around^^

You're probably better off writing a little benchmark about the replace blending method yourself, but in theory it should give at least a little boost since it's formula is the simplest.
I can't see it though.
Attachments
perf_test_1.love
(1.62 KiB) Downloaded 74 times
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: [solved] flickering when not redrawing every frame

Post by pgimeno »

Yeah, it may not make any difference depending on the driver. I don't note any either. But I can tell you that I have serious FPS problems (under 30 FPS) on the RPi3 when I draw something with alpha, so the blending mode may matter in some architectures.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 54 guests