Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/openxr/src/common/object_info.cpp
9903 views
1
// Copyright (c) 2017-2025 The Khronos Group Inc.
2
// Copyright (c) 2017-2019 Valve Corporation
3
// Copyright (c) 2017-2019 LunarG, Inc.
4
// Copyright (c) 2019 Collabora, Ltd.
5
//
6
// SPDX-License-Identifier: Apache-2.0 OR MIT
7
//
8
// Initial Authors: Mark Young <[email protected]>
9
// Rylie Pavlik <[email protected]>
10
// Dave Houlton <[email protected]>
11
//
12
13
#include "object_info.h"
14
15
#include "extra_algorithms.h"
16
#include "hex_and_handles.h"
17
18
#include <openxr/openxr.h>
19
20
#include <algorithm>
21
#include <iterator>
22
#include <memory>
23
#include <sstream>
24
#include <string>
25
#include <vector>
26
27
#include "memory.h"
28
29
std::string XrSdkLogObjectInfo::ToString() const {
30
std::ostringstream oss;
31
oss << Uint64ToHexString(handle);
32
if (!name.empty()) {
33
oss << " (" << name << ")";
34
}
35
return oss.str();
36
}
37
38
void ObjectInfoCollection::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {
39
// If name is empty, we should erase it
40
if (object_name.empty()) {
41
RemoveObject(object_handle, object_type);
42
return;
43
}
44
45
// Otherwise, add it or update the name
46
XrSdkLogObjectInfo new_obj = {object_handle, object_type};
47
48
// If it already exists, update the name
49
auto lookup_info = LookUpStoredObjectInfo(new_obj);
50
if (lookup_info != nullptr) {
51
lookup_info->name = object_name;
52
return;
53
}
54
55
// It doesn't exist, so add a new info block
56
new_obj.name = object_name;
57
object_info_.push_back(new_obj);
58
}
59
60
void ObjectInfoCollection::RemoveObject(uint64_t object_handle, XrObjectType object_type) {
61
vector_remove_if_and_erase(
62
object_info_, [=](XrSdkLogObjectInfo const& info) { return info.handle == object_handle && info.type == object_type; });
63
}
64
65
XrSdkLogObjectInfo const* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const {
66
auto e = object_info_.end();
67
auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); });
68
if (it != e) {
69
return &(*it);
70
}
71
return nullptr;
72
}
73
74
XrSdkLogObjectInfo* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) {
75
auto e = object_info_.end();
76
auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); });
77
if (it != e) {
78
return &(*it);
79
}
80
return nullptr;
81
}
82
83
bool ObjectInfoCollection::LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const {
84
auto info_lookup = LookUpStoredObjectInfo(info.objectHandle, info.objectType);
85
if (info_lookup != nullptr) {
86
info.objectName = info_lookup->name.c_str();
87
return true;
88
}
89
return false;
90
}
91
92
bool ObjectInfoCollection::LookUpObjectName(XrSdkLogObjectInfo& info) const {
93
auto info_lookup = LookUpStoredObjectInfo(info);
94
if (info_lookup != nullptr) {
95
info.name = info_lookup->name;
96
return true;
97
}
98
return false;
99
}
100
101
static std::vector<XrDebugUtilsObjectNameInfoEXT> PopulateObjectNameInfo(std::vector<XrSdkLogObjectInfo> const& obj) {
102
std::vector<XrDebugUtilsObjectNameInfoEXT> ret;
103
ret.reserve(obj.size());
104
std::transform(obj.begin(), obj.end(), std::back_inserter(ret), [](XrSdkLogObjectInfo const& info) {
105
return XrDebugUtilsObjectNameInfoEXT{XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, info.type, info.handle,
106
info.name.c_str()};
107
});
108
return ret;
109
}
110
111
NamesAndLabels::NamesAndLabels(std::vector<XrSdkLogObjectInfo> obj, std::vector<XrDebugUtilsLabelEXT> lab)
112
: sdk_objects(std::move(obj)), objects(PopulateObjectNameInfo(sdk_objects)), labels(std::move(lab)) {}
113
114
void NamesAndLabels::PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& callback_data) const {
115
callback_data.objects = objects.empty() ? nullptr : const_cast<XrDebugUtilsObjectNameInfoEXT*>(objects.data());
116
callback_data.objectCount = static_cast<uint32_t>(objects.size());
117
callback_data.sessionLabels = labels.empty() ? nullptr : const_cast<XrDebugUtilsLabelEXT*>(labels.data());
118
callback_data.sessionLabelCount = static_cast<uint32_t>(labels.size());
119
}
120
121
void DebugUtilsData::LookUpSessionLabels(XrSession session, std::vector<XrDebugUtilsLabelEXT>& labels) const {
122
auto session_label_iterator = session_labels_.find(session);
123
if (session_label_iterator != session_labels_.end()) {
124
auto& XrSdkSessionLabels = *session_label_iterator->second;
125
// Copy the debug utils labels in reverse order in the the labels vector.
126
std::transform(XrSdkSessionLabels.rbegin(), XrSdkSessionLabels.rend(), std::back_inserter(labels),
127
[](XrSdkSessionLabelPtr const& label) { return label->debug_utils_label; });
128
}
129
}
130
131
XrSdkSessionLabel::XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual)
132
: label_name(label_info.labelName), debug_utils_label(label_info), is_individual_label(individual) {
133
// Update the c string pointer to the one we hold.
134
debug_utils_label.labelName = label_name.c_str();
135
// Zero out the next pointer to avoid a dangling pointer
136
debug_utils_label.next = nullptr;
137
}
138
139
XrSdkSessionLabelPtr XrSdkSessionLabel::make(const XrDebugUtilsLabelEXT& label_info, bool individual) {
140
XrSdkSessionLabelPtr ret(new XrSdkSessionLabel(label_info, individual));
141
return ret;
142
}
143
void DebugUtilsData::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {
144
object_info_.AddObjectName(object_handle, object_type, object_name);
145
}
146
147
// We always want to remove the old individual label before we do anything else.
148
// So, do that in its own method
149
void DebugUtilsData::RemoveIndividualLabel(XrSdkSessionLabelList& label_vec) {
150
if (!label_vec.empty() && label_vec.back()->is_individual_label) {
151
label_vec.pop_back();
152
}
153
}
154
155
XrSdkSessionLabelList* DebugUtilsData::GetSessionLabelList(XrSession session) {
156
auto session_label_iterator = session_labels_.find(session);
157
if (session_label_iterator == session_labels_.end()) {
158
return nullptr;
159
}
160
return session_label_iterator->second.get();
161
}
162
163
XrSdkSessionLabelList& DebugUtilsData::GetOrCreateSessionLabelList(XrSession session) {
164
XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
165
if (vec_ptr == nullptr) {
166
std::unique_ptr<XrSdkSessionLabelList> vec(new XrSdkSessionLabelList);
167
vec_ptr = vec.get();
168
session_labels_[session] = std::move(vec);
169
}
170
return *vec_ptr;
171
}
172
173
void DebugUtilsData::BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info) {
174
auto& vec = GetOrCreateSessionLabelList(session);
175
176
// Individual labels do not stay around in the transition into a new label region
177
RemoveIndividualLabel(vec);
178
179
// Start the new label region
180
vec.emplace_back(XrSdkSessionLabel::make(label_info, false));
181
}
182
183
void DebugUtilsData::EndLabelRegion(XrSession session) {
184
XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
185
if (vec_ptr == nullptr) {
186
return;
187
}
188
189
// Individual labels do not stay around in the transition out of label region
190
RemoveIndividualLabel(*vec_ptr);
191
192
// Remove the last label region
193
if (!vec_ptr->empty()) {
194
vec_ptr->pop_back();
195
}
196
}
197
198
void DebugUtilsData::InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info) {
199
auto& vec = GetOrCreateSessionLabelList(session);
200
201
// Remove any individual layer that might already be there
202
RemoveIndividualLabel(vec);
203
204
// Insert a new individual label
205
vec.emplace_back(XrSdkSessionLabel::make(label_info, true));
206
}
207
208
void DebugUtilsData::DeleteObject(uint64_t object_handle, XrObjectType object_type) {
209
object_info_.RemoveObject(object_handle, object_type);
210
211
if (object_type == XR_OBJECT_TYPE_SESSION) {
212
auto session = TreatIntegerAsHandle<XrSession>(object_handle);
213
XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
214
if (vec_ptr != nullptr) {
215
session_labels_.erase(session);
216
}
217
}
218
}
219
220
void DebugUtilsData::DeleteSessionLabels(XrSession session) { session_labels_.erase(session); }
221
222
NamesAndLabels DebugUtilsData::PopulateNamesAndLabels(std::vector<XrSdkLogObjectInfo> objects) const {
223
std::vector<XrDebugUtilsLabelEXT> labels;
224
for (auto& obj : objects) {
225
// Check for any names that have been associated with the objects and set them up here
226
object_info_.LookUpObjectName(obj);
227
// If this is a session, see if there are any labels associated with it for us to add
228
// to the callback content.
229
if (XR_OBJECT_TYPE_SESSION == obj.type) {
230
LookUpSessionLabels(obj.GetTypedHandle<XrSession>(), labels);
231
}
232
}
233
234
return {objects, labels};
235
}
236
237
void DebugUtilsData::WrapCallbackData(AugmentedCallbackData* aug_data,
238
const XrDebugUtilsMessengerCallbackDataEXT* callback_data) const {
239
// If there's nothing to add, just return the original data as the augmented copy
240
aug_data->exported_data = callback_data;
241
if (object_info_.Empty() || callback_data->objectCount == 0) {
242
return;
243
}
244
245
// Inspect each of the callback objects
246
bool name_found = false;
247
for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
248
auto& current_obj = callback_data->objects[obj];
249
name_found |= (nullptr != object_info_.LookUpStoredObjectInfo(current_obj.objectHandle, current_obj.objectType));
250
251
// If this is a session, record any labels associated with it
252
if (XR_OBJECT_TYPE_SESSION == current_obj.objectType) {
253
XrSession session = TreatIntegerAsHandle<XrSession>(current_obj.objectHandle);
254
LookUpSessionLabels(session, aug_data->labels);
255
}
256
}
257
258
// If we found nothing to add, return the original data
259
if (!name_found && aug_data->labels.empty()) {
260
return;
261
}
262
263
// Found additional data - modify an internal copy and return that as the exported data
264
memcpy(&aug_data->modified_data, callback_data, sizeof(XrDebugUtilsMessengerCallbackDataEXT));
265
aug_data->new_objects.assign(callback_data->objects, callback_data->objects + callback_data->objectCount);
266
267
// Record (overwrite) the names of all incoming objects provided in our internal list
268
for (auto& obj : aug_data->new_objects) {
269
object_info_.LookUpObjectName(obj);
270
}
271
272
// Update local copy & point export to it
273
aug_data->modified_data.objects = aug_data->new_objects.data();
274
aug_data->modified_data.sessionLabelCount = static_cast<uint32_t>(aug_data->labels.size());
275
aug_data->modified_data.sessionLabels = aug_data->labels.empty() ? nullptr : aug_data->labels.data();
276
aug_data->exported_data = &aug_data->modified_data;
277
return;
278
}
279
280