[Bf-blender-cvs] [74fc1db25b8] soc-2019-openxr: Add helper class to RAII manage OpenXR handles

Julian Eisel noreply at git.blender.org
Wed Jul 17 14:05:21 CEST 2019


Commit: 74fc1db25b8bf3327c029566b9d10e50a3eb591e
Author: Julian Eisel
Date:   Wed Jul 17 13:35:14 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB74fc1db25b8bf3327c029566b9d10e50a3eb591e

Add helper class to RAII manage OpenXR handles

Adds generic unique_oxr_ptr to wrap xrCreate and xrDestroy functions of
OpenXR handles into a unique_ptr like RAII interface.

While for most cases, OpenXR resources can be freed by their owning
object, sometimes errors may occor before final ownership is established.
E.g. swapchain ownership is only transfered to the session object once
its swapchain-images are created - which may fail. With this RAII
wrapper, the swapchain would be freed on error (as this triggers stack
unwinding through an exception), no matter who holds ownership to it
currently.
There are other solutions to this problem, e.g. by establishing final
ownership right after/upon creation, or by explicit freeing in case an
error is spotted; it's too easy to make mistakes here though. Plus, we
may want to experiment with using this API for all OpenXR resources, to
entirely avoid the possibility of them leaking.

===================================================================

M	intern/ghost/intern/GHOST_Xr_intern.h

===================================================================

diff --git a/intern/ghost/intern/GHOST_Xr_intern.h b/intern/ghost/intern/GHOST_Xr_intern.h
index c495a6c4468..b0258ae36a1 100644
--- a/intern/ghost/intern/GHOST_Xr_intern.h
+++ b/intern/ghost/intern/GHOST_Xr_intern.h
@@ -55,4 +55,69 @@
   } \
   (void)0
 
+/**
+ * Helper for RAII usage of OpenXR handles (defined with XR_DEFINE_HANDLE). This is based on
+ * `std::unique_ptr`, to give similar behavior and usage (e.g. functions like #get() and #release()
+ * are supported).
+ */
+template<typename _OXR_HANDLE> class unique_oxr_ptr {
+ public:
+  using xr_destroy_func = XrResult (*)(_OXR_HANDLE);
+
+  unique_oxr_ptr(xr_destroy_func destroy_fn) : m_destroy_fn(destroy_fn)
+  {
+  }
+
+  unique_oxr_ptr(unique_oxr_ptr &&other) : m_ptr(other.m_ptr), m_destroy_fn(other.m_destroy_fn)
+  {
+  }
+
+  /**
+   * Construct the pointer from a xrCreate function passed as \a create_fn, with additional
+   * arguments forwarded from \a args.
+   * For example, this:
+   * \code
+   * some_unique_oxr_ptr.contruct(xrCreateFoo, some_arg, some_other_arg);
+   * \endcode
+   * effectively results in this call:
+   * \code
+   * xrCreateFoo(some_arg, some_other_arg, &some_unique_oxr_ptr.m_ptr);
+   * \endcode
+   */
+  template<typename _create_func, typename... _Args>
+  XrResult construct(_create_func create_fn, _Args &&... args)
+  {
+    assert(m_ptr == XR_NULL_HANDLE);
+    return create_fn(std::forward<_Args>(args)..., &m_ptr);
+  }
+
+  ~unique_oxr_ptr()
+  {
+    if (m_ptr != XR_NULL_HANDLE) {
+      m_destroy_fn(m_ptr);
+    }
+  }
+
+  _OXR_HANDLE get()
+  {
+    return m_ptr;
+  }
+
+  _OXR_HANDLE release()
+  {
+    _OXR_HANDLE ptr = get();
+    m_ptr = XR_NULL_HANDLE;
+    return ptr;
+  }
+
+  /* operator= defines not needed for now. */
+
+  unique_oxr_ptr(const unique_oxr_ptr &) = delete;
+  unique_oxr_ptr &operator=(const unique_oxr_ptr &) = delete;
+
+ private:
+  _OXR_HANDLE m_ptr{XR_NULL_HANDLE};
+  xr_destroy_func m_destroy_fn;
+};
+
 #endif /* __GHOST_XR_INTERN_H__ */



More information about the Bf-blender-cvs mailing list