// Generic OpenXR swapchain + per-image GL framebuffer helper, shared by
// every quad this app submits - the game quad (xr_session.c) and every
// xr_overlay.c instance (menu launcher, keyboard) - since they all need
// exactly the same setup, just at their own size/format.
#ifndef QUESTSHOCK_XR_SWAPCHAIN_H
#define QUESTSHOCK_XR_SWAPCHAIN_H

#include <stdbool.h>
#include <stdint.h>

#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <jni.h>

#define XR_USE_PLATFORM_ANDROID 1
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>

#ifdef __cplusplus
extern "C" {
#endif

// Up to this many swapchain images/FBOs - real runtimes report small counts
// (2-4); this is just a fixed upper bound for the cache arrays below.
#define XR_SWAPCHAIN_MAX_IMAGES 8

typedef struct {
    XrSwapchain swapchain;
    GLuint fbos[XR_SWAPCHAIN_MAX_IMAGES];
    uint32_t image_count;
    int width;
    int height;
} XrSwapchainState;

// Creates the swapchain and wraps each of its images in its own GL
// framebuffer, ready to bind and render into directly. instance is only
// used to log a human-readable error string on failure.
bool xr_swapchain_create(XrInstance instance, XrSession session, int64_t format, int width,
                          int height, XrSwapchainState *out);

void xr_swapchain_destroy(XrSwapchainState *state);

// Acquires the next image, waits for the runtime to finish with it, and
// binds its framebuffer (sized to exactly fill it) as the current render
// target.
bool xr_swapchain_acquire(XrInstance instance, XrSwapchainState *state);

void xr_swapchain_release(XrInstance instance, XrSwapchainState *state);

#ifdef __cplusplus
}
#endif

#endif
