Skip to content

Commit 4e75119

Browse files
committed
Merge pull request #109753 from dsnopek/openxr-ext-threading-docs
`OpenXRExtensionWrapper`: Document how to safely work when rendering with "Separate" thread model
2 parents 50ac10f + 30d2a8a commit 4e75119

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

modules/openxr/doc_classes/OpenXRAPIExtension.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,20 +228,23 @@
228228
<param index="0" name="extension" type="OpenXRExtensionWrapper" />
229229
<description>
230230
Registers the given extension as a composition layer provider.
231+
[b]Note:[/b] This cannot be called after the OpenXR session has started. However, it can be called in [method OpenXRExtensionWrapper._on_session_created].
231232
</description>
232233
</method>
233234
<method name="register_frame_info_extension">
234235
<return type="void" />
235236
<param index="0" name="extension" type="OpenXRExtensionWrapper" />
236237
<description>
237238
Registers the given extension as modifying frame info via the [method OpenXRExtensionWrapper._set_frame_wait_info_and_get_next_pointer], [method OpenXRExtensionWrapper._set_view_locate_info_and_get_next_pointer], or [method OpenXRExtensionWrapper._set_frame_end_info_and_get_next_pointer] virtual methods.
239+
[b]Note:[/b] This cannot be called after the OpenXR session has started. However, it can be called in [method OpenXRExtensionWrapper._on_session_created].
238240
</description>
239241
</method>
240242
<method name="register_projection_views_extension">
241243
<return type="void" />
242244
<param index="0" name="extension" type="OpenXRExtensionWrapper" />
243245
<description>
244246
Registers the given extension as a provider of additional data structures to projections views.
247+
[b]Note:[/b] This cannot be called after the OpenXR session has started. However, it can be called in [method OpenXRExtensionWrapper._on_session_created].
245248
</description>
246249
</method>
247250
<method name="set_custom_play_space">
@@ -307,20 +310,23 @@
307310
<param index="0" name="extension" type="OpenXRExtensionWrapper" />
308311
<description>
309312
Unregisters the given extension as a composition layer provider.
313+
[b]Note:[/b] This cannot be called while the OpenXR session is still running.
310314
</description>
311315
</method>
312316
<method name="unregister_frame_info_extension">
313317
<return type="void" />
314318
<param index="0" name="extension" type="OpenXRExtensionWrapper" />
315319
<description>
316320
Unregisters the given extension as modifying frame info.
321+
[b]Note:[/b] This cannot be called while the OpenXR session is still running.
317322
</description>
318323
</method>
319324
<method name="unregister_projection_views_extension">
320325
<return type="void" />
321326
<param index="0" name="extension" type="OpenXRExtensionWrapper" />
322327
<description>
323328
Unregisters the given extension as a provider of additional data structures to projections views.
329+
[b]Note:[/b] This cannot be called while the OpenXR session is still running.
324330
</description>
325331
</method>
326332
<method name="xr_result">

