I've successfully connected a 120/144hz (it supports both, but I usually use 120) monitor to my mac and set it to 120hz in system preferences. It generally works perfect on most programs (no jitter), but in my Love2D game when using window.vsync it tries to sync to 60 for some reason instead of 120, and the timer for that is also very inaccurate resulting in very laggy/jittery/stuttering motion. That means it's not true vsync, just a crappy timer, which seems almost like it could be a deliberate, hardcoded 60hz framerate limiter (part of SDL maybe?)
It works fine when I use the same monitor (120hz + LOVE) on a windows PC. And it also gives smooth, non-jittery, tear-free 60hz movement in LOVE when I set the monitor to 60hz mode on mac. However even though LOVE tries to sync to 60hz, it does correctly report 120hz in the window flags which is odd. Could this be an SDL/OpenGL bug on macOS, considering the somewhat uncommon situation of mac+120hz+LOVE+vsync? I doubt this is a bug in mac, that would be pretty ridiculous.
EDIT: Okay, I did more testing... here's what's actually happening: with vsync *off* @120hz it tries to sync to 65 FPS (which explains the jittering), with vsync *on* @120hz it tries to sync to 62 FPS! (which produces slightly less jittering than vsync *off* (65 FPS), but still jittery)
120hz monitor on macOS, LOVE(?) tries to sync to 62 or 65 FPS instead of 120.
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- slime
- Solid Snayke
- Posts: 3170
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: 120hz monitor on macOS, LOVE(?) tries to sync to 62 or 65 FPS instead of 120.
SDL just sets the NSOpenGLContext swap interval (number of monitor refreshes per frame) to 1 when you use vsync, it doesn't have any hard-coded limiter.
Have you tested other non-love games in macOS? Are you running your love game in fullscreen mode?
Do you get a lot more than 65 fps when vsync is off on a 60hz monitor of a similar resolution? If not, you probably need to optimize your game to get the framerate you expect.RonanZero wrote: ↑Wed Dec 27, 2017 7:55 pmI did more testing... here's what's actually happening: with vsync *off* @120hz it tries to sync to 65 FPS (which explains the jittering), with vsync *on* @120hz it tries to sync to 62 FPS! (which produces slightly less jittering than vsync *off* (65 FPS), but still jittery)
The way vsync works is it forces the game framerate to be the lowest possible multiple of the monitor's refresh rate. Ideally that multiple will be 1, which means 120 hz == 120 frames. If the game can't produce 120 frames per second, vsync will drop it down to the next multiple (2), which means the game will produce a frame every 2 monitor refreshes - i.e. ~60 FPS for a 120 hz monitor.
Re: 120hz monitor on macOS, LOVE(?) tries to sync to 62 or 65 FPS instead of 120.
Yes. See bottom of post.slime wrote:Have you tested other non-love games in macOS?
No, but that probably wouldn't make a difference since mac uses borderless full screen (I think? Usually?)slime wrote:Are you running your love game in fullscreen mode?
Even with 60hz monitor mode, LOVE with vsync set to off still vsyncs (perfectly) to 60hz. My game isn't very demanding, I should be able to get a ton of FPS. It doesn't slow down much more if at all when I add a ton (50+) of more enemies on screen for example.slime wrote:Do you get a lot more than 65 fps when vsync is off on a 60hz monitor of a similar resolution? If not, you probably need to optimize your game to get the framerate you expect.
Here are some stats from more extensive testing:
Half-Life macOS (OpenGL)
....60hz mode
........Vsync OFF
............Uncapped; very high framerate.
........Vsync ON
............Caps itself at 60fps, no jitter. true vsync
....120hz mode
........Vsync OFF
............Uncapped; very high framerate.
........Vsync ON
............Caps itself at 120fps, no jitter. true vsync(?): fluctuates between 119-121, but probably just a cl_showfps error
LOVE macOS (OpenGL)
....60hz mode
........Vsync OFF
............Caps itself at 60fps, no jitter. true vsync(?)
........Vsync ON
............Caps itself at 60fps, no jitter. true vsync
....120hz mode
........Vsync OFF
............Cap unknown, fluctuates between 60-64fps, usually at 62fps, slightly more noticeable jitter
........Vsync ON
............Cap unknown, fluctuates between 61-65fps, usually at 64fps, noticeable jitter
Keep in mind my does nothing to limit the framerate on mac except set t.window.vsync (as well as it works perfect on 120hz windows pc). But I'll keep messing with the code and system settings/conf.lua in case I missed something stupid.
EDIT: Okay, what... it is something in my game that's causing it...?
I was calling love.window.setMode to scale the game. But that's only part of the issue.
I've managed to trace it down to this (without the line i commented about it runs perfectly):
Code: Select all
function tile.get_quad(p, l)
local world = getWorld();
local tile_width, tile_height = world.tile.layer[l].image:getWidth()/16,world.tile.layer[l].image:getHeight()/16;
if (world.tile.layer == nil) then
love.event.quit();
end
if (world.tile.layer[l].quads == nil) then
love.event.quit();
end
if (world.tile.layer[l].quads[1][1] == nil) then
love.event.quit();
end
if (world.tile.layer[l].quads == nil) then
love.event.quit();
end
return world.tile.layer[l].quads[math.ceil(p/(tile_height+1))][((p-1) % tile_width)+1];
end
...
local lx = 0;
for l, _v in pairs(self.tile.level) do
for k, v in pairs(_v.t) do
for kk, vv in pairs(v) do
local tile_width, tile_height = self.tile.layer[1].image:getWidth()/16,self.tile.layer[1].image:getHeight()/16;
local zx = self.tile.layer[1].quads[math.ceil(vv/(tile_height+1))];
if (zx ~= nil) then
-- THE FOLLOWING LINE OF CODE causes a weirdly consistent framerate limit... what?????!!!!!!!!!!!!!!!!!!!!!!1
-- commenting it out allows vsync to work as it should
love.graphics.draw(self.tile.layer[l].image, tile.get_quad(vv, 1), (kk-1)*16, (k-1)*16); -- this one
end
end
end
lx = lx + 1;
end
Last edited by RonanZero on Thu Dec 28, 2017 1:14 am, edited 2 times in total.
while true do end;
- slime
- Solid Snayke
- Posts: 3170
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: 120hz monitor on macOS, LOVE(?) tries to sync to 62 or 65 FPS instead of 120.
macOS (and most other modern operating systems) optimize borderless fullscreen opengl windows to skip compositing when possible. You should try it.
Keep in mind any call to love.window.setMode will enable vsync by default, unless you explicitly set vsync=false in the table you pass in.
Re: 120hz monitor on macOS, LOVE(?) tries to sync to 62 or 65 FPS instead of 120.
I've updated my post. That was half of the issueslime wrote: ↑Thu Dec 28, 2017 1:10 am Keep in mind any call to love.window.setMode will enable vsync by default, unless you explicitly set vsync=false in the table you pass in.
while true do end;
- slime
- Solid Snayke
- Posts: 3170
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: 120hz monitor on macOS, LOVE(?) tries to sync to 62 or 65 FPS instead of 120.
Your code is producing a lot of draw calls per frame, so it's probably as I described above (reduced performance is pushing vsync down to one frame every other monitor refresh). I recommend using one or more SpriteBatch objects which drastically reduce draw calls (even if you have to clear and re-add everything every frame), especially if you combine them with texture atlases / sprite sheets.
nvidia drivers on Windows are known for optimizing / amortizing the cost of a draw call a lot, but most other drivers aren't able to so much.
You can use love.graphics.getStats to track how many draw calls are in a given frame. Generally they should be in the dozens or low hundreds on mobile, and in the single-digit thousands tops (preferably lower) on desktops.
nvidia drivers on Windows are known for optimizing / amortizing the cost of a draw call a lot, but most other drivers aren't able to so much.
You can use love.graphics.getStats to track how many draw calls are in a given frame. Generally they should be in the dozens or low hundreds on mobile, and in the single-digit thousands tops (preferably lower) on desktops.
Who is online
Users browsing this forum: No registered users and 2 guests