X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fegl%2Fmain%2Feglapi.c;h=df355a50424a3b376a03d60b51bb0015d3c869b3;hb=017946b7247ea7c36219b44dfc118ccad4da7d1d;hp=e4d098c1eaaeb2bc491935f31fcf64d933f96a99;hpb=ffc94e32a38b3948fe4ae2717a3f55802eb8aae8;p=mesa.git diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index e4d098c1eaa..df355a50424 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" @@ -100,7 +101,6 @@ #include "eglconfig.h" #include "eglimage.h" #include "eglsync.h" -#include "eglstring.h" /** @@ -251,6 +251,31 @@ _eglUnlockDisplay(_EGLDisplay *dpy) } +static EGLint * +_eglConvertAttribsToInt(const EGLAttrib *attr_list) +{ + EGLint *int_attribs = NULL; + + /* Convert attributes from EGLAttrib[] to EGLint[] */ + if (attr_list) { + int i, size = 0; + + while (attr_list[size] != EGL_NONE) + size += 2; + + size += 1; /* add space for EGL_NONE */ + + int_attribs = calloc(size, sizeof(int_attribs[0])); + if (!int_attribs) + return NULL; + + for (i = 0; i < size; i++) + int_attribs[i] = attr_list[i]; + } + return int_attribs; +} + + /** * This is typically the first EGL function that an application calls. * It associates a private _EGLDisplay object to the native display. @@ -270,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; @@ -301,6 +326,29 @@ 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; + + int_attribs = _eglConvertAttribsToInt(attrib_list); + if (attrib_list && !int_attribs) + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL); + + display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs); + free(int_attribs); + return display; +} + /** * Copy the extension into the string and update the string pointer. */ @@ -341,49 +389,49 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) char *exts = dpy->ExtensionsString; - _EGL_CHECK_EXTENSION(MESA_copy_context); - _EGL_CHECK_EXTENSION(MESA_drm_display); - _EGL_CHECK_EXTENSION(MESA_drm_image); - _EGL_CHECK_EXTENSION(MESA_configless_context); + /* 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(WL_bind_wayland_display); - _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image); + _EGL_CHECK_EXTENSION(CHROMIUM_sync_control); - _EGL_CHECK_EXTENSION(KHR_image_base); - _EGL_CHECK_EXTENSION(KHR_image_pixmap); - if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap) - _eglAppendExtension(&exts, "EGL_KHR_image"); + _EGL_CHECK_EXTENSION(EXT_buffer_age); + _EGL_CHECK_EXTENSION(EXT_create_context_robustness); + _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import); + _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage); - _EGL_CHECK_EXTENSION(KHR_vg_parent_image); + _EGL_CHECK_EXTENSION(KHR_cl_event2); + _EGL_CHECK_EXTENSION(KHR_create_context); + _EGL_CHECK_EXTENSION(KHR_fence_sync); _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses); + _EGL_CHECK_EXTENSION(KHR_gl_colorspace); + _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image); - _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image); _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image); - _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); - + _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image); + if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap) + _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_fence_sync); + _EGL_CHECK_EXTENSION(KHR_surfaceless_context); _EGL_CHECK_EXTENSION(KHR_wait_sync); - _EGL_CHECK_EXTENSION(KHR_cl_event2); - _EGL_CHECK_EXTENSION(KHR_surfaceless_context); - _EGL_CHECK_EXTENSION(KHR_create_context); + 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); _EGL_CHECK_EXTENSION(NOK_swap_region); _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap); - _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer); - - _EGL_CHECK_EXTENSION(CHROMIUM_sync_control); - - _EGL_CHECK_EXTENSION(EXT_create_context_robustness); - _EGL_CHECK_EXTENSION(EXT_buffer_age); - _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage); - _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import); - _EGL_CHECK_EXTENSION(NV_post_sub_buffer); - _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export); + _EGL_CHECK_EXTENSION(WL_bind_wayland_display); + _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image); + #undef _EGL_CHECK_EXTENSION } @@ -393,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 "); @@ -408,6 +453,26 @@ _eglCreateAPIsString(_EGLDisplay *dpy) assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString)); } +static void +_eglComputeVersion(_EGLDisplay *disp) +{ + disp->Version = 14; + + if (disp->Extensions.KHR_fence_sync && + disp->Extensions.KHR_cl_event2 && + disp->Extensions.KHR_wait_sync && + disp->Extensions.KHR_image_base && + disp->Extensions.KHR_gl_texture_2D_image && + disp->Extensions.KHR_gl_texture_3D_image && + disp->Extensions.KHR_gl_texture_cubemap_image && + disp->Extensions.KHR_gl_renderbuffer_image && + disp->Extensions.KHR_create_context && + disp->Extensions.EXT_create_context_robustness && + disp->Extensions.KHR_get_all_proc_addresses && + disp->Extensions.KHR_gl_colorspace && + disp->Extensions.KHR_surfaceless_context) + disp->Version = 15; +} /** * This is typically the second EGL function that an application calls. @@ -445,17 +510,18 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) */ disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE; + _eglComputeVersion(disp); _eglCreateExtensionsString(disp); _eglCreateAPIsString(disp); - _eglsnprintf(disp->VersionString, sizeof(disp->VersionString), - "%d.%d (%s)", disp->VersionMajor, disp->VersionMinor, + snprintf(disp->VersionString, sizeof(disp->VersionString), + "%d.%d (%s)", disp->Version / 10, disp->Version % 10, disp->Driver->Name); } /* Update applications version of major and minor if not NULL */ if ((major != NULL) && (minor != NULL)) { - *major = disp->VersionMajor; - *minor = disp->VersionMinor; + *major = disp->Version / 10; + *minor = disp->Version % 10; } RETURN_EGL_SUCCESS(disp, EGL_TRUE); @@ -571,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) @@ -722,6 +788,24 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, } +EGLSurface EGLAPIENTRY +eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, + void *native_window, + const EGLAttrib *attrib_list) +{ + 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); + free(int_attribs); + return surface; +} + + static EGLSurface _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, void *native_pixmap, const EGLint *attrib_list) @@ -775,6 +859,24 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, } +EGLSurface EGLAPIENTRY +eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, + void *native_pixmap, + const EGLAttrib *attrib_list) +{ + 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); + free(int_attribs); + return surface; +} + + EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) @@ -919,8 +1021,6 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) } -#ifdef EGL_EXT_swap_buffers_with_damage - static EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects) @@ -946,8 +1046,6 @@ eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, RETURN_EGL_EVAL(disp, ret); } -#endif /* EGL_EXT_swap_buffers_with_damage */ - EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { @@ -1000,18 +1098,8 @@ eglWaitClient(void) 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 eglWaitClient(); } @@ -1108,17 +1196,6 @@ eglGetError(void) } -#ifdef EGL_MESA_drm_display - -static EGLDisplay EGLAPIENTRY -eglGetDRMDisplayMESA(int fd) -{ - _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd); - return _eglGetDisplayHandle(dpy); -} - -#endif /* EGL_MESA_drm_display */ - /** ** EGL 1.2 **/ @@ -1145,7 +1222,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); } @@ -1161,7 +1238,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); } @@ -1194,25 +1271,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(); @@ -1221,7 +1290,7 @@ eglReleaseThread(void) } -static EGLImageKHR EGLAPIENTRY +static EGLImage EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { @@ -1229,7 +1298,7 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, _EGLContext *context = _eglLookupContext(ctx, disp); _EGLDriver *drv; _EGLImage *img; - EGLImageKHR ret; + EGLImage ret; _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); if (!disp->Extensions.KHR_image_base) @@ -1250,8 +1319,24 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, } -static EGLBoolean EGLAPIENTRY -eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +EGLImage EGLAPIENTRY +eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLAttrib *attr_list) +{ + EGLImage image; + EGLint *int_attribs = _eglConvertAttribsToInt(attr_list); + + if (attr_list && !int_attribs) + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE); + + image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs); + free(int_attribs); + return image; +} + + +EGLBoolean EGLAPIENTRY +eglDestroyImage(EGLDisplay dpy, EGLImage image) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img = _eglLookupImage(image, disp); @@ -1271,15 +1356,16 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) } -static EGLSyncKHR +static EGLSync _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, - const EGLAttribKHR *attrib_list64, EGLBoolean is64) + const EGLAttrib *attrib_list64, EGLBoolean is64, + EGLenum invalid_type_error) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *ctx = _eglGetCurrentContext(); _EGLDriver *drv; _EGLSync *sync; - EGLSyncKHR ret; + EGLSync ret; _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); @@ -1294,18 +1380,18 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, switch (type) { case EGL_SYNC_FENCE_KHR: if (!disp->Extensions.KHR_fence_sync) - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; case EGL_SYNC_REUSABLE_KHR: if (!disp->Extensions.KHR_reusable_sync) - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; case EGL_SYNC_CL_EVENT_KHR: if (!disp->Extensions.KHR_cl_event2) - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; default: - RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); } sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64); @@ -1315,22 +1401,32 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, } -static EGLSyncKHR EGLAPIENTRY +static EGLSync EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) { - return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE); + return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE, + EGL_BAD_ATTRIBUTE); } -static EGLSyncKHR EGLAPIENTRY -eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list) +static EGLSync EGLAPIENTRY +eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) { - return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE); + return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE, + EGL_BAD_ATTRIBUTE); } -static EGLBoolean EGLAPIENTRY -eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +EGLSync EGLAPIENTRY +eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) +{ + return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE, + EGL_BAD_PARAMETER); +} + + +EGLBoolean EGLAPIENTRY +eglDestroySync(EGLDisplay dpy, EGLSync sync) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1348,8 +1444,8 @@ eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) } -static EGLint EGLAPIENTRY -eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +EGLint EGLAPIENTRY +eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1363,14 +1459,29 @@ eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR t 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, EGLSyncKHR sync, EGLint flags) +eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1395,8 +1506,19 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) } +EGLBoolean EGLAPIENTRY +eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) +{ + /* The KHR version returns EGLint, while the core version returns + * EGLBoolean. In both cases, the return values can only be EGL_FALSE and + * EGL_TRUE. + */ + return eglWaitSyncKHR(dpy, sync, flags); +} + + static EGLBoolean EGLAPIENTRY -eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) +eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1411,8 +1533,8 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) } -static EGLBoolean EGLAPIENTRY -eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +EGLBoolean EGLAPIENTRY +eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); @@ -1422,13 +1544,35 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *v _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || disp->Extensions.KHR_fence_sync); - ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); + ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value); RETURN_EGL_EVAL(disp, ret); } -#ifdef EGL_NOK_swap_region +static EGLBoolean EGLAPIENTRY +eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value) +{ + EGLAttrib attrib; + EGLBoolean result; + + if (!value) + RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); + + attrib = *value; + result = eglGetSyncAttrib(dpy, sync, attribute, &attrib); + + /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR: + * + * If any error occurs, <*value> is not modified. + */ + if (result == EGL_FALSE) + return result; + + *value = attrib; + return result; +} + static EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, @@ -1455,18 +1599,14 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, RETURN_EGL_EVAL(disp, ret); } -#endif /* EGL_NOK_swap_region */ - -#ifdef EGL_MESA_drm_image - -static EGLImageKHR EGLAPIENTRY +static EGLImage EGLAPIENTRY eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLDriver *drv; _EGLImage *img; - EGLImageKHR ret; + EGLImage ret; _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); if (!disp->Extensions.MESA_drm_image) @@ -1479,7 +1619,7 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) } static EGLBoolean EGLAPIENTRY -eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, +eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image, EGLint *name, EGLint *handle, EGLint *stride) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1498,9 +1638,7 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, RETURN_EGL_EVAL(disp, ret); } -#endif -#ifdef EGL_WL_bind_wayland_display struct wl_display; static EGLBoolean EGLAPIENTRY @@ -1557,11 +1695,10 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, RETURN_EGL_EVAL(disp, ret); } -#endif -#ifdef EGL_WL_create_wayland_buffer_from_image + static struct wl_buffer * EGLAPIENTRY -eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image) +eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img; @@ -1580,7 +1717,6 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image) RETURN_EGL_EVAL(disp, ret); } -#endif static EGLBoolean EGLAPIENTRY eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, @@ -1623,9 +1759,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface, RETURN_EGL_EVAL(disp, ret); } -#ifdef EGL_MESA_image_dma_buf_export static EGLBoolean EGLAPIENTRY -eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image, +eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image, EGLint *fourcc, EGLint *nplanes, EGLuint64KHR *modifiers) { @@ -1647,7 +1782,7 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image, } static EGLBoolean EGLAPIENTRY -eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image, +eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image, int *fds, EGLint *strides, EGLint *offsets) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1665,7 +1800,6 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image, RETURN_EGL_EVAL(disp, ret); } -#endif __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) @@ -1674,8 +1808,9 @@ eglGetProcAddress(const char *procname) const char *name; _EGLProc function; } egl_functions[] = { - /* core functions should not be queryable, but, well... */ -#ifdef _EGL_GET_CORE_ADDRESSES + /* core functions queryable in the presence of + * EGL_KHR_get_all_proc_addresses or EGL 1.5 + */ /* alphabetical order */ { "eglBindAPI", (_EGLProc) eglBindAPI }, { "eglBindTexImage", (_EGLProc) eglBindTexImage }, @@ -1711,46 +1846,40 @@ eglGetProcAddress(const char *procname) { "eglWaitClient", (_EGLProc) eglWaitClient }, { "eglWaitGL", (_EGLProc) eglWaitGL }, { "eglWaitNative", (_EGLProc) eglWaitNative }, -#endif /* _EGL_GET_CORE_ADDRESSES */ -#ifdef EGL_MESA_drm_display - { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, -#endif + { "eglCreateSync", (_EGLProc) eglCreateSync }, + { "eglDestroySync", (_EGLProc) eglDestroySync }, + { "eglClientWaitSync", (_EGLProc) eglClientWaitSync }, + { "eglGetSyncAttrib", (_EGLProc) eglGetSyncAttrib }, + { "eglWaitSync", (_EGLProc) eglWaitSync }, + { "eglCreateImage", (_EGLProc) eglCreateImage }, + { "eglDestroyImage", (_EGLProc) eglDestroyImage }, + { "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay }, + { "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface }, + { "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface }, { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, - { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, + { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage }, { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR }, - { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR }, - { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR }, + { "eglDestroySyncKHR", (_EGLProc) eglDestroySync }, + { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync }, { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR }, { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR }, { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR }, -#ifdef EGL_NOK_swap_region { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, -#endif -#ifdef EGL_MESA_drm_image { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, -#endif -#ifdef EGL_WL_bind_wayland_display { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, -#endif -#ifdef EGL_WL_create_wayland_buffer_from_image { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL }, -#endif { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, -#ifdef EGL_EXT_swap_buffers_with_damage { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT }, -#endif { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT }, { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT }, { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT }, { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, -#ifdef EGL_MESA_image_dma_buf_export { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA }, { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA }, -#endif { NULL, NULL } }; EGLint i; @@ -1773,3 +1902,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; +}