Cleanup: C++ code style for Ghost-XR

* Avoid deep copy of vectors (technically more than a cleanup).
* Use `std::make_unique` for allocating unique pointers, rather than
  manual `new`.
* Use `std::optional` for optional by-value return values, rather than
  C-style `bool` to indicate success + return-argument.
* Use references rather than pointers for non-optional arguments.
* Avoid manual `new`/`delete`. Use `std::unique_ptr` for local scope
  bound lifetime.
* Use C++ `nullptr` rather than C's `NULL`.
* Remove unnecessary friend declaration.

These changes are generally considered good practise and move us more to
a "modern C++" style. We can still go much further of course.
See https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.
This commit is contained in:
Julian Eisel 2020-08-14 12:37:53 +02:00
parent 1ff1b7fcea
commit 2d65336408
9 changed files with 121 additions and 130 deletions

View File

@ -21,15 +21,13 @@
#pragma once
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "GHOST_Xr_openxr_includes.h"
class GHOST_IXrGraphicsBinding {
friend std::unique_ptr<GHOST_IXrGraphicsBinding> GHOST_XrGraphicsBindingCreateFromType(
GHOST_TXrGraphicsBinding type);
public:
union {
#if defined(WITH_GHOST_X11)
@ -49,18 +47,17 @@ class GHOST_IXrGraphicsBinding {
* \param r_requirement_info Return argument to retrieve an informal string on the requirements
* to be met. Useful for error/debug messages.
*/
virtual bool checkVersionRequirements(class GHOST_Context *ghost_ctx,
virtual bool checkVersionRequirements(class GHOST_Context &ghost_ctx,
XrInstance instance,
XrSystemId system_id,
std::string *r_requirement_info) const = 0;
virtual void initFromGhostContext(class GHOST_Context *ghost_ctx) = 0;
virtual bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
int64_t &r_result,
bool &r_is_rgb_format) const = 0;
virtual void initFromGhostContext(class GHOST_Context &ghost_ctx) = 0;
virtual std::optional<int64_t> chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
bool &r_is_rgb_format) const = 0;
virtual std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(
uint32_t image_count) = 0;
virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader *swapchain_image,
const GHOST_XrDrawViewInfo *draw_info) = 0;
virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image,
const GHOST_XrDrawViewInfo &draw_info) = 0;
virtual bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const = 0;
protected:
@ -69,4 +66,4 @@ class GHOST_IXrGraphicsBinding {
};
std::unique_ptr<GHOST_IXrGraphicsBinding> GHOST_XrGraphicsBindingCreateFromType(
GHOST_TXrGraphicsBinding type, GHOST_Context *ghost_ctx);
GHOST_TXrGraphicsBinding type, GHOST_Context &ghost_ctx);

View File

@ -31,7 +31,7 @@
GHOST_XrContextHandle GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info)
{
GHOST_XrContext *xr_context = new GHOST_XrContext(create_info);
auto xr_context = std::make_unique<GHOST_XrContext>(create_info);
/* TODO GHOST_XrContext's should probably be owned by the GHOST_System, which will handle context
* creation and destruction. Try-catch logic can be moved to C-API then. */
@ -40,12 +40,11 @@ GHOST_XrContextHandle GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *cre
}
catch (GHOST_XrException &e) {
xr_context->dispatchErrorMessage(&e);
delete xr_context;
return nullptr;
}
return (GHOST_XrContextHandle)xr_context;
/* Give ownership to the caller. */
return (GHOST_XrContextHandle)xr_context.release();
}
void GHOST_XrContextDestroy(GHOST_XrContextHandle xr_contexthandle)

View File

