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

Add new device setting OHMD_IDS_KEEP_ON_AT_CLOSE. #101

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kleinerm
Copy link
Contributor

This setting can be set to 1 to prevent OpenHMD from powering off
a device when it is closed with ohmd_close_device(). It defaults to
0 = try to power device off on close.

The flag so far applies to the HTC Vive. Powering off a device and
its display will cause the OS to detect the display as being unplugged.

This is, e.g., problematic in a X11 X-Server environment if one wants
to create a separate X-Screen for the video output of the HMD to gain
a performance boost and reduction in motion-to-photon latency, and to
avoid potential tearing artifacts. For best performance, the graphics
card should use page-flipping, but this only works if the HMD output
window covers the full X-Screen, so this can only be achieved if one
creates a separate X-Screen for the HMD. Separate X-Screens only work
if the HMD display is active (= "connected") while the X-Server starts,
otherwise such a separate X-Screen is discarded, iow. the separate
X-Screen is not hot-pluggable.

This flag allows to run a little helper application which opens the
HMD, e.g. during system boot, then closes it again, just to turn on
the display. Then one can (re-)start the X-Server, getting the extra
X-Screen for the HMD, and then use a VR application enjoying the
better performance and timing of this setup.

Signed-off-by: Mario Kleiner [email protected]

This setting can be set to 1 to prevent OpenHMD from powering off
a device when it is closed with ohmd_close_device(). It defaults to
0 = try to power device off on close.

The flag so far applies to the HTC Vive. Powering off a device and
its display will cause the OS to detect the display as being unplugged.

This is, e.g., problematic in a X11 X-Server environment if one wants
to create a separate X-Screen for the video output of the HMD to gain
a performance boost and reduction in motion-to-photon latency, and to
avoid potential tearing artifacts. For best performance, the graphics
card should use page-flipping, but this only works if the HMD output
window covers the full X-Screen, so this can only be achieved if one
creates a separate X-Screen for the HMD. Separate X-Screens only work
if the HMD display is active (= "connected") while the X-Server starts,
otherwise such a separate X-Screen is discarded, iow. the separate
X-Screen is not hot-pluggable.

This flag allows to run a little helper application which opens the
HMD, e.g. during system boot, then closes it again, just to turn on
the display. Then one can (re-)start the X-Server, getting the extra
X-Screen for the HMD, and then use a VR application enjoying the
better performance and timing of this setup.

Signed-off-by: Mario Kleiner <[email protected]>
@kleinerm
Copy link
Contributor Author

kleinerm commented Aug 21, 2017

A bit more background info: I tested and verified that you can't create a separate x-screen when the HMDs display is powered off with a Rift CV1, both with the open-source graphics/display drivers, and the amdgpu-pro and NVidia proprietary display drivers.

The way i solved it is by writing a little daemon application "openhmdkeepalivedaemon", the source of which is here:

https://github.com/kleinerm/Psychtoolbox-3/blob/master/PsychSourceGL/Cohorts/openhmdkeepalivedaemon.c

What it does is using OpenHMD to enumerate all connected HMD's every 5 seconds. For each HMD that needs some "keep display on" treatment to solve the mentioned problem, it opens the HMD's device and then closes it again, rinse wash repeat in 5 seconds.

The Rift DK1 and DK2 don't need this, but all other supported HMDs seem to need periodic keep-alive packets to keep their displays on, e.g., the Rift CV1.

According to the code in vive.c, the Vive doesn't seem to need such packets, but one needs to turn it on, so the little helper daemon does that. However, closing the Vive would normally turn the display off again, so the daemons code contains an ugly hack to prevent that: It does a single pass without closing the device or destroying the ohmd context and then kills itself. Less than ideal! Hence this flag, to allow the daemon to do its job in a less ugly manner. Btw. i haven't tested this with an actual Vive, don't have one available atm. This is just from reading the vive.c source code.

If somebody thinks that daemon has any value for OpenHMD, i'm happy to contribute it to OpenHMD, and also change the license to Boost if you like.

Another reason to have that daemon even in a hot-pluggable RandR setup is that my own application doesn't like hot-plugged outputs - it doesn't handle it at runtime for some complex but good reasons, so i need that daemon to run in the background even in the single-x-screen case to keep the HMD output connected. Maybe there are other applications which have similar needs, if they weren't designed for VR only, but like mine just with VR as another use-case.

Thanks,
-mario

@TheOnlyJoey
Copy link
Member

Interesting patch, we need to discuss this with the team to see if this is something we want to add in the API.
The Vive driver is still slightly experimental so the current behavior for turning the device on/off is not definitive.

Part of the benefits of OpenHMD is the lack of a daemon, so i don't think we will adapt that into the driver, we do have default multi-threading that handles updates like the keep alive packages though.

I would like @Wallbraker and @noname22 their opinion on the matter before deciding what to do.

@noname22
Copy link
Member

No big objections from me, apart from possibly the name. What's "IDS"? Id:s? Perhaps something with "device" instead?

@kleinerm
Copy link
Contributor Author

I chose the IDS prefix for consistency with the other setting in that enum called OHMD_IDS_AUTOMATIC_UPDATE. I assumed it is the convention? IDS = IntegerDeviceSetting? InternalDeviceSetting? InitialDeviceSetting?

@noname22
Copy link
Member

Oh, haha!

That would be my naming convention then, oops.

@TheOnlyJoey
Copy link
Member

I think the current idea is to have enabling/disabling of the device as part of the seti functions so you can call the device after opening to not set the off command when closing the device, would that be sufficient for your case?

@kleinerm
Copy link
Contributor Author

You mean moving the new setting to ohmd_device_seti(), so it can be set after device open?
Yes, that would be fine. Should i update the pull request accordingly, ie. move the setting code, and maybe use a setting name like OHMD_KEEP_ON_AT_CLOSE - dropping the IDS ?

@TheOnlyJoey
Copy link
Member

Well the idea is to have a value like OHMD_DISABLE_DEVICE or OHMD_ENABLE_DEVICE that can be set by openhmd_device_seti().
When set, it should overwrite the default behavior and keep a device enabled or disabled until it is manually set again.
I will draft up a PR and submit myself, will keep this open as reference.

@kleinerm
Copy link
Contributor Author

Ok, good. Thanks for that!

Btw. is it expected that the distortion rendering on the Rift CV1 is a bit worse than on the DK2? I can't see any artifacts when using the DK2, but with the CV1, if i move my head, i see some slight "wobbling" of the 3d scene, as if something would be slightly off in undistortion? I wonder if it is something wrong in the way i setup rendering in my app, or if the current set of hard-coded undistortion coefficients are just generally a bit less accurate than for the CV1?

@Wallbraker
Copy link
Member

@TheOnlyJoey Can we close this now?

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

Successfully merging this pull request may close these issues.

4 participants