Skip to content

Commit

Permalink
Surface framerate info/functionality in openxr (#239)
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Adams <[email protected]>
  • Loading branch information
msub2 authored Aug 16, 2024
1 parent dd76329 commit 08a6d70
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
8 changes: 8 additions & 0 deletions webxr-api/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ pub trait DeviceAPI: 'static {
fn cancel_hit_test(&mut self, _id: HitTestId) {
panic!("This device does not support hit tests");
}

fn update_frame_rate(&mut self, rate: f32) -> f32 {
rate
}

fn supported_frame_rates(&self) -> Vec<f32> {
Vec::new()
}
}

impl<GL: 'static> DiscoveryAPI<GL> for Box<dyn DiscoveryAPI<GL>> {
Expand Down
16 changes: 16 additions & 0 deletions webxr-api/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ enum SessionMsg {
RenderAnimationFrame,
RequestHitTest(HitTestSource),
CancelHitTest(HitTestId),
UpdateFrameRate(f32, Sender<f32>),
Quit,
}

Expand Down Expand Up @@ -144,6 +145,7 @@ pub struct Session {
initial_inputs: Vec<InputSource>,
granted_features: Vec<String>,
id: SessionId,
supported_frame_rates: Vec<f32>,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -242,6 +244,14 @@ impl Session {
pub fn cancel_hit_test(&self, id: HitTestId) {
let _ = self.sender.send(SessionMsg::CancelHitTest(id));
}

pub fn update_frame_rate(&mut self, rate: f32, sender: Sender<f32>) {
let _ = self.sender.send(SessionMsg::UpdateFrameRate(rate, sender));
}

pub fn supported_frame_rates(&self) -> &[f32] {
&self.supported_frame_rates
}
}

#[derive(PartialEq)]
Expand Down Expand Up @@ -303,6 +313,7 @@ where
let initial_inputs = self.device.initial_inputs();
let environment_blend_mode = self.device.environment_blend_mode();
let granted_features = self.device.granted_features().into();
let supported_frame_rates = self.device.supported_frame_rates();
Session {
floor_transform,
viewports,
Expand All @@ -311,6 +322,7 @@ where
environment_blend_mode,
granted_features,
id: self.id,
supported_frame_rates,
}
}

Expand Down Expand Up @@ -389,6 +401,10 @@ where

let _ = self.frame_sender.send(frame);
}
SessionMsg::UpdateFrameRate(rate, sender) => {
let new_framerate = self.device.update_frame_rate(rate);
let _ = sender.send(new_framerate);
}
SessionMsg::Quit => {
if self.render_state == RenderState::NotInRenderLoop {
self.quit();
Expand Down
34 changes: 34 additions & 0 deletions webxr/openxr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ pub struct CreatedInstance {
supports_mutable_fov: bool,
supported_interaction_profiles: Vec<&'static str>,
supports_passthrough: bool,
supports_updating_framerate: bool,
}

pub fn create_instance(
Expand All @@ -240,6 +241,8 @@ pub fn create_instance(
let supports_secondary = needs_secondary
&& supported.msft_secondary_view_configuration
&& supported.msft_first_person_observer;
let supports_updating_framerate = supported.fb_display_refresh_rate;

let app_info = ApplicationInfo {
application_name: &app_info.application_name,
application_version: app_info.application_version,
Expand All @@ -263,6 +266,10 @@ pub fn create_instance(
exts.fb_passthrough = true;
}

if supports_updating_framerate {
exts.fb_display_refresh_rate = true;
}

let supported_interaction_profiles = get_supported_interaction_profiles(&supported, &mut exts);

let instance = entry
Expand Down Expand Up @@ -293,6 +300,7 @@ pub fn create_instance(
supports_mutable_fov,
supported_interaction_profiles,
supports_passthrough,
supports_updating_framerate,
})
}

Expand Down Expand Up @@ -439,6 +447,7 @@ struct OpenXrDevice {
clip_planes: ClipPlanes,
supports_secondary: bool,
supports_mutable_fov: bool,
supports_updating_framerate: bool,

// input
action_set: ActionSet,
Expand Down Expand Up @@ -948,6 +957,7 @@ impl OpenXrDevice {
supports_mutable_fov,
supported_interaction_profiles,
supports_passthrough,
supports_updating_framerate,
} = instance;

let (init_tx, init_rx) = crossbeam_channel::unbounded();
Expand Down Expand Up @@ -1153,6 +1163,7 @@ impl OpenXrDevice {
clip_planes: Default::default(),
supports_secondary,
supports_mutable_fov,
supports_updating_framerate,
layer_manager,
shared_data,

Expand Down Expand Up @@ -1585,6 +1596,29 @@ impl DeviceAPI for OpenXrDevice {
fn granted_features(&self) -> &[String] {
&self.granted_features
}

fn update_frame_rate(&mut self, rate: f32) -> f32 {
if self.supports_updating_framerate {
self.session
.request_display_refresh_rate(rate)
.expect("Failed to request display refresh rate");
self.session
.get_display_refresh_rate()
.expect("Failed to get display refresh rate")
} else {
-1.0
}
}

fn supported_frame_rates(&self) -> Vec<f32> {
if self.supports_updating_framerate {
self.session
.enumerate_display_refresh_rates()
.expect("Failed to enumerate display refresh rates")
} else {
vec![]
}
}
}

fn transform<Src, Dst>(pose: &Posef) -> RigidTransform3D<f32, Src, Dst> {
Expand Down

0 comments on commit 08a6d70

Please sign in to comment.