Page 2 of 4

Re: LÖVE framerate stutters?

Posted: Sat Aug 02, 2014 10:09 pm
by murks
Do the 60fps drop if that stutter occurs?

Re: LÖVE framerate stutters?

Posted: Sat Aug 02, 2014 10:39 pm
by Metalcookie
Jasoco wrote:I accept it as something that's going to happen either way.
That seems to be the case.
murks wrote:Do the 60fps drop if that stutter occurs?
Generally, yes.

Re: LÖVE framerate stutters?

Posted: Sun Aug 03, 2014 2:16 am
by Jasoco
davisdude wrote:For me, (using a Windows 8 laptop) it stays constant at around 59 FPS, except for when booting up: it starts at 1, then goes to about 54, then stays steady at 59.
Don't trust the FPS counter. It only updates once a second with the average FPS from that previous second. Trust your own eyes. You could have a constant 59-61FPS on your counter but see stuttering. It's a visual thing.

Re: LÖVE framerate stutters?

Posted: Sun Aug 03, 2014 2:55 am
by davisdude
Ah- I see. It looked smooth to me, at any rate.

Re: LÖVE framerate stutters?

Posted: Sun Aug 03, 2014 3:26 am
by Clouds
Ref wrote:The attached script doesn't stutter on my machine.
For me:
VSYNC allowed: 59-61 FPS reported, inconsistent motion with frequent jumps in position.
VSYNC disallowed, 509 FPS reported, smooth uniform motion.

Re: LÖVE framerate stutters?

Posted: Mon Aug 04, 2014 3:17 pm
by Jasoco
Here's a neat little trick you can try if you want to check your framerate performance over time. In case you notice stuttering or want to find out where all your CPU cycles are going.

In my 3D "SuperEffex" project I had created a performance graph which draws a colored Minecraft-style graph plotting out how long the update and draw functions are taking each frame. I have created one for my current project that looks like this:
Screen Shot 2014-08-04 at 10.31.40 AM.png
Screen Shot 2014-08-04 at 10.31.40 AM.png (25.75 KiB) Viewed 6066 times
The green is the update time. The blue is the draw time. The white line represents 1/60th of a second, i.e. 1 frame if assuming 60FPS. In this shot you can see it go from my title screen, which draws hardly anything and updates even less, to my interim game level state, which is a stress test that loops over 1500 8x8 rectangles every frame, to a third state which has a bit more updating but is less stressful on the drawing. Frames are scaled up 6000x in order to be visible above.

Here's some code:

Code: Select all

local win = love.window
local lgr = love.graphics
local tmr = love.timer

local performanceGraph = {}
performanceGraph.enabled = false

local performanceGraphUpdateTime = 0
local performanceGraphDrawTime = 0
local performanceGraphTickPos = 0
local performanceGraphTickScale = 10000
local performanceGraphWidth = 1000
local performanceGraphScale = win.getPixelScale()
local performanceGraphCanvas = lgr.newCanvas(performanceGraphWidth, 800)
performanceGraphCanvas:setFilter("nearest")

local _performanceGraphTime = 0

local function performanceGraphReset()
	local _s = 1 / 60
	performanceGraphTickPos = 0
	performanceGraphCanvas:clear(0,0,0,0)
	lgr.setColor(0,0,0,100)
	lgr.rectangle("fill", 0, 0, performanceGraphWidth, _s * performanceGraphTickScale)
	lgr.setColor(255,255,255)
	lgr.line(0, _s * performanceGraphTickScale, performanceGraphWidth, _s * performanceGraphTickScale)
end

-- Call this at the top of love.update before anything else
function performanceGraph:preUpdate()
	if not self.enabled then return false end
	_performanceGraphTime = tmr.getTime()
end

-- Call this at the bottom of love.update after everything else
function performanceGraph:postUpdate()
	if not self.enabled then return false end
	performanceGraphUpdateTime = tmr.getTime() - _performanceGraphTime
end

-- Call this at the top of love.draw before anything else
function performanceGraph:preDraw()
	if not self.enabled then return false end
	_performanceGraphTime = tmr.getTime()
end

-- Call this at the bottom of love.draw after everything else
function performanceGraph:postDraw()
	if not self.enabled then return false end
	performanceGraphDrawTime = tmr.getTime() - _performanceGraphTime

	lgr.setCanvas(performanceGraphCanvas)

	if performanceGraphTickPos == 0 then performanceGraphReset() end
	lgr.setColor(0,255,0)
	lgr.rectangle("fill", performanceGraphTickPos, 0, 1, performanceGraphUpdateTime * performanceGraphTickScale)
	lgr.setColor(0,0,255)
	lgr.rectangle("fill", performanceGraphTickPos, performanceGraphUpdateTime * performanceGraphTickScale, 1, performanceGraphDrawTime * performanceGraphTickScale)
	performanceGraphTickPos = performanceGraphTickPos + 1
	if performanceGraphTickPos >= performanceGraphWidth then performanceGraphTickPos = 0 end
	lgr.setCanvas()

	lgr.setColor(255,255,255)
	lgr.draw(performanceGraphCanvas, 0, lgr.getHeight(), 0, performanceGraphScale, -performanceGraphScale)
end

function performanceGraph:toggle()
	performanceGraphReset()
	self.enabled = not self.enabled
end

return performanceGraph
You simply require it as performanceGraph = require "performancegraph" and call the four main functions in the right places. (Top and bottom of update and draw) It requires Canvas support though. You might need to tweak the size too if your system has Po2 problems too. It also takes into account HighDPI mode by using Pixel Scale to draw the graph. I am pretty sure I have self-contained it so it only uses one global variable. Everything else is localized within the lua file.

If VSync is enabled, the graph will move at a steady pace. But the bar will not be filled out just because there's a timer sleep time. So you can tell exactly how much frame time you have left over each frame. If VSync is disabled, the graph will draw much faster and refresh a lot more.

Re: LÖVE framerate stutters?

Posted: Mon Aug 04, 2014 6:55 pm
by Metalcookie
That's a neat script, thanks.

Image

Unfortunately, the stutters wouldn't appear in the graph. It would continue at the ~1px height for love.draw as it does right from the start.
I guess all this means that the reason of the stutters are not inside love.update or love.draw.

Re: LÖVE framerate stutters?

Posted: Tue Aug 05, 2014 12:15 am
by murks
Thanks a lot Jasoco, this is an increadibly useful tool for profiling.
A small usage hint: for the graph to show up it is necessary to call:

Code: Select all

performanceGraph:toggle()

Re: LÖVE framerate stutters?

Posted: Tue Aug 05, 2014 7:30 am
by Jasoco
Oops. I thought I had it set to enabled by default.

Whatever. I like to attach the toggle to an F-key like F11 or F1 or something for easy access when I need it.

Re: LÖVE framerate stutters?

Posted: Sun Oct 05, 2014 10:21 am
by bcolin
Hi all,
Same problem here on my machine : win8 x64 with ATI graphic card.
I actually see the stutter by running the "stuttertest.love" program on this thread, and the stutter is very visible on my own program with intensive drawing. Every second (more or less), the graphic freeze, I also notice that the dt received by love.update(dt) is far higher (about 0.25s) instead of usuals dt around 0.1.
It looks like, every second, the draw process take much longer.
I tried various settings combinations (vsync, screen resolution, other graphic card settings I don't remember) without success.
It looks like something in Love itself. I'll try download the love source and take a look.
I'll also do some tests with previous versions of love2d - it could be a bug in the new version only
and knowing this it will be easier to track down the problem.