X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglapi.c;h=9a59d9e0c3571f937f1311cb079f5a749a08e90d;hb=caf7fb627dae6b49830a11b85952815e0fd096db;hp=cab05c2301a9c933f26a8ba42065de3abbf351bf;hpb=fbb4af96c6b6be08ed93e8d5a704b9f7002642f8;p=mesa.git diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index cab05c2301a..9a59d9e0c35 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -88,8 +88,7 @@ #include #include "c99_compat.h" #include "c11/threads.h" -#include "GL/mesa_glinterop.h" -#include "eglcompiler.h" +#include "util/macros.h" #include "eglglobals.h" #include "eglcontext.h" @@ -102,6 +101,7 @@ #include "eglimage.h" #include "eglsync.h" +#include "GL/mesa_glinterop.h" /** * Macros to help return an API entrypoint. @@ -157,6 +157,12 @@ _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) +struct _egl_entrypoint { + const char *name; + _EGLProc function; +}; + + static inline _EGLDriver * _eglCheckDisplay(_EGLDisplay *disp, const char *msg) { @@ -268,8 +274,7 @@ _eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EG return EGL_TRUE; } - _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName, - EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL); + _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL); return EGL_FALSE; } @@ -371,7 +376,7 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay) static EGLDisplay _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display, - const EGLint *attrib_list) + const EGLint *attrib_list) { _EGLDisplay *dpy; @@ -482,11 +487,13 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) _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_image_dma_buf_import_modifiers); _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage); _EGL_CHECK_EXTENSION(KHR_cl_event2); _EGL_CHECK_EXTENSION(KHR_config_attribs); _EGL_CHECK_EXTENSION(KHR_create_context); + _EGL_CHECK_EXTENSION(KHR_create_context_no_error); _EGL_CHECK_EXTENSION(KHR_fence_sync); _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses); _EGL_CHECK_EXTENSION(KHR_gl_colorspace); @@ -499,6 +506,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) _EGL_CHECK_EXTENSION(KHR_image_base); _EGL_CHECK_EXTENSION(KHR_image_pixmap); _EGL_CHECK_EXTENSION(KHR_no_config_context); + _EGL_CHECK_EXTENSION(KHR_partial_update); _EGL_CHECK_EXTENSION(KHR_reusable_sync); _EGL_CHECK_EXTENSION(KHR_surfaceless_context); if (dpy->Extensions.EXT_swap_buffers_with_damage) @@ -607,8 +615,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) _eglCreateExtensionsString(disp); _eglCreateAPIsString(disp); snprintf(disp->VersionString, sizeof(disp->VersionString), - "%d.%d (%s)", disp->Version / 10, disp->Version % 10, - disp->Driver->Name); + "%d.%d (%s)", disp->Version / 10, disp->Version % 10, + disp->Driver->Name); } /* Update applications version of major and minor if not NULL */ @@ -651,7 +659,11 @@ eglQueryString(EGLDisplay dpy, EGLint name) _EGLDriver *drv; if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) { - RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString); + const char *ret = _eglGetClientExtensionString(); + if (ret != NULL) + RETURN_EGL_SUCCESS(NULL, ret); + else + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL); } disp = _eglLockDisplay(dpy); @@ -702,7 +714,7 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, - config_size, num_config); + config_size, num_config); RETURN_EGL_EVAL(disp, ret); } @@ -818,6 +830,14 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); } + /* If a native window underlying either draw or read is no longer valid, + * an EGL_BAD_NATIVE_WINDOW error is generated. + */ + if (draw_surf && draw_surf->Lost) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); + if (read_surf && read_surf->Lost) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); + ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); RETURN_EGL_EVAL(disp, ret); @@ -902,7 +922,7 @@ static void * _fixupNativeWindow(_EGLDisplay *disp, void *native_window) { #ifdef HAVE_X11_PLATFORM - if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) { + if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) { /* The `native_window` parameter for the X11 platform differs between * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In * eglCreateWindowSurface(), the type of `native_window` is an Xlib @@ -957,14 +977,14 @@ 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) + /* 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 && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) return (void *)(* (Pixmap*) native_pixmap); #endif return native_pixmap; @@ -1000,6 +1020,9 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0) RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); + if (native_pixmap == NULL) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); + surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap, attrib_list); ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; @@ -1017,13 +1040,13 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); STATIC_ASSERT(sizeof(void*) == sizeof(pixmap)); return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap, - attrib_list); + attrib_list); } static EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, - void *native_pixmap, - const EGLint *attrib_list) + void *native_pixmap, + const EGLint *attrib_list) { _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1180,7 +1203,17 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval) if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE) RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - ret = drv->API.SwapInterval(drv, disp, surf, interval); + interval = CLAMP(interval, + surf->Config->MinSwapInterval, + surf->Config->MaxSwapInterval); + + if (surf->SwapInterval != interval) + ret = drv->API.SwapInterval(drv, disp, surf, interval); + else + ret = EGL_TRUE; + + if (ret) + surf->SwapInterval = interval; RETURN_EGL_EVAL(disp, ret); } @@ -1205,8 +1238,26 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); #endif + /* From the EGL 1.5 spec: + * + * If eglSwapBuffers is called and the native window associated with + * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is + * generated. + */ + if (surf->Lost) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); + ret = drv->API.SwapBuffers(drv, disp, surf); + /* EGL_KHR_partial_update + * Frame boundary successfully reached, + * reset damage region and reset BufferAgeRead + */ + if (ret) { + surf->SetDamageRegionCalled = EGL_FALSE; + surf->BufferAgeRead = EGL_FALSE; + } + RETURN_EGL_EVAL(disp, ret); } @@ -1231,6 +1282,15 @@ _eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf, ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects); + /* EGL_KHR_partial_update + * Frame boundary successfully reached, + * reset damage region and reset BufferAgeRead + */ + if (ret) { + surf->SetDamageRegionCalled = EGL_FALSE; + surf->BufferAgeRead = EGL_FALSE; + } + RETURN_EGL_EVAL(disp, ret); } @@ -1254,6 +1314,70 @@ eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects); } +/** + * If the width of the passed rect is greater than the surface's + * width then it is clamped to the width of the surface. Same with + * height. + */ + +static void +_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf, + EGLint *rects, EGLint n_rects) +{ + EGLint i; + EGLint surf_height = surf->Height; + EGLint surf_width = surf->Width; + + for (i = 0; i < (4 * n_rects); i += 4) { + EGLint x, y, rect_width, rect_height; + x = rects[i]; + y = rects[i + 1]; + rect_width = rects[i + 2]; + rect_height = rects[i + 3]; + + if (rect_width > surf_width - x) + rects[i + 2] = surf_width - x; + + if (rect_height > surf_height - y) + rects[i + 3] = surf_height - y; + } +} + +static EGLBoolean EGLAPIENTRY +eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, + EGLint *rects, EGLint n_rects) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); + _EGLContext *ctx = _eglGetCurrentContext(); + _EGLDriver *drv; + EGLBoolean ret; + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + + if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || + surf->Type != EGL_WINDOW_BIT || + ctx->DrawSurface != surf || + surf->SwapBehavior != EGL_BUFFER_DESTROYED) + RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); + + /* If the damage region is already set or + * buffer age is not queried between + * frame boundaries, throw bad access error + */ + + if (surf->SetDamageRegionCalled || !surf->BufferAgeRead) + RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE); + + _eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects); + ret = drv->API.SetDamageRegion(drv, disp, surf, rects, n_rects); + + if (ret) + surf->SetDamageRegionCalled = EGL_TRUE; + + RETURN_EGL_EVAL(disp, ret); +} + EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { @@ -1519,7 +1643,7 @@ eglReleaseThread(void) static EGLImage _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target, - EGLClientBuffer buffer, const EGLint *attr_list) + EGLClientBuffer buffer, const EGLint *attr_list) { _EGLContext *context = _eglLookupContext(ctx, disp); _EGLDriver *drv; @@ -1537,8 +1661,8 @@ _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target, if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT) RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - img = drv->API.CreateImageKHR(drv, - disp, context, target, buffer, attr_list); + img = drv->API.CreateImageKHR(drv, disp, context, target, + buffer, attr_list); ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; RETURN_EGL_EVAL(disp, ret); @@ -1574,16 +1698,12 @@ eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, } -EGLBoolean EGLAPIENTRY -eglDestroyImage(EGLDisplay dpy, EGLImage image) +static EGLBoolean +_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img) { - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLImage *img = _eglLookupImage(image, disp); _EGLDriver *drv; EGLBoolean ret; - _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); if (!disp->Extensions.KHR_image_base) RETURN_EGL_EVAL(disp, EGL_FALSE); @@ -1596,6 +1716,24 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image) RETURN_EGL_EVAL(disp, ret); } +EGLBoolean EGLAPIENTRY +eglDestroyImage(EGLDisplay dpy, EGLImage image) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLImage *img = _eglLookupImage(image, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); + return _eglDestroyImageCommon(disp, img); +} + +static EGLBoolean EGLAPIENTRY +eglDestroyImageKHR(EGLDisplay dpy, EGLImage image) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLImage *img = _eglLookupImage(image, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); + return _eglDestroyImageCommon(disp, img); +} + static EGLSync _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list, @@ -1632,7 +1770,7 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list, /* return an error if the client API doesn't support GL_OES_EGL_sync */ if (ctx && (ctx->Resource.Display != disp || - ctx->ClientAPI != EGL_OPENGL_ES_API)) + ctx->ClientAPI != EGL_OPENGL_ES_API)) RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); switch (type) { @@ -1712,16 +1850,12 @@ eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) } -EGLBoolean EGLAPIENTRY -eglDestroySync(EGLDisplay dpy, EGLSync sync) +static EGLBoolean +_eglDestroySync(_EGLDisplay *disp, _EGLSync *s) { - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); _EGLDriver *drv; EGLBoolean ret; - _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); - _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || disp->Extensions.KHR_fence_sync || @@ -1733,17 +1867,32 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync) RETURN_EGL_EVAL(disp, ret); } +EGLBoolean EGLAPIENTRY +eglDestroySync(EGLDisplay dpy, EGLSync sync) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); + return _eglDestroySync(disp, s); +} -EGLint EGLAPIENTRY -eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) +static EGLBoolean EGLAPIENTRY +eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLSync *s = _eglLookupSync(sync, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); + return _eglDestroySync(disp, s); +} + + +static EGLint +_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy, + _EGLSync *s, EGLint flags, EGLTime timeout) +{ _EGLDriver *drv; EGLint ret; - _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); - _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || disp->Extensions.KHR_fence_sync || @@ -1772,6 +1921,26 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) RETURN_EGL_EVAL(disp, ret); } +EGLint EGLAPIENTRY +eglClientWaitSync(EGLDisplay dpy, EGLSync sync, + EGLint flags, EGLTime timeout) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); + return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout); +} + +static EGLint EGLAPIENTRY +eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync, + EGLint flags, EGLTime timeout) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); + return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout); +} + static EGLint _eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags) @@ -1916,7 +2085,7 @@ eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) static EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, - EGLint numRects, const EGLint *rects) + EGLint numRects, const EGLint *rects) { _EGLContext *ctx = _eglGetCurrentContext(); _EGLDisplay *disp = _eglLockDisplay(dpy); @@ -1964,7 +2133,7 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) static EGLBoolean EGLAPIENTRY eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image, - EGLint *name, EGLint *handle, EGLint *stride) + EGLint *name, EGLint *handle, EGLint *stride) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img = _eglLookupImage(image, disp); @@ -2060,7 +2229,8 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image) _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); _EGL_CHECK_DISPLAY(disp, NULL, drv); - assert(disp->Extensions.WL_create_wayland_buffer_from_image); + if (!disp->Extensions.WL_create_wayland_buffer_from_image) + RETURN_EGL_EVAL(disp, NULL); img = _eglLookupImage(image, disp); @@ -2165,7 +2335,7 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image, static EGLint EGLAPIENTRY eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object, - EGLLabelKHR label) + EGLLabelKHR label) { _EGLDisplay *disp = NULL; _EGLResourceType type; @@ -2232,7 +2402,7 @@ _validDebugMessageLevel(EGLAttrib level) static EGLint EGLAPIENTRY eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, - const EGLAttrib *attrib_list) + const EGLAttrib *attrib_list) { unsigned int newEnabled; @@ -2257,7 +2427,7 @@ eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, // debug callback, and return the error code. mtx_unlock(_eglGlobal.Mutex); _eglReportError(EGL_BAD_ATTRIBUTE, NULL, - "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]); + "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]); return EGL_BAD_ATTRIBUTE; } } @@ -2297,7 +2467,7 @@ eglQueryDebugKHR(EGLint attribute, EGLAttrib *value) mtx_unlock(_eglGlobal.Mutex); _eglReportError(EGL_BAD_ATTRIBUTE, NULL, - "Invalid attribute 0x%04lx", (unsigned long) attribute); + "Invalid attribute 0x%04lx", (unsigned long) attribute); return EGL_FALSE; } while (0); @@ -2305,109 +2475,77 @@ eglQueryDebugKHR(EGLint attribute, EGLAttrib *value) return EGL_TRUE; } +static int +_eglFunctionCompare(const void *key, const void *elem) +{ + const char *procname = key; + const struct _egl_entrypoint *entrypoint = elem; + return strcmp(procname, entrypoint->name); +} + +static EGLBoolean EGLAPIENTRY +eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats, + EGLint *formats, EGLint *num_formats) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + + ret = drv->API.QueryDmaBufFormatsEXT(drv, disp, max_formats, formats, + num_formats); + + RETURN_EGL_EVAL(disp, ret); +} + +static EGLBoolean EGLAPIENTRY +eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers, + EGLuint64KHR *modifiers, EGLBoolean *external_only, + EGLint *num_modifiers) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + + ret = drv->API.QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers, + modifiers, external_only, + num_modifiers); + + RETURN_EGL_EVAL(disp, ret); +} + __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) { - static const struct { - const char *name; - _EGLProc function; - } egl_functions[] = { - /* 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 }, - { "eglChooseConfig", (_EGLProc) eglChooseConfig }, - { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, - { "eglCreateContext", (_EGLProc) eglCreateContext }, - { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, - { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, - { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, - { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, - { "eglDestroyContext", (_EGLProc) eglDestroyContext }, - { "eglDestroySurface", (_EGLProc) eglDestroySurface }, - { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, - { "eglGetConfigs", (_EGLProc) eglGetConfigs }, - { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, - { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, - { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, - { "eglGetDisplay", (_EGLProc) eglGetDisplay }, - { "eglGetError", (_EGLProc) eglGetError }, - { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, - { "eglInitialize", (_EGLProc) eglInitialize }, - { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, - { "eglQueryAPI", (_EGLProc) eglQueryAPI }, - { "eglQueryContext", (_EGLProc) eglQueryContext }, - { "eglQueryString", (_EGLProc) eglQueryString }, - { "eglQuerySurface", (_EGLProc) eglQuerySurface }, - { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, - { "eglReleaseThread", (_EGLProc) eglReleaseThread }, - { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, - { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, - { "eglSwapInterval", (_EGLProc) eglSwapInterval }, - { "eglTerminate", (_EGLProc) eglTerminate }, - { "eglWaitClient", (_EGLProc) eglWaitClient }, - { "eglWaitGL", (_EGLProc) eglWaitGL }, - { "eglWaitNative", (_EGLProc) eglWaitNative }, - { "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) eglDestroyImage }, - { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, - { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR }, - { "eglDestroySyncKHR", (_EGLProc) eglDestroySync }, - { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync }, - { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR }, - { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR }, - { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR }, - { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, - { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, - { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, - { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, - { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, - { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, - { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL }, - { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, - { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT }, - { "eglSwapBuffersWithDamageKHR", (_EGLProc) eglSwapBuffersWithDamageKHR }, - { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT }, - { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT }, - { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT }, - { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, - { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA }, - { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA }, - { "eglLabelObjectKHR", (_EGLProc) eglLabelObjectKHR }, - { "eglDebugMessageControlKHR", (_EGLProc) eglDebugMessageControlKHR }, - { "eglQueryDebugKHR", (_EGLProc) eglQueryDebugKHR }, - { "eglDupNativeFenceFDANDROID", (_EGLProc) eglDupNativeFenceFDANDROID }, - { NULL, NULL } + static const struct _egl_entrypoint egl_functions[] = { +#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f }, +#include "eglentrypoint.h" +#undef EGL_ENTRYPOINT }; - EGLint i; - _EGLProc ret; + _EGLProc ret = NULL; if (!procname) RETURN_EGL_SUCCESS(NULL, NULL); _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL); - ret = NULL; if (strncmp(procname, "egl", 3) == 0) { - for (i = 0; egl_functions[i].name; i++) { - if (strcmp(egl_functions[i].name, procname) == 0) { - ret = egl_functions[i].function; - break; - } - } + const struct _egl_entrypoint *entrypoint = + bsearch(procname, + egl_functions, ARRAY_SIZE(egl_functions), + sizeof(egl_functions[0]), + _eglFunctionCompare); + if (entrypoint) + ret = entrypoint->function; } + if (!ret) ret = _eglGetDriverProc(procname);