Add fetch_gamepads() support on VRDisplay #70
Conversation
…mepads on GoogleVRDisplay
…mepads on OculusVRDisplay
a422a21
to
d0ac41d
Compare
@@ -26,6 +27,7 @@ const PREDICTION_OFFSET_NANOS: i64 = 50000000; // 50ms | |||
|
|||
pub struct GoogleVRDisplay { | |||
service: *const GoogleVRService, | |||
gamepad: Option<GoogleVRGamepadPtr>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lenovo Mireage uses googlevr API and has 2 controllers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but that's not how we use it right now -- I'd rather update the code to handle multiple controllers in a different issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looks good, just some nits. You can r=me when you're happy with it.
|
||
script: | ||
- cargo check --target x86_64-pc-windows-gnu | ||
- cd rust-webvr && cargo check --features "mock oculusvr googlevr" --no-default-features --target=armv7-linux-androideabi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not obvious why these targets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cfg(Android) for these, they can't be tested normally
@@ -13,6 +13,9 @@ pub trait VRDisplay: Send + Sync { | |||
/// Returns the current display data. | |||
fn data(&self) -> VRDisplayData; | |||
|
|||
/// Returns gamepads attached to this display | |||
fn fetch_gamepads(&mut self) -> Result<Vec<VRGamepadPtr>, String>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance of a spec link? (Probably not, but you never know.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a specced method, I need it here to be able to safely fetch gamepads on the servo side without having to further complicate the unsafe code dealing with display pointers.
@@ -328,6 +335,9 @@ impl GoogleVRDisplay { | |||
let right_eye_vp = gvr::gvr_buffer_viewport_create(ctx); | |||
gvr::gvr_buffer_viewport_list_get_item(list, gvr::gvr_eye::GVR_RIGHT_EYE as usize, right_eye_vp); | |||
|
|||
let display_id = utils::new_id(); | |||
let gamepad = GoogleVRGamepad::new(ctx, controller_ctx, display_id).ok(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log the error if this fails?
})) | ||
} | ||
|
||
pub fn gamepad(&self) -> Option<&GoogleVRGamepadPtr> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this return a Option<GoogleVRGamepadPtr>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to clone when it's not necessary, you don't need the new arc for poll_events()
@@ -17,8 +16,7 @@ const SERVICE_CLASS_NAME:&'static str = "com/rust/webvr/GVRService"; | |||
pub struct GoogleVRService { | |||
ctx: *mut gvr::gvr_context, | |||
controller_ctx: *mut gvr::gvr_controller_context, | |||
displays: Vec<GoogleVRDisplayPtr>, | |||
gamepads: Vec<GoogleVRGamepadPtr>, | |||
display: Option<GoogleVRDisplayPtr>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like an odd change, does Google VR really guarantee only one display?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the API it seems so?
Either way, our API usage guarantees one display, so the question is moot for the purposes of this PR.
} else { | ||
self.display = unsafe { Some(GoogleVRDisplay::new(self, self.ctx, self.controller_ctx)) }; | ||
Ok(self.display.as_ref().unwrap()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use Option::get_or_insert_with
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that, we borrow self
here so we can't
@@ -14,7 +14,7 @@ const SERVICE_CLASS_NAME:&'static str = "com/rust/webvr/OVRService"; | |||
|
|||
pub struct OculusVRService { | |||
initialized: bool, | |||
displays: Vec<OculusVRDisplayPtr>, | |||
display: Option<OculusVRDisplayPtr>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only one display?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API seems to think so, and we use it that way
self.display = Some(OculusVRDisplay::new(self.service_java.clone(), self.ovr_java.handle())); | ||
Ok(self.display.as_ref().unwrap()) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_or_insert_with
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self
Overall except for openvr all of our API usage assumes that there is a single display and a single gamepad, so I've fit the code to that assumption. If it is violated we already had problems, this PR isn't making them worse -- we can update our API usage to deal with this separately. I don't want this PR to be more than a refactoring and a change in the external API. I don't think anything supports multiple displays, and WebXR seems to do away with the ability to do this anyway (webvr is being deprecated in favor of webxr). In webxr you can request one immersive session at a time, and infinite inline sessions (to support inline we need direct gyroscope data, not more displays). So we may actually want to eventually make the external API reflect one-display-per-session since webxr can't make use of more displays anyway. |
@bors-servo r=asajeffrey,mortimergoro |
📌 Commit 7964f14 has been approved by |
Add fetch_gamepads() support on VRDisplay WebXR considers gamepads to be attached to the display. I could pass around the VR service on the Servo side, however the safety invariants seem super tricky and I'd rather not complicate that. This also cleans up the code on backends which don't support multiple displays or gamepads. Eventually VR displays should have a way to subscribe to individual gamepads so that sync_poses calls can get all the updates they need at once. r? @MortimerGoro
hmm the build has succeeded but github hasn't gotten the notification yet |
@bors-servo retry |
Add fetch_gamepads() support on VRDisplay WebXR considers gamepads to be attached to the display. I could pass around the VR service on the Servo side, however the safety invariants seem super tricky and I'd rather not complicate that. This also cleans up the code on backends which don't support multiple displays or gamepads. Eventually VR displays should have a way to subscribe to individual gamepads so that sync_poses calls can get all the updates they need at once. r? @MortimerGoro
☀️ Test successful - checks-travis |
💥 Test timed out |
WebXR considers gamepads to be attached to the display. I could pass around the VR service on the Servo side, however the safety invariants seem super tricky and I'd rather not complicate that.
This also cleans up the code on backends which don't support multiple displays or gamepads.
Eventually VR displays should have a way to subscribe to individual gamepads so that sync_poses calls can get all the updates they need at once.
r? @MortimerGoro