Skip to content

Commit dc3abf3

Browse files
authored
Add CPU and GPU performance level control (#3066)
* Set CPU performance level * CPU and GPU perf levels * Class migration and enable the required functions for performance control * Remove old performance settings code * Add log * Fix extension activation * Remove dedicated class for performance level settings * Remove comments * Move power saving setting location and remove unused imports * Alphabetically order requested extensions. * Add performance level setting * Update text and default config * Add realtime power mode setting and add boost level * OpenXR Client performance level * Formatting * Remove commented code * Performance level refactoring * Remove powersavings performance level for lobby * More accurate performance level help strings and hide Boost level. * Combine duplicate strings. * Update help string for performance level config
1 parent 8f849eb commit dc3abf3

File tree

3 files changed

+102
-2
lines changed

3 files changed

+102
-2
lines changed

alvr/client_openxr/src/lib.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use alvr_common::{
1515
parking_lot::RwLock,
1616
};
1717
use alvr_graphics::GraphicsContext;
18-
use alvr_session::{BodyTrackingBDConfig, BodyTrackingSourcesConfig};
18+
use alvr_session::{BodyTrackingBDConfig, BodyTrackingSourcesConfig, PerformanceLevel};
1919
use alvr_system_info::Platform;
2020
use extra_extensions::{
2121
BD_BODY_TRACKING_EXTENSION_NAME, BD_MOTION_TRACKING_EXTENSION_NAME,
@@ -95,6 +95,32 @@ fn to_xr_time(timestamp: Duration) -> xr::Time {
9595
xr::Time::from_nanos(timestamp.as_nanos() as _)
9696
}
9797

98+
fn to_perf_settings_level(level: PerformanceLevel) -> xr::PerfSettingsLevelEXT {
99+
match level {
100+
PerformanceLevel::PowerSavings => xr::PerfSettingsLevelEXT::POWER_SAVINGS,
101+
PerformanceLevel::SustainedLow => xr::PerfSettingsLevelEXT::SUSTAINED_LOW,
102+
PerformanceLevel::SustainedHigh => xr::PerfSettingsLevelEXT::SUSTAINED_HIGH,
103+
PerformanceLevel::Boost => xr::PerfSettingsLevelEXT::BOOST,
104+
}
105+
}
106+
107+
fn set_performance_level(
108+
xr_instance: &xr::Instance,
109+
xr_session: &xr::Session<xr::OpenGlEs>,
110+
domain: xr::PerfSettingsDomainEXT,
111+
level: PerformanceLevel,
112+
) {
113+
if let Some(performance_settings) = xr_instance.exts().ext_performance_settings {
114+
unsafe {
115+
(performance_settings.perf_settings_set_performance_level)(
116+
xr_session.as_raw(),
117+
domain,
118+
to_perf_settings_level(level),
119+
);
120+
}
121+
}
122+
}
123+
98124
fn default_view() -> xr::View {
99125
xr::View {
100126
pose: xr::Posef {
@@ -182,6 +208,7 @@ pub fn entry_point() {
182208
exts.ext_eye_gaze_interaction = available_extensions.ext_eye_gaze_interaction;
183209
exts.ext_hand_tracking = available_extensions.ext_hand_tracking;
184210
exts.ext_local_floor = available_extensions.ext_local_floor;
211+
exts.ext_performance_settings = available_extensions.ext_performance_settings;
185212
exts.ext_user_presence = available_extensions.ext_user_presence;
186213
exts.fb_body_tracking = available_extensions.fb_body_tracking;
187214
exts.fb_color_space = available_extensions.fb_color_space;
@@ -514,6 +541,24 @@ pub fn entry_point() {
514541
passthrough_layer = None;
515542
}
516543

544+
if let Some(cpu_performance_level) = &config.cpu_performance_level {
545+
set_performance_level(
546+
&xr_instance,
547+
&xr_session,
548+
xr::PerfSettingsDomainEXT::CPU,
549+
cpu_performance_level.clone(),
550+
);
551+
}
552+
553+
if let Some(gpu_performance_level) = &config.gpu_performance_level {
554+
set_performance_level(
555+
&xr_instance,
556+
&xr_session,
557+
xr::PerfSettingsDomainEXT::GPU,
558+
gpu_performance_level.clone(),
559+
);
560+
}
561+
517562
if let Some(stream) = &mut stream_context {
518563
stream.update_real_time_config(&config);
519564
}

alvr/packets/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use alvr_common::{
55
semver::Version,
66
};
77
use alvr_session::{
8-
ClientsidePostProcessingConfig, CodecType, PassthroughMode, SessionConfig, Settings,
8+
ClientsidePostProcessingConfig, CodecType, PassthroughMode, PerformanceLevel, SessionConfig,
9+
Settings,
910
};
1011
use serde::{Deserialize, Serialize};
1112
use serde_json as json;
@@ -327,6 +328,8 @@ pub enum FirewallRulesAction {
327328
pub struct RealTimeConfig {
328329
pub passthrough: Option<PassthroughMode>,
329330
pub clientside_post_processing: Option<ClientsidePostProcessingConfig>,
331+
pub cpu_performance_level: Option<PerformanceLevel>,
332+
pub gpu_performance_level: Option<PerformanceLevel>,
330333
pub ext_str: String,
331334
}
332335

@@ -339,6 +342,8 @@ impl RealTimeConfig {
339342
.clientside_post_processing
340343
.clone()
341344
.into_option(),
345+
cpu_performance_level: settings.headset.performance_level.clone().cpu.into_option(),
346+
gpu_performance_level: settings.headset.performance_level.clone().gpu.into_option(),
342347
ext_str: String::new(), // No extensions for now
343348
}
344349
}

alvr/session/src/settings.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,34 @@ pub enum HeadsetEmulationMode {
878878
},
879879
}
880880

881+
#[derive(SettingsSchema, Serialize, Deserialize, PartialEq, Clone)]
882+
pub enum PerformanceLevel {
883+
#[schema(strings(display_name = "Power Saving"))]
884+
PowerSavings,
885+
#[schema(strings(display_name = "Sustained Low"))]
886+
SustainedLow,
887+
#[schema(strings(display_name = "Sustained High"))]
888+
SustainedHigh,
889+
#[schema(flag = "hidden")]
890+
Boost,
891+
}
892+
893+
#[derive(SettingsSchema, Serialize, Deserialize, PartialEq, Clone)]
894+
pub struct PerformanceLevelConfig {
895+
#[schema(flag = "real-time")]
896+
#[schema(strings(
897+
display_name = "CPU",
898+
help = "When disabling this, the client needs to be restarted for the change to be applied."
899+
))]
900+
pub cpu: Switch<PerformanceLevel>,
901+
#[schema(flag = "real-time")]
902+
#[schema(strings(
903+
display_name = "GPU",
904+
help = "When disabling this, the client needs to be restarted for the change to be applied."
905+
))]
906+
pub gpu: Switch<PerformanceLevel>,
907+
}
908+
881909
#[derive(SettingsSchema, Serialize, Deserialize, Clone, PartialEq)]
882910
pub enum FaceTrackingSourcesConfig {
883911
PreferEyeTrackingOnly,
@@ -1274,6 +1302,14 @@ Tilted: the world gets tilted when long pressing the oculus button. This is usef
12741302
#[schema(flag = "steamvr-restart")]
12751303
pub emulation_mode: HeadsetEmulationMode,
12761304

1305+
#[schema(strings(
1306+
help = r#"Power Savings might increase latency or reduce framerate consistency but decreases temperatures and improves battery life.
1307+
Sustained Low provides consistent framerates but might increase latency if necessary.
1308+
Sustained High provides consistent framerates but increases temperature.
1309+
This is mainly for Quest headsets, mileage may vary on other devices."#
1310+
))]
1311+
pub performance_level: PerformanceLevelConfig,
1312+
12771313
#[schema(flag = "steamvr-restart")]
12781314
#[schema(strings(display_name = "Extra OpenVR properties"))]
12791315
pub extra_openvr_props: Vec<OpenvrProperty>,
@@ -1923,6 +1959,20 @@ pub fn session_settings_default() -> SettingsDefault {
19231959
},
19241960
variant: HeadsetEmulationModeDefaultVariant::Quest2,
19251961
},
1962+
performance_level: PerformanceLevelConfigDefault {
1963+
cpu: SwitchDefault {
1964+
enabled: false,
1965+
content: PerformanceLevelDefault {
1966+
variant: PerformanceLevelDefaultVariant::PowerSavings,
1967+
},
1968+
},
1969+
gpu: SwitchDefault {
1970+
enabled: false,
1971+
content: PerformanceLevelDefault {
1972+
variant: PerformanceLevelDefaultVariant::PowerSavings,
1973+
},
1974+
},
1975+
},
19261976
extra_openvr_props: default_custom_openvr_props.clone(),
19271977
tracking_ref_only: false,
19281978
enable_vive_tracker_proxy: false,

0 commit comments

Comments
 (0)