mirror of
https://github.com/Cateners/tiny_computer.git
synced 2026-05-20 16:35:47 +08:00
191 lines
7.0 KiB
C
191 lines
7.0 KiB
C
#include "engine.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
void XrEngineInit(struct XrEngine* engine, void* system, const char* name, int version) {
|
|
if (engine->Initialized)
|
|
return;
|
|
memset(engine, 0, sizeof(engine));
|
|
|
|
#ifdef ANDROID
|
|
PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
|
|
xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR",
|
|
(PFN_xrVoidFunction*)&xrInitializeLoaderKHR);
|
|
if (xrInitializeLoaderKHR != NULL) {
|
|
xrJava* java = (xrJava*)system;
|
|
XrLoaderInitInfoAndroidKHR loader_info;
|
|
memset(&loader_info, 0, sizeof(loader_info));
|
|
loader_info.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR;
|
|
loader_info.next = NULL;
|
|
loader_info.applicationVM = java->vm;
|
|
loader_info.applicationContext = java->activity;
|
|
xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loader_info);
|
|
}
|
|
#endif
|
|
|
|
int count = 0;
|
|
const char* extensions[32];
|
|
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
|
|
extensions[count++] = XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME;
|
|
#endif
|
|
#ifdef ANDROID
|
|
if (engine->PlatformFlag[PLATFORM_EXTENSION_INSTANCE]) {
|
|
extensions[count++] = XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME;
|
|
}
|
|
if (engine->PlatformFlag[PLATFORM_EXTENSION_PASSTHROUGH]) {
|
|
extensions[count++] = XR_FB_PASSTHROUGH_EXTENSION_NAME;
|
|
}
|
|
if (engine->PlatformFlag[PLATFORM_EXTENSION_PERFORMANCE]) {
|
|
extensions[count++] = XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME;
|
|
extensions[count++] = XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME;
|
|
}
|
|
#endif
|
|
|
|
// Create the OpenXR instance.
|
|
XrApplicationInfo app_info;
|
|
memset(&app_info, 0, sizeof(app_info));
|
|
strcpy(app_info.applicationName, name);
|
|
strcpy(app_info.engineName, name);
|
|
app_info.applicationVersion = version;
|
|
app_info.engineVersion = version;
|
|
app_info.apiVersion = XR_API_VERSION_1_0;
|
|
|
|
XrInstanceCreateInfo instance_info;
|
|
memset(&instance_info, 0, sizeof(instance_info));
|
|
instance_info.type = XR_TYPE_INSTANCE_CREATE_INFO;
|
|
instance_info.next = NULL;
|
|
instance_info.createFlags = 0;
|
|
instance_info.applicationInfo = app_info;
|
|
instance_info.enabledApiLayerCount = 0;
|
|
instance_info.enabledApiLayerNames = NULL;
|
|
instance_info.enabledExtensionCount = count;
|
|
instance_info.enabledExtensionNames = extensions;
|
|
|
|
#ifdef ANDROID
|
|
XrInstanceCreateInfoAndroidKHR instance_info_android = {XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR};
|
|
if (engine->PlatformFlag[PLATFORM_EXTENSION_INSTANCE]) {
|
|
xrJava* java = (xrJava*)system;
|
|
instance_info_android.applicationVM = java->vm;
|
|
instance_info_android.applicationActivity = java->activity;
|
|
instance_info.next = (XrBaseInStructure*)&instance_info_android;
|
|
}
|
|
#endif
|
|
|
|
XrResult result;
|
|
OXR(result = xrCreateInstance(&instance_info, &engine->Instance));
|
|
if (result != XR_SUCCESS) {
|
|
ALOGE("Failed to create XR instance: %d", (int)result);
|
|
exit(1);
|
|
}
|
|
|
|
XrInstanceProperties instance_properties;
|
|
instance_properties.type = XR_TYPE_INSTANCE_PROPERTIES;
|
|
instance_properties.next = NULL;
|
|
OXR(xrGetInstanceProperties(engine->Instance, &instance_properties));
|
|
ALOGV("Runtime %s: Version : %d.%d.%d", instance_properties.runtimeName,
|
|
XR_VERSION_MAJOR(instance_properties.runtimeVersion),
|
|
XR_VERSION_MINOR(instance_properties.runtimeVersion),
|
|
XR_VERSION_PATCH(instance_properties.runtimeVersion));
|
|
|
|
XrSystemGetInfo system_info;
|
|
memset(&system_info, 0, sizeof(system_info));
|
|
system_info.type = XR_TYPE_SYSTEM_GET_INFO;
|
|
system_info.next = NULL;
|
|
system_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
|
|
|
|
OXR(result = xrGetSystem(engine->Instance, &system_info, &engine->SystemId));
|
|
if (result != XR_SUCCESS) {
|
|
ALOGE("Failed to get system");
|
|
exit(1);
|
|
}
|
|
|
|
// Get the graphics requirements.
|
|
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
|
|
PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = NULL;
|
|
OXR(xrGetInstanceProcAddr(engine->Instance, "xrGetOpenGLESGraphicsRequirementsKHR",
|
|
(PFN_xrVoidFunction*)(&pfnGetOpenGLESGraphicsRequirementsKHR)));
|
|
|
|
XrGraphicsRequirementsOpenGLESKHR graphics_requirements = {};
|
|
graphics_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
|
|
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(engine->Instance, engine->SystemId, &graphics_requirements));
|
|
#endif
|
|
|
|
#ifdef ANDROID
|
|
engine->MainThreadId = gettid();
|
|
#endif
|
|
engine->Initialized = true;
|
|
}
|
|
|
|
void XrEngineDestroy(struct XrEngine* engine) {
|
|
if (engine->Initialized) {
|
|
xrDestroyInstance(engine->Instance);
|
|
engine->Initialized = false;
|
|
}
|
|
}
|
|
|
|
void XrEngineEnter(struct XrEngine* engine) {
|
|
if (engine->Session) {
|
|
ALOGE("EnterXR called with existing session");
|
|
return;
|
|
}
|
|
|
|
// Create the OpenXR Session.
|
|
XrSessionCreateInfo session_info;
|
|
memset(&session_info, 0, sizeof(session_info));
|
|
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
|
|
XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl = {};
|
|
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR;
|
|
graphics_binding_gl.next = NULL;
|
|
graphics_binding_gl.display = eglGetCurrentDisplay();
|
|
graphics_binding_gl.config = NULL;
|
|
graphics_binding_gl.context = eglGetCurrentContext();
|
|
session_info.next = &graphics_binding_gl;
|
|
#endif
|
|
session_info.type = XR_TYPE_SESSION_CREATE_INFO;
|
|
session_info.createFlags = 0;
|
|
session_info.systemId = engine->SystemId;
|
|
|
|
XrResult result;
|
|
OXR(result = xrCreateSession(engine->Instance, &session_info, &engine->Session));
|
|
if (result != XR_SUCCESS) {
|
|
ALOGE("Failed to create XR session: %d", (int)result);
|
|
exit(1);
|
|
}
|
|
|
|
// Create a space to the first path
|
|
XrReferenceSpaceCreateInfo space_info = {};
|
|
space_info.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
|
|
space_info.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
|
|
space_info.poseInReferenceSpace.orientation.w = 1.0f;
|
|
OXR(xrCreateReferenceSpace(engine->Session, &space_info, &engine->HeadSpace));
|
|
}
|
|
|
|
void XrEngineLeave(struct XrEngine* engine) {
|
|
if (engine->Session) {
|
|
OXR(xrDestroySpace(engine->HeadSpace));
|
|
// StageSpace is optional.
|
|
if (engine->StageSpace != XR_NULL_HANDLE) {
|
|
OXR(xrDestroySpace(engine->StageSpace));
|
|
}
|
|
OXR(xrDestroySpace(engine->FakeSpace));
|
|
engine->CurrentSpace = XR_NULL_HANDLE;
|
|
OXR(xrDestroySession(engine->Session));
|
|
engine->Session = XR_NULL_HANDLE;
|
|
}
|
|
}
|
|
|
|
void XrEngineWaitForFrame(struct XrEngine* engine) {
|
|
XrFrameWaitInfo wait_frame_info = {};
|
|
wait_frame_info.type = XR_TYPE_FRAME_WAIT_INFO;
|
|
wait_frame_info.next = NULL;
|
|
|
|
XrFrameState frame_state = {};
|
|
frame_state.type = XR_TYPE_FRAME_STATE;
|
|
frame_state.next = NULL;
|
|
|
|
OXR(xrWaitFrame(engine->Session, &wait_frame_info, &frame_state));
|
|
engine->PredictedDisplayTime = frame_state.predictedDisplayTime;
|
|
}
|