Skip to content

Commit 03a7f70

Browse files
Add latency drop down
1 parent e089bad commit 03a7f70

4 files changed

Lines changed: 46 additions & 1 deletion

File tree

deps/cloudxr/webxr_client/helpers/react/CloudXRComponent.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ export default function CloudXRComponent({
230230
referenceSpace = referenceSpace.getOffsetReferenceSpace(offsetTransform);
231231
}
232232

233+
const lowLatency = config.networkLatencyMode === 'LOW';
234+
233235
// Fill in CloudXR session options.
234236
const cloudXROptions: CloudXR.SessionOptions = {
235237
serverAddress: connectionConfig.serverIP,
@@ -244,7 +246,13 @@ export default function CloudXRComponent({
244246
gl: gl,
245247
referenceSpace: referenceSpace,
246248
deviceFrameRate: config.deviceFrameRate,
247-
maxStreamingBitrateKbps: config.maxStreamingBitrateMbps * 1000, // Convert Mbps to Kbps
249+
networkLatencyMode: lowLatency
250+
? CloudXR.NetworkLatencyMode.Low
251+
: CloudXR.NetworkLatencyMode.Default,
252+
// LOW preset sets bitrate, DRC, and tracking uplink in SessionImpl; do not override.
253+
...(lowLatency
254+
? {}
255+
: { maxStreamingBitrateKbps: config.maxStreamingBitrateMbps * 1000 }),
248256
enablePoseSmoothing: config.enablePoseSmoothing,
249257
posePredictionFactor: config.posePredictionFactor,
250258
enableTexSubImage2D: config.enableTexSubImage2D,

deps/cloudxr/webxr_client/helpers/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ export interface CloudXRConfig {
146146
/** Maximum streaming bitrate in Megabits per second (Mbps) */
147147
maxStreamingBitrateMbps: number;
148148

149+
/** CloudXR network latency preset (`LOW` caps bitrate and throttles tracking uplink for congested links). */
150+
networkLatencyMode?: 'DEFAULT' | 'LOW';
151+
149152
/** Preferred video codec used for streaming */
150153
codec?: 'h264' | 'h265' | 'av1';
151154

deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export class CloudXR2DUI {
8686
private immersiveSelect!: HTMLSelectElement;
8787
/** Dropdown to select device frame rate (FPS) */
8888
private deviceFrameRateSelect!: HTMLSelectElement;
89+
/** Dropdown for CloudXR networkLatencyMode preset */
90+
private networkLatencyModeSelect!: HTMLSelectElement;
8991
/** Dropdown to select max streaming bitrate (Mbps) */
9092
private maxStreamingBitrateMbpsSelect!: HTMLSelectElement;
9193
/** Dropdown to select preferred streaming codec */
@@ -213,6 +215,7 @@ export class CloudXR2DUI {
213215
// Set initial display value
214216
this.posePredictionFactorValue.textContent = this.posePredictionFactorInput.value;
215217
this.updateConfiguration();
218+
this.updateNetworkLatencyModeUi();
216219
this.updateDeviceProfileWarning(resolveDeviceProfileId(this.deviceProfileSelect.value));
217220
this.updateConnectButtonState();
218221
this.initialized = true;
@@ -361,6 +364,7 @@ export class CloudXR2DUI {
361364
this.proxyUrlInput = this.getElement<HTMLInputElement>('proxyUrl');
362365
this.immersiveSelect = this.getElement<HTMLSelectElement>('immersive');
363366
this.deviceFrameRateSelect = this.getElement<HTMLSelectElement>('deviceFrameRate');
367+
this.networkLatencyModeSelect = this.getElement<HTMLSelectElement>('networkLatencyMode');
364368
this.maxStreamingBitrateMbpsSelect =
365369
this.getElement<HTMLSelectElement>('maxStreamingBitrateMbps');
366370
this.codecSelect = this.getElement<HTMLSelectElement>('codec');
@@ -444,6 +448,7 @@ export class CloudXR2DUI {
444448
reprojectionGridRows: 0,
445449
deviceFrameRate: 90,
446450
maxStreamingBitrateMbps: 150,
451+
networkLatencyMode: 'DEFAULT',
447452
codec: 'av1',
448453
immersiveMode: 'ar',
449454
deviceProfileId: 'custom',
@@ -477,6 +482,7 @@ export class CloudXR2DUI {
477482
enableLocalStorage(this.reprojectionGridRowsInput, 'reprojectionGridRows');
478483
enableLocalStorage(this.proxyUrlInput, 'proxyUrl');
479484
enableLocalStorage(this.deviceFrameRateSelect, 'deviceFrameRate');
485+
enableLocalStorage(this.networkLatencyModeSelect, 'networkLatencyMode');
480486
enableLocalStorage(this.maxStreamingBitrateMbpsSelect, 'maxStreamingBitrateMbps');
481487
enableLocalStorage(this.codecSelect, 'codec');
482488
enableLocalStorage(this.enablePoseSmoothingSelect, 'enablePoseSmoothing');
@@ -563,6 +569,10 @@ export class CloudXR2DUI {
563569
addListener(this.reprojectionGridRowsInput, 'keyup', updateGridValidation);
564570
this.updateGridValidationMessage();
565571
addListener(this.deviceFrameRateSelect, 'change', onProfileLinkedChange);
572+
addListener(this.networkLatencyModeSelect, 'change', () => {
573+
this.updateNetworkLatencyModeUi();
574+
onProfileLinkedChange();
575+
});
566576
addListener(this.maxStreamingBitrateMbpsSelect, 'change', onProfileLinkedChange);
567577
addListener(this.codecSelect, 'change', onProfileLinkedChange);
568578
addListener(this.enablePoseSmoothingSelect, 'change', onProfileLinkedChange);
@@ -745,6 +755,7 @@ export class CloudXR2DUI {
745755
maxStreamingBitrateMbps:
746756
parseInt(this.maxStreamingBitrateMbpsSelect.value) ||
747757
this.getDefaultConfiguration().maxStreamingBitrateMbps,
758+
networkLatencyMode: this.networkLatencyModeSelect.value === 'LOW' ? 'LOW' : 'DEFAULT',
748759
codec:
749760
(this.codecSelect.value as 'h264' | 'h265' | 'av1') || this.getDefaultConfiguration().codec,
750761
// Headless mode turns off the client's CloudXR frame blit but keeps tracking; the WebXR
@@ -870,6 +881,7 @@ export class CloudXR2DUI {
870881
localStorage.setItem('reprojectionGridCols', this.reprojectionGridColsInput.value);
871882
localStorage.setItem('reprojectionGridRows', this.reprojectionGridRowsInput.value);
872883
localStorage.setItem('deviceFrameRate', this.deviceFrameRateSelect.value);
884+
localStorage.setItem('networkLatencyMode', this.networkLatencyModeSelect.value);
873885
localStorage.setItem('maxStreamingBitrateMbps', this.maxStreamingBitrateMbpsSelect.value);
874886
localStorage.setItem('codec', this.codecSelect.value);
875887
localStorage.setItem('enablePoseSmoothing', this.enablePoseSmoothingSelect.value);
@@ -881,6 +893,17 @@ export class CloudXR2DUI {
881893
}
882894
}
883895

896+
private updateNetworkLatencyModeUi(): void {
897+
const low = this.networkLatencyModeSelect.value === 'LOW';
898+
this.maxStreamingBitrateMbpsSelect.disabled = low;
899+
const help = document.getElementById('networkLatencyModeHelp');
900+
if (help) {
901+
help.textContent = low
902+
? 'Low mode sets ~15 Mbit/s max bitrate, Ragnarok DRC, ~30 Hz pose/controller uplink, and disables hand/body bulk. Settings below do not apply.'
903+
: 'Default: full-rate tracking (including hands/body), Ragnarok ALL adaptive streaming. Set max Mbps below.';
904+
}
905+
}
906+
884907
private updateDeviceProfileWarning(profileId: DeviceProfileId): void {
885908
if (!this.deviceProfileWarning) return;
886909
const profile = getDeviceProfile(profileId);

deps/cloudxr/webxr_client/src/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,17 @@ <h3 class="debug-title">Debug Settings</h3>
723723
</div>
724724
</div>
725725

726+
<div class="config-section">
727+
<label for="networkLatencyMode" class="input-label">Network Latency Mode</label>
728+
<select id="networkLatencyMode" class="ui-input config-input">
729+
<option value="DEFAULT" selected>Default (high quality)</option>
730+
<option value="LOW">Low (congested Wi‑Fi)</option>
731+
</select>
732+
<div id="networkLatencyModeHelp" class="config-text">
733+
Default: full-rate tracking and Mbps below. Low: applies ~15 Mbit/s, Ragnarok DRC, and throttled pose/controller uplink (ignores Mbps).
734+
</div>
735+
</div>
736+
726737
<div class="config-section">
727738
<label class="input-label">Maximum Streaming Bitrate</label>
728739
<label for="maxStreamingBitrateMbps" class="input-label">Megabits per second</label>

0 commit comments

Comments
 (0)