Skip to content

Commit 069b877

Browse files
committed
Implement dynamic framerate
Reduce tracking frequency to head fps
1 parent bb559d1 commit 069b877

File tree

12 files changed

+97
-36
lines changed

12 files changed

+97
-36
lines changed

alvr/client_core/src/c_api.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,14 @@ pub extern "C" fn alvr_get_tracker_prediction_offset_ns() -> u64 {
398398
}
399399

400400
#[no_mangle]
401-
pub extern "C" fn alvr_report_submit(target_timestamp_ns: u64, vsync_queue_ns: u64) {
401+
pub extern "C" fn alvr_report_submit(
402+
target_timestamp_ns: u64,
403+
frame_interval_ns: u64,
404+
vsync_queue_ns: u64,
405+
) {
402406
crate::report_submit(
403407
Duration::from_nanos(target_timestamp_ns),
408+
Duration::from_nanos(frame_interval_ns),
404409
Duration::from_nanos(vsync_queue_ns),
405410
);
406411
}

alvr/client_core/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ pub fn get_tracker_prediction_offset() -> Duration {
197197
}
198198
}
199199

200-
pub fn report_submit(target_timestamp: Duration, vsync_queue: Duration) {
200+
pub fn report_submit(target_timestamp: Duration, frame_interval: Duration, vsync_queue: Duration) {
201201
if let Some(stats) = &mut *STATISTICS_MANAGER.lock() {
202-
stats.report_submit(target_timestamp, vsync_queue);
202+
stats.report_submit(target_timestamp, frame_interval, vsync_queue);
203203

204204
if let Some(sender) = &*STATISTICS_SENDER.lock() {
205205
if let Some(stats) = stats.summary(target_timestamp) {

alvr/client_core/src/statistics.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,15 @@ impl StatisticsManager {
9595
}
9696

9797
// vsync_queue is the latency between this call and the vsync. it cannot be measured by ALVR and
98-
// should be reported by the VR runtime
99-
pub fn report_submit(&mut self, target_timestamp: Duration, vsync_queue: Duration) {
98+
// should be reported by the VR runtime.
99+
// predicted_frame_interval is the frame interval returned by the runtime. this is more stable
100+
// any any interval mearued by us.
101+
pub fn report_submit(
102+
&mut self,
103+
target_timestamp: Duration,
104+
predicted_frame_interval: Duration,
105+
vsync_queue: Duration,
106+
) {
100107
let now = Instant::now();
101108

102109
if let Some(frame) = self
@@ -118,6 +125,8 @@ impl StatisticsManager {
118125
let vsync = now + vsync_queue;
119126
frame.client_stats.frame_interval = vsync.saturating_duration_since(self.prev_vsync);
120127
self.prev_vsync = vsync;
128+
129+
frame.client_stats.predicted_frame_interval = predicted_frame_interval
121130
}
122131
}
123132

alvr/client_mock/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ fn tracking_thread(streaming: Arc<RelaxedAtomic>, fps: f32, input: Arc<RwLock<Wi
196196

197197
drop(input_lock);
198198

199-
loop_deadline += Duration::from_secs_f32(1.0 / fps / 3.0);
199+
loop_deadline += Duration::from_secs_f32(1.0 / fps);
200200
thread::sleep(loop_deadline.saturating_duration_since(Instant::now()))
201201
}
202202
}
@@ -271,6 +271,7 @@ fn client_thread(
271271

272272
alvr_client_core::report_submit(
273273
window_output.current_frame_timestamp,
274+
Duration::from_secs_f32(1.0 / window_output.fps),
274275
Duration::from_millis(input_lock.emulated_vsync_ms),
275276
);
276277

alvr/client_openxr/src/lib.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ pub fn entry_point() {
463463
let mut views_history = VecDeque::new();
464464

465465
let (history_view_sender, history_view_receiver) = mpsc::channel();
466+
let mut frame_interval_sender = None;
466467
let mut reference_space_sender = None::<mpsc::Sender<_>>;
467468

468469
let default_view = xr::View {
@@ -692,10 +693,13 @@ pub fn entry_point() {
692693

693694
let (sender, reference_space_receiver) = mpsc::channel();
694695
reference_space_sender = Some(sender);
696+
let (sender, frame_interval_receiver) = mpsc::channel();
697+
frame_interval_sender = Some(sender);
695698

696699
streaming_input_thread = Some(thread::spawn(move || {
697700
let mut deadline = Instant::now();
698-
let frame_interval = Duration::from_secs_f32(1.0 / refresh_rate_hint);
701+
let mut frame_interval =
702+
Duration::from_secs_f32(1.0 / refresh_rate_hint);
699703

700704
while is_streaming.value() {
701705
update_streaming_input(&mut context);
@@ -704,7 +708,11 @@ pub fn entry_point() {
704708
context.reference_space = reference_space;
705709
}
706710

707-
deadline += frame_interval / 3;
711+
if let Ok(interval) = frame_interval_receiver.try_recv() {
712+
frame_interval = interval;
713+
}
714+
715+
deadline += frame_interval;
708716
thread::sleep(deadline.saturating_duration_since(Instant::now()));
709717
}
710718
}));
@@ -832,6 +840,10 @@ pub fn entry_point() {
832840
let vsync_time =
833841
Duration::from_nanos(frame_state.predicted_display_time.as_nanos() as _);
834842

843+
if let Some(sender) = &frame_interval_sender {
844+
sender.send(frame_interval).ok();
845+
}
846+
835847
xr_frame_stream.begin().unwrap();
836848

837849
if !frame_state.should_render {
@@ -901,7 +913,11 @@ pub fn entry_point() {
901913

902914
if !hardware_buffer.is_null() {
903915
if let Some(now) = xr_runtime_now(&xr_instance) {
904-
alvr_client_core::report_submit(timestamp, vsync_time.saturating_sub(now));
916+
alvr_client_core::report_submit(
917+
timestamp,
918+
frame_interval,
919+
vsync_time.saturating_sub(now),
920+
);
905921
}
906922
}
907923

alvr/packets/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ pub struct ClientStatistics {
204204
pub rendering: Duration,
205205
pub vsync_queue: Duration,
206206
pub total_pipeline_latency: Duration,
207+
pub predicted_frame_interval: Duration,
207208
}
208209

209210
#[derive(Serialize, Deserialize, Clone, Debug)]

alvr/server/cpp/alvr_server/alvr_server.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,6 @@ void DeinitializeStreaming() {
227227
}
228228
}
229229

230-
void SendVSync() { vr::VRServerDriverHost()->VsyncEvent(0.0); }
231-
232230
void RequestIDR() {
233231
if (g_driver_provider.hmd && g_driver_provider.hmd->m_encoder) {
234232
g_driver_provider.hmd->m_encoder->InsertIDR();

alvr/server/cpp/alvr_server/bindings.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ extern "C" void (*WaitForVSync)();
128128
extern "C" void *CppEntryPoint(const char *pInterfaceName, int *pReturnCode);
129129
extern "C" void InitializeStreaming();
130130
extern "C" void DeinitializeStreaming();
131-
extern "C" void SendVSync();
132131
extern "C" void RequestIDR();
133132
extern "C" void SetTracking(unsigned long long targetTimestampNs,
134133
float controllerPoseTimeOffsetS,

alvr/server/src/connection.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
bitrate::BitrateManager,
33
buttons::BUTTON_PATH_FROM_ID,
44
face_tracking::FaceTrackingSink,
5-
haptics,
5+
haptics, openvr_props,
66
sockets::WelcomeSocket,
77
statistics::StatisticsManager,
88
tracking::{self, TrackingManager},
@@ -24,7 +24,10 @@ use alvr_packets::{
2424
ButtonValue, ClientConnectionResult, ClientControlPacket, ClientListAction, ClientStatistics,
2525
ServerControlPacket, StreamConfigPacket, Tracking, AUDIO, HAPTICS, STATISTICS, TRACKING, VIDEO,
2626
};
27-
use alvr_session::{CodecType, ControllersEmulationMode, FrameSize, OpenvrConfig};
27+
use alvr_session::{
28+
CodecType, ControllersEmulationMode, FrameSize, OpenvrConfig, OpenvrPropValue,
29+
OpenvrPropertyKey,
30+
};
2831
use alvr_sockets::{
2932
spawn_cancelable, ControlSocketReceiver, ControlSocketSender, PeerType, ProtoControlSocket,
3033
StreamSocketBuilder, KEEPALIVE_INTERVAL,
@@ -637,8 +640,8 @@ async fn connection_pipeline(
637640
crate::SetOpenvrProperty(
638641
*alvr_common::HEAD_ID,
639642
crate::openvr_props::to_ffi_openvr_prop(
640-
alvr_session::OpenvrPropertyKey::AudioDefaultPlaybackDeviceId,
641-
alvr_session::OpenvrPropValue::String(id),
643+
OpenvrPropertyKey::AudioDefaultPlaybackDeviceId,
644+
OpenvrPropValue::String(id),
642645
),
643646
)
644647
}
@@ -661,8 +664,8 @@ async fn connection_pipeline(
661664
crate::SetOpenvrProperty(
662665
*alvr_common::HEAD_ID,
663666
crate::openvr_props::to_ffi_openvr_prop(
664-
alvr_session::OpenvrPropertyKey::AudioDefaultPlaybackDeviceId,
665-
alvr_session::OpenvrPropValue::String(id),
667+
OpenvrPropertyKey::AudioDefaultPlaybackDeviceId,
668+
OpenvrPropValue::String(id),
666669
),
667670
)
668671
}
@@ -686,8 +689,8 @@ async fn connection_pipeline(
686689
crate::SetOpenvrProperty(
687690
*alvr_common::HEAD_ID,
688691
crate::openvr_props::to_ffi_openvr_prop(
689-
alvr_session::OpenvrPropertyKey::AudioDefaultRecordingDeviceId,
690-
alvr_session::OpenvrPropValue::String(id),
692+
OpenvrPropertyKey::AudioDefaultRecordingDeviceId,
693+
OpenvrPropValue::String(id),
691694
),
692695
)
693696
}
@@ -925,6 +928,12 @@ async fn connection_pipeline(
925928
network_latency,
926929
decoder_latency,
927930
);
931+
932+
openvr_props::set_prop(
933+
*HEAD_ID,
934+
OpenvrPropertyKey::DisplayFrequency,
935+
OpenvrPropValue::Float(1.0 / stats.frame_interval_average().as_secs_f32()),
936+
);
928937
}
929938
}
930939
}

alvr/server/src/lib.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -468,13 +468,8 @@ pub unsafe extern "C" fn HmdDriverFactory(
468468
}
469469

470470
extern "C" fn wait_for_vsync() {
471-
let wait_duration = STATISTICS_MANAGER
472-
.lock()
473-
.as_mut()
474-
.map(|stats| stats.duration_until_next_vsync());
475-
476-
if let Some(duration) = wait_duration {
477-
thread::sleep(duration);
471+
if let Some(stats) = &mut *STATISTICS_MANAGER.lock() {
472+
thread::sleep(stats.duration_until_next_vsync());
478473
}
479474
}
480475

0 commit comments

Comments
 (0)