• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Razakhel / RaZ / 11823370997

13 Nov 2024 06:19PM UTC coverage: 74.341% (+0.003%) from 74.338%
11823370997

push

github

Razakhel
[Script/LuaXr] Added Lua bindings for XR features

- Const'd XR rendering functions that could be

11 of 14 new or added lines in 6 files covered. (78.57%)

2 existing lines in 1 file now uncovered.

8069 of 10854 relevant lines covered (74.34%)

1813.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/RaZ/XR/XrSystem.cpp
1
#include "RaZ/Utils/Logger.hpp"
2
#include "RaZ/XR/XrSystem.hpp"
3

4
#include "openxr/openxr.h"
5

6
#include <array>
7

8
namespace Raz {
9

10
namespace {
11

12
const char* getResultStr(XrInstance instance, XrResult result) {
×
13
  static std::array<char, XR_MAX_RESULT_STRING_SIZE> errorStr {};
14
  xrResultToString(instance, result, errorStr.data());
×
15
  return errorStr.data();
×
16
}
17

18
std::string getErrorStr(const std::string& errorMsg, XrResult result, XrInstance instance) {
×
19
  return "[XrSystem] " + errorMsg + ": " + getResultStr(instance, result) + " (" + std::to_string(result) + ')';
×
20
}
21

22
void checkLog(XrResult result, const std::string& errorMsg, XrInstance instance) {
×
23
  if (XR_SUCCEEDED(result))
×
24
    return;
×
25

26
  Logger::error(getErrorStr(errorMsg, result, instance));
×
27
}
28

29
bool pollNextEvent(XrInstance instance, XrEventDataBuffer& eventData) {
×
30
  eventData      = {};
×
31
  eventData.type = XR_TYPE_EVENT_DATA_BUFFER;
×
32

33
  return (xrPollEvent(instance, &eventData) == XR_SUCCESS);
×
34
}
35

36
void processEventData(const XrEventDataEventsLost& eventsLost) {
×
37
  Logger::info("[XrSystem] " + std::to_string(eventsLost.lostEventCount) + " events lost");
×
38
}
×
39

40
void processEventData(const XrEventDataInstanceLossPending& instanceLossPending) {
×
41
  // After the period of time specified by lossTime, the application can try recreating an instance again
42
  // See: https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrEventDataInstanceLossPending.html#_description
43
  Logger::info("[XrSystem] Instance loss pending at: " + std::to_string(instanceLossPending.lossTime));
×
44
}
×
45

46
void processEventData(const XrEventDataInteractionProfileChanged& interactionProfileChanged, ::XrSession session) {
×
47
  Logger::info("[XrSystem] Interaction profile changed for "
×
48
             + std::string(interactionProfileChanged.session != session ? "unknown" : "current")
×
49
             + " session");
×
50
}
×
51

52
void processEventData(const XrEventDataReferenceSpaceChangePending& referenceSpaceChangePending, ::XrSession session) {
×
53
  Logger::info("[XrSystem] Reference space changed pending for "
×
54
             + std::string(referenceSpaceChangePending.session != session ? "unknown" : "current")
×
55
             + " session");
×
56
}
×
57

58
} // namespace
59

60
XrSystem::XrSystem(const std::string& appName) : m_context(appName), m_session(m_context) {
×
61
  recoverViewConfigurations();
×
62

63
  m_optimalViewWidth  = m_viewConfigViews.front().recommendedImageRectWidth;
×
64
  m_optimalViewHeight = m_viewConfigViews.front().recommendedImageRectHeight;
×
65

66
  if (m_viewConfigViews.size() > 1) {
×
67
    for (const XrViewConfigurationView& viewConfigView : m_viewConfigViews) {
×
68
      if (viewConfigView.recommendedImageRectWidth != m_optimalViewWidth || viewConfigView.recommendedImageRectHeight != m_optimalViewHeight)
×
69
        Logger::warn("[XrSystem] The optimal configuration view size is not the same for all views; rendering may be altered");
×
70
    }
71
  }
72

73
  recoverEnvironmentBlendModes();
×
74
}
×
75

76
bool XrSystem::update(const FrameTimeInfo&) {
×
77
  XrEventDataBuffer eventData {};
×
78

79
  while (pollNextEvent(m_context.m_instance, eventData)) {
×
80
    switch (eventData.type) {
×
81
      case XR_TYPE_EVENT_DATA_EVENTS_LOST:
×
82
        processEventData(*reinterpret_cast<XrEventDataEventsLost*>(&eventData));
×
83
        break;
×
84

85
      case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
×
86
        processEventData(*reinterpret_cast<XrEventDataInstanceLossPending*>(&eventData));
×
87
        m_session.m_isRunning = false;
×
88
        return false;
×
89

90
      case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
×
91
        processEventData(*reinterpret_cast<XrEventDataInteractionProfileChanged*>(&eventData), m_session.m_handle);
×
92
        break;
×
93

94
      case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING:
×
95
        processEventData(*reinterpret_cast<XrEventDataReferenceSpaceChangePending*>(&eventData), m_session.m_handle);
×
96
        break;
×
97

98
      case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
×
99
        processSessionStateChanged(*reinterpret_cast<XrEventDataSessionStateChanged*>(&eventData));
×
100
        break;
×
101

102
      default:
×
103
        break;
×
104
    }
105
  }
106

107
  return true;
×
108
}
109

110
XrSystem::~XrSystem() = default;
×
111

112
void XrSystem::recoverViewConfigurations() {
×
113
  uint32_t viewConfigCount {};
×
114
  checkLog(xrEnumerateViewConfigurations(m_context.m_instance, m_context.m_systemId, 0, &viewConfigCount, nullptr),
×
115
           "Failed to get view configuration count",
116
           m_context.m_instance);
117
  m_viewConfigTypes.resize(viewConfigCount);
×
118
  checkLog(xrEnumerateViewConfigurations(m_context.m_instance, m_context.m_systemId, viewConfigCount, &viewConfigCount,
×
119
                                         reinterpret_cast<XrViewConfigurationType*>(m_viewConfigTypes.data())),
×
120
           "Failed to enumerate view configurations",
121
           m_context.m_instance);
122

123
  for (const XrViewConfigurationType viewConfigType : { XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO }) {
×
124
    if (std::find(m_viewConfigTypes.cbegin(), m_viewConfigTypes.cend(), viewConfigType) == m_viewConfigTypes.cend())
×
125
      continue;
×
126

127
    m_viewConfigType = viewConfigType;
×
128
    break;
×
129
  }
130

131
  if (m_viewConfigType == 0) {
×
132
    Logger::warn("[XrSystem] Failed to find a view configuration type; defaulting to XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO");
×
133
    m_viewConfigType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
×
134
  }
135

136
  uint32_t viewConfigViewCount {};
×
137
  checkLog(xrEnumerateViewConfigurationViews(m_context.m_instance, m_context.m_systemId, static_cast<XrViewConfigurationType>(m_viewConfigType),
×
138
                                             0, &viewConfigViewCount, nullptr),
139
           "Failed to get view configuration view count",
140
           m_context.m_instance);
141
  m_viewConfigViews.resize(viewConfigViewCount, { XR_TYPE_VIEW_CONFIGURATION_VIEW });
×
142
  checkLog(xrEnumerateViewConfigurationViews(m_context.m_instance, m_context.m_systemId, static_cast<XrViewConfigurationType>(m_viewConfigType),
×
143
                                             viewConfigViewCount, &viewConfigViewCount,
144
                                             m_viewConfigViews.data()),
145
           "Failed to enumerate view configuration views",
146
           m_context.m_instance);
147

148
#if !defined(NDEBUG) || defined(RAZ_FORCE_DEBUG_LOG)
149
  {
150
    std::string viewConfigViewsMsg = "[XrSystem] View configuration views:";
×
151
    for (const XrViewConfigurationView& viewConfigView : m_viewConfigViews) {
×
152
      viewConfigViewsMsg += "\n    View:"
153
                            "\n        Recom. image rect width:       " + std::to_string(viewConfigView.recommendedImageRectWidth)
×
154
                          + "\n        Max. image rect width:         " + std::to_string(viewConfigView.maxImageRectWidth)
×
155
                          + "\n        Recom. image rect height:      " + std::to_string(viewConfigView.recommendedImageRectHeight)
×
156
                          + "\n        Max. image rect height:        " + std::to_string(viewConfigView.maxImageRectHeight)
×
157
                          + "\n        Recom. swapchain sample count: " + std::to_string(viewConfigView.recommendedSwapchainSampleCount)
×
158
                          + "\n        Max. swapchain sample count:   " + std::to_string(viewConfigView.maxSwapchainSampleCount);
×
159
    }
160
    Logger::debug(viewConfigViewsMsg);
×
161
  }
×
162
#endif
163
}
×
164

165
void XrSystem::recoverEnvironmentBlendModes() {
×
166
  uint32_t environmentBlendModeCount {};
×
167
  checkLog(xrEnumerateEnvironmentBlendModes(m_context.m_instance, m_context.m_systemId, static_cast<XrViewConfigurationType>(m_viewConfigType),
×
168
                                            0, &environmentBlendModeCount, nullptr),
169
           "Failed to get environment blend mode count",
170
           m_context.m_instance);
171
  m_environmentBlendModes.resize(environmentBlendModeCount);
×
172
  checkLog(xrEnumerateEnvironmentBlendModes(m_context.m_instance, m_context.m_systemId, static_cast<XrViewConfigurationType>(m_viewConfigType),
×
173
                                            environmentBlendModeCount, &environmentBlendModeCount,
174
                                            reinterpret_cast<XrEnvironmentBlendMode*>(m_environmentBlendModes.data())),
×
175
           "Failed to enumerate environment blend modes",
176
           m_context.m_instance);
177

178
  for (const XrEnvironmentBlendMode environmentBlendMode : { XR_ENVIRONMENT_BLEND_MODE_OPAQUE, XR_ENVIRONMENT_BLEND_MODE_ADDITIVE }) {
×
179
    if (std::find(m_environmentBlendModes.cbegin(), m_environmentBlendModes.cend(), environmentBlendMode) == m_environmentBlendModes.cend())
×
180
      continue;
×
181

182
    m_environmentBlendMode = environmentBlendMode;
×
183
    break;
×
184
  }
185

186
  if (m_environmentBlendMode == 0) {
×
187
    Logger::warn("Failed to find a compatible blend mode; defaulting to XR_ENVIRONMENT_BLEND_MODE_OPAQUE");
×
188
    m_environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
×
189
  }
190
}
×
191

192
void XrSystem::initializeSession() {
×
193
  m_session.initialize(m_context.m_systemId);
×
194
  m_session.createSwapchains(m_viewConfigViews);
×
195
}
×
196

NEW
197
bool XrSystem::renderFrame(const ViewRenderFunc& viewRenderFunc) const {
×
198
  return m_session.renderFrame(m_viewConfigViews, m_viewConfigType, m_environmentBlendMode, viewRenderFunc);
×
199
}
200

201
bool XrSystem::processSessionStateChanged(const XrEventDataSessionStateChanged& sessionStateChanged) {
×
202
  if (sessionStateChanged.session != m_session.m_handle) {
×
203
    Logger::info("[XrSystem] Data session state changed for unknown session");
×
204
    return true;
×
205
  }
206

207
  switch (sessionStateChanged.state) {
×
208
    case XR_SESSION_STATE_READY:
×
209
      m_session.begin(m_viewConfigType);
×
210
      m_session.m_isRunning = true;
×
211
      break;
×
212

213
    case XR_SESSION_STATE_STOPPING:
×
214
      m_session.end();
×
215
      m_session.m_isRunning = false;
×
216
      break;
×
217

218
    case XR_SESSION_STATE_LOSS_PENDING:
×
219
      // TODO: "It's possible to try to reestablish an XrInstance and XrSession"
220
      m_session.m_isRunning = false;
×
221
      return false;
×
222

223
    case XR_SESSION_STATE_EXITING:
×
224
      m_session.m_isRunning = false;
×
225
      return false;
×
226

227
    default:
×
228
      break;
×
229
  }
230

231
  m_session.m_state = sessionStateChanged.state;
×
232

233
  return true;
×
234
}
235

236
} // namespace Raz
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc