Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sokol_app: turning off vsync ? #292

Open
septag opened this issue May 8, 2020 · 11 comments
Open

sokol_app: turning off vsync ? #292

septag opened this issue May 8, 2020 · 11 comments

Comments

@septag
Copy link
Contributor

septag commented May 8, 2020

Hi,
Can I turn off vsync ? :)
because according to what I'm seeing, the swap_interval defaults to 1 if we set it to 0.

@floooh
Copy link
Owner

floooh commented May 12, 2020

Hmm, no this isn't supported unfortunately, it would be hard to do on all platforms. For instance MTKView only has a preferredFramesPerSecond method (https://developer.apple.com/documentation/metalkit/mtkview/1536027-preferredframespersecond?language=objc). Setting this to zero will simply never call the frame callback, and setting it to a very high value (e.g. 1000) will clamp at the display refresh rate.

Similar problem on the web platform most likely.

These APIs are basically also the reason why there is this swap_interval member instead of a simple vsync flag.

@septag
Copy link
Contributor Author

septag commented May 13, 2020

ouch! so as a workaround, how about changing the swap_interval to an enum value:

typedef enum sg_swap_interval {
  SG_SWAPINTERVAL_DEFAULT = 0,
  SG_SWAPINTERVAL_ONE = 1,
  SG_SWAPINTERVAL_TWO = 2,
  SG_SWAPINTERVAL_FOUR = 4,
  SG_SWAPINTERVAL_EIGHT = 8,
  SG_SWAPINTERVAL_NOSYNC = 0x7fffffff // or something
} sg_swap_interval ;

So default would be ONE, and NOSYNC would set it to 0 for the platforms that support this behavior. As for metal and the web that you mentioned, we could divide it by the refresh rate of the display, and of course make an exception for NOSYNC option (right now you are doing the same in metal but shouldn't we query the refresh rate instead of hard coded 60 ?)

@floooh
Copy link
Owner

floooh commented May 13, 2020

Yeah a special value for "no sync" might work, I wouldn't use a new enum type though, just a special constant for "NOSYNC", and it would be need to be ignored on some platforms (but swap_interval is also not guaranteed to work, so I guess that's ok).

shouldn't we query the refresh rate instead of hard coded 60

Yes, on the macOS code path that would definitely make sense, there seems to be a CGDisplayModeGetRefreshRate() function.

I don't think there's a way to query the display refresh rate on the web though. Only way is to measure the time between calls to the frame callback and round to the closest "likely" refresh rate (I'm currently adding a function to sokol_time.h for that).

@septag
Copy link
Contributor Author

septag commented May 13, 2020

yeah. constants would work pretty well too, it's your call.

Refresh rate would also make sense on iOS, cuz ipad pro is 120hz

would you like me to submit a PR for this ? because I can happily do that. (however I'm not familiar with web platforms)

@lithiumtoast
Copy link

For Metal, why not use CAMetalLayer.displaySyncEnabled?

@floooh
Copy link
Owner

floooh commented May 28, 2020

would you like me to submit a PR for this ?

I'm terribly behind on PRs and open issues. Let's discuss at a later time again :)

@lithiumtoast: sokol_app.h is using the higher level MTKView which takes care of the entire frame loop and presentation, I'm not sure if it's possible to access the CAMetalLayer owned by the MTKView (and if yes, whether it's "legal" to poke around in it).

@lithiumtoast
Copy link

I don't think it is possible but it's possible to ditch MTKView and use CAMetalLayer directly with a NSView for macOS and a UIView for iOS. I do this myself when using SDL with sokol_gfx.

@lithiumtoast
Copy link

@iryont Did you read the Apple docs on CAMetalLayer? There are also some docs on best practices with how to use drawable. You may also want to try presentsWithTransaction.

@floooh Sorry, you can access the CAMetalLayer from MTKView but I don't know how "legal" this is.

CAMetalLayer* layer = self.layer;
layer.displaySyncEnabled = NO;

@edubart
Copy link
Contributor

edubart commented Dec 30, 2021

I've also felt the need to disable vertical synchronization for benchmarking purposes, my workaround at the moment is to use the following after initializing (Linux only):

#ifdef _SAPP_LINUX
    /* Disable swap interval */
    _sapp_glx_swapinterval(0);
#endif

@cloudhead
Copy link

Also interested in this, unless there's a way to reduce latency as much as disabling vsync, without disabling vsync :)

@lou256
Copy link

lou256 commented Nov 27, 2023

I would also really appreciate if this was added, working on an app where I need vsync off to minimise latency and screen tearing isn't really a concern, seems harder to do this on mac os I guess...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants