diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml
index 5d38788dcd0a..1136ac1b6973 100644
--- a/modules/openxr/doc_classes/OpenXRInterface.xml
+++ b/modules/openxr/doc_classes/OpenXRInterface.xml
@@ -152,6 +152,13 @@
Informs the user queued a recenter of the player position.
+
+
+
+ Informs the user the HMD refresh rate has changed.
+ [b]Node:[/b] Only emitted if XR runtime supports the refresh rate extension.
+
+
Informs our OpenXR session has been started.
diff --git a/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.cpp b/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.cpp
index 0ef70705310e..402389144abc 100644
--- a/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.cpp
+++ b/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.cpp
@@ -29,6 +29,7 @@
/**************************************************************************/
#include "openxr_fb_display_refresh_rate_extension.h"
+#include "../openxr_interface.h"
OpenXRDisplayRefreshRateExtension *OpenXRDisplayRefreshRateExtension::singleton = nullptr;
@@ -64,6 +65,23 @@ void OpenXRDisplayRefreshRateExtension::on_instance_destroyed() {
display_refresh_rate_ext = false;
}
+bool OpenXRDisplayRefreshRateExtension::on_event_polled(const XrEventDataBuffer &event) {
+ switch (event.type) {
+ case XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB: {
+ const XrEventDataDisplayRefreshRateChangedFB *event_fb = (XrEventDataDisplayRefreshRateChangedFB *)&event;
+
+ OpenXRInterface *xr_interface = OpenXRAPI::get_singleton()->get_xr_interface();
+ if (xr_interface) {
+ xr_interface->on_refresh_rate_changes(event_fb->toDisplayRefreshRate);
+ }
+
+ return true;
+ } break;
+ default:
+ return false;
+ }
+}
+
float OpenXRDisplayRefreshRateExtension::get_refresh_rate() const {
float refresh_rate = 0.0;
diff --git a/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.h b/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.h
index d8015fe600e9..1048d245a474 100644
--- a/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.h
+++ b/modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.h
@@ -51,6 +51,7 @@ class OpenXRDisplayRefreshRateExtension : public OpenXRExtensionWrapper {
virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override;
+ virtual bool on_event_polled(const XrEventDataBuffer &event) override;
float get_refresh_rate() const;
void set_refresh_rate(float p_refresh_rate);
diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h
index 615643591f28..9eb51eee7a2b 100644
--- a/modules/openxr/openxr_api.h
+++ b/modules/openxr/openxr_api.h
@@ -336,6 +336,7 @@ class OpenXRAPI {
String get_error_string(XrResult result) const;
String get_swapchain_format_name(int64_t p_swapchain_format) const;
+ OpenXRInterface *get_xr_interface() const { return xr_interface; }
void set_xr_interface(OpenXRInterface *p_xr_interface);
static void register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper);
static void unregister_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper);
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
index 956e5ed3f318..7eb9a6ebe1ed 100644
--- a/modules/openxr/openxr_interface.cpp
+++ b/modules/openxr/openxr_interface.cpp
@@ -43,6 +43,7 @@ void OpenXRInterface::_bind_methods() {
ADD_SIGNAL(MethodInfo("session_focussed"));
ADD_SIGNAL(MethodInfo("session_visible"));
ADD_SIGNAL(MethodInfo("pose_recentered"));
+ ADD_SIGNAL(MethodInfo("refresh_rate_changed", PropertyInfo(Variant::FLOAT, "refresh_rate")));
// Display refresh rate
ClassDB::bind_method(D_METHOD("get_display_refresh_rate"), &OpenXRInterface::get_display_refresh_rate);
@@ -1258,6 +1259,10 @@ void OpenXRInterface::on_pose_recentered() {
emit_signal(SNAME("pose_recentered"));
}
+void OpenXRInterface::on_refresh_rate_changes(float p_new_rate) {
+ emit_signal(SNAME("refresh_rate_changed"), p_new_rate);
+}
+
/** Hand tracking. */
void OpenXRInterface::set_motion_range(const Hand p_hand, const HandMotionRange p_motion_range) {
ERR_FAIL_INDEX(p_hand, HAND_MAX);
diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h
index aee9751d6b99..737f22d64227 100644
--- a/modules/openxr/openxr_interface.h
+++ b/modules/openxr/openxr_interface.h
@@ -174,6 +174,7 @@ class OpenXRInterface : public XRInterface {
void on_state_focused();
void on_state_stopping();
void on_pose_recentered();
+ void on_refresh_rate_changes(float p_new_rate);
void tracker_profile_changed(RID p_tracker, RID p_interaction_profile);
/** Hand tracking. */