modules/openxr/doc_classes/OpenXRExtensionWrapper.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
</brief_description>
66
<description>
77
[OpenXRExtensionWrapper] allows implementing OpenXR extensions with GDExtension. The extension should be registered with [method register_extension_wrapper].
8+
When [OpenXRInterface] is initialized as the primary interface and any [Viewport] has [member Viewport.use_xr] set to [code]true[/code], OpenXR will become involved in Godot's rendering process. If [member ProjectSettings.rendering/driver/threads/thread_model] is set to "Separate", Godot's renderer will run on its own thread, and special care must be taken in all [OpenXRExtensionWrapper]s in order to prevent crashes or unexpected behavior. Some virtual methods will be called on the render thread, and any data they access should not be directly written to on the main thread. This is to prevent two potential issues:
9+
1. Changes intended for the next frame, taking effect on the current frame. When using the "Separate" thread model, the main thread will immediately start working on the next frame while the render thread may still be rendering the current frame. If the main thread changes anything used by the render thread directly, the change could end up being used one frame earlier than intended.
10+
2. Reading and writing to the same data at the same time from different threads can lead to the render thread using data in an invalid state.
11+
In most cases, the solution is to use [method RenderingServer.call_on_render_thread] to schedule [Callable]s to write to any data used on the render thread. When using the "Separate" thread model, these [Callable]s will run after the renderer finishes the current frame and before it starts rendering the next frame. When not using this mode, they'll run immediately, so it's recommended to always use [method RenderingServer.call_on_render_thread] in these cases, which will allow your code to do the right thing regardless of the thread model.
12+
Any virtual methods that run on the render thread will be noted below.
813
</description>
914
<tutorials>
1015
</tutorials>
@@ -15,13 +20,15 @@
1520
<description>
1621
Returns a pointer to an [code]XrCompositionLayerBaseHeader[/code] struct to provide the given composition layer.
1722
This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_composition_layer_provider].
23+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
1824
</description>
1925
</method>
2026
<method name="_get_composition_layer_count" qualifiers="virtual">
2127
<return type="int" />
2228
<description>
2329
Returns the number of composition layers this extension wrapper provides via [method _get_composition_layer].
2430
This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_composition_layer_provider].
31+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
2532
</description>
2633
</method>
2734
<method name="_get_composition_layer_order" qualifiers="virtual">
@@ -30,6 +37,7 @@
3037
<description>
3138
Returns an integer that will be used to sort the given composition layer provided via [method _get_composition_layer]. Lower numbers will move the layer to the front of the list, and higher numbers to the end. The default projection layer has an order of [code]0[/code], so layers provided by this method should probably be above or below (but not exactly) [code]0[/code].
3239
This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_composition_layer_provider].
40+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
3341
</description>
3442
</method>
3543
<method name="_get_requested_extensions" qualifiers="virtual">
@@ -50,6 +58,7 @@
5058
<return type="Dictionary[]" />
5159
<description>
5260
Gets an array of [Dictionary]s that represent properties, just like [method Object._get_property_list], that will be added to [OpenXRCompositionLayer] nodes.
61+
[b]Note:[/b] This virtual method will be called on the render thread.
5362
</description>
5463
</method>
5564
<method name="_get_viewport_composition_layer_extension_property_defaults" qualifiers="virtual">
@@ -62,6 +71,7 @@
6271
<return type="void" />
6372
<description>
6473
Called before the OpenXR instance is created.
74+
[b]Note:[/b] This virtual method will be called on the main thread, however, it will be called [i]before[/i] OpenXR becomes involved in rendering, so it is safe to write to data that will be used by the render thread.
6575
</description>
6676
</method>
6777
<method name="_on_event_polled" qualifiers="virtual">
@@ -76,18 +86,21 @@
7686
<param index="0" name="instance" type="int" />
7787
<description>
7888
Called right after the OpenXR instance is created.
89+
[b]Note:[/b] This virtual method will be called on the main thread, however, it will be called [i]before[/i] OpenXR becomes involved in rendering, so it is safe to write to data that will be used by the render thread.
7990
</description>
8091
</method>
8192
<method name="_on_instance_destroyed" qualifiers="virtual">
8293
<return type="void" />
8394
<description>
8495
Called right before the OpenXR instance is destroyed.
96+
[b]Note:[/b] This virtual method will be called on the main thread, however, it will be called [i]after[/i] OpenXR is done being involved in rendering, so it is safe to write to data that was used by the render thread.
8597
</description>
8698
</method>
8799
<method name="_on_main_swapchains_created" qualifiers="virtual">
88100
<return type="void" />
89101
<description>
90102
Called right after the main swapchains are (re)created.
103+
[b]Note:[/b] This virtual method will be called on the render thread.
91104
</description>
92105
</method>
93106
<method name="_on_post_draw_viewport" qualifiers="virtual">
@@ -96,19 +109,22 @@
96109
<description>
97110
Called right after the given viewport is rendered.
98111
[b]Note:[/b] The draw commands might only be queued at this point, not executed.
112+
[b]Note:[/b] This virtual method will be called on the render thread.
99113
</description>
100114
</method>
101115
<method name="_on_pre_draw_viewport" qualifiers="virtual">
102116
<return type="void" />
103117
<param index="0" name="viewport" type="RID" />
104118
<description>
105119
Called right before the given viewport is rendered.
120+
[b]Note:[/b] This virtual method will be called on the render thread.
106121
</description>
107122
</method>
108123
<method name="_on_pre_render" qualifiers="virtual">
109124
<return type="void" />
110125
<description>
111126
Called right before the XR viewports begin their rendering step.
127+
[b]Note:[/b] This virtual method will be called on the render thread.
112128
</description>
113129
</method>
114130
<method name="_on_process" qualifiers="virtual">
@@ -129,12 +145,14 @@
129145
<param index="0" name="session" type="int" />
130146
<description>
131147
Called right after the OpenXR session is created.
148+
[b]Note:[/b] This virtual method will be called on the main thread, however, it will be called [i]before[/i] OpenXR becomes involved in rendering, so it is safe to write to data that will be used by the render thread.
132149
</description>
133150
</method>
134151
<method name="_on_session_destroyed" qualifiers="virtual">
135152
<return type="void" />
136153
<description>
137154
Called right before the OpenXR session is destroyed.
155+
[b]Note:[/b] This virtual method will be called on the main thread, however, it will be called [i]after[/i] OpenXR is done being involved in rendering, so it is safe to write to data that was used by the render thread.
138156
</description>
139157
</method>
140158
<method name="_on_state_exiting" qualifiers="virtual">
@@ -206,6 +224,7 @@
206224
<description>
207225
Adds additional data structures to Android surface swapchains created by [OpenXRCompositionLayer].
208226
[param property_values] contains the values of the properties returned by [method _get_viewport_composition_layer_extension_properties].
227+
[b]Note:[/b] This virtual method will be called on the render thread.
209228
</description>
210229
</method>
211230
<method name="_set_frame_end_info_and_get_next_pointer" qualifiers="virtual">
@@ -214,6 +233,7 @@
214233
<description>
215234
Adds additional data structures to [code]XrFrameEndInfo[/code].
216235
This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_frame_info_extension].
236+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
217237
</description>
218238
</method>
219239
<method name="_set_frame_wait_info_and_get_next_pointer" qualifiers="virtual">
@@ -222,6 +242,7 @@
222242
<description>
223243
Adds additional data structures to [code]XrFrameWaitInfo[/code].
224244
This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_frame_info_extension].
245+
[b]Note:[/b] This virtual method will be called on the render thread.
225246
</description>
226247
</method>
227248
<method name="_set_hand_joint_locations_and_get_next_pointer" qualifiers="virtual">
@@ -245,6 +266,7 @@
245266
<param index="1" name="next_pointer" type="void*" />
246267
<description>
247268
Adds additional data structures to the projection view of the given [param view_index].
269+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
248270
</description>
249271
</method>
250272
<method name="_set_reference_space_create_info_and_get_next_pointer" qualifiers="virtual">
@@ -282,6 +304,7 @@
282304
<description>
283305
Adds additional data structures to [code]XrViewLocateInfo[/code].
284306
This will only be called if the extension previously registered itself with [method OpenXRAPIExtension.register_frame_info_extension].
307+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
285308
</description>
286309
</method>
287310
<method name="_set_viewport_composition_layer_and_get_next_pointer" qualifiers="virtual">
@@ -293,6 +316,7 @@
293316
Adds additional data structures to composition layers created by [OpenXRCompositionLayer].
294317
[param property_values] contains the values of the properties returned by [method _get_viewport_composition_layer_extension_properties].
295318
[param layer] is a pointer to an [code]XrCompositionLayerBaseHeader[/code] struct.
319+
[b]Note:[/b] This virtual method will be called on the render thread. Additionally, the data it returns will be used shortly after this method is called, so it needs to remain valid until the next time [method _on_pre_render] runs.
296320
</description>
297321
</method>
298322
<method name="get_openxr_api">
@@ -305,6 +329,7 @@
305329
<return type="void" />
306330
<description>
307331
Registers the extension. This should happen at core module initialization level.
332+
[b]Note:[/b] This cannot be called once OpenXR has been initialized.
308333
</description>
309334
</method>
310335
</methods>

0 commit comments

Comments
 (0)