Skip to content

Commit 788745e

Browse files
committed
Merge pull request godotengine#108644 from bnjmntmm/secure-android-surface
Use of `XrSwapchainCreateFlags` for `OpenXRCompositionLayer`
2 parents 12aa435 + ecfb962 commit 788745e

File tree

5 files changed

+37
-2
lines changed

5 files changed

+37
-2
lines changed

modules/openxr/doc_classes/OpenXRCompositionLayer.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
<member name="layer_viewport" type="SubViewport" setter="set_layer_viewport" getter="get_layer_viewport">
5050
The [SubViewport] to render on the composition layer.
5151
</member>
52+
<member name="protected_content" type="bool" setter="set_protected_content" getter="is_protected_content" default="false">
53+
If enabled, the OpenXR swapchain will be created with the [code]XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT[/code] flag, which will protect its contents from CPU access.
54+
When used with an Android Surface, this may allow DRM content to be presented, and will only take effect when the Surface is first created; later changes to this property will have no effect.
55+
</member>
5256
<member name="sort_order" type="int" setter="set_sort_order" getter="get_sort_order" default="1">
5357
The sort order for this composition layer. Higher numbers will be shown in front of lower numbers.
5458
[b]Note:[/b] This will have no effect if a fallback mesh is being used.

modules/openxr/extensions/openxr_composition_layer_extension.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,19 @@ void OpenXRViewportCompositionLayerProvider::create_android_surface() {
269269
}
270270
}
271271

