#include <string.h>
#include "c99_compat.h"
#include "c11/threads.h"
+#include "GL/mesa_glinterop.h"
#include "eglcompiler.h"
#include "eglglobals.h"
#include "eglconfig.h"
#include "eglimage.h"
#include "eglsync.h"
-#include "eglstring.h"
/**
}
+static EGLint *
+_eglConvertAttribsToInt(const EGLAttrib *attr_list)
+{
+ EGLint *int_attribs = NULL;
+
+ /* Convert attributes from EGLAttrib[] to EGLint[] */
+ if (attr_list) {
+ int i, size = 0;
+
+ while (attr_list[size] != EGL_NONE)
+ size += 2;
+
+ size += 1; /* add space for EGL_NONE */
+
+ int_attribs = calloc(size, sizeof(int_attribs[0]));
+ if (!int_attribs)
+ return NULL;
+
+ for (i = 0; i < size; i++)
+ int_attribs[i] = attr_list[i];
+ }
+ return int_attribs;
+}
+
+
/**
* This is typically the first EGL function that an application calls.
* It associates a private _EGLDisplay object to the native display.
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;
return _eglGetDisplayHandle(dpy);
}
+static EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
+ const EGLint *attrib_list)
+{
+ return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+}
+
+EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplay(EGLenum platform, void *native_display,
+ const EGLAttrib *attrib_list)
+{
+ EGLDisplay display;
+ EGLint *int_attribs;
+
+ int_attribs = _eglConvertAttribsToInt(attrib_list);
+ if (attrib_list && !int_attribs)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
+
+ display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
+ free(int_attribs);
+ return display;
+}
+
/**
* Copy the extension into the string and update the string pointer.
*/
char *exts = dpy->ExtensionsString;
- _EGL_CHECK_EXTENSION(MESA_copy_context);
- _EGL_CHECK_EXTENSION(MESA_drm_display);
- _EGL_CHECK_EXTENSION(MESA_drm_image);
- _EGL_CHECK_EXTENSION(MESA_configless_context);
+ /* Please keep these sorted alphabetically. */
+ _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
+ _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
+ _EGL_CHECK_EXTENSION(ANDROID_recordable);
- _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
- _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
+ _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
- _EGL_CHECK_EXTENSION(KHR_image_base);
- _EGL_CHECK_EXTENSION(KHR_image_pixmap);
- if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
- _eglAppendExtension(&exts, "EGL_KHR_image");
+ _EGL_CHECK_EXTENSION(EXT_buffer_age);
+ _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
+ _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
+ _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
- _EGL_CHECK_EXTENSION(KHR_vg_parent_image);
+ _EGL_CHECK_EXTENSION(KHR_cl_event2);
+ _EGL_CHECK_EXTENSION(KHR_create_context);
+ _EGL_CHECK_EXTENSION(KHR_fence_sync);
_EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
+ _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
+ _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
_EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
- _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
- _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
-
+ _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
+ if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
+ _eglAppendExtension(&exts, "EGL_KHR_image");
+ _EGL_CHECK_EXTENSION(KHR_image_base);
+ _EGL_CHECK_EXTENSION(KHR_image_pixmap);
+ _EGL_CHECK_EXTENSION(KHR_no_config_context);
_EGL_CHECK_EXTENSION(KHR_reusable_sync);
- _EGL_CHECK_EXTENSION(KHR_fence_sync);
+ _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
_EGL_CHECK_EXTENSION(KHR_wait_sync);
- _EGL_CHECK_EXTENSION(KHR_cl_event2);
- _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
- _EGL_CHECK_EXTENSION(KHR_create_context);
+ if (dpy->Extensions.KHR_no_config_context)
+ _eglAppendExtension(&exts, "EGL_MESA_configless_context");
+ _EGL_CHECK_EXTENSION(MESA_drm_image);
+ _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
_EGL_CHECK_EXTENSION(NOK_swap_region);
_EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
- _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
-
- _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
-
- _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
- _EGL_CHECK_EXTENSION(EXT_buffer_age);
- _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
- _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
-
_EGL_CHECK_EXTENSION(NV_post_sub_buffer);
- _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
+ _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
+ _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
+
#undef _EGL_CHECK_EXTENSION
}
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 ");
assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
}
+static void
+_eglComputeVersion(_EGLDisplay *disp)
+{
+ disp->Version = 14;
+
+ if (disp->Extensions.KHR_fence_sync &&
+ disp->Extensions.KHR_cl_event2 &&
+ disp->Extensions.KHR_wait_sync &&
+ disp->Extensions.KHR_image_base &&
+ disp->Extensions.KHR_gl_texture_2D_image &&
+ disp->Extensions.KHR_gl_texture_3D_image &&
+ disp->Extensions.KHR_gl_texture_cubemap_image &&
+ disp->Extensions.KHR_gl_renderbuffer_image &&
+ disp->Extensions.KHR_create_context &&
+ disp->Extensions.EXT_create_context_robustness &&
+ disp->Extensions.KHR_get_all_proc_addresses &&
+ disp->Extensions.KHR_gl_colorspace &&
+ disp->Extensions.KHR_surfaceless_context)
+ disp->Version = 15;
+}
/**
* This is typically the second EGL function that an application calls.
*/
disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
+ _eglComputeVersion(disp);
_eglCreateExtensionsString(disp);
_eglCreateAPIsString(disp);
- _eglsnprintf(disp->VersionString, sizeof(disp->VersionString),
- "%d.%d (%s)", disp->VersionMajor, disp->VersionMinor,
+ snprintf(disp->VersionString, sizeof(disp->VersionString),
+ "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
disp->Driver->Name);
}
/* Update applications version of major and minor if not NULL */
if ((major != NULL) && (minor != NULL)) {
- *major = disp->VersionMajor;
- *minor = disp->VersionMinor;
+ *major = disp->Version / 10;
+ *minor = disp->Version % 10;
}
RETURN_EGL_SUCCESS(disp, EGL_TRUE);
_EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
- if (!config && !disp->Extensions.MESA_configless_context)
+ if (!config && !disp->Extensions.KHR_no_config_context)
RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
if (!share && share_list != EGL_NO_CONTEXT)
}
+EGLSurface EGLAPIENTRY
+eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
+ void *native_window,
+ const EGLAttrib *attrib_list)
+{
+ EGLSurface surface;
+ EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+
+ if (attrib_list && !int_attribs)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+ surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window,
+ int_attribs);
+ free(int_attribs);
+ return surface;
+}
+
+
static EGLSurface
_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
void *native_pixmap, const EGLint *attrib_list)
}
+EGLSurface EGLAPIENTRY
+eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
+ void *native_pixmap,
+ const EGLAttrib *attrib_list)
+{
+ EGLSurface surface;
+ EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+
+ if (attrib_list && !int_attribs)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+ surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap,
+ int_attribs);
+ free(int_attribs);
+ return surface;
+}
+
+
EGLSurface EGLAPIENTRY
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
}
-#ifdef EGL_EXT_swap_buffers_with_damage
-
static EGLBoolean EGLAPIENTRY
eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
EGLint *rects, EGLint n_rects)
RETURN_EGL_EVAL(disp, ret);
}
-#endif /* EGL_EXT_swap_buffers_with_damage */
-
EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = t->CurrentAPIIndex;
- EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
- EGLBoolean ret;
-
- if (api_index != es_index && _eglIsCurrentThreadDummy())
- RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
-
- t->CurrentAPIIndex = es_index;
- ret = eglWaitClient();
- t->CurrentAPIIndex = api_index;
- return ret;
+ /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
+ return eglWaitClient();
}
}
-#ifdef EGL_MESA_drm_display
-
-static EGLDisplay EGLAPIENTRY
-eglGetDRMDisplayMESA(int fd)
-{
- _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
- return _eglGetDisplayHandle(dpy);
-}
-
-#endif /* EGL_MESA_drm_display */
-
/**
** EGL 1.2
**/
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);
}
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);
}
/* unbind current contexts */
if (!_eglIsCurrentThreadDummy()) {
_EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = t->CurrentAPIIndex;
- EGLint i;
-
- for (i = 0; i < _EGL_API_NUM_APIS; i++) {
- _EGLContext *ctx = t->CurrentContexts[i];
- if (ctx) {
- _EGLDisplay *disp = ctx->Resource.Display;
- _EGLDriver *drv;
- t->CurrentAPIIndex = i;
+ _EGLContext *ctx = t->CurrentContext;
+ if (ctx) {
+ _EGLDisplay *disp = ctx->Resource.Display;
+ _EGLDriver *drv;
- mtx_lock(&disp->Mutex);
- drv = disp->Driver;
- (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
- mtx_unlock(&disp->Mutex);
- }
+ mtx_lock(&disp->Mutex);
+ drv = disp->Driver;
+ (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+ mtx_unlock(&disp->Mutex);
}
-
- t->CurrentAPIIndex = api_index;
}
_eglDestroyCurrentThread();
}
-static EGLImageKHR EGLAPIENTRY
+static EGLImage EGLAPIENTRY
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
{
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLDriver *drv;
_EGLImage *img;
- EGLImageKHR ret;
+ EGLImage ret;
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
if (!disp->Extensions.KHR_image_base)
}
-static EGLBoolean EGLAPIENTRY
-eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+EGLImage EGLAPIENTRY
+eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLAttrib *attr_list)
+{
+ EGLImage image;
+ EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
+
+ if (attr_list && !int_attribs)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE);
+
+ image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs);
+ free(int_attribs);
+ return image;
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglDestroyImage(EGLDisplay dpy, EGLImage image)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLImage *img = _eglLookupImage(image, disp);
}
-static EGLSyncKHR
+static EGLSync
_eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
- const EGLAttribKHR *attrib_list64, EGLBoolean is64)
+ const EGLAttrib *attrib_list64, EGLBoolean is64,
+ EGLenum invalid_type_error)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *ctx = _eglGetCurrentContext();
_EGLDriver *drv;
_EGLSync *sync;
- EGLSyncKHR ret;
+ EGLSync ret;
_EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
switch (type) {
case EGL_SYNC_FENCE_KHR:
if (!disp->Extensions.KHR_fence_sync)
- RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
break;
case EGL_SYNC_REUSABLE_KHR:
if (!disp->Extensions.KHR_reusable_sync)
- RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
break;
case EGL_SYNC_CL_EVENT_KHR:
if (!disp->Extensions.KHR_cl_event2)
- RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
break;
default:
- RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+ RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
}
sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
}
-static EGLSyncKHR EGLAPIENTRY
+static EGLSync EGLAPIENTRY
eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
{
- return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE);
+ return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE,
+ EGL_BAD_ATTRIBUTE);
}
-static EGLSyncKHR EGLAPIENTRY
-eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list)
+static EGLSync EGLAPIENTRY
+eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
- return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE);
+ return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+ EGL_BAD_ATTRIBUTE);
}
-static EGLBoolean EGLAPIENTRY
-eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+EGLSync EGLAPIENTRY
+eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+ return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+ EGL_BAD_PARAMETER);
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglDestroySync(EGLDisplay dpy, EGLSync sync)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
}
-static EGLint EGLAPIENTRY
-eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+EGLint EGLAPIENTRY
+eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
if (s->SyncStatus == EGL_SIGNALED_KHR)
RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
+ /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
+ * unlocked here to allow other threads also to be able to
+ * go into waiting state.
+ */
+
+ if (s->Type == EGL_SYNC_REUSABLE_KHR)
+ _eglUnlockDisplay(dpy);
+
ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
- RETURN_EGL_EVAL(disp, ret);
+ /*
+ * 'disp' is already unlocked for reusable sync type,
+ * so passing 'NULL' to bypass unlocking display.
+ */
+ if (s->Type == EGL_SYNC_REUSABLE_KHR)
+ RETURN_EGL_EVAL(NULL, ret);
+ else
+ RETURN_EGL_EVAL(disp, ret);
}
static EGLint EGLAPIENTRY
-eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
+eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
}
+EGLBoolean EGLAPIENTRY
+eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ /* The KHR version returns EGLint, while the core version returns
+ * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
+ * EGL_TRUE.
+ */
+ return eglWaitSyncKHR(dpy, sync, flags);
+}
+
+
static EGLBoolean EGLAPIENTRY
-eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
}
-static EGLBoolean EGLAPIENTRY
-eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+EGLBoolean EGLAPIENTRY
+eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLSync *s = _eglLookupSync(sync, disp);
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
assert(disp->Extensions.KHR_reusable_sync ||
disp->Extensions.KHR_fence_sync);
- ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
+ ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
-#ifdef EGL_NOK_swap_region
+static EGLBoolean EGLAPIENTRY
+eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
+{
+ EGLAttrib attrib;
+ EGLBoolean result;
+
+ if (!value)
+ RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ attrib = *value;
+ result = eglGetSyncAttrib(dpy, sync, attribute, &attrib);
+
+ /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
+ *
+ * If any error occurs, <*value> is not modified.
+ */
+ if (result == EGL_FALSE)
+ return result;
+
+ *value = attrib;
+ return result;
+}
+
static EGLBoolean EGLAPIENTRY
eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
RETURN_EGL_EVAL(disp, ret);
}
-#endif /* EGL_NOK_swap_region */
-
-#ifdef EGL_MESA_drm_image
-
-static EGLImageKHR EGLAPIENTRY
+static EGLImage EGLAPIENTRY
eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLDriver *drv;
_EGLImage *img;
- EGLImageKHR ret;
+ EGLImage ret;
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
if (!disp->Extensions.MESA_drm_image)
}
static EGLBoolean EGLAPIENTRY
-eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
+eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
EGLint *name, EGLint *handle, EGLint *stride)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
RETURN_EGL_EVAL(disp, ret);
}
-#endif
-#ifdef EGL_WL_bind_wayland_display
struct wl_display;
static EGLBoolean EGLAPIENTRY
RETURN_EGL_EVAL(disp, ret);
}
-#endif
-#ifdef EGL_WL_create_wayland_buffer_from_image
+
static struct wl_buffer * EGLAPIENTRY
-eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
+eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLImage *img;
RETURN_EGL_EVAL(disp, ret);
}
-#endif
static EGLBoolean EGLAPIENTRY
eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
RETURN_EGL_EVAL(disp, ret);
}
-#ifdef EGL_MESA_image_dma_buf_export
static EGLBoolean EGLAPIENTRY
-eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
+eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
EGLint *fourcc, EGLint *nplanes,
EGLuint64KHR *modifiers)
{
}
static EGLBoolean EGLAPIENTRY
-eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image,
+eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
int *fds, EGLint *strides, EGLint *offsets)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
RETURN_EGL_EVAL(disp, ret);
}
-#endif
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname)
const char *name;
_EGLProc function;
} egl_functions[] = {
- /* core functions should not be queryable, but, well... */
-#ifdef _EGL_GET_CORE_ADDRESSES
+ /* core functions queryable in the presence of
+ * EGL_KHR_get_all_proc_addresses or EGL 1.5
+ */
/* alphabetical order */
{ "eglBindAPI", (_EGLProc) eglBindAPI },
{ "eglBindTexImage", (_EGLProc) eglBindTexImage },
{ "eglWaitClient", (_EGLProc) eglWaitClient },
{ "eglWaitGL", (_EGLProc) eglWaitGL },
{ "eglWaitNative", (_EGLProc) eglWaitNative },
-#endif /* _EGL_GET_CORE_ADDRESSES */
-#ifdef EGL_MESA_drm_display
- { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
-#endif
+ { "eglCreateSync", (_EGLProc) eglCreateSync },
+ { "eglDestroySync", (_EGLProc) eglDestroySync },
+ { "eglClientWaitSync", (_EGLProc) eglClientWaitSync },
+ { "eglGetSyncAttrib", (_EGLProc) eglGetSyncAttrib },
+ { "eglWaitSync", (_EGLProc) eglWaitSync },
+ { "eglCreateImage", (_EGLProc) eglCreateImage },
+ { "eglDestroyImage", (_EGLProc) eglDestroyImage },
+ { "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay },
+ { "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface },
+ { "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface },
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
- { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
+ { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage },
{ "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
{ "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
- { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
- { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
+ { "eglDestroySyncKHR", (_EGLProc) eglDestroySync },
+ { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync },
{ "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
{ "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
{ "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
-#ifdef EGL_NOK_swap_region
{ "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
-#endif
-#ifdef EGL_MESA_drm_image
{ "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
{ "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
-#endif
-#ifdef EGL_WL_bind_wayland_display
{ "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
{ "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
{ "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
-#endif
-#ifdef EGL_WL_create_wayland_buffer_from_image
{ "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
-#endif
{ "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
-#ifdef EGL_EXT_swap_buffers_with_damage
{ "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
-#endif
{ "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
{ "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
{ "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
{ "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
-#ifdef EGL_MESA_image_dma_buf_export
{ "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
{ "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
-#endif
{ NULL, NULL }
};
EGLint i;
RETURN_EGL_SUCCESS(NULL, ret);
}
+
+static int
+_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
+ _EGLDisplay **disp, _EGLDriver **drv,
+ _EGLContext **ctx)
+{
+
+ *disp = _eglLockDisplay(dpy);
+ if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
+ if (*disp)
+ _eglUnlockDisplay(*disp);
+ return MESA_GLINTEROP_INVALID_DISPLAY;
+ }
+
+ *drv = (*disp)->Driver;
+
+ *ctx = _eglLookupContext(context, *disp);
+ if (!*ctx ||
+ ((*ctx)->ClientAPI != EGL_OPENGL_API &&
+ (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
+ _eglUnlockDisplay(*disp);
+ return MESA_GLINTEROP_INVALID_CONTEXT;
+ }
+
+ return MESA_GLINTEROP_SUCCESS;
+}
+
+int
+MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
+ struct mesa_glinterop_device_info *out)
+{
+ _EGLDisplay *disp;
+ _EGLDriver *drv;
+ _EGLContext *ctx;
+ int ret;
+
+ ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+ if (ret != MESA_GLINTEROP_SUCCESS)
+ return ret;
+
+ if (drv->API.GLInteropQueryDeviceInfo)
+ ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
+ else
+ ret = MESA_GLINTEROP_UNSUPPORTED;
+
+ _eglUnlockDisplay(disp);
+ return ret;
+}
+
+int
+MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
+ struct mesa_glinterop_export_in *in,
+ struct mesa_glinterop_export_out *out)
+{
+ _EGLDisplay *disp;
+ _EGLDriver *drv;
+ _EGLContext *ctx;
+ int ret;
+
+ ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+ if (ret != MESA_GLINTEROP_SUCCESS)
+ return ret;
+
+ if (drv->API.GLInteropExportObject)
+ ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
+ else
+ ret = MESA_GLINTEROP_UNSUPPORTED;
+
+ _eglUnlockDisplay(disp);
+ return ret;
+}