mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +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
|
||||
old_restore(struct old_helper *old, EGLDisplay current_dpy)
|
||||
save_context(struct client_egl_context *ctx)
|
||||
{
|
||||
if (old->dpy == EGL_NO_DISPLAY) {
|
||||
// There were no display, just unbind the context.
|
||||
if (eglMakeCurrent(current_dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (eglMakeCurrent(old->dpy, old->draw, old->read, old->ctx)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx->dpy = eglGetCurrentDisplay();
|
||||
ctx->ctx = EGL_NO_CONTEXT;
|
||||
ctx->read = EGL_NO_SURFACE;
|
||||
ctx->draw = EGL_NO_SURFACE;
|
||||
|
||||
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);
|
||||
|
||||
*out_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID;
|
||||
EGLDisplay dpy = ceglc->dpy;
|
||||
EGLDisplay dpy = ceglc->current.dpy;
|
||||
|
||||
#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
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
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
|
||||
|
@ -286,8 +279,9 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
|||
// On Android this extension is 'hidden'.
|
||||
ensure_native_fence_is_loaded(display, get_gl_procaddr);
|
||||
|
||||
// Save old display, context and drawables.
|
||||
struct old_helper old = old_save();
|
||||
// Save old EGL display, context and drawables.
|
||||
struct client_egl_context old = {0};
|
||||
save_context(&old);
|
||||
|
||||
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()));
|
||||
|
@ -297,7 +291,7 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
|||
|
||||
EGLint 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;
|
||||
}
|
||||
|
||||
|
@ -308,7 +302,7 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
|||
break;
|
||||
#else
|
||||
EGL_ERROR("OpenGL support not including in this runtime build");
|
||||
old_restore(&old, display);
|
||||
restore_context(&old);
|
||||
return XRT_ERROR_OPENGL;
|
||||
#endif
|
||||
|
||||
|
@ -318,14 +312,15 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
|||
break;
|
||||
#else
|
||||
EGL_ERROR("OpenGL|ES support not including in this runtime build");
|
||||
old_restore(&old, display);
|
||||
restore_context(&old);
|
||||
return XRT_ERROR_OPENGL;
|
||||
#endif
|
||||
default: EGL_ERROR("Unsupported EGL client type"); return XRT_ERROR_OPENGL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -365,7 +360,7 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
|||
EGL_ERROR(
|
||||
"Could not find a required extension: need either EGL_EXT_image_dma_buf_import or "
|
||||
"GL_EXT_memory_object_fd");
|
||||
old_restore(&old, display);
|
||||
restore_context(&old);
|
||||
return XRT_ERROR_OPENGL;
|
||||
}
|
||||
|
||||
|
@ -396,12 +391,12 @@ xrt_gfx_provider_create_gl_egl(struct xrt_compositor_native *xcn,
|
|||
if (!bret) {
|
||||
free(ceglc);
|
||||
EGL_ERROR("Failed to initialize compositor");
|
||||
old_restore(&old, display);
|
||||
restore_context(&old);
|
||||
return XRT_ERROR_OPENGL;
|
||||
}
|
||||
|
||||
ceglc->base.base.base.destroy = client_egl_compositor_destroy;
|
||||
old_restore(&old, display);
|
||||
restore_context(&old);
|
||||
*out_xcgl = &ceglc->base.base;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
|
|
|
@ -20,6 +20,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct client_egl_context
|
||||
{
|
||||
EGLDisplay dpy;
|
||||
EGLContext ctx;
|
||||
EGLSurface read, draw;
|
||||
};
|
||||
|
||||
/*!
|
||||
* EGL based compositor, carries the extra needed EGL information needed by the
|
||||
|
@ -30,8 +36,7 @@ extern "C" {
|
|||
struct client_egl_compositor
|
||||
{
|
||||
struct client_gl_compositor base;
|
||||
|
||||
EGLDisplay dpy;
|
||||
struct client_egl_context current, previous;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -200,7 +200,7 @@ client_gl_eglimage_swapchain_create(struct xrt_compositor *xc,
|
|||
sc->base.base.base.image_count =
|
||||
native_xsc->image_count; // Fetch the number of images from the native swapchain.
|
||||
sc->base.xscn = xscn;
|
||||
sc->display = ceglc->dpy;
|
||||
sc->display = ceglc->current.dpy;
|
||||
|
||||
struct xrt_swapchain_gl *xscgl = &sc->base.base;
|
||||
|
||||
|
|
Loading…
Reference in a new issue