272+
// Check to see if content should be protected.
273+
XrSwapchainCreateFlags create_flags = 0;
274+
275+
if (protected_content) {
276+
create_flags = XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT;
277+
}
278+
272279
// The XR_FB_android_surface_swapchain_create extension mandates that format, sampleCount,
273280
// faceCount, arraySize, and mipCount must be zero.
274281
XrSwapchainCreateInfo info = {
275282
XR_TYPE_SWAPCHAIN_CREATE_INFO, // type
276283
next_pointer, // next
277-
0, // createFlags
284+
create_flags, // createFlags
278285
XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, // usageFlags
279286
0, // format
280287
0, // sampleCount
@@ -471,7 +478,7 @@ bool OpenXRViewportCompositionLayerProvider::update_and_acquire_swapchain(bool p
471478
// See if our current swapchain is outdated.
472479
if (subviewport.swapchain_info.get_swapchain() != XR_NULL_HANDLE) {
473480
// If this swap chain, or the previous one, were static, then we can't reuse it.
474-
if (swapchain_size == subviewport.viewport_size && !p_static_image && !subviewport.static_image) {
481+
if (swapchain_size == subviewport.viewport_size && !p_static_image && !subviewport.static_image && protected_content == subviewport.swapchain_protected_content) {
475482
// We're all good! Just acquire it.
476483
// We can ignore should_render here, return will be false.
477484
bool should_render = true;
@@ -489,6 +496,9 @@ bool OpenXRViewportCompositionLayerProvider::update_and_acquire_swapchain(bool p
489496
if (p_static_image) {
490497
create_flags |= XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT;
491498
}
499+
if (protected_content) {
500+
create_flags |= XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT;
501+
}
492502
if (!subviewport.swapchain_info.create(create_flags, XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, swapchain_format, subviewport.viewport_size.width, subviewport.viewport_size.height, sample_count, array_size)) {
493503
swapchain_size = Size2i();
494504
return false;
@@ -503,6 +513,7 @@ bool OpenXRViewportCompositionLayerProvider::update_and_acquire_swapchain(bool p
503513

504514
swapchain_size = subviewport.viewport_size;
505515
subviewport.static_image = p_static_image;
516+
subviewport.swapchain_protected_content = protected_content;
506517
return ret;
507518
}
508519

modules/openxr/extensions/openxr_composition_layer_extension.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class OpenXRViewportCompositionLayerProvider {
161161
Size2i viewport_size;
162162
OpenXRAPI::OpenXRSwapChainInfo swapchain_info;
163163
bool static_image = false;
164+
bool swapchain_protected_content = false;
164165
} subviewport;
165166

166167
#ifdef ANDROID_ENABLED
@@ -171,6 +172,7 @@ class OpenXRViewportCompositionLayerProvider {
171172
#endif
172173

173174
bool use_android_surface = false;
175+
bool protected_content = false;
174176
Size2i swapchain_size;
175177

176178
OpenXRAPI *openxr_api = nullptr;
@@ -204,6 +206,9 @@ class OpenXRViewportCompositionLayerProvider {
204206
void set_use_android_surface(bool p_enable, Size2i p_size);
205207
bool get_use_android_surface() const { return use_android_surface; }
206208

209+
void set_protected_content(bool p_protected_content) { protected_content = p_protected_content; }
210+
bool is_protected_content() const { return protected_content; }
211+
207212
Ref<JavaObject> get_android_surface();
208213

209214
void set_extension_property_values(const Dictionary &p_property_values);

modules/openxr/scene/openxr_composition_layer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ void OpenXRCompositionLayer::_bind_methods() {
113113
ClassDB::bind_method(D_METHOD("get_android_surface"), &OpenXRCompositionLayer::get_android_surface);
114114
ClassDB::bind_method(D_METHOD("is_natively_supported"), &OpenXRCompositionLayer::is_natively_supported);
115115

116+
ClassDB::bind_method(D_METHOD("is_protected_content"), &OpenXRCompositionLayer::is_protected_content);
117+
ClassDB::bind_method(D_METHOD("set_protected_content", "protected_content"), &OpenXRCompositionLayer::set_protected_content);
118+
116119
ClassDB::bind_method(D_METHOD("set_min_filter", "mode"), &OpenXRCompositionLayer::set_min_filter);
117120
ClassDB::bind_method(D_METHOD("get_min_filter"), &OpenXRCompositionLayer::get_min_filter);
118121

@@ -150,6 +153,7 @@ void OpenXRCompositionLayer::_bind_methods() {
150153

151154
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "layer_viewport", PROPERTY_HINT_NODE_TYPE, "SubViewport"), "set_layer_viewport", "get_layer_viewport");
152155
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_android_surface", PROPERTY_HINT_NONE, ""), "set_use_android_surface", "get_use_android_surface");
156+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "protected_content", PROPERTY_HINT_NONE, ""), "set_protected_content", "is_protected_content");
153157
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "android_surface_size", PROPERTY_HINT_NONE, ""), "set_android_surface_size", "get_android_surface_size");
154158
ADD_PROPERTY(PropertyInfo(Variant::INT, "sort_order", PROPERTY_HINT_NONE, ""), "set_sort_order", "get_sort_order");
155159
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alpha_blend", PROPERTY_HINT_NONE, ""), "set_alpha_blend", "get_alpha_blend");
@@ -419,6 +423,14 @@ bool OpenXRCompositionLayer::is_natively_supported() const {
419423
return false;
420424
}
421425

426+
void OpenXRCompositionLayer::set_protected_content(bool p_protected_content) {
427+
openxr_layer_provider->set_protected_content(p_protected_content);
428+
}
429+
430+
bool OpenXRCompositionLayer::is_protected_content() const {
431+
return openxr_layer_provider->is_protected_content();
432+
}
433+
422434
void OpenXRCompositionLayer::set_min_filter(Filter p_mode) {
423435
if (swapchain_state->min_filter == (OpenXRViewportCompositionLayerProvider::Filter)p_mode) {
424436
return;

modules/openxr/scene/openxr_composition_layer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ class OpenXRCompositionLayer : public Node3D {
155155
Ref<JavaObject> get_android_surface();
156156
bool is_natively_supported() const;
157157

158+
void set_protected_content(bool p_protected_content);
159+
bool is_protected_content() const;
160+
158161
void set_min_filter(Filter p_mode);
159162
Filter get_min_filter() const;
160163

0 commit comments

Comments
 (0)