#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"
_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)
{
* Return an EGL error code. The output parameter out_attrib_list is modified
* only on success.
*/
-EGLint
+static EGLint
_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
{
size_t len = 0;
_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);
_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)
*/
disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
+ /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
+ * programs. It is driver agnostic and handled in the main EGL code.
+ */
+ disp->Extensions.KHR_config_attribs = EGL_TRUE;
+
_eglComputeVersion(disp);
_eglCreateExtensionsString(disp);
_eglCreateAPIsString(disp);
_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);
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);
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
#ifdef HAVE_SURFACELESS_PLATFORM
- if (disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
/* From the EGL_MESA_platform_surfaceless spec (v1):
*
* eglCreatePlatformWindowSurface fails when called with a <display>
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+ if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
+ RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
+
surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
EGLSurface ret;
#if HAVE_SURFACELESS_PLATFORM
- if (disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
/* From the EGL_MESA_platform_surfaceless spec (v1):
*
* [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
#endif
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+
+ if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
+ RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
+
surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+ if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
+ RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
+
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
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);
}
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);
}
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);
}
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)
{
}
-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);
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,
}
-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 ||
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 ||
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)
_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);
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);