ValveSoftware / openvr

OpenVR SDK
http://steamvr.com
BSD 3-Clause "New" or "Revised" License
6.1k stars 1.28k forks source link

When to send IVRServerDriverHost()::VsyncEvent (from DirectMode driver)? #415

Closed TheDeveloperGuy closed 7 years ago

TheDeveloperGuy commented 7 years ago

Implementing IVRDriverDirectModeComponent driver, that is not coupled to a Windows monitor equivalent. I'm sending a VSyncEvent each time a frame is sent to the HMD (wireless, not that it matters), but even though I'm completely matching the framerate (reported to OpenVR via Prop_DisplayFrequency_Float) I'm getting a missed frame warning on every other frame if I send the VSyncEvent. If I don't send it then there are no missing frames (obviously). I'm sending the VSyncEvent with an offset of 0 seconds. What am I doing wrong?

TheDeveloperGuy commented 7 years ago

On 4/11/17 8:01 PM, Joe Ludwig wrote:

For #415, you don't need to call VsyncEvent. We call it for you when Present returns. We also add a 2.8ms delay to it because that's what the Oculus driver needs. That will probably need to change.

I'm not convinced about this. If I don't send VsyncEvent events, applications like Virtual Desktop get the frame rate wrong. If I do send the events, everything works as you'd expect, except for the dropped frame warnings...

LoSealL commented 7 years ago

Begin to do the same thing, keeping an eye on this question :)

aleiby commented 7 years ago

The thread that calls IVRDriverDirectModeComponent::Present calls: VsyncEvent(k_nDriverNone, 2.8f / 1000.0f); after Present returns. The 2.8ms was to account for how Oculus SDK timing worked (their "queue ahead" period).

We should probably push this into the driver itself, but that's how things are currently implemented.

IVRDriverDirectModeComponent was never really intended to be implemented outside of wrapping the Oculus SDK, but it turns out to have been useful for other driver implementations. I'm in the process of adding a new interface which drivers can optionally implement which might be a better fit going forward.

TheDeveloperGuy commented 7 years ago

Ok, but what if there is no Vsync at all (ie. in the case where there is no actual display backing the HMD), how does OpenVR time the Present? It seems to work better if I set up a fake Vsync at the framerate I want and then send the VsyncEvent on my fake Vsync...

TheDeveloperGuy commented 7 years ago

There's some kind of issue here. I'm able to see the effective rate of frame updates coming to the HMD. If I don't send a VsyncEvent then I don't get any dropped frame warnings but my effective framerate is around 80Hz (instead of 90Hz as it should be). If I do send a VsyncEvent after each frame I output, then I get dropped frame warnings but my effective framerate is 90Hz. So (for me) it's better to send the event and ignore the warnings. Also, if I send the event, apps like VirtualDesktop, which report the framerate, report the correct framerate, whereas if I don't send it an incorrect (lower) framerate is reported.

TheDeveloperGuy commented 7 years ago

Measurement error. As long as the driver does its own frame timing (simulated Vsync), then there's no need to send this event (and sending it causes warnings).