mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 04:36:07 +00:00
c/client: implement EGL context begin and end
This commit is contained in:
parent
f91ada32c2
commit
c8b4f7c64c
|
@ -72,50 +72,34 @@ typedef EGLBoolean
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct old_helper
|
|
||||||
{
|
|
||||||
EGLDisplay dpy;
|
|
||||||
EGLContext ctx;
|
|
||||||
EGLSurface read, draw;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct old_helper
|
|
||||||
old_save(void)
|
|
||||||
{
|
|
||||||
struct old_helper old = {
|
|
||||||
.dpy = eglGetCurrentDisplay(),
|
|
||||||
.ctx = EGL_NO_CONTEXT,
|
|
||||||
.read = EGL_NO_SURFACE,
|
|
||||||
.draw = EGL_NO_SURFACE,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Do we have a valid display?
|
|
||||||
if (old.dpy != EGL_NO_DISPLAY) {
|
|
||||||
old.ctx = eglGetCurrentContext();
|
|
||||||
old.read = eglGetCurrentSurface(EGL_READ);
|
|
||||||
old.draw = eglGetCurrentSurface(EGL_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
old_restore(struct old_helper *old, EGLDisplay current_dpy)
|
save_context(struct client_egl_context *ctx)
|
||||||
{
|
{
|
||||||
if (old->dpy == EGL_NO_DISPLAY) {
|
ctx->dpy = eglGetCurrentDisplay();
|
||||||
// There were no display, just unbind the context.
|
ctx->ctx = EGL_NO_CONTEXT;
|
||||||
if (eglMakeCurrent(current_dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE)) {
|
ctx->read = EGL_NO_SURFACE;
|
||||||
return;
|
ctx->draw = EGL_NO_SURFACE;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (eglMakeCurrent(old->dpy, old->draw, old->read, old->ctx)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EGL_ERROR("Failed to make old EGL context current! (%p, %p, %p, %p)", old->dpy, old->draw, old->read, old->ctx);
|
if (ctx->dpy != EGL_NO_DISPLAY) {
|
||||||
|
ctx->ctx = eglGetCurrentContext();
|
||||||
|
ctx->read = eglGetCurrentSurface(EGL_READ);
|
||||||
|
ctx->draw = eglGetCurrentSurface(EGL_DRAW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
restore_context(struct client_egl_context *ctx)
|
||||||
|
{
|
||||||
|
/* We're using the current display if we're trying to restore a null context */
|
||||||
|
EGLDisplay dpy = ctx->dpy == EGL_NO_DISPLAY ? eglGetCurrentDisplay() : ctx->dpy;
|
||||||
|
|
||||||
|
if (dpy == EGL_NO_DISPLAY) {
|
||||||
|
/* If the current display is also null then the call is a no-op */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eglMakeCurrent(dpy, ctx->draw, ctx->read, ctx->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -207,7 +191,7 @@ insert_fence_android_native(struct xrt_compositor *xc, xrt_graphics_sync_handle_
|
||||||
struct client_egl_compositor *ceglc = client_egl_compositor(xc);
|
struct client_egl_compositor *ceglc = client_egl_compositor(xc);
|
||||||
|
|
||||||
*out_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID;
|
*out_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID;
|
||||||
EGLDisplay dpy = ceglc->dpy;
|
EGLDisplay dpy = ceglc->current.dpy;
|
||||||
|
|
||||||
#ifdef XRT_GRAPHICS_SYNC_HANDLE_IS_FD
|
#ifdef XRT_GRAPHICS_SYNC_HANDLE_IS_FD
|
||||||
|
|
||||||
|
@ -239,14 +223,23 @@ insert_fence_android_native(struct xrt_compositor *xc, xrt_graphics_sync_handle_
|
||||||
static xrt_result_t
|
static xrt_result_t
|
||||||
client_egl_context_begin(struct xrt_compositor *xc)
|
client_egl_context_begin(struct xrt_compositor *xc)
|
||||||
{
|
{
|
||||||
//! @todo Implement
|
struct client_egl_compositor *eglc = client_egl_compositor(xc);
|
||||||
|
|
||||||
|
save_context(&eglc->previous);
|
||||||
|
struct client_egl_context *cur = &eglc->current;
|
||||||
|
|
||||||
|
if (!eglMakeCurrent(cur->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, cur->ctx)) {
|
||||||
|
return XRT_ERROR_OPENGL;
|
||||||
|
}
|
||||||
return XRT_SUCCESS;
|
return XRT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_egl_context_end(struct xrt_compositor *xc)
|
client_egl_context_end(struct xrt_compositor *xc)
|
||||||
{
|
{
|
||||||
//! @todo Implement
|
struct client_egl_compositor *eglc = client_egl_compositor(xc);
|
||||||
|
|
||||||
|
restore_context(&eglc->previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -286,8 +279,9 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
||||||
// On Android this extension is 'hidden'.
|
// On Android this extension is 'hidden'.
|
||||||
ensure_native_fence_is_loaded(display, get_gl_procaddr);
|
ensure_native_fence_is_loaded(display, get_gl_procaddr);
|
||||||
|
|
||||||
// Save old display, context and drawables.
|
// Save old EGL display, context and drawables.
|
||||||
struct old_helper old = old_save();
|
struct client_egl_context old = {0};
|
||||||
|
save_context(&old);
|
||||||
|
|
||||||
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context)) {
|
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context)) {
|
||||||
EGL_ERROR("eglMakeCurrent: %s\n\tFailed to make EGL context current", egl_error_str(eglGetError()));
|
EGL_ERROR("eglMakeCurrent: %s\n\tFailed to make EGL context current", egl_error_str(eglGetError()));
|
||||||
|
@ -297,7 +291,7 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
||||||
|
|
||||||
EGLint egl_client_type;
|
EGLint egl_client_type;
|
||||||
if (!eglQueryContext(display, context, EGL_CONTEXT_CLIENT_TYPE, &egl_client_type)) {
|
if (!eglQueryContext(display, context, EGL_CONTEXT_CLIENT_TYPE, &egl_client_type)) {
|
||||||
old_restore(&old, display);
|
restore_context(&old);
|
||||||
return XRT_ERROR_OPENGL;
|
return XRT_ERROR_OPENGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +302,7 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
EGL_ERROR("OpenGL support not including in this runtime build");
|
EGL_ERROR("OpenGL support not including in this runtime build");
|
||||||
old_restore(&old, display);
|
restore_context(&old);
|
||||||
return XRT_ERROR_OPENGL;
|
return XRT_ERROR_OPENGL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -318,14 +312,15 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
EGL_ERROR("OpenGL|ES support not including in this runtime build");
|
EGL_ERROR("OpenGL|ES support not including in this runtime build");
|
||||||
old_restore(&old, display);
|
restore_context(&old);
|
||||||
return XRT_ERROR_OPENGL;
|
return XRT_ERROR_OPENGL;
|
||||||
#endif
|
#endif
|
||||||
default: EGL_ERROR("Unsupported EGL client type"); return XRT_ERROR_OPENGL;
|
default: EGL_ERROR("Unsupported EGL client type"); return XRT_ERROR_OPENGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct client_egl_compositor *ceglc = U_TYPED_CALLOC(struct client_egl_compositor);
|
struct client_egl_compositor *ceglc = U_TYPED_CALLOC(struct client_egl_compositor);
|
||||||
ceglc->dpy = display;
|
ceglc->current.dpy = display;
|
||||||
|
ceglc->current.ctx = context;
|
||||||
|
|
||||||
client_gl_swapchain_create_func_t sc_create = NULL;
|
client_gl_swapchain_create_func_t sc_create = NULL;
|
||||||
|
|
||||||
|
@ -365,7 +360,7 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
||||||
EGL_ERROR(
|
EGL_ERROR(
|
||||||
"Could not find a required extension: need either EGL_EXT_image_dma_buf_import or "
|
"Could not find a required extension: need either EGL_EXT_image_dma_buf_import or "
|
||||||
"GL_EXT_memory_object_fd");
|
"GL_EXT_memory_object_fd");
|
||||||
old_restore(&old, display);
|
restore_context(&old);
|
||||||
return XRT_ERROR_OPENGL;
|
return XRT_ERROR_OPENGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,12 +391,12 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
||||||
if (!bret) {
|
if (!bret) {
|
||||||
free(ceglc);
|
free(ceglc);
|
||||||
EGL_ERROR("Failed to initialize compositor");
|
EGL_ERROR("Failed to initialize compositor");
|
||||||
old_restore(&old, display);
|
restore_context(&old);
|
||||||
return XRT_ERROR_OPENGL;
|
return XRT_ERROR_OPENGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ceglc->base.base.base.destroy = client_egl_compositor_destroy;
|
ceglc->base.base.base.destroy = client_egl_compositor_destroy;
|
||||||
old_restore(&old, display);
|
restore_context(&old);
|
||||||
*out_xcgl = &ceglc->base.base;
|
*out_xcgl = &ceglc->base.base;
|
||||||
|
|
||||||
return XRT_SUCCESS;
|
return XRT_SUCCESS;
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct client_egl_context
|
||||||
|
{
|
||||||
|
EGLDisplay dpy;
|
||||||
|
EGLContext ctx;
|
||||||
|
EGLSurface read, draw;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* EGL based compositor, carries the extra needed EGL information needed by the
|
* EGL based compositor, carries the extra needed EGL information needed by the
|
||||||
|
@ -30,8 +36,7 @@ extern "C" {
|
||||||
struct client_egl_compositor
|
struct client_egl_compositor
|
||||||
{
|
{
|
||||||
struct client_gl_compositor base;
|
struct client_gl_compositor base;
|
||||||
|
struct client_egl_context current, previous;
|
||||||
EGLDisplay dpy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -200,7 +200,7 @@ client_gl_eglimage_swapchain_create(struct xrt_compositor *xc,
|
||||||
sc->base.base.base.image_count =
|
sc->base.base.base.image_count =
|
||||||
native_xsc->image_count; // Fetch the number of images from the native swapchain.
|
native_xsc->image_count; // Fetch the number of images from the native swapchain.
|
||||||
sc->base.xscn = xscn;
|
sc->base.xscn = xscn;
|
||||||
sc->display = ceglc->dpy;
|
sc->display = ceglc->current.dpy;
|
||||||
|
|
||||||
struct xrt_swapchain_gl *xscgl = &sc->base.base;
|
struct xrt_swapchain_gl *xscgl = &sc->base.base;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue