X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglapi.c;h=1c62a8049e4c47a4c87e57ec3a1131a8d5c0e514;hb=1d535c1e83ae45b67a141420298c5d08082e0ed8;hp=323634e451180fdb3245ced0ce2a8aaa7ae9a59c;hpb=6a7ca4ef2cd3f39d3b5e77051cb3f3175e9e60df;p=mesa.git diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 323634e4511..1c62a8049e4 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -88,6 +88,7 @@ #include #include "c99_compat.h" #include "c11/threads.h" +#include "GL/mesa_glinterop.h" #include "eglcompiler.h" #include "eglglobals.h" @@ -294,9 +295,9 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay) return _eglGetDisplayHandle(dpy); } -static EGLDisplay EGLAPIENTRY -eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, - const EGLint *attrib_list) +static EGLDisplay +_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display, + const EGLint *attrib_list) { _EGLDisplay *dpy; @@ -325,17 +326,25 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, return _eglGetDisplayHandle(dpy); } +static EGLDisplay EGLAPIENTRY +eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, + const EGLint *attrib_list) +{ + return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list); +} + EGLDisplay EGLAPIENTRY eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) { EGLDisplay display; - EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list); + EGLint *int_attribs; + int_attribs = _eglConvertAttribsToInt(attrib_list); if (attrib_list && !int_attribs) RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL); - display = eglGetPlatformDisplayEXT(platform, native_display, int_attribs); + display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs); free(int_attribs); return display; } @@ -381,7 +390,9 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) char *exts = dpy->ExtensionsString; /* Please keep these sorted alphabetically. */ + _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target); _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer); + _EGL_CHECK_EXTENSION(ANDROID_recordable); _EGL_CHECK_EXTENSION(CHROMIUM_sync_control); @@ -403,13 +414,13 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) _eglAppendExtension(&exts, "EGL_KHR_image"); _EGL_CHECK_EXTENSION(KHR_image_base); _EGL_CHECK_EXTENSION(KHR_image_pixmap); + _EGL_CHECK_EXTENSION(KHR_no_config_context); _EGL_CHECK_EXTENSION(KHR_reusable_sync); _EGL_CHECK_EXTENSION(KHR_surfaceless_context); - _EGL_CHECK_EXTENSION(KHR_vg_parent_image); _EGL_CHECK_EXTENSION(KHR_wait_sync); - _EGL_CHECK_EXTENSION(MESA_configless_context); - _EGL_CHECK_EXTENSION(MESA_drm_display); + if (dpy->Extensions.KHR_no_config_context) + _eglAppendExtension(&exts, "EGL_MESA_configless_context"); _EGL_CHECK_EXTENSION(MESA_drm_image); _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export); @@ -430,14 +441,11 @@ _eglCreateAPIsString(_EGLDisplay *dpy) if (dpy->ClientAPIs & EGL_OPENGL_BIT) strcat(dpy->ClientAPIsString, "OpenGL "); - if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT) + if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT || + dpy->ClientAPIs & EGL_OPENGL_ES2_BIT || + dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) { strcat(dpy->ClientAPIsString, "OpenGL_ES "); - - if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT) - strcat(dpy->ClientAPIsString, "OpenGL_ES2 "); - - if (dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) - strcat(dpy->ClientAPIsString, "OpenGL_ES3 "); + } if (dpy->ClientAPIs & EGL_OPENVG_BIT) strcat(dpy->ClientAPIsString, "OpenVG "); @@ -629,7 +637,7 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv); - if (!config && !disp->Extensions.MESA_configless_context) + if (!config && !disp->Extensions.KHR_no_config_context) RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT); if (!share && share_list != EGL_NO_CONTEXT) @@ -754,14 +762,9 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, attrib_list); } - -static EGLSurface EGLAPIENTRY -eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, - void *native_window, - const EGLint *attrib_list) +static void * +fixupNativeWindow(_EGLDisplay *disp, void *native_window) { - _EGLDisplay *disp = _eglLockDisplay(dpy); - #ifdef HAVE_X11_PLATFORM if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) { /* The `native_window` parameter for the X11 platform differs between @@ -771,9 +774,20 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, * `Window*`. Convert `Window*` to `Window` because that's what * dri2_x11_create_window_surface() expects. */ - native_window = (void*) (* (Window*) native_window); + return (void *)(* (Window*) native_window); } #endif + return native_window; +} + +static EGLSurface EGLAPIENTRY +eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, + void *native_window, + const EGLint *attrib_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + + native_window = fixupNativeWindow(disp, native_window); return _eglCreateWindowSurfaceCommon(disp, config, native_window, attrib_list); @@ -785,18 +799,36 @@ eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list) { + _EGLDisplay *disp = _eglLockDisplay(dpy); EGLSurface surface; EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list); if (attrib_list && !int_attribs) RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE); - surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window, - int_attribs); + native_window = fixupNativeWindow(disp, native_window); + surface = _eglCreateWindowSurfaceCommon(disp, config, native_window, + int_attribs); free(int_attribs); return surface; } +static void * +fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap) +{ +#ifdef HAVE_X11_PLATFORM + /* The `native_pixmap` parameter for the X11 platform differs between + * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In + * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib + * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is + * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what + * dri2_x11_create_pixmap_surface() expects. + */ + if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) + return (void *)(* (Pixmap*) native_pixmap); +#endif + return native_pixmap; +} static EGLSurface _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, @@ -833,19 +865,7 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, { _EGLDisplay *disp = _eglLockDisplay(dpy); -#ifdef HAVE_X11_PLATFORM - /* The `native_pixmap` parameter for the X11 platform differs between - * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In - * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib - * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is - * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what - * dri2_x11_create_pixmap_surface() expects. - */ - if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) { - native_pixmap = (void*) (* (Pixmap*) native_pixmap); - } -#endif - + native_pixmap = fixupNativePixmap(disp, native_pixmap); return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap, attrib_list); } @@ -856,14 +876,16 @@ eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list) { + _EGLDisplay *disp = _eglLockDisplay(dpy); EGLSurface surface; EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list); if (attrib_list && !int_attribs) RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE); - surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, - int_attribs); + native_pixmap = fixupNativePixmap(disp, native_pixmap); + surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap, + int_attribs); free(int_attribs); return surface; } @@ -1059,8 +1081,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) } -EGLBoolean EGLAPIENTRY -eglWaitClient(void) +static EGLBoolean +_eglWaitClientCommon(void) { _EGLContext *ctx = _eglGetCurrentContext(); _EGLDisplay *disp; @@ -1086,22 +1108,17 @@ eglWaitClient(void) RETURN_EGL_EVAL(disp, ret); } +EGLBoolean EGLAPIENTRY +eglWaitClient(void) +{ + return _eglWaitClientCommon(); +} EGLBoolean EGLAPIENTRY eglWaitGL(void) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint api_index = t->CurrentAPIIndex; - EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); - EGLBoolean ret; - - if (api_index != es_index && _eglIsCurrentThreadDummy()) - RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); - - t->CurrentAPIIndex = es_index; - ret = eglWaitClient(); - t->CurrentAPIIndex = api_index; - return ret; + /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */ + return _eglWaitClientCommon(); } @@ -1198,13 +1215,6 @@ eglGetError(void) } -static EGLDisplay EGLAPIENTRY -eglGetDRMDisplayMESA(int fd) -{ - _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd); - return _eglGetDisplayHandle(dpy); -} - /** ** EGL 1.2 **/ @@ -1231,7 +1241,7 @@ eglBindAPI(EGLenum api) if (!_eglIsApiValid(api)) RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); - t->CurrentAPIIndex = _eglConvertApiToIndex(api); + t->CurrentAPI = api; RETURN_EGL_SUCCESS(NULL, EGL_TRUE); } @@ -1247,7 +1257,7 @@ eglQueryAPI(void) EGLenum ret; /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ - ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); + ret = t->CurrentAPI; RETURN_EGL_SUCCESS(NULL, ret); } @@ -1280,25 +1290,17 @@ eglReleaseThread(void) /* unbind current contexts */ if (!_eglIsCurrentThreadDummy()) { _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint api_index = t->CurrentAPIIndex; - EGLint i; - - for (i = 0; i < _EGL_API_NUM_APIS; i++) { - _EGLContext *ctx = t->CurrentContexts[i]; - if (ctx) { - _EGLDisplay *disp = ctx->Resource.Display; - _EGLDriver *drv; - t->CurrentAPIIndex = i; + _EGLContext *ctx = t->CurrentContext; + if (ctx) { + _EGLDisplay *disp = ctx->Resource.Display; + _EGLDriver *drv; - mtx_lock(&disp->Mutex); - drv = disp->Driver; - (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); - mtx_unlock(&disp->Mutex); - } + mtx_lock(&disp->Mutex); + drv = disp->Driver; + (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + mtx_unlock(&disp->Mutex); } - - t->CurrentAPIIndex = api_index; } _eglDestroyCurrentThread(); @@ -1307,11 +1309,10 @@ eglReleaseThread(void) } -static EGLImage EGLAPIENTRY -eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, +static EGLImage +_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { - _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *context = _eglLookupContext(ctx, disp); _EGLDriver *drv; _EGLImage *img; @@ -1335,18 +1336,27 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, RETURN_EGL_EVAL(disp, ret); } +static EGLImage EGLAPIENTRY +eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list); +} + EGLImage EGLAPIENTRY eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attr_list) { + _EGLDisplay *disp = _eglLockDisplay(dpy); EGLImage image; EGLint *int_attribs = _eglConvertAttribsToInt(attr_list); if (attr_list && !int_attribs) - RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE); + RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE); - image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs); + image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs); free(int_attribs); return image; } @@ -1374,11 +1384,10 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image) static EGLSync -_eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, +_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLint *attrib_list, const EGLAttrib *attrib_list64, EGLBoolean is64, EGLenum invalid_type_error) { - _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *ctx = _eglGetCurrentContext(); _EGLDriver *drv; _EGLSync *sync; @@ -1390,7 +1399,7 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR); /* return an error if the client API doesn't support GL_OES_EGL_sync */ - if (!ctx || ctx->Resource.Display != dpy || + if (!ctx || ctx->Resource.Display != disp || ctx->ClientAPI != EGL_OPENGL_ES_API) RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); @@ -1421,7 +1430,8 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, static EGLSync EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) { - return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE, + _EGLDisplay *disp = _eglLockDisplay(dpy); + return _eglCreateSync(disp, type, attrib_list, NULL, EGL_FALSE, EGL_BAD_ATTRIBUTE); } @@ -1429,7 +1439,8 @@ eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) static EGLSync EGLAPIENTRY eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) { - return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE, + _EGLDisplay *disp = _eglLockDisplay(dpy); + return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE, EGL_BAD_ATTRIBUTE); } @@ -1437,7 +1448,8 @@ eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) EGLSync EGLAPIENTRY eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) { - return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE, + _EGLDisplay *disp = _eglLockDisplay(dpy); + return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE, EGL_BAD_PARAMETER); } @@ -1476,17 +1488,30 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) if (s->SyncStatus == EGL_SIGNALED_KHR) RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR); + /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be + * unlocked here to allow other threads also to be able to + * go into waiting state. + */ + + if (s->Type == EGL_SYNC_REUSABLE_KHR) + _eglUnlockDisplay(dpy); + ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout); - RETURN_EGL_EVAL(disp, ret); + /* + * 'disp' is already unlocked for reusable sync type, + * so passing 'NULL' to bypass unlocking display. + */ + if (s->Type == EGL_SYNC_REUSABLE_KHR) + RETURN_EGL_EVAL(NULL, ret); + else + RETURN_EGL_EVAL(disp, ret); } -static EGLint EGLAPIENTRY -eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags) +static EGLint +_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags) { - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); _EGLContext *ctx = _eglGetCurrentContext(); _EGLDriver *drv; EGLint ret; @@ -1507,6 +1532,14 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags) RETURN_EGL_EVAL(disp, ret); } +static EGLint EGLAPIENTRY +eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + return _eglWaitSyncCommon(disp, s, flags); +} + EGLBoolean EGLAPIENTRY eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) @@ -1515,7 +1548,9 @@ eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) * EGLBoolean. In both cases, the return values can only be EGL_FALSE and * EGL_TRUE. */ - return eglWaitSyncKHR(dpy, sync, flags); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + return _eglWaitSyncCommon(disp, s, flags); } @@ -1535,11 +1570,9 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode) } -EGLBoolean EGLAPIENTRY -eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) +static EGLBoolean +_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value) { - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); _EGLDriver *drv; EGLBoolean ret; @@ -1551,12 +1584,28 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *valu RETURN_EGL_EVAL(disp, ret); } +EGLBoolean EGLAPIENTRY +eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + return _eglGetSyncAttribCommon(disp, s, attribute, value); +} + static EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value) { - EGLAttrib attrib = *value; - EGLBoolean result = eglGetSyncAttrib(dpy, sync, attribute, &attrib); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + EGLAttrib attrib; + EGLBoolean result; + + if (!value) + RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); + + attrib = *value; + result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib); /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR: * @@ -1852,7 +1901,6 @@ eglGetProcAddress(const char *procname) { "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay }, { "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface }, { "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface }, - { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage }, { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, @@ -1899,3 +1947,74 @@ eglGetProcAddress(const char *procname) RETURN_EGL_SUCCESS(NULL, ret); } + +static int +_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context, + _EGLDisplay **disp, _EGLDriver **drv, + _EGLContext **ctx) +{ + + *disp = _eglLockDisplay(dpy); + if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) { + if (*disp) + _eglUnlockDisplay(*disp); + return MESA_GLINTEROP_INVALID_DISPLAY; + } + + *drv = (*disp)->Driver; + + *ctx = _eglLookupContext(context, *disp); + if (!*ctx || + ((*ctx)->ClientAPI != EGL_OPENGL_API && + (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) { + _eglUnlockDisplay(*disp); + return MESA_GLINTEROP_INVALID_CONTEXT; + } + + return MESA_GLINTEROP_SUCCESS; +} + +int +MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context, + struct mesa_glinterop_device_info *out) +{ + _EGLDisplay *disp; + _EGLDriver *drv; + _EGLContext *ctx; + int ret; + + ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx); + if (ret != MESA_GLINTEROP_SUCCESS) + return ret; + + if (drv->API.GLInteropQueryDeviceInfo) + ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out); + else + ret = MESA_GLINTEROP_UNSUPPORTED; + + _eglUnlockDisplay(disp); + return ret; +} + +int +MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context, + struct mesa_glinterop_export_in *in, + struct mesa_glinterop_export_out *out) +{ + _EGLDisplay *disp; + _EGLDriver *drv; + _EGLContext *ctx; + int ret; + + ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx); + if (ret != MESA_GLINTEROP_SUCCESS) + return ret; + + if (drv->API.GLInteropExportObject) + ret = drv->API.GLInteropExportObject(disp, ctx, in, out); + else + ret = MESA_GLINTEROP_UNSUPPORTED; + + _eglUnlockDisplay(disp); + return ret; +}