@ -58,7 +58,7 @@ void *GHOST_XrContext::s_error_handler_customdata = nullptr;
* \{ */
GHOST_XrContext::GHOST_XrContext(const GHOST_XrContextCreateInfo *create_info)
: m_oxr(new OpenXRInstanceData()),
: m_oxr(std::make_unique<OpenXRInstanceData>()),
m_debug(create_info->context_flag & GHOST_kXrContextDebug),
m_debug_time(create_info->context_flag & GHOST_kXrContextDebugTime)
{
@ -327,7 +327,7 @@ void GHOST_XrContext::initApiLayers()
}
}
static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> layers_info,
static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> &layers_info,
const std::string &layer_name)
{
for (const XrApiLayerProperties &layer_info : layers_info) {
@ -339,8 +339,8 @@ static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> la
return false;
}
static bool openxr_extension_is_available(const std::vector<XrExtensionProperties> extensions_info,
const std::string &extension_name)
static bool openxr_extension_is_available(
const std::vector<XrExtensionProperties> &extensions_info, const std::string &extension_name)
{
for (const XrExtensionProperties &ext_info : extensions_info) {
if (ext_info.extensionName == extension_name) {
@ -459,7 +459,7 @@ void GHOST_XrContext::startSession(const GHOST_XrSessionBeginInfo *begin_info)
m_custom_funcs.session_exit_customdata = begin_info->exit_customdata;
if (m_session == nullptr) {
m_session = std::unique_ptr<GHOST_XrSession>(new GHOST_XrSession(this));
m_session = std::make_unique<GHOST_XrSession>(*this);
}
m_session->start(begin_info);
}
@ -489,7 +489,7 @@ void GHOST_XrContext::drawSessionViews(void *draw_customdata)
/**
* Delegates event to session, allowing context to destruct the session if needed.
*/
void GHOST_XrContext::handleSessionStateChange(const XrEventDataSessionStateChanged *lifecycle)
void GHOST_XrContext::handleSessionStateChange(const XrEventDataSessionStateChanged &lifecycle)
{
if (m_session &&
m_session->handleStateChangeEvent(lifecycle) == GHOST_XrSession::SESSION_DESTROY) {

View File

@ -80,7 +80,7 @@ class GHOST_XrContext : public GHOST_IXrContext {
void setDrawViewFunc(GHOST_XrDrawViewFn draw_view_fn) override;
bool needsUpsideDownDrawing() const override;
void handleSessionStateChange(const XrEventDataSessionStateChanged *lifecycle);
void handleSessionStateChange(const XrEventDataSessionStateChanged &lifecycle);
GHOST_TXrOpenXRRuntimeID getOpenXRRuntimeID() const;
const GHOST_XrCustomFuncs &getCustomFuncs() const;

View File

@ -35,25 +35,25 @@ static bool GHOST_XrEventPollNext(XrInstance instance, XrEventDataBuffer &r_even
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_contexthandle)
{
GHOST_XrContext *xr_context = (GHOST_XrContext *)xr_contexthandle;
XrEventDataBuffer event_buffer; /* Structure big enough to hold all possible events. */
if (xr_context == NULL) {
if (xr_contexthandle == nullptr) {
return GHOST_kFailure;
}
while (GHOST_XrEventPollNext(xr_context->getInstance(), event_buffer)) {
GHOST_XrContext &xr_context = *(GHOST_XrContext *)xr_contexthandle;
XrEventDataBuffer event_buffer; /* Structure big enough to hold all possible events. */
while (GHOST_XrEventPollNext(xr_context.getInstance(), event_buffer)) {
XrEventDataBaseHeader *event = (XrEventDataBaseHeader *)&event_buffer;
switch (event->type) {
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED:
xr_context->handleSessionStateChange((XrEventDataSessionStateChanged *)event);
xr_context.handleSessionStateChange((XrEventDataSessionStateChanged &)*event);
return GHOST_kSuccess;
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
GHOST_XrContextDestroy(xr_contexthandle);
return GHOST_kSuccess;
default:
if (xr_context->isDebugMode()) {
if (xr_context.isDebugMode()) {
printf("Unhandled event: %i\n", event->type);
}
return GHOST_kFailure;

View File

@ -34,12 +34,11 @@
#include "GHOST_IXrGraphicsBinding.h"
static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_binding_formats,
std::vector<int64_t> runtime_formats,
int64_t &r_result)
static std::optional<int64_t> choose_swapchain_format_from_candidates(
const std::vector<int64_t> &gpu_binding_formats, const std::vector<int64_t> &runtime_formats)
{
if (gpu_binding_formats.empty()) {
return false;
return std::nullopt;
}
auto res = std::find_first_of(gpu_binding_formats.begin(),
@ -47,11 +46,10 @@ static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_bin
runtime_formats.begin(),
runtime_formats.end());
if (res == gpu_binding_formats.end()) {
return false;
return std::nullopt;
}
r_result = *res;
return true;
return *res;
}
class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
@ -63,21 +61,21 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
}
}
bool checkVersionRequirements(GHOST_Context *ghost_ctx,
bool checkVersionRequirements(GHOST_Context &ghost_ctx,
XrInstance instance,
XrSystemId system_id,
std::string *r_requirement_info) const override
{
#if defined(WITH_GHOST_X11)
GHOST_ContextGLX *ctx_gl = static_cast<GHOST_ContextGLX *>(ghost_ctx);
GHOST_ContextGLX &ctx_gl = static_cast<GHOST_ContextGLX &>(ghost_ctx);
#else
GHOST_ContextWGL *ctx_gl = static_cast<GHOST_ContextWGL *>(ghost_ctx);
GHOST_ContextWGL &ctx_gl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
#endif
static PFN_xrGetOpenGLGraphicsRequirementsKHR s_xrGetOpenGLGraphicsRequirementsKHR_fn =
nullptr;
XrGraphicsRequirementsOpenGLKHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR};
const XrVersion gl_version = XR_MAKE_VERSION(
ctx_gl->m_contextMajorVersion, ctx_gl->m_contextMinorVersion, 0);
ctx_gl.m_contextMajorVersion, ctx_gl.m_contextMinorVersion, 0);
if (!s_xrGetOpenGLGraphicsRequirementsKHR_fn &&
XR_FAILED(xrGetInstanceProcAddr(
@ -105,47 +103,45 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
(gl_version <= gpu_requirements.maxApiVersionSupported);
}
void initFromGhostContext(GHOST_Context *ghost_ctx) override
void initFromGhostContext(GHOST_Context &ghost_ctx) override
{
#if defined(WITH_GHOST_X11)
GHOST_ContextGLX *ctx_glx = static_cast<GHOST_ContextGLX *>(ghost_ctx);
XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx->m_display, ctx_glx->m_fbconfig);
GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx);
XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig);
oxr_binding.glx.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
oxr_binding.glx.xDisplay = ctx_glx->m_display;
oxr_binding.glx.glxFBConfig = ctx_glx->m_fbconfig;
oxr_binding.glx.glxDrawable = ctx_glx->m_window;
oxr_binding.glx.glxContext = ctx_glx->m_context;
oxr_binding.glx.xDisplay = ctx_glx.m_display;
oxr_binding.glx.glxFBConfig = ctx_glx.m_fbconfig;
oxr_binding.glx.glxDrawable = ctx_glx.m_window;
oxr_binding.glx.glxContext = ctx_glx.m_context;
oxr_binding.glx.visualid = visual_info->visualid;
XFree(visual_info);
#elif defined(WIN32)
GHOST_ContextWGL *ctx_wgl = static_cast<GHOST_ContextWGL *>(ghost_ctx);
GHOST_ContextWGL &ctx_wgl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
oxr_binding.wgl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR;
oxr_binding.wgl.hDC = ctx_wgl->m_hDC;
oxr_binding.wgl.hGLRC = ctx_wgl->m_hGLRC;
oxr_binding.wgl.hDC = ctx_wgl.m_hDC;
oxr_binding.wgl.hGLRC = ctx_wgl.m_hGLRC;
#endif
/* Generate a framebuffer to use for blitting into the texture. */
glGenFramebuffers(1, &m_fbo);
}
bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
int64_t &r_result,
bool &r_is_srgb_format) const override
std::optional<int64_t> chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
bool &r_is_srgb_format) const override
{
std::vector<int64_t> gpu_binding_formats = {
GL_RGBA8,
GL_SRGB8_ALPHA8,
};
if (choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result)) {
r_is_srgb_format = (r_result == GL_SRGB8_ALPHA8);
return true;
}
std::optional result = choose_swapchain_format_from_candidates(gpu_binding_formats,
runtime_formats);
r_is_srgb_format = result ? (*result == GL_SRGB8_ALPHA8) : false;
return false;
return result;
}
std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(uint32_t image_count) override
@ -166,25 +162,25 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
return base_images;
}
void submitToSwapchainImage(XrSwapchainImageBaseHeader *swapchain_image,
const GHOST_XrDrawViewInfo *draw_info) override
void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image,
const GHOST_XrDrawViewInfo &draw_info) override
{
XrSwapchainImageOpenGLKHR *ogl_swapchain_image = reinterpret_cast<XrSwapchainImageOpenGLKHR *>(
XrSwapchainImageOpenGLKHR &ogl_swapchain_image = reinterpret_cast<XrSwapchainImageOpenGLKHR &>(
swapchain_image);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ogl_swapchain_image->image, 0);
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ogl_swapchain_image.image, 0);
glBlitFramebuffer(draw_info->ofsx,
draw_info->ofsy,
draw_info->ofsx + draw_info->width,
draw_info->ofsy + draw_info->height,
draw_info->ofsx,
draw_info->ofsy,
draw_info->ofsx + draw_info->width,
draw_info->ofsy + draw_info->height,
glBlitFramebuffer(draw_info.ofsx,
draw_info.ofsy,
draw_info.ofsx + draw_info.width,
draw_info.ofsy + draw_info.height,
draw_info.ofsx,
draw_info.ofsy,
draw_info.ofsx + draw_info.width,
draw_info.ofsy + draw_info.height,
GL_COLOR_BUFFER_BIT,
GL_LINEAR);
@ -204,8 +200,8 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
#ifdef WIN32
class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
public:
GHOST_XrGraphicsBindingD3D(GHOST_Context *ghost_ctx)
: GHOST_IXrGraphicsBinding(), m_ghost_wgl_ctx(*static_cast<GHOST_ContextWGL *>(ghost_ctx))
GHOST_XrGraphicsBindingD3D(GHOST_Context &ghost_ctx)
: GHOST_IXrGraphicsBinding(), m_ghost_wgl_ctx(static_cast<GHOST_ContextWGL &>(ghost_ctx))
{
m_ghost_d3d_ctx = GHOST_SystemWin32::createOffscreenContextD3D();
}
@ -220,7 +216,7 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
}
bool checkVersionRequirements(
GHOST_Context * /*ghost_ctx*/, /* Remember: This is the OpenGL context! */
GHOST_Context & /*ghost_ctx*/, /* Remember: This is the OpenGL context! */
XrInstance instance,
XrSystemId system_id,
std::string *r_requirement_info) const override
@ -250,27 +246,25 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
}
void initFromGhostContext(
GHOST_Context * /*ghost_ctx*/ /* Remember: This is the OpenGL context! */
GHOST_Context & /*ghost_ctx*/ /* Remember: This is the OpenGL context! */
) override
{
oxr_binding.d3d11.type = XR_TYPE_GRAPHICS_BINDING_D3D11_KHR;
oxr_binding.d3d11.device = m_ghost_d3d_ctx->m_device;
}
bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
int64_t &r_result,
bool &r_is_srgb_format) const override
std::optional<int64_t> chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
bool &r_is_srgb_format) const override
{
std::vector<int64_t> gpu_binding_formats = {
DXGI_FORMAT_R8G8B8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
};
if (choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result)) {
r_is_srgb_format = (r_result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
return true;
}
return false;
std::optional result = choose_swapchain_format_from_candidates(gpu_binding_formats,
runtime_formats);
r_is_srgb_format = result ? (*result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) : false;
return result;
}
std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(uint32_t image_count) override
@ -291,10 +285,10 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
return base_images;
}
void submitToSwapchainImage(XrSwapchainImageBaseHeader *swapchain_image,
const GHOST_XrDrawViewInfo *draw_info) override
void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image,
const GHOST_XrDrawViewInfo &draw_info) override
{
XrSwapchainImageD3D11KHR *d3d_swapchain_image = reinterpret_cast<XrSwapchainImageD3D11KHR *>(
XrSwapchainImageD3D11KHR &d3d_swapchain_image = reinterpret_cast<XrSwapchainImageD3D11KHR &>(
swapchain_image);
# if 0
@ -308,22 +302,22 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(D3D11_RTV_DIMENSION_TEXTURE2D,
DXGI_FORMAT_R8G8B8A8_UNORM);
m_ghost_ctx->m_device->CreateRenderTargetView(d3d_swapchain_image->texture, &rtv_desc, &rtv);
m_ghost_ctx->m_device->CreateRenderTargetView(d3d_swapchain_image.texture, &rtv_desc, &rtv);
if (!m_shared_resource) {
m_shared_resource = m_ghost_ctx->createSharedOpenGLResource(
draw_info->width, draw_info->height, rtv);
draw_info.width, draw_info.height, rtv);
}
m_ghost_ctx->blitFromOpenGLContext(m_shared_resource, draw_info->width, draw_info->height);
m_ghost_ctx->blitFromOpenGLContext(m_shared_resource, draw_info.width, draw_info.height);
# else
if (!m_shared_resource) {
m_shared_resource = m_ghost_d3d_ctx->createSharedOpenGLResource(draw_info->width,
draw_info->height);
m_shared_resource = m_ghost_d3d_ctx->createSharedOpenGLResource(draw_info.width,
draw_info.height);
}
m_ghost_d3d_ctx->blitFromOpenGLContext(m_shared_resource, draw_info->width, draw_info->height);
m_ghost_d3d_ctx->blitFromOpenGLContext(m_shared_resource, draw_info.width, draw_info.height);
m_ghost_d3d_ctx->m_device_ctx->OMSetRenderTargets(0, nullptr, nullptr);
m_ghost_d3d_ctx->m_device_ctx->CopyResource(
d3d_swapchain_image->texture, m_ghost_d3d_ctx->getSharedTexture2D(m_shared_resource));
d3d_swapchain_image.texture, m_ghost_d3d_ctx->getSharedTexture2D(m_shared_resource));
# endif
}
@ -345,14 +339,14 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
#endif // WIN32
std::unique_ptr<GHOST_IXrGraphicsBinding> GHOST_XrGraphicsBindingCreateFromType(
GHOST_TXrGraphicsBinding type, GHOST_Context *context)
GHOST_TXrGraphicsBinding type, GHOST_Context &context)
{
switch (type) {
case GHOST_kXrGraphicsOpenGL:
return std::unique_ptr<GHOST_XrGraphicsBindingOpenGL>(new GHOST_XrGraphicsBindingOpenGL());
return std::make_unique<GHOST_XrGraphicsBindingOpenGL>();
#ifdef WIN32
case GHOST_kXrGraphicsD3D11:
return std::unique_ptr<GHOST_XrGraphicsBindingD3D>(new GHOST_XrGraphicsBindingD3D(context));
return std::make_unique<GHOST_XrGraphicsBindingD3D>(context);
#endif
default:
return nullptr;

View File

@ -62,8 +62,8 @@ struct GHOST_XrDrawInfo {
*
* \{ */
GHOST_XrSession::GHOST_XrSession(GHOST_XrContext *xr_context)
: m_context(xr_context), m_oxr(new OpenXRSessionData())
GHOST_XrSession::GHOST_XrSession(GHOST_XrContext &xr_context)
: m_context(&xr_context), m_oxr(std::make_unique<OpenXRSessionData>())
{
}
@ -113,7 +113,7 @@ void GHOST_XrSession::initSystem()
*
* \{ */
static void create_reference_spaces(OpenXRSessionData *oxr, const GHOST_XrPose *base_pose)
static void create_reference_spaces(OpenXRSessionData &oxr, const GHOST_XrPose &base_pose)
{
XrReferenceSpaceCreateInfo create_info = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
create_info.poseInReferenceSpace.orientation.w = 1.0f;
@ -142,11 +142,11 @@ static void create_reference_spaces(OpenXRSessionData *oxr, const GHOST_XrPose *
(void)base_pose;
#endif
CHECK_XR(xrCreateReferenceSpace(oxr->session, &create_info, &oxr->reference_space),
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.reference_space),
"Failed to create reference space.");
create_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
CHECK_XR(xrCreateReferenceSpace(oxr->session, &create_info, &oxr->view_space),
CHECK_XR(xrCreateReferenceSpace(oxr.session, &create_info, &oxr.view_space),
"Failed to create view reference space.");
}
@ -173,15 +173,15 @@ void GHOST_XrSession::start(const GHOST_XrSessionBeginInfo *begin_info)
std::string requirement_str;
m_gpu_binding = GHOST_XrGraphicsBindingCreateFromType(m_context->getGraphicsBindingType(),
m_gpu_ctx);
*m_gpu_ctx);
if (!m_gpu_binding->checkVersionRequirements(
m_gpu_ctx, m_context->getInstance(), m_oxr->system_id, &requirement_str)) {
*m_gpu_ctx, m_context->getInstance(), m_oxr->system_id, &requirement_str)) {
std::ostringstream strstream;
strstream << "Available graphics context version does not meet the following requirements: "
<< requirement_str;
throw GHOST_XrException(strstream.str().c_str());
}
m_gpu_binding->initFromGhostContext(m_gpu_ctx);
m_gpu_binding->initFromGhostContext(*m_gpu_ctx);
XrSessionCreateInfo create_info = {};
create_info.type = XR_TYPE_SESSION_CREATE_INFO;
@ -195,7 +195,7 @@ void GHOST_XrSession::start(const GHOST_XrSessionBeginInfo *begin_info)
"detailed error information to the command line.");
prepareDrawing();
create_reference_spaces(m_oxr.get(), &begin_info->base_pose);
create_reference_spaces(*m_oxr, begin_info->base_pose);
}
void GHOST_XrSession::requestEnd()
@ -217,14 +217,14 @@ void GHOST_XrSession::endSession()
}
GHOST_XrSession::LifeExpectancy GHOST_XrSession::handleStateChangeEvent(
const XrEventDataSessionStateChanged *lifecycle)
const XrEventDataSessionStateChanged &lifecycle)
{
m_oxr->session_state = lifecycle->state;
m_oxr->session_state = lifecycle.state;
/* Runtime may send events for apparently destroyed session. Our handle should be NULL then. */
assert((m_oxr->session == XR_NULL_HANDLE) || (m_oxr->session == lifecycle->session));
assert((m_oxr->session == XR_NULL_HANDLE) || (m_oxr->session == lifecycle.session));
switch (lifecycle->state) {
switch (lifecycle.state) {
case XR_SESSION_STATE_READY: {
beginSession();
break;
@ -272,7 +272,7 @@ void GHOST_XrSession::prepareDrawing()
m_oxr->views.resize(view_count, {XR_TYPE_VIEW});
m_draw_info = std::unique_ptr<GHOST_XrDrawInfo>(new GHOST_XrDrawInfo());
m_draw_info = std::make_unique<GHOST_XrDrawInfo>();
}
void GHOST_XrSession::beginFrameDrawing()
@ -295,43 +295,43 @@ void GHOST_XrSession::beginFrameDrawing()
}
}
static void print_debug_timings(GHOST_XrDrawInfo *draw_info)
static void print_debug_timings(GHOST_XrDrawInfo &draw_info)
{
/** Render time of last 8 frames (in ms) to calculate an average. */
std::chrono::duration<double, std::milli> duration = std::chrono::high_resolution_clock::now() -
draw_info->frame_begin_time;
draw_info.frame_begin_time;
const double duration_ms = duration.count();
const int avg_frame_count = 8;
double avg_ms_tot = 0.0;
if (draw_info->last_frame_times.size() >= avg_frame_count) {
draw_info->last_frame_times.pop_front();
assert(draw_info->last_frame_times.size() == avg_frame_count - 1);
if (draw_info.last_frame_times.size() >= avg_frame_count) {
draw_info.last_frame_times.pop_front();
assert(draw_info.last_frame_times.size() == avg_frame_count - 1);
}
draw_info->last_frame_times.push_back(duration_ms);
for (double ms_iter : draw_info->last_frame_times) {
draw_info.last_frame_times.push_back(duration_ms);
for (double ms_iter : draw_info.last_frame_times) {
avg_ms_tot += ms_iter;
}
printf("VR frame render time: %.0fms - %.2f FPS (%.2f FPS 8 frames average)\n",
duration_ms,
1000.0 / duration_ms,
1000.0 / (avg_ms_tot / draw_info->last_frame_times.size()));
1000.0 / (avg_ms_tot / draw_info.last_frame_times.size()));
}
void GHOST_XrSession::endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> *layers)
void GHOST_XrSession::endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> &layers)
{
XrFrameEndInfo end_info = {XR_TYPE_FRAME_END_INFO};
end_info.displayTime = m_draw_info->frame_state.predictedDisplayTime;
end_info.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
end_info.layerCount = layers->size();
end_info.layers = layers->data();
end_info.layerCount = layers.size();
end_info.layers = layers.data();
CHECK_XR(xrEndFrame(m_oxr->session, &end_info), "Failed to submit rendered frame.");
if (m_context->isDebugTimeMode()) {
print_debug_timings(m_draw_info.get());
print_debug_timings(*m_draw_info);
}
}
@ -349,7 +349,7 @@ void GHOST_XrSession::draw(void *draw_customdata)
layers.push_back(reinterpret_cast<XrCompositionLayerBaseHeader *>(&proj_layer));
}
endFrameDrawing(&layers);
endFrameDrawing(layers);
}
static void copy_openxr_pose_to_ghost_pose(const XrPosef &oxr_pose, GHOST_XrPose &r_ghost_pose)
@ -399,7 +399,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
/* Draw! */
m_context->getCustomFuncs().draw_view_fn(&draw_view_info, draw_customdata);
m_gpu_binding->submitToSwapchainImage(swapchain_image, &draw_view_info);
m_gpu_binding->submitToSwapchainImage(*swapchain_image, draw_view_info);
swapchain.releaseImage();
}

