glfwSwapInterval() issue

kvarkus wrote on Tuesday, March 10, 2009:

The method glfwSwapInterval is useful, but have one big disadvantage.

In the main loop of the game engine I’m updating animations at first, then drawing.
So if a big delay happen between animation & drawing we can see incorrect jerky movement.
I haven’t worked with v-sync before, but I thought there should some workaround exist around this issue.
The animations use keboard/mouse input info as well, so the automatic polling events at drawing is not useful. Hopefully GLFW has an explicit PollEvents function.

Can we have a function to wait for a retrace?
I’d like to have my main loop do the following:
1) *wait retrace*, fix current time, capture input
2) parse input, update animations
3) draw scene, swap buffers

dalfy wrote on Tuesday, March 10, 2009:

It exists. you can separate the processing of input with the rendering by using glfwPollEvents().
Also you can make sure the event are not processed at the same time the rendering occurs through glfwDisable(GLFW_AUTO_POLL_EVENTS).

Both are well documented in the reference manual and the user manual. You should be able to do exactly what you want with them.

kvarkus wrote on Tuesday, March 10, 2009:

Thanks, Oliver, but you seem to misunderstand my question.
I know what glfwPollEvents() function is ("Hopefully GLFW has an explicit PollEvents function.").

The problem is that I’d like to have a similar glfwWaitTrace() function - an explicit alternative to the glfwSwapInterval(int) functionality.

dalfy wrote on Tuesday, March 10, 2009:

I completly not get it. That’s completly true. I think I will pass this one to Camilla that might understand your problem better or give a try at it tomorrow morning. My brain seems to be out for lunch.

kvarkus wrote on Tuesday, March 10, 2009:

Sorry, I might not explain the problem correctly… Before Camilla look here I’ll try to explain with more details.

My original goal: to provide smooth animations in the game engine, but not consume 100% CPU.
Old solution: introduce a desired frame time value and call glfwSleep(nextFrameTime - currentFrame) before processing the next frame.
Result: fine

New solution: wait for a vertical retrace using glfwSwapInterval(1) on program init. This way the program actually freezes (sleeps) after processing frame but before it’s drawing (actual SwapBuffers() call).
Result: poor, because the delay happen between animation processing and actual drawing.

My question is whether it’s possible to move this delay (trace wait) out of glfwSwapBuffers() into, to say, some glfwWaitTrace() function. This way would allow processing animations after the delay, so they would play correctly.

Hope this time my words are easier to understand…

elmindreda wrote on Wednesday, March 11, 2009:

The short answer is no.

The long answer is that SwapInterval is implemented by telling the GPU driver (via platform specific calls or vendor specific extensions) to wait a certain number of vblanks before flipping/swapping the colour buffer. We can’t separate the two as both are done through a single call (aglSwapBuffers/wglSwapBuffers/glXSwapBuffers/CGLFlushDrawable).

For specifics, see the implementation of _glfwPlatformSwapBuffers for your platform.

There may, possibly, be a way to implement such a function in a sane fashion on all the platforms we support. If there is, it’s something I’d consider adding to GLFW proper. I haven’t had time to look into it before writing this reply, but I’ll put it somewhere on my list.

Right now, however, what’s on my list is getting 2.7 out the door ASAP.

kvarkus wrote on Wednesday, March 11, 2009:

Thanks, Camilla

I’ve looked at the sources and haven’t found a way for v-sync to separate waiting & drawing. It seems like the reason for it is that it’s just not possible.

Maybe the reason of jerky movement is not behind v-sync… But without it the animation is smooth even with 30 fps.