summaryrefslogtreecommitdiff
path: root/lib/mesa/src/egl/main/eglapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/egl/main/eglapi.c')
-rw-r--r--lib/mesa/src/egl/main/eglapi.c765
1 files changed, 643 insertions, 122 deletions
diff --git a/lib/mesa/src/egl/main/eglapi.c b/lib/mesa/src/egl/main/eglapi.c
index 4dee9cf1b..697b6fef0 100644
--- a/lib/mesa/src/egl/main/eglapi.c
+++ b/lib/mesa/src/egl/main/eglapi.c
@@ -88,6 +88,7 @@
#include <string.h>
#include "c99_compat.h"
#include "c11/threads.h"
+#include "GL/mesa_glinterop.h"
#include "eglcompiler.h"
#include "eglglobals.h"
@@ -249,6 +250,78 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
mtx_unlock(&dpy->Mutex);
}
+static EGLBoolean
+_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
+{
+ _EGLThreadInfo *thr = _eglGetCurrentThread();
+ if (!_eglIsCurrentThreadDummy()) {
+ thr->CurrentFuncName = funcName;
+ thr->CurrentObjectLabel = NULL;
+
+ if (objectType == EGL_OBJECT_THREAD_KHR)
+ thr->CurrentObjectLabel = thr->Label;
+ else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
+ thr->CurrentObjectLabel = disp->Label;
+ else if (object)
+ thr->CurrentObjectLabel = object->Label;
+
+ return EGL_TRUE;
+ }
+
+ _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName,
+ EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+ return EGL_FALSE;
+}
+
+#define _EGL_FUNC_START(disp, objectType, object, ret) \
+ do { \
+ if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
+ if (disp) \
+ _eglUnlockDisplay(disp); \
+ return ret; \
+ } \
+ } while(0)
+
+/**
+ * Convert an attribute list from EGLint[] to EGLAttrib[].
+ *
+ * Return an EGL error code. The output parameter out_attrib_list is modified
+ * only on success.
+ */
+EGLint
+_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
+{
+ size_t len = 0;
+ EGLAttrib *attrib_list;
+
+ if (int_list) {
+ while (int_list[2*len] != EGL_NONE)
+ ++len;
+ }
+
+ if (len == 0) {
+ *out_attrib_list = NULL;
+ return EGL_SUCCESS;
+ }
+
+ if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
+ return EGL_BAD_ALLOC;
+
+ attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
+ if (!attrib_list)
+ return EGL_BAD_ALLOC;
+
+ for (size_t i = 0; i < len; ++i) {
+ attrib_list[2*i + 0] = int_list[2*i + 0];
+ attrib_list[2*i + 1] = int_list[2*i + 1];
+ }
+
+ attrib_list[2*len] = EGL_NONE;
+
+ *out_attrib_list = attrib_list;
+ return EGL_SUCCESS;
+}
+
static EGLint *
_eglConvertAttribsToInt(const EGLAttrib *attr_list)
@@ -286,6 +359,8 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
_EGLDisplay *dpy;
void *native_display_ptr;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+
STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
native_display_ptr = (void*) nativeDisplay;
@@ -294,9 +369,9 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
return _eglGetDisplayHandle(dpy);
}
-static EGLDisplay EGLAPIENTRY
-eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
- const EGLint *attrib_list)
+static EGLDisplay
+_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
+ const EGLint *attrib_list)
{
_EGLDisplay *dpy;
@@ -318,6 +393,11 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
attrib_list);
break;
#endif
+#ifdef HAVE_SURFACELESS_PLATFORM
+ case EGL_PLATFORM_SURFACELESS_MESA:
+ dpy = _eglGetSurfacelessDisplay(native_display, attrib_list);
+ break;
+#endif
default:
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
}
@@ -325,17 +405,28 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
return _eglGetDisplayHandle(dpy);
}
+static EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
+ const EGLint *attrib_list)
+{
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+ return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+}
+
EGLDisplay EGLAPIENTRY
eglGetPlatformDisplay(EGLenum platform, void *native_display,
const EGLAttrib *attrib_list)
{
EGLDisplay display;
- EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+ EGLint *int_attribs;
+ _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 = eglGetPlatformDisplayEXT(platform, native_display, int_attribs);
+ display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
free(int_attribs);
return display;
}
@@ -405,13 +496,15 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
_eglAppendExtension(&exts, "EGL_KHR_image");
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
+ _EGL_CHECK_EXTENSION(KHR_no_config_context);
_EGL_CHECK_EXTENSION(KHR_reusable_sync);
_EGL_CHECK_EXTENSION(KHR_surfaceless_context);
- _EGL_CHECK_EXTENSION(KHR_vg_parent_image);
+ if (dpy->Extensions.EXT_swap_buffers_with_damage)
+ _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
_EGL_CHECK_EXTENSION(KHR_wait_sync);
- _EGL_CHECK_EXTENSION(MESA_configless_context);
- _EGL_CHECK_EXTENSION(MESA_drm_display);
+ if (dpy->Extensions.KHR_no_config_context)
+ _eglAppendExtension(&exts, "EGL_MESA_configless_context");
_EGL_CHECK_EXTENSION(MESA_drm_image);
_EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
@@ -432,14 +525,11 @@ _eglCreateAPIsString(_EGLDisplay *dpy)
if (dpy->ClientAPIs & EGL_OPENGL_BIT)
strcat(dpy->ClientAPIsString, "OpenGL ");
- if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT)
+ if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
+ dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
+ dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
strcat(dpy->ClientAPIsString, "OpenGL_ES ");
-
- if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT)
- strcat(dpy->ClientAPIsString, "OpenGL_ES2 ");
-
- if (dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR)
- strcat(dpy->ClientAPIsString, "OpenGL_ES3 ");
+ }
if (dpy->ClientAPIs & EGL_OPENVG_BIT)
strcat(dpy->ClientAPIsString, "OpenVG ");
@@ -477,6 +567,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -527,6 +619,8 @@ eglTerminate(EGLDisplay dpy)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -554,6 +648,7 @@ eglQueryString(EGLDisplay dpy, EGLint name)
}
disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
_EGL_CHECK_DISPLAY(disp, NULL, drv);
switch (name) {
@@ -579,6 +674,8 @@ eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
_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);
@@ -594,6 +691,8 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
_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);
@@ -611,6 +710,8 @@ eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
_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);
@@ -629,9 +730,13 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
_EGLContext *context;
EGLContext ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
+
_EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
- if (!config && !disp->Extensions.MESA_configless_context)
+ if (config != EGL_NO_CONFIG_KHR)
+ _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
+ else if (!disp->Extensions.KHR_no_config_context)
RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
if (!share && share_list != EGL_NO_CONTEXT)
@@ -652,6 +757,8 @@ eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
_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);
@@ -671,6 +778,8 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
if (!disp)
RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
drv = disp->Driver;
@@ -717,6 +826,8 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
_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);
@@ -733,11 +844,30 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
_EGLSurface *surf;
EGLSurface ret;
- _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
if (native_window == NULL)
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+#ifdef HAVE_SURFACELESS_PLATFORM
+ if (disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ /* From the EGL_MESA_platform_surfaceless spec (v1):
+ *
+ * eglCreatePlatformWindowSurface fails when called with a <display>
+ * that belongs to the surfaceless platform. It returns
+ * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
+ * justification for this unconditional failure is that the
+ * surfaceless platform has no native windows, and therefore the
+ * <native_window> parameter is always invalid.
+ *
+ * This check must occur before checking the EGLConfig, which emits
+ * EGL_BAD_CONFIG.
+ */
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+#endif
+
+ _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+
surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -751,19 +881,16 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType window, const EGLint *attrib_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
STATIC_ASSERT(sizeof(void*) == sizeof(window));
return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
attrib_list);
}
-
-static EGLSurface EGLAPIENTRY
-eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
- void *native_window,
- const EGLint *attrib_list)
+static void *
+fixupNativeWindow(_EGLDisplay *disp, void *native_window)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
-
#ifdef HAVE_X11_PLATFORM
if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
/* The `native_window` parameter for the X11 platform differs between
@@ -773,10 +900,22 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
* `Window*`. Convert `Window*` to `Window` because that's what
* dri2_x11_create_window_surface() expects.
*/
- native_window = (void*) (* (Window*) native_window);
+ return (void *)(* (Window*) native_window);
}
#endif
+ return native_window;
+}
+
+static EGLSurface EGLAPIENTRY
+eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
+ void *native_window,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+ native_window = fixupNativeWindow(disp, native_window);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
return _eglCreateWindowSurfaceCommon(disp, config, native_window,
attrib_list);
}
@@ -787,18 +926,39 @@ eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
void *native_window,
const EGLAttrib *attrib_list)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
EGLSurface surface;
- EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+ EGLint *int_attribs;
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+ int_attribs = _eglConvertAttribsToInt(attrib_list);
if (attrib_list && !int_attribs)
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
- surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window,
- int_attribs);
+ native_window = fixupNativeWindow(disp, native_window);
+ surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
+ int_attribs);
free(int_attribs);
return surface;
}
+static void *
+fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
+{
+#ifdef HAVE_X11_PLATFORM
+ /* The `native_pixmap` parameter for the X11 platform differs between
+ * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
+ * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
+ * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
+ * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
+ * dri2_x11_create_pixmap_surface() expects.
+ */
+ if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
+ return (void *)(* (Pixmap*) native_pixmap);
+#endif
+ return native_pixmap;
+}
static EGLSurface
_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
@@ -809,6 +969,22 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
_EGLSurface *surf;
EGLSurface ret;
+#if HAVE_SURFACELESS_PLATFORM
+ if (disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+ /* From the EGL_MESA_platform_surfaceless spec (v1):
+ *
+ * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
+ * also fails when called with a <display> that belongs to the
+ * surfaceless platform. It returns EGL_NO_SURFACE and generates
+ * EGL_BAD_NATIVE_PIXMAP.
+ *
+ * This check must occur before checking the EGLConfig, which emits
+ * EGL_BAD_CONFIG.
+ */
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
+ }
+#endif
+
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
attrib_list);
@@ -823,6 +999,8 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+
+ _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);
@@ -835,19 +1013,8 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
-#ifdef HAVE_X11_PLATFORM
- /* The `native_pixmap` parameter for the X11 platform differs between
- * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
- * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
- * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
- * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
- * dri2_x11_create_pixmap_surface() expects.
- */
- if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
- native_pixmap = (void*) (* (Pixmap*) native_pixmap);
- }
-#endif
-
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+ native_pixmap = fixupNativePixmap(disp, native_pixmap);
return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
attrib_list);
}
@@ -858,14 +1025,19 @@ eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
void *native_pixmap,
const EGLAttrib *attrib_list)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
EGLSurface surface;
- EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+ EGLint *int_attribs;
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+ int_attribs = _eglConvertAttribsToInt(attrib_list);
if (attrib_list && !int_attribs)
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
- surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap,
- int_attribs);
+ native_pixmap = fixupNativePixmap(disp, native_pixmap);
+ surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
+ int_attribs);
free(int_attribs);
return surface;
}
@@ -881,6 +1053,7 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
_EGLSurface *surf;
EGLSurface ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
@@ -898,6 +1071,7 @@ eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
_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);
@@ -914,6 +1088,7 @@ eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
_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);
@@ -929,6 +1104,7 @@ eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
_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);
@@ -944,6 +1120,7 @@ eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
_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);
@@ -959,6 +1136,7 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
_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);
@@ -971,17 +1149,17 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLSurface *surf;
+ _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
ctx->Resource.Display != disp)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
- surf = ctx->DrawSurface;
if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
@@ -1000,6 +1178,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
/* surface must be bound to current context in EGL 1.4 */
@@ -1015,13 +1194,11 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
}
-static EGLBoolean EGLAPIENTRY
-eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
- EGLint *rects, EGLint n_rects)
+static EGLBoolean
+eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
+ EGLint *rects, EGLint n_rects)
{
_EGLContext *ctx = _eglGetCurrentContext();
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSurface *surf = _eglLookupSurface(surface, disp);
_EGLDriver *drv;
EGLBoolean ret;
@@ -1040,6 +1217,26 @@ eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
RETURN_EGL_EVAL(disp, ret);
}
+static EGLBoolean EGLAPIENTRY
+eglSwapBuffersWithDamageEXT(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);
+ return eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
+}
+
+static EGLBoolean EGLAPIENTRY
+eglSwapBuffersWithDamageKHR(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);
+ return eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
+}
+
EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
@@ -1049,6 +1246,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
EGLBoolean ret;
void *native_pixmap_ptr;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
STATIC_ASSERT(sizeof(void*) == sizeof(target));
native_pixmap_ptr = (void*) target;
@@ -1061,8 +1259,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
}
-EGLBoolean EGLAPIENTRY
-eglWaitClient(void)
+static EGLBoolean
+_eglWaitClientCommon(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDisplay *disp;
@@ -1088,22 +1286,19 @@ eglWaitClient(void)
RETURN_EGL_EVAL(disp, ret);
}
+EGLBoolean EGLAPIENTRY
+eglWaitClient(void)
+{
+ _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
+ return _eglWaitClientCommon();
+}
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = t->CurrentAPIIndex;
- EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
- EGLBoolean ret;
-
- if (api_index != es_index && _eglIsCurrentThreadDummy())
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
-
- t->CurrentAPIIndex = es_index;
- ret = eglWaitClient();
- t->CurrentAPIIndex = api_index;
- return ret;
+ /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
+ _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
+ return _eglWaitClientCommon();
}
@@ -1118,6 +1313,8 @@ eglWaitNative(EGLint engine)
if (!ctx)
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+
disp = ctx->Resource.Display;
mtx_lock(&disp->Mutex);
@@ -1167,6 +1364,8 @@ eglGetCurrentSurface(EGLint readdraw)
_EGLSurface *surf;
EGLSurface ret;
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
+
if (!ctx)
RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
@@ -1200,13 +1399,6 @@ eglGetError(void)
}
-static EGLDisplay EGLAPIENTRY
-eglGetDRMDisplayMESA(int fd)
-{
- _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
- return _eglGetDisplayHandle(dpy);
-}
-
/**
** EGL 1.2
**/
@@ -1225,15 +1417,18 @@ eglGetDRMDisplayMESA(int fd)
EGLBoolean EGLAPIENTRY
eglBindAPI(EGLenum api)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
+ _EGLThreadInfo *t;
+
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+ t = _eglGetCurrentThread();
if (_eglIsCurrentThreadDummy())
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
if (!_eglIsApiValid(api))
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
- t->CurrentAPIIndex = _eglConvertApiToIndex(api);
+ t->CurrentAPI = api;
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
}
@@ -1249,7 +1444,7 @@ eglQueryAPI(void)
EGLenum ret;
/* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
- ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
+ ret = t->CurrentAPI;
RETURN_EGL_SUCCESS(NULL, ret);
}
@@ -1266,6 +1461,8 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
_EGLSurface *surf;
EGLSurface ret;
+ _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,
@@ -1282,25 +1479,19 @@ eglReleaseThread(void)
/* unbind current contexts */
if (!_eglIsCurrentThreadDummy()) {
_EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = t->CurrentAPIIndex;
- EGLint i;
+ _EGLContext *ctx = t->CurrentContext;
- for (i = 0; i < _EGL_API_NUM_APIS; i++) {
- _EGLContext *ctx = t->CurrentContexts[i];
- if (ctx) {
- _EGLDisplay *disp = ctx->Resource.Display;
- _EGLDriver *drv;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
- t->CurrentAPIIndex = i;
+ if (ctx) {
+ _EGLDisplay *disp = ctx->Resource.Display;
+ _EGLDriver *drv;
- mtx_lock(&disp->Mutex);
- drv = disp->Driver;
- (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
- mtx_unlock(&disp->Mutex);
- }
+ mtx_lock(&disp->Mutex);
+ drv = disp->Driver;
+ (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+ mtx_unlock(&disp->Mutex);
}
-
- t->CurrentAPIIndex = api_index;
}
_eglDestroyCurrentThread();
@@ -1309,11 +1500,10 @@ eglReleaseThread(void)
}
-static EGLImage EGLAPIENTRY
-eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+static EGLImage
+_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLDriver *drv;
_EGLImage *img;
@@ -1337,18 +1527,31 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
RETURN_EGL_EVAL(disp, ret);
}
+static EGLImage EGLAPIENTRY
+eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
+ return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
+}
+
EGLImage EGLAPIENTRY
eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
EGLClientBuffer buffer, const EGLAttrib *attr_list)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
EGLImage image;
- EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
+ EGLint *int_attribs;
+
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
+ int_attribs = _eglConvertAttribsToInt(attr_list);
if (attr_list && !int_attribs)
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
- image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs);
+ image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
free(int_attribs);
return image;
}
@@ -1362,6 +1565,8 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
_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);
@@ -1376,11 +1581,10 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
static EGLSync
-_eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
- const EGLAttrib *attrib_list64, EGLBoolean is64,
+_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
+ EGLBoolean orig_is_EGLAttrib,
EGLenum invalid_type_error)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDriver *drv;
_EGLSync *sync;
@@ -1388,11 +1592,21 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
_EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
- if (!disp->Extensions.KHR_cl_event2 && is64)
- RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
+ if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
+ /* There exist two EGLAttrib variants of eglCreateSync*:
+ * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
+ * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
+ * support as a proxy for EGL 1.5 support, even though that's not
+ * entirely correct (though _eglComputeVersion does the same).
+ *
+ * The EGL spec provides no guidance on how to handle unsupported
+ * functions. EGL_BAD_MATCH seems reasonable.
+ */
+ 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 */
- if (!ctx || ctx->Resource.Display != dpy ||
+ if (!ctx || ctx->Resource.Display != disp ||
ctx->ClientAPI != EGL_OPENGL_ES_API)
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
@@ -1413,7 +1627,7 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
}
- sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
+ sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
RETURN_EGL_EVAL(disp, ret);
@@ -1421,17 +1635,40 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
static EGLSync EGLAPIENTRY
-eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
{
- return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE,
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
+ EGLSync sync;
+ EGLAttrib *attrib_list;
+ EGLint err;
+
+ if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
+ attrib_list = (EGLAttrib *) int_list;
+ } else {
+ err = _eglConvertIntsToAttribs(int_list, &attrib_list);
+ if (err != EGL_SUCCESS)
+ RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
+ }
+
+ sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
EGL_BAD_ATTRIBUTE);
+
+ if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
+ free(attrib_list);
+
+ /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
+ return sync;
}
static EGLSync EGLAPIENTRY
eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
- return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+ return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
EGL_BAD_ATTRIBUTE);
}
@@ -1439,7 +1676,9 @@ eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
EGLSync EGLAPIENTRY
eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
- return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+ return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
EGL_BAD_PARAMETER);
}
@@ -1452,6 +1691,8 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync)
_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);
@@ -1471,6 +1712,8 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, 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);
@@ -1478,17 +1721,30 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
if (s->SyncStatus == EGL_SIGNALED_KHR)
RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
+ /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
+ * unlocked here to allow other threads also to be able to
+ * go into waiting state.
+ */
+
+ if (s->Type == EGL_SYNC_REUSABLE_KHR)
+ _eglUnlockDisplay(dpy);
+
ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
- RETURN_EGL_EVAL(disp, ret);
+ /*
+ * 'disp' is already unlocked for reusable sync type,
+ * so passing 'NULL' to bypass unlocking display.
+ */
+ if (s->Type == EGL_SYNC_REUSABLE_KHR)
+ RETURN_EGL_EVAL(NULL, ret);
+ else
+ RETURN_EGL_EVAL(disp, ret);
}
-static EGLint EGLAPIENTRY
-eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
+static EGLint
+_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSync *s = _eglLookupSync(sync, disp);
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDriver *drv;
EGLint ret;
@@ -1509,6 +1765,15 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
RETURN_EGL_EVAL(disp, ret);
}
+static EGLint EGLAPIENTRY
+eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+ return _eglWaitSyncCommon(disp, s, flags);
+}
+
EGLBoolean EGLAPIENTRY
eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
@@ -1517,7 +1782,10 @@ eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
* EGLBoolean. In both cases, the return values can only be EGL_FALSE and
* EGL_TRUE.
*/
- return eglWaitSyncKHR(dpy, sync, flags);
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+ return _eglWaitSyncCommon(disp, s, flags);
}
@@ -1529,6 +1797,8 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
_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);
@@ -1537,11 +1807,9 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
}
-EGLBoolean EGLAPIENTRY
-eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+static EGLBoolean
+_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
- _EGLSync *s = _eglLookupSync(sync, disp);
_EGLDriver *drv;
EGLBoolean ret;
@@ -1553,18 +1821,31 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *valu
RETURN_EGL_EVAL(disp, ret);
}
+EGLBoolean EGLAPIENTRY
+eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+ return _eglGetSyncAttribCommon(disp, s, attribute, value);
+}
+
static EGLBoolean EGLAPIENTRY
eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSync *s = _eglLookupSync(sync, disp);
EGLAttrib attrib;
EGLBoolean result;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
if (!value)
- RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
attrib = *value;
- result = eglGetSyncAttrib(dpy, sync, attribute, &attrib);
+ result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
/* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
*
@@ -1588,6 +1869,8 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.NOK_swap_region)
@@ -1612,6 +1895,8 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
_EGLImage *img;
EGLImage ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
if (!disp->Extensions.MESA_drm_image)
RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
@@ -1631,6 +1916,8 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.MESA_drm_image);
@@ -1652,6 +1939,8 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
@@ -1670,6 +1959,8 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
@@ -1689,6 +1980,8 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
@@ -1709,6 +2002,8 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
_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);
@@ -1731,6 +2026,8 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.NV_post_sub_buffer)
@@ -1751,6 +2048,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.CHROMIUM_sync_control)
RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1773,6 +2072,8 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.MESA_image_dma_buf_export);
@@ -1794,6 +2095,8 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
_EGLDriver *drv;
EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.MESA_image_dma_buf_export);
@@ -1805,6 +2108,148 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
RETURN_EGL_EVAL(disp, ret);
}
+static EGLint EGLAPIENTRY
+eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
+ EGLLabelKHR label)
+{
+ _EGLDisplay *disp = NULL;
+ _EGLResourceType type;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
+
+ if (objectType == EGL_OBJECT_THREAD_KHR) {
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+
+ if (!_eglIsCurrentThreadDummy()) {
+ t->Label = label;
+ return EGL_SUCCESS;
+ }
+
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
+ }
+
+ disp = _eglLockDisplay(dpy);
+ if (disp == NULL)
+ RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
+
+ if (objectType == EGL_OBJECT_DISPLAY_KHR) {
+ if (dpy != (EGLDisplay) object)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
+
+ disp->Label = label;
+ RETURN_EGL_EVAL(disp, EGL_SUCCESS);
+ }
+
+ switch (objectType) {
+ case EGL_OBJECT_CONTEXT_KHR:
+ type = _EGL_RESOURCE_CONTEXT;
+ break;
+ case EGL_OBJECT_SURFACE_KHR:
+ type = _EGL_RESOURCE_SURFACE;
+ break;
+ case EGL_OBJECT_IMAGE_KHR:
+ type = _EGL_RESOURCE_IMAGE;
+ break;
+ case EGL_OBJECT_SYNC_KHR:
+ type = _EGL_RESOURCE_SYNC;
+ break;
+ case EGL_OBJECT_STREAM_KHR:
+ default:
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
+ }
+
+ if (_eglCheckResource(object, type, disp)) {
+ _EGLResource *res = (_EGLResource *) object;
+
+ res->Label = label;
+ RETURN_EGL_EVAL(disp, EGL_SUCCESS);
+ }
+
+ 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)
+{
+ unsigned int newEnabled;
+
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
+
+ mtx_lock(_eglGlobal.Mutex);
+
+ newEnabled = _eglGlobal.debugTypesEnabled;
+ if (attrib_list != NULL) {
+ int i;
+
+ for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
+ if (validDebugMessageLevel(attrib_list[i])) {
+ if (attrib_list[i + 1])
+ newEnabled |= DebugBitFromType(attrib_list[i]);
+ else
+ newEnabled &= ~DebugBitFromType(attrib_list[i]);
+ continue;
+ }
+
+ // 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;
+ }
+ }
+
+ if (callback != NULL) {
+ _eglGlobal.debugCallback = callback;
+ _eglGlobal.debugTypesEnabled = newEnabled;
+ } else {
+ _eglGlobal.debugCallback = NULL;
+ _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
+ }
+
+ mtx_unlock(_eglGlobal.Mutex);
+ return EGL_SUCCESS;
+}
+
+static EGLBoolean EGLAPIENTRY
+eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
+{
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
+
+ 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;
+ }
+
+ mtx_unlock(_eglGlobal.Mutex);
+ _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
+ "Invalid attribute 0x%04lx", (unsigned long) attribute);
+ return EGL_FALSE;
+ } while (0);
+
+ mtx_unlock(_eglGlobal.Mutex);
+ return EGL_TRUE;
+}
+
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname)
{
@@ -1860,7 +2305,6 @@ eglGetProcAddress(const char *procname)
{ "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay },
{ "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface },
{ "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface },
- { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImage },
{ "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
@@ -1879,12 +2323,16 @@ eglGetProcAddress(const char *procname)
{ "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 },
{ NULL, NULL }
};
EGLint i;
@@ -1893,6 +2341,8 @@ eglGetProcAddress(const char *procname)
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++) {
@@ -1907,3 +2357,74 @@ eglGetProcAddress(const char *procname)
RETURN_EGL_SUCCESS(NULL, ret);
}
+
+static int
+_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
+ _EGLDisplay **disp, _EGLDriver **drv,
+ _EGLContext **ctx)
+{
+
+ *disp = _eglLockDisplay(dpy);
+ if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
+ if (*disp)
+ _eglUnlockDisplay(*disp);
+ return MESA_GLINTEROP_INVALID_DISPLAY;
+ }
+
+ *drv = (*disp)->Driver;
+
+ *ctx = _eglLookupContext(context, *disp);
+ if (!*ctx ||
+ ((*ctx)->ClientAPI != EGL_OPENGL_API &&
+ (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
+ _eglUnlockDisplay(*disp);
+ return MESA_GLINTEROP_INVALID_CONTEXT;
+ }
+
+ return MESA_GLINTEROP_SUCCESS;
+}
+
+PUBLIC int
+MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
+ struct mesa_glinterop_device_info *out)
+{
+ _EGLDisplay *disp;
+ _EGLDriver *drv;
+ _EGLContext *ctx;
+ int ret;
+
+ ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+ if (ret != MESA_GLINTEROP_SUCCESS)
+ return ret;
+
+ if (drv->API.GLInteropQueryDeviceInfo)
+ ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
+ else
+ ret = MESA_GLINTEROP_UNSUPPORTED;
+
+ _eglUnlockDisplay(disp);
+ return ret;
+}
+
+PUBLIC int
+MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
+ struct mesa_glinterop_export_in *in,
+ struct mesa_glinterop_export_out *out)
+{
+ _EGLDisplay *disp;
+ _EGLDriver *drv;
+ _EGLContext *ctx;
+ int ret;
+
+ ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+ if (ret != MESA_GLINTEROP_SUCCESS)
+ return ret;
+
+ if (drv->API.GLInteropExportObject)
+ ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
+ else
+ ret = MESA_GLINTEROP_UNSUPPORTED;
+
+ _eglUnlockDisplay(disp);
+ return ret;
+}