View File

@ -37,13 +37,13 @@ class GHOST_XrSession {
SESSION_DESTROY,
};
GHOST_XrSession(GHOST_XrContext *xr_context);
GHOST_XrSession(GHOST_XrContext &xr_context);
~GHOST_XrSession();
void start(const GHOST_XrSessionBeginInfo *begin_info);
void requestEnd();
LifeExpectancy handleStateChangeEvent(const XrEventDataSessionStateChanged *lifecycle);
LifeExpectancy handleStateChangeEvent(const XrEventDataSessionStateChanged &lifecycle);
bool isRunning() const;
bool needsUpsideDownDrawing() const;
@ -81,5 +81,5 @@ class GHOST_XrSession {
XrView &view,
void *draw_customdata);
void beginFrameDrawing();
void endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> *layers);
void endFrameDrawing(std::vector<XrCompositionLayerBaseHeader *> &layers);
};

View File

@ -54,11 +54,10 @@ static OpenXRSwapchainData::ImageVec swapchain_images_create(XrSwapchain swapcha
GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding,
const XrSession &session,
const XrViewConfigurationView &view_config)
: m_oxr(new OpenXRSwapchainData())
: m_oxr(std::make_unique<OpenXRSwapchainData>())
{
XrSwapchainCreateInfo create_info = {XR_TYPE_SWAPCHAIN_CREATE_INFO};
uint32_t format_count = 0;
int64_t chosen_format;
CHECK_XR(xrEnumerateSwapchainFormats(session, 0, &format_count, nullptr),
"Failed to get count of swapchain image formats.");
@ -68,14 +67,16 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding,
"Failed to get swapchain image formats.");
assert(swapchain_formats.size() == format_count);
if (!gpu_binding.chooseSwapchainFormat(swapchain_formats, chosen_format, m_is_srgb_buffer)) {
std::optional chosen_format = gpu_binding.chooseSwapchainFormat(swapchain_formats,
m_is_srgb_buffer);
if (!chosen_format) {
throw GHOST_XrException(
"Error: No format matching OpenXR runtime supported swapchain formats found.");
}
create_info.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT |
XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
create_info.format = chosen_format;
create_info.format = *chosen_format;
create_info.sampleCount = view_config.recommendedSwapchainSampleCount;
create_info.width = view_config.recommendedImageRectWidth;
create_info.height = view_config.recommendedImageRectHeight;