diff options
| author | David Snopek <dsnopek@gmail.com> | 2023-02-08 21:02:13 -0600 |
|---|---|---|
| committer | David Snopek <dsnopek@gmail.com> | 2023-02-10 19:21:38 -0600 |
| commit | 886f2270edd4c96ea357caa2a5da5a785a1ae415 (patch) | |
| tree | e819c60ec42291cf4249428212571873d72f41af /modules/webxr/native | |
| parent | 929333fe267f488638c76564237faff9d5d572fc (diff) | |
| download | redot-engine-886f2270edd4c96ea357caa2a5da5a785a1ae415.tar.gz | |
[WebXR] Add support for getting and setting display refresh rate
Diffstat (limited to 'modules/webxr/native')
| -rw-r--r-- | modules/webxr/native/library_godot_webxr.js | 50 | ||||
| -rw-r--r-- | modules/webxr/native/webxr.externs.js | 16 |
2 files changed, 66 insertions, 0 deletions
diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js index 1c00ebebb4..7d797e11d9 100644 --- a/modules/webxr/native/library_godot_webxr.js +++ b/modules/webxr/native/library_godot_webxr.js @@ -42,6 +42,7 @@ const GodotWebXR = { view_count: 1, input_sources: new Array(16), touches: new Array(5), + onsimpleevent: null, // Monkey-patch the requestAnimationFrame() used by Emscripten for the main // loop, so that we can swap it out for XRSession.requestAnimationFrame() @@ -283,6 +284,9 @@ const GodotWebXR = { GodotRuntime.free(c_str); }); + // Store onsimpleevent so we can use it later. + GodotWebXR.onsimpleevent = onsimpleevent; + const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef const gl = GL.getContext(gl_context_handle).GLctx; GodotWebXR.gl = gl; @@ -368,6 +372,7 @@ const GodotWebXR = { GodotWebXR.view_count = 1; GodotWebXR.input_sources = new Array(16); GodotWebXR.touches = new Array(5); + GodotWebXR.onsimpleevent = null; // Disable the monkey-patched window.requestAnimationFrame() and // pause/restart the main loop to activate it on all platforms. @@ -595,6 +600,51 @@ const GodotWebXR = { return point_count; }, + + godot_webxr_get_frame_rate__proxy: 'sync', + godot_webxr_get_frame_rate__sig: 'i', + godot_webxr_get_frame_rate: function () { + if (!GodotWebXR.session || GodotWebXR.session.frameRate === undefined) { + return 0; + } + return GodotWebXR.session.frameRate; + }, + + godot_webxr_update_target_frame_rate__proxy: 'sync', + godot_webxr_update_target_frame_rate__sig: 'vi', + godot_webxr_update_target_frame_rate: function (p_frame_rate) { + if (!GodotWebXR.session || GodotWebXR.session.updateTargetFrameRate === undefined) { + return; + } + + GodotWebXR.session.updateTargetFrameRate(p_frame_rate).then(() => { + const c_str = GodotRuntime.allocString('display_refresh_rate_changed'); + GodotWebXR.onsimpleevent(c_str); + GodotRuntime.free(c_str); + }); + }, + + godot_webxr_get_supported_frame_rates__proxy: 'sync', + godot_webxr_get_supported_frame_rates__sig: 'ii', + godot_webxr_get_supported_frame_rates: function (r_frame_rates) { + if (!GodotWebXR.session || GodotWebXR.session.supportedFrameRates === undefined) { + return 0; + } + + const frame_rate_count = GodotWebXR.session.supportedFrameRates.length; + if (frame_rate_count === 0) { + return 0; + } + + const buf = GodotRuntime.malloc(frame_rate_count * 4); + for (let i = 0; i < frame_rate_count; i++) { + GodotRuntime.setHeapValue(buf + (i * 4), GodotWebXR.session.supportedFrameRates[i], 'float'); + } + GodotRuntime.setHeapValue(r_frame_rates, buf, 'i32'); + + return frame_rate_count; + }, + }; autoAddDeps(GodotWebXR, '$GodotWebXR'); diff --git a/modules/webxr/native/webxr.externs.js b/modules/webxr/native/webxr.externs.js index 4b88820b19..7f7c297acc 100644 --- a/modules/webxr/native/webxr.externs.js +++ b/modules/webxr/native/webxr.externs.js @@ -68,6 +68,16 @@ XRSession.prototype.inputSources; XRSession.prototype.visibilityState; /** + * @type {?number} + */ +XRSession.prototype.frameRate; + +/** + * @type {?Float32Array} + */ +XRSession.prototype.supportedFrameRates; + +/** * @type {?function (Event)} */ XRSession.prototype.onend; @@ -142,6 +152,12 @@ XRSession.prototype.end = function () {}; XRSession.prototype.requestReferenceSpace = function (referenceSpaceType) {}; /** + * @param {number} rate + * @return {Promise<undefined>} + */ +XRSession.prototype.updateTargetFrameRate = function (rate) {}; + +/** * @typedef {function(number, XRFrame): undefined} */ var XRFrameRequestCallback; |
