*/
+#ifdef USE_LIBGLVND
+#define EGLAPI
+#undef PUBLIC
+#define PUBLIC
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "c99_compat.h"
#include "c11/threads.h"
-#include "GL/mesa_glinterop.h"
-#include "eglcompiler.h"
+#include "util/macros.h"
+#include "egldefines.h"
#include "eglglobals.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egltypedefs.h"
#include "eglcurrent.h"
+#include "egldevice.h"
#include "egldriver.h"
#include "eglsurface.h"
#include "eglconfig.h"
#include "eglimage.h"
#include "eglsync.h"
+#include "GL/mesa_glinterop.h"
/**
* Macros to help return an API entrypoint.
_EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
-static inline _EGLDriver *
+struct _egl_entrypoint {
+ const char *name;
+ _EGLProc function;
+};
+
+
+static inline const _EGLDriver *
_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
{
if (!disp) {
}
-static inline _EGLDriver *
+static inline const _EGLDriver *
_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
{
- _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
if (!drv)
return NULL;
if (!surf) {
}
-static inline _EGLDriver *
+static inline const _EGLDriver *
_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
{
- _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
if (!drv)
return NULL;
if (!context) {
}
-static inline _EGLDriver *
+static inline const _EGLDriver *
_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
{
- _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
if (!drv)
return NULL;
if (!conf) {
}
-static inline _EGLDriver *
+static inline const _EGLDriver *
_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
{
- _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
if (!drv)
return NULL;
if (!s) {
* Lookup and lock a display.
*/
static inline _EGLDisplay *
-_eglLockDisplay(EGLDisplay display)
+_eglLockDisplay(EGLDisplay dpy)
{
- _EGLDisplay *dpy = _eglLookupDisplay(display);
- if (dpy)
- mtx_lock(&dpy->Mutex);
- return dpy;
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ if (disp)
+ mtx_lock(&disp->Mutex);
+ return disp;
}
* Unlock a display.
*/
static inline void
-_eglUnlockDisplay(_EGLDisplay *dpy)
+_eglUnlockDisplay(_EGLDisplay *disp)
{
- mtx_unlock(&dpy->Mutex);
+ mtx_unlock(&disp->Mutex);
}
static EGLBoolean
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;
}
static EGLint *
_eglConvertAttribsToInt(const EGLAttrib *attr_list)
{
+ size_t size = _eglNumAttribs(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 */
-
+ if (size) {
int_attribs = calloc(size, sizeof(int_attribs[0]));
if (!int_attribs)
return NULL;
- for (i = 0; i < size; i++)
+ for (size_t i = 0; i < size; i++)
int_attribs[i] = attr_list[i];
}
return int_attribs;
eglGetDisplay(EGLNativeDisplayType nativeDisplay)
{
_EGLPlatformType plat;
- _EGLDisplay *dpy;
+ _EGLDisplay *disp;
void *native_display_ptr;
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
native_display_ptr = (void*) nativeDisplay;
plat = _eglGetNativePlatform(native_display_ptr);
- dpy = _eglFindDisplay(plat, native_display_ptr);
- return _eglGetDisplayHandle(dpy);
+ disp = _eglFindDisplay(plat, native_display_ptr, NULL);
+ return _eglGetDisplayHandle(disp);
}
static EGLDisplay
_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
- const EGLint *attrib_list)
+ const EGLAttrib *attrib_list)
{
- _EGLDisplay *dpy;
+ _EGLDisplay *disp;
switch (platform) {
#ifdef HAVE_X11_PLATFORM
case EGL_PLATFORM_X11_EXT:
- dpy = _eglGetX11Display((Display*) native_display, attrib_list);
+ disp = _eglGetX11Display((Display*) native_display, attrib_list);
break;
#endif
#ifdef HAVE_DRM_PLATFORM
case EGL_PLATFORM_GBM_MESA:
- dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
+ disp = _eglGetGbmDisplay((struct gbm_device*) native_display,
attrib_list);
break;
#endif
#ifdef HAVE_WAYLAND_PLATFORM
case EGL_PLATFORM_WAYLAND_EXT:
- dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
+ disp = _eglGetWaylandDisplay((struct wl_display*) native_display,
attrib_list);
break;
#endif
-#ifdef HAVE_SURFACELESS_PLATFORM
case EGL_PLATFORM_SURFACELESS_MESA:
- dpy = _eglGetSurfacelessDisplay(native_display, attrib_list);
+ disp = _eglGetSurfacelessDisplay(native_display, attrib_list);
+ break;
+#ifdef HAVE_ANDROID_PLATFORM
+ case EGL_PLATFORM_ANDROID_KHR:
+ disp = _eglGetAndroidDisplay(native_display, attrib_list);
break;
#endif
+ case EGL_PLATFORM_DEVICE_EXT:
+ disp = _eglGetDeviceDisplay(native_display, attrib_list);
+ break;
default:
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
}
- return _eglGetDisplayHandle(dpy);
+ return _eglGetDisplayHandle(disp);
}
static EGLDisplay EGLAPIENTRY
eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
- const EGLint *attrib_list)
+ const EGLint *int_attribs)
{
+ EGLAttrib *attrib_list;
+ EGLDisplay disp;
+
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
- return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+
+ if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
+
+ disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+ free(attrib_list);
+ return disp;
}
EGLDisplay EGLAPIENTRY
eglGetPlatformDisplay(EGLenum platform, void *native_display,
const EGLAttrib *attrib_list)
{
- EGLDisplay display;
- EGLint *int_attribs;
-
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
-
- 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;
+ return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
}
/**
* the driver's Extensions string.
*/
static void
-_eglCreateExtensionsString(_EGLDisplay *dpy)
+_eglCreateExtensionsString(_EGLDisplay *disp)
{
#define _EGL_CHECK_EXTENSION(ext) \
do { \
- if (dpy->Extensions.ext) { \
+ if (disp->Extensions.ext) { \
_eglAppendExtension(&exts, "EGL_" #ext); \
- assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
+ assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
} \
} while (0)
- char *exts = dpy->ExtensionsString;
+ char *exts = disp->ExtensionsString;
/* Please keep these sorted alphabetically. */
+ _EGL_CHECK_EXTENSION(ANDROID_blob_cache);
_EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
_EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
_EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
_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_surface_CTA861_3_metadata);
+ _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
_EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
+ _EGL_CHECK_EXTENSION(IMG_context_priority);
+
_EGL_CHECK_EXTENSION(KHR_cl_event2);
_EGL_CHECK_EXTENSION(KHR_config_attribs);
+ _EGL_CHECK_EXTENSION(KHR_context_flush_control);
_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_gl_texture_2D_image);
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_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");
+ if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap)
+ disp->Extensions.KHR_image = EGL_TRUE;
+ _EGL_CHECK_EXTENSION(KHR_image);
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
+ _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
_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)
+ if (disp->Extensions.EXT_swap_buffers_with_damage)
_eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
+ _EGL_CHECK_EXTENSION(EXT_pixel_format_float);
_EGL_CHECK_EXTENSION(KHR_wait_sync);
- if (dpy->Extensions.KHR_no_config_context)
+ if (disp->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(MESA_query_driver);
_EGL_CHECK_EXTENSION(NOK_swap_region);
_EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
}
static void
-_eglCreateAPIsString(_EGLDisplay *dpy)
-{
- if (dpy->ClientAPIs & EGL_OPENGL_BIT)
- strcat(dpy->ClientAPIsString, "OpenGL ");
+_eglCreateAPIsString(_EGLDisplay *disp)
+{
+#define addstr(str) \
+ { \
+ const size_t old_len = strlen(disp->ClientAPIsString); \
+ const size_t add_len = sizeof(str); \
+ const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
+ if (old_len + add_len <= max_len) \
+ strcat(disp->ClientAPIsString, str " "); \
+ else \
+ assert(!"disp->ClientAPIsString is not large enough"); \
+ }
- 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 (disp->ClientAPIs & EGL_OPENGL_BIT)
+ addstr("OpenGL");
+
+ if (disp->ClientAPIs & EGL_OPENGL_ES_BIT ||
+ disp->ClientAPIs & EGL_OPENGL_ES2_BIT ||
+ disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
+ addstr("OpenGL_ES");
}
- if (dpy->ClientAPIs & EGL_OPENVG_BIT)
- strcat(dpy->ClientAPIsString, "OpenVG ");
+ if (disp->ClientAPIs & EGL_OPENVG_BIT)
+ addstr("OpenVG");
- assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
+#undef addstr
}
static void
disp->Extensions.KHR_gl_colorspace &&
disp->Extensions.KHR_surfaceless_context)
disp->Version = 15;
+
+ /* For Android P and below limit the EGL version to 1.4 */
+#if defined(ANDROID) && ANDROID_API_LEVEL <= 28
+ disp->Version = 14;
+#endif
}
/**
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
if (!disp->Initialized) {
- if (!_eglMatchDriver(disp, EGL_FALSE))
+ if (!_eglInitializeDisplay(disp))
RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
/* limit to APIs supported by core */
_eglCreateExtensionsString(disp);
_eglCreateAPIsString(disp);
snprintf(disp->VersionString, sizeof(disp->VersionString),
- "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
- disp->Driver->Name);
+ "%d.%d", disp->Version / 10, disp->Version % 10);
}
/* Update applications version of major and minor if not NULL */
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
if (disp->Initialized) {
- _EGLDriver *drv = disp->Driver;
-
- drv->API.Terminate(drv, disp);
+ disp->Driver->Terminate(disp);
/* do not reset disp->Driver */
disp->ClientAPIsString[0] = 0;
disp->Initialized = EGL_FALSE;
+
+ /* Reset blob cache funcs on terminate. */
+ disp->BlobCacheSet = NULL;
+ disp->BlobCacheGet = NULL;
}
RETURN_EGL_SUCCESS(disp, EGL_TRUE);
eglQueryString(EGLDisplay dpy, EGLint name)
{
_EGLDisplay *disp;
- _EGLDriver *drv;
+ const _EGLDriver *drv;
+#if !USE_LIBGLVND
if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
}
+#endif
disp = _eglLockDisplay(dpy);
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
- ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
+
+ if (!num_config)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = _eglGetConfigs(drv, disp, configs, config_size, num_config);
RETURN_EGL_EVAL(disp, ret);
}
EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
- ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
- config_size, num_config);
+
+ if (!num_config)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = _eglChooseConfig(drv, disp, attrib_list, configs,
+ config_size, num_config);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLConfig *conf = _eglLookupConfig(config, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
_EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
- ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
+
+ ret = _eglGetConfigAttrib(drv, disp, conf, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLConfig *conf = _eglLookupConfig(config, disp);
_EGLContext *share = _eglLookupContext(share_list, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLContext *context;
EGLContext ret;
if (!share && share_list != EGL_NO_CONTEXT)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
- context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
+ context = drv->CreateContext(disp, conf, share, attrib_list);
ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
RETURN_EGL_EVAL(disp, ret);
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *context = _eglLookupContext(ctx, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
_eglUnlinkContext(context);
- ret = drv->API.DestroyContext(drv, disp, context);
+ ret = drv->DestroyContext(disp, context);
RETURN_EGL_EVAL(disp, ret);
}
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
_EGLSurface *read_surf = _eglLookupSurface(read, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
}
- ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
+ /* 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->MakeCurrent(disp, draw_surf, read_surf, context);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *context = _eglLookupContext(ctx, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
- ret = drv->API.QueryContext(drv, disp, context, attribute, value);
+
+ ret = _eglQueryContext(drv, disp, context, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
+/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says
+ * that if native_surface was already used to create a window or pixmap, we
+ * can't create a new one. This is what this function checks for.
+ */
+static bool
+_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface)
+{
+ _EGLResource *list;
+
+ list = disp->ResourceLists[_EGL_RESOURCE_SURFACE];
+ while (list) {
+ _EGLSurface *surf = (_EGLSurface *) list;
+
+ list = list->Next;
+
+ if (surf->Type == EGL_PBUFFER_BIT)
+ continue;
+
+ if (surf->NativeSurface == native_surface)
+ return true;
+ }
+
+ return false;
+}
+
+
static EGLSurface
_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
void *native_window, const EGLint *attrib_list)
{
_EGLConfig *conf = _eglLookupConfig(config, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLSurface *surf;
EGLSurface ret;
if (native_window == NULL)
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
-#ifdef HAVE_SURFACELESS_PLATFORM
- if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
+ disp->Platform == _EGL_PLATFORM_DEVICE)) {
/* From the EGL_MESA_platform_surfaceless spec (v1):
*
* eglCreatePlatformWindowSurface fails when called with a <display>
*/
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
-#endif
_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);
+ if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+ surf = drv->CreateWindowSurface(disp, conf, native_window, attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
_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
_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;
void *native_pixmap, const EGLint *attrib_list)
{
_EGLConfig *conf = _eglLookupConfig(config, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLSurface *surf;
EGLSurface ret;
-#if HAVE_SURFACELESS_PLATFORM
- if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
+ disp->Platform == _EGL_PLATFORM_DEVICE)) {
/* From the EGL_MESA_platform_surfaceless spec (v1):
*
* [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
*/
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
}
-#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);
+ if (native_pixmap == NULL)
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
+
+ if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+ surf = drv->CreatePixmapSurface(disp, conf, native_pixmap, attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
_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);
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLConfig *conf = _eglLookupConfig(config, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLSurface *surf;
EGLSurface ret;
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);
+ surf = drv->CreatePbufferSurface(disp, conf, attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
_eglUnlinkSurface(surf);
- ret = drv->API.DestroySurface(drv, disp, surf);
+ ret = drv->DestroySurface(disp, surf);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
- ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
+
+ if (drv->QuerySurface)
+ ret = drv->QuerySurface(disp, surf, attribute, value);
+ else
+ ret = _eglQuerySurface(disp, surf, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
- ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
+
+ ret = _eglSurfaceAttrib(drv, disp, surf, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
- ret = drv->API.BindTexImage(drv, disp, surf, buffer);
+ ret = drv->BindTexImage(disp, surf, buffer);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
- ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
+ ret = drv->ReleaseTexImage(disp, surf, buffer);
RETURN_EGL_EVAL(disp, ret);
}
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
_EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
- ret = drv->API.SwapInterval(drv, disp, surf, interval);
+ if (surf->Type != EGL_WINDOW_BIT)
+ RETURN_EGL_EVAL(disp, EGL_TRUE);
+
+ interval = CLAMP(interval,
+ surf->Config->MinSwapInterval,
+ surf->Config->MaxSwapInterval);
+
+ if (surf->SwapInterval != interval) {
+ if (drv->SwapInterval)
+ ret = drv->SwapInterval(disp, surf, interval);
+ else
+ ret = _eglSwapInterval(disp, surf, interval);
+ }
+ else {
+ ret = EGL_TRUE;
+ }
+
+ if (ret)
+ surf->SwapInterval = interval;
RETURN_EGL_EVAL(disp, ret);
}
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
#endif
- ret = drv->API.SwapBuffers(drv, disp, surf);
+ if (surf->Type != EGL_WINDOW_BIT)
+ RETURN_EGL_EVAL(disp, EGL_TRUE);
+
+ /* 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->SwapBuffers(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);
}
static EGLBoolean
_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
- EGLint *rects, EGLint n_rects)
+ const EGLint *rects, EGLint n_rects)
{
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
surf != ctx->DrawSurface)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+ if (surf->Type != EGL_WINDOW_BIT)
+ RETURN_EGL_EVAL(disp, EGL_TRUE);
+
if ((n_rects > 0 && rects == NULL) || n_rects < 0)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
+ ret = drv->SwapBuffersWithDamageEXT(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);
}
static EGLBoolean EGLAPIENTRY
eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
- EGLint *rects, EGLint n_rects)
+ const EGLint *rects, EGLint n_rects)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
static EGLBoolean EGLAPIENTRY
eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
- EGLint *rects, EGLint n_rects)
+ const EGLint *rects, EGLint n_rects)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
}
+/**
+ * Clamp the rectangles so that they lie within the surface.
+ */
+
+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 x1, y1, x2, y2;
+ x1 = rects[i];
+ y1 = rects[i + 1];
+ x2 = rects[i + 2] + x1;
+ y2 = rects[i + 3] + y1;
+
+ rects[i] = CLAMP(x1, 0, surf_width);
+ rects[i + 1] = CLAMP(y1, 0, surf_height);
+ rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i];
+ rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1];
+ }
+}
+
+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();
+ const _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->SetDamageRegion(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)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
void *native_pixmap_ptr;
native_pixmap_ptr = (void*) target;
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
- if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
- RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
- ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
+ ret = drv->CopyBuffers(disp, surf, native_pixmap_ptr);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDisplay *disp;
- _EGLDriver *drv;
EGLBoolean ret;
if (!ctx)
/* a valid current context implies an initialized current display */
assert(disp->Initialized);
- drv = disp->Driver;
- ret = drv->API.WaitClient(drv, disp, ctx);
+ ret = disp->Driver->WaitClient(disp, ctx);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDisplay *disp;
- _EGLDriver *drv;
EGLBoolean ret;
if (!ctx)
/* a valid current context implies an initialized current display */
assert(disp->Initialized);
- drv = disp->Driver;
- ret = drv->API.WaitNative(drv, disp, engine);
+ ret = disp->Driver->WaitNative(engine);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLConfig *conf = _eglLookupConfig(config, disp);
- _EGLDriver *drv;
- _EGLSurface *surf;
- EGLSurface ret;
+ const _EGLDriver *drv;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
- surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
- conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
-
- RETURN_EGL_EVAL(disp, ret);
+ /* OpenVG is not supported */
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
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);
+ (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL);
mtx_unlock(&disp->Mutex);
}
}
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;
+ const _EGLDriver *drv;
_EGLImage *img;
EGLImage ret;
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->CreateImageKHR(disp, context, target, buffer, attr_list);
ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
RETURN_EGL_EVAL(disp, ret);
static EGLBoolean
_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
{
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
_eglUnlinkImage(img);
- ret = drv->API.DestroyImageKHR(drv, disp, img);
+ ret = drv->DestroyImageKHR(disp, img);
RETURN_EGL_EVAL(disp, ret);
}
EGLenum invalid_type_error)
{
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLSync *sync;
EGLSync ret;
(type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
- /* return an error if the client API doesn't support GL_OES_EGL_sync */
+ /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
if (ctx && (ctx->Resource.Display != disp ||
- ctx->ClientAPI != EGL_OPENGL_ES_API))
+ (ctx->ClientAPI != EGL_OPENGL_ES_API &&
+ ctx->ClientAPI != EGL_OPENGL_API)))
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
switch (type) {
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
}
- sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
+ sync = drv->CreateSyncKHR(drv, disp, type, attrib_list);
ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
RETURN_EGL_EVAL(disp, ret);
static EGLBoolean
_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
{
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
disp->Extensions.ANDROID_native_fence_sync);
_eglUnlinkSync(s);
- ret = drv->API.DestroySyncKHR(drv, disp, s);
+ ret = drv->DestroySyncKHR(drv, disp, s);
RETURN_EGL_EVAL(disp, ret);
}
}
-EGLint EGLAPIENTRY
-eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+static EGLint
+_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
+ _EGLSync *s, EGLint flags, EGLTime timeout)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSync *s = _eglLookupSync(sync, disp);
- _EGLDriver *drv;
+ const _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 ||
if (s->Type == EGL_SYNC_REUSABLE_KHR)
_eglUnlockDisplay(dpy);
- ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
+ ret = drv->ClientWaitSyncKHR(drv, disp, s, flags, timeout);
/*
* 'disp' is already unlocked for reusable sync type,
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)
{
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLint ret;
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
assert(disp->Extensions.KHR_wait_sync);
- /* return an error if the client API doesn't support GL_OES_EGL_sync */
- if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
+ /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
+ if (ctx == EGL_NO_CONTEXT ||
+ (ctx->ClientAPI != EGL_OPENGL_ES_API &&
+ ctx->ClientAPI != EGL_OPENGL_API))
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
/* the API doesn't allow any flags yet */
if (flags != 0)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.WaitSyncKHR(drv, disp, s);
+ ret = drv->WaitSyncKHR(drv, disp, s);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
- _EGLDriver *drv;
+ const _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);
- ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
+ ret = drv->SignalSyncKHR(drv, disp, s, mode);
RETURN_EGL_EVAL(disp, ret);
}
static EGLBoolean
_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
{
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
assert(disp->Extensions.KHR_reusable_sync ||
disp->Extensions.KHR_fence_sync ||
disp->Extensions.ANDROID_native_fence_sync);
- ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
+
+ ret = _eglGetSyncAttrib(drv, disp, s, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
+ if (!value)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
return _eglGetSyncAttribCommon(disp, s, attribute, value);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
_EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv);
assert(disp->Extensions.ANDROID_native_fence_sync);
- ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s);
+ ret = drv->DupNativeFenceFDANDROID(drv, disp, s);
RETURN_EGL_EVAL(disp, ret);
}
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);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
surf != ctx->DrawSurface)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
- ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
+ ret = drv->SwapBuffersRegionNOK(disp, surf, numRects, rects);
RETURN_EGL_EVAL(disp, ret);
}
eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLImage *img;
EGLImage ret;
if (!disp->Extensions.MESA_drm_image)
RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
- img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
+ img = drv->CreateDRMImageMESA(drv, disp, attr_list);
ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
RETURN_EGL_EVAL(disp, ret);
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);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
if (!img)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
+ ret = drv->ExportDRMImageMESA(drv, disp, img, name, handle, stride);
RETURN_EGL_EVAL(disp, ret);
}
eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
if (!display)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
+ ret = drv->BindWaylandDisplayWL(drv, disp, display);
RETURN_EGL_EVAL(disp, ret);
}
eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
if (!display)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
+ ret = drv->UnbindWaylandDisplayWL(drv, disp, display);
RETURN_EGL_EVAL(disp, ret);
}
EGLint attribute, EGLint *value)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
if (!buffer)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
+ ret = drv->QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLImage *img;
- _EGLDriver *drv;
+ const _EGLDriver *drv;
struct wl_buffer *ret;
_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);
if (!img)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
- ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
+ ret = drv->CreateWaylandBufferFromImageWL(drv, disp, img);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
if (!disp->Extensions.NV_post_sub_buffer)
RETURN_EGL_EVAL(disp, EGL_FALSE);
- ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
+ ret = drv->PostSubBufferNV(drv, disp, surf, x, y, width, height);
RETURN_EGL_EVAL(disp, ret);
}
static EGLBoolean EGLAPIENTRY
-eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
+eglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
EGLuint64KHR *ust, EGLuint64KHR *msc,
EGLuint64KHR *sbc)
{
- _EGLDisplay *disp = _eglLockDisplay(display);
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSurface *surf = _eglLookupSurface(surface, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
if (!ust || !msc || !sbc)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
+ ret = drv->GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
RETURN_EGL_EVAL(disp, ret);
}
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLImage *img = _eglLookupImage(image, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
if (!img)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
+ ret = drv->ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
modifiers);
RETURN_EGL_EVAL(disp, ret);
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLImage *img = _eglLookupImage(image, disp);
- _EGLDriver *drv;
+ const _EGLDriver *drv;
EGLBoolean ret;
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
if (!img)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
- ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
+ ret = drv->ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
RETURN_EGL_EVAL(disp, ret);
}
static EGLint EGLAPIENTRY
eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
- EGLLabelKHR label)
+ EGLLabelKHR label)
{
_EGLDisplay *disp = NULL;
_EGLResourceType type;
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
}
-static EGLBoolean
-_validDebugMessageLevel(EGLAttrib level)
-{
- return (level >= EGL_DEBUG_MSG_CRITICAL_KHR &&
- level <= EGL_DEBUG_MSG_INFO_KHR);
-}
-
static EGLint EGLAPIENTRY
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
- const EGLAttrib *attrib_list)
+ const EGLAttrib *attrib_list)
{
unsigned int newEnabled;
int i;
for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
- if (_validDebugMessageLevel(attrib_list[i])) {
+ switch (attrib_list[i]) {
+ case EGL_DEBUG_MSG_CRITICAL_KHR:
+ case EGL_DEBUG_MSG_ERROR_KHR:
+ case EGL_DEBUG_MSG_WARN_KHR:
+ case EGL_DEBUG_MSG_INFO_KHR:
if (attrib_list[i + 1])
newEnabled |= DebugBitFromType(attrib_list[i]);
else
newEnabled &= ~DebugBitFromType(attrib_list[i]);
- continue;
+ break;
+ default:
+ // On error, set the last error code, call the current
+ // 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]);
+ return EGL_BAD_ATTRIBUTE;
}
-
- // On error, set the last error code, call the current
- // 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]);
- return EGL_BAD_ATTRIBUTE;
}
}
mtx_lock(_eglGlobal.Mutex);
- do {
- if (_validDebugMessageLevel(attribute)) {
- if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
- *value = EGL_TRUE;
- else
- *value = EGL_FALSE;
- break;
- }
-
- if (attribute == EGL_DEBUG_CALLBACK_KHR) {
- *value = (EGLAttrib) _eglGlobal.debugCallback;
- break;
- }
-
+ switch (attribute) {
+ case EGL_DEBUG_MSG_CRITICAL_KHR:
+ case EGL_DEBUG_MSG_ERROR_KHR:
+ case EGL_DEBUG_MSG_WARN_KHR:
+ case EGL_DEBUG_MSG_INFO_KHR:
+ if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
+ *value = EGL_TRUE;
+ else
+ *value = EGL_FALSE;
+ break;
+ case EGL_DEBUG_CALLBACK_KHR:
+ *value = (EGLAttrib) _eglGlobal.debugCallback;
+ break;
+ default:
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);
+ }
mtx_unlock(_eglGlobal.Mutex);
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);
+ const _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ ret = drv->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);
+ const _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ ret = drv->QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
+ modifiers, external_only,
+ num_modifiers);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+static void EGLAPIENTRY
+eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get)
+{
+ /* This function does not return anything so we cannot
+ * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY.
+ */
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) {
+ if (disp)
+ _eglUnlockDisplay(disp);
+ return;
+ }
+
+ const _EGLDriver *drv = _eglCheckDisplay(disp, __func__);
+ if (!drv) {
+ if (disp)
+ _eglUnlockDisplay(disp);
+ return;
+ }
+
+ if (!set || !get) {
+ _eglError(EGL_BAD_PARAMETER,
+ "eglSetBlobCacheFuncsANDROID: NULL handler given");
+ _eglUnlockDisplay(disp);
+ return;
+ }
+
+ if (disp->BlobCacheSet) {
+ _eglError(EGL_BAD_PARAMETER,
+ "eglSetBlobCacheFuncsANDROID: functions already set");
+ _eglUnlockDisplay(disp);
+ return;
+ }
+
+ disp->BlobCacheSet = set;
+ disp->BlobCacheGet = get;
+
+ drv->SetBlobCacheFuncsANDROID(drv, disp, set, get);
+
+ _eglUnlockDisplay(disp);
+}
+
+static EGLBoolean EGLAPIENTRY
+eglQueryDeviceAttribEXT(EGLDeviceEXT device,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ _EGLDevice *dev = _eglLookupDevice(device);
+ EGLBoolean ret;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+ if (!dev)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE);
+
+ ret = _eglQueryDeviceAttribEXT(dev, attribute, value);
+ RETURN_EGL_EVAL(NULL, ret);
+}
+
+static const char * EGLAPIENTRY
+eglQueryDeviceStringEXT(EGLDeviceEXT device,
+ EGLint name)
+{
+ _EGLDevice *dev = _eglLookupDevice(device);
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
+ if (!dev)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL);
+
+ RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name));
+}
+
+static EGLBoolean EGLAPIENTRY
+eglQueryDevicesEXT(EGLint max_devices,
+ EGLDeviceEXT *devices,
+ EGLint *num_devices)
+{
+ EGLBoolean ret;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+ ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices,
+ num_devices);
+ RETURN_EGL_EVAL(NULL, ret);
+}
+
+static EGLBoolean EGLAPIENTRY
+eglQueryDisplayAttribEXT(EGLDisplay dpy,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ const _EGLDriver *drv;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ switch (attribute) {
+ case EGL_DEVICE_EXT:
+ *value = (EGLAttrib) disp->Device;
+ break;
+ default:
+ RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ }
+ RETURN_EGL_SUCCESS(disp, EGL_TRUE);
+}
+
+static char * EGLAPIENTRY
+eglGetDisplayDriverConfig(EGLDisplay dpy)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ const _EGLDriver *drv;
+ char *ret;
+
+ _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
+ _EGL_CHECK_DISPLAY(disp, NULL, drv);
+
+ assert(disp->Extensions.MESA_query_driver);
+
+ ret = drv->QueryDriverConfig(disp);
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+static const char * EGLAPIENTRY
+eglGetDisplayDriverName(EGLDisplay dpy)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ const _EGLDriver *drv;
+ const char *ret;
+
+ _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
+ _EGL_CHECK_DISPLAY(disp, NULL, drv);
+
+ assert(disp->Extensions.MESA_query_driver);
+
+ ret = drv->QueryDriverName(disp);
+ 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) eglDestroyImageKHR },
- { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
- { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
- { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
- { "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);
static int
_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
- _EGLDisplay **disp, _EGLDriver **drv,
+ _EGLDisplay **disp, const _EGLDriver **drv,
_EGLContext **ctx)
{
struct mesa_glinterop_device_info *out)
{
_EGLDisplay *disp;
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLContext *ctx;
int ret;
if (ret != MESA_GLINTEROP_SUCCESS)
return ret;
- if (drv->API.GLInteropQueryDeviceInfo)
- ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
+ if (drv->GLInteropQueryDeviceInfo)
+ ret = drv->GLInteropQueryDeviceInfo(disp, ctx, out);
else
ret = MESA_GLINTEROP_UNSUPPORTED;
struct mesa_glinterop_export_out *out)
{
_EGLDisplay *disp;
- _EGLDriver *drv;
+ const _EGLDriver *drv;
_EGLContext *ctx;
int ret;
if (ret != MESA_GLINTEROP_SUCCESS)
return ret;
- if (drv->API.GLInteropExportObject)
- ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
+ if (drv->GLInteropExportObject)
+ ret = drv->GLInteropExportObject(disp, ctx, in, out);
else
ret = MESA_GLINTEROP_UNSUPPORTED;