mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-05 13:28:16 +00:00
st/oxr: Add a path store
This commit is contained in:
parent
9173e1d31c
commit
77b3b7b840
|
@ -25,6 +25,7 @@ set(OXR_SOURCE_FILES
|
|||
oxr/oxr_logger.h
|
||||
oxr/oxr_messenger.c
|
||||
oxr/oxr_objects.h
|
||||
oxr/oxr_path.c
|
||||
oxr/oxr_session.c
|
||||
oxr/oxr_session_gl.c
|
||||
oxr/oxr_session_vk.c
|
||||
|
|
|
@ -41,6 +41,12 @@ oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
|||
struct xrt_prober *prober = inst->prober;
|
||||
struct xrt_device *dev = inst->system.device;
|
||||
|
||||
oxr_path_destroy_all(log, inst);
|
||||
|
||||
if (inst->path_store != NULL) {
|
||||
u_hashset_destroy(&inst->path_store);
|
||||
}
|
||||
|
||||
if (dev != NULL) {
|
||||
dev->destroy(dev);
|
||||
inst->system.device = NULL;
|
||||
|
@ -65,9 +71,18 @@ oxr_instance_create(struct oxr_logger *log,
|
|||
struct oxr_instance **out_instance)
|
||||
{
|
||||
struct oxr_instance *inst = NULL;
|
||||
int h_ret;
|
||||
|
||||
OXR_ALLOCATE_HANDLE_OR_RETURN(log, inst, OXR_XR_DEBUG_INSTANCE,
|
||||
oxr_instance_destroy, NULL);
|
||||
|
||||
h_ret = u_hashset_create(&inst->path_store);
|
||||
if (h_ret != 0) {
|
||||
free(inst);
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
||||
"Failed to create hashset");
|
||||
}
|
||||
|
||||
inst->prober = xrt_create_prober();
|
||||
|
||||
struct xrt_device *dev =
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "xrt/xrt_compositor.h"
|
||||
#include "xrt/xrt_vulkan_includes.h"
|
||||
#include "xrt/xrt_openxr_includes.h"
|
||||
#include "util/u_hashset.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -42,6 +43,7 @@ extern "C" {
|
|||
#define OXR_XR_DEBUG_INSTANCE (*(uint64_t *)"oxrinst\0")
|
||||
#define OXR_XR_DEBUG_SESSION (*(uint64_t *)"oxrsess\0")
|
||||
#define OXR_XR_DEBUG_SPACE (*(uint64_t *)"oxrspac\0")
|
||||
#define OXR_XR_DEBUG_PATH (*(uint64_t *)"oxrpath\0")
|
||||
#define OXR_XR_DEBUG_ACTION (*(uint64_t *)"oxracti\0")
|
||||
#define OXR_XR_DEBUG_SWAPCHAIN (*(uint64_t *)"oxrswap\0")
|
||||
#define OXR_XR_DEBUG_ACTIONSET (*(uint64_t *)"oxraset\0")
|
||||
|
@ -149,6 +151,60 @@ oxr_instance_convert_timespec_to_time(struct oxr_logger *log,
|
|||
XrTime *time);
|
||||
#endif // XR_USE_TIMESPEC
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* oxr_path.c
|
||||
*
|
||||
*/
|
||||
|
||||
void *
|
||||
oxr_path_get_attached(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath path);
|
||||
|
||||
/*!
|
||||
* Get the path for the given string if it exists, or create it if it does not.
|
||||
*/
|
||||
XrResult
|
||||
oxr_path_get_or_create(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
const char *str,
|
||||
size_t length,
|
||||
XrPath *out_path);
|
||||
|
||||
/*!
|
||||
* Only get the path for the given string if it exists.
|
||||
*/
|
||||
XrResult
|
||||
oxr_path_only_get(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
const char *str,
|
||||
size_t length,
|
||||
XrPath *out_path);
|
||||
|
||||
/*!
|
||||
* Get a pointer and length of the internal string.
|
||||
*
|
||||
* The pointer has the same life time as the instance. The length is the number
|
||||
* of valid characters, not including the null termination character (but a
|
||||
* extra null byte is always reserved at the end so can strings can be given
|
||||
* to functions expecting null terminated strings).
|
||||
*/
|
||||
XrResult
|
||||
oxr_path_get_string(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath path,
|
||||
const char **out_str,
|
||||
size_t *out_length);
|
||||
|
||||
/*!
|
||||
* Destroy all paths that the instance has created.
|
||||
*/
|
||||
void
|
||||
oxr_path_destroy_all(struct oxr_logger *log, struct oxr_instance *inst);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* oxr_session.c
|
||||
|
@ -538,6 +594,9 @@ struct oxr_instance
|
|||
|
||||
struct time_state *timekeeping;
|
||||
|
||||
//! Path store, for looking up paths.
|
||||
struct u_hashset *path_store;
|
||||
|
||||
// Event queue.
|
||||
struct oxr_event *last_event;
|
||||
struct oxr_event *next_event;
|
||||
|
|
220
src/xrt/state_trackers/oxr/oxr_path.c
Normal file
220
src/xrt/state_trackers/oxr/oxr_path.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Holds path related functions.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup oxr_main
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "math/m_api.h"
|
||||
#include "util/u_misc.h"
|
||||
|
||||
#include "oxr_objects.h"
|
||||
#include "oxr_logger.h"
|
||||
|
||||
|
||||
/*!
|
||||
* Internal representation of a path, item follows this struct in memory and
|
||||
* that in turn is followed by the string.
|
||||
*
|
||||
* @ingroup oxr_main
|
||||
*/
|
||||
struct oxr_path
|
||||
{
|
||||
uint64_t debug;
|
||||
void *attached;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Helpers
|
||||
*
|
||||
*/
|
||||
|
||||
static inline struct oxr_path *
|
||||
oxr_path(XrPath path)
|
||||
{
|
||||
return (struct oxr_path *)path;
|
||||
}
|
||||
|
||||
static inline XrPath
|
||||
to_xr_path(struct oxr_path *path)
|
||||
{
|
||||
return (XrPath)path;
|
||||
}
|
||||
|
||||
static inline struct u_hashset_item *
|
||||
get_item(struct oxr_path *path)
|
||||
{
|
||||
return (struct u_hashset_item *)&path[1];
|
||||
}
|
||||
|
||||
static inline struct oxr_path *
|
||||
from_item(struct u_hashset_item *item)
|
||||
{
|
||||
return &((struct oxr_path *)item)[-1];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Static functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static XrResult
|
||||
oxr_allocate_path(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
const char *str,
|
||||
size_t length,
|
||||
struct oxr_path **out_path)
|
||||
{
|
||||
struct u_hashset_item *item = NULL;
|
||||
struct oxr_path *path = NULL;
|
||||
size_t size = 0;
|
||||
int ret;
|
||||
|
||||
size += sizeof(struct oxr_path); // Main path object.
|
||||
size += sizeof(struct u_hashset_item); // Embedded hashset item.
|
||||
size += length; // String.
|
||||
size += 1; // Null terminate it.
|
||||
|
||||
// Now allocate and setup the path.
|
||||
path = U_CALLOC_WITH_CAST(struct oxr_path, size);
|
||||
if (path == NULL) {
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
||||
"Failed to allocate path");
|
||||
}
|
||||
path->debug = OXR_XR_DEBUG_PATH;
|
||||
|
||||
// Setup the item.
|
||||
item = get_item(path);
|
||||
item->hash = math_hash_string(str, length);
|
||||
item->length = length;
|
||||
|
||||
// Yes a const cast! D:
|
||||
char *store = (char *)item->c_str;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
store[i] = str[i];
|
||||
}
|
||||
store[length] = '\0';
|
||||
|
||||
// Insert and return.
|
||||
ret = u_hashset_insert_item(inst->path_store, item);
|
||||
if (ret) {
|
||||
free(path);
|
||||
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
||||
"Failed to insert item");
|
||||
}
|
||||
|
||||
*out_path = path;
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* "Exported" functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void *
|
||||
oxr_path_get_attached(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath xr_path)
|
||||
{
|
||||
if (xr_path == XR_NULL_PATH) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return oxr_path(xr_path)->attached;
|
||||
}
|
||||
|
||||
XrResult
|
||||
oxr_path_get_or_create(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
const char *str,
|
||||
size_t length,
|
||||
XrPath *out_path)
|
||||
{
|
||||
struct u_hashset_item *item;
|
||||
struct oxr_path *path;
|
||||
XrResult ret;
|
||||
int h_ret;
|
||||
|
||||
// Look it up the instance path store.
|
||||
h_ret = u_hashset_find_str(inst->path_store, str, length, &item);
|
||||
if (h_ret == 0) {
|
||||
*out_path = to_xr_path(from_item(item));
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
// Create the path since it was not found.
|
||||
ret = oxr_allocate_path(log, inst, str, length, &path);
|
||||
if (ret != XR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_path = to_xr_path(path);
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
XrResult
|
||||
oxr_path_only_get(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
const char *str,
|
||||
size_t length,
|
||||
XrPath *out_path)
|
||||
{
|
||||
struct u_hashset_item *item;
|
||||
int h_ret;
|
||||
|
||||
// Look it up the instance path store.
|
||||
h_ret = u_hashset_find_str(inst->path_store, str, length, &item);
|
||||
if (h_ret == 0) {
|
||||
*out_path = to_xr_path(from_item(item));
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
*out_path = XR_NULL_PATH;
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
XrResult
|
||||
oxr_path_get_string(struct oxr_logger *log,
|
||||
struct oxr_instance *inst,
|
||||
XrPath xr_path,
|
||||
const char **out_str,
|
||||
size_t *out_length)
|
||||
{
|
||||
struct oxr_path *path = oxr_path(xr_path);
|
||||
|
||||
*out_str = get_item(path)->c_str;
|
||||
*out_length = get_item(path)->length;
|
||||
|
||||
return XR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_callback(struct u_hashset_item *item, void *priv)
|
||||
{
|
||||
struct oxr_path *path = from_item(item);
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
void
|
||||
oxr_path_destroy_all(struct oxr_logger *log,
|
||||
struct oxr_instance *inst)
|
||||
{
|
||||
u_hashset_clear_and_call_for_each(inst->path_store, destroy_callback,
|
||||
inst);
|
||||
}
|
Loading…
Reference in a new issue