X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglapi.c;h=e8f856f6beb35e14ed10571da705b1d6c3ea3abb;hb=cd6a31cd4a9ea6deef4778c2eaef2d47240c3a6e;hp=b74b96015814b781c7f96ab14d1d63fbd37def9f;hpb=f3e03e1277839cddc35e0cc3427a7972bc17a10a;p=mesa.git diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index b74b9601581..e8f856f6beb 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -56,10 +56,11 @@ #include #include #include + +#include "eglstring.h" #include "eglcontext.h" #include "egldisplay.h" #include "egltypedefs.h" -#include "eglglobals.h" #include "eglcurrent.h" #include "egldriver.h" #include "eglsurface.h" @@ -67,49 +68,67 @@ #include "eglscreen.h" #include "eglmode.h" #include "eglimage.h" +#include "eglsync.h" /** * Macros to help return an API entrypoint. + * + * These macros will unlock the display and record the error code. */ -#define _EGL_ERROR(disp, err, ret) \ - ({ \ +#define RETURN_EGL_ERROR(disp, err, ret) \ + do { \ + if (disp) \ + _eglUnlockDisplay(disp); \ /* EGL error codes are non-zero */ \ if (err) \ _eglError(err, __FUNCTION__); \ - ret; \ - }) + return ret; \ + } while (0) +#define RETURN_EGL_SUCCESS(disp, ret) \ + RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret) -/** +/* record EGL_SUCCESS only when ret evaluates to true */ +#define RETURN_EGL_EVAL(disp, ret) \ + RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) + + +/* * A bunch of macros and checks to simplify error checking. */ -#define _EGL_CHECK_DISPLAY(disp, ret) \ - ({ \ - _EGLDriver *__drv = _eglCheckDisplay(disp, __FUNCTION__); \ - if (!__drv) \ - return _EGL_ERROR(disp, 0, ret); \ - __drv; \ - }) - - -#define _EGL_CHECK_OBJECT(disp, type, obj, ret) \ - ({ \ - _EGLDriver *__drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ - if (!__drv) \ - return _EGL_ERROR(disp, 0, ret); \ - __drv; \ - }) -#define _EGL_CHECK_SURFACE(disp, surf, ret) \ - _EGL_CHECK_OBJECT(disp, Surface, surf, ret) -#define _EGL_CHECK_CONTEXT(disp, context, ret) \ - _EGL_CHECK_OBJECT(disp, Context, context, ret) -#define _EGL_CHECK_CONFIG(disp, conf, ret) \ - _EGL_CHECK_OBJECT(disp, Config, conf, ret) -#define _EGL_CHECK_SCREEN(disp, scrn, ret) \ - _EGL_CHECK_OBJECT(disp, Screen, scrn, ret) -#define _EGL_CHECK_MODE(disp, m, ret) \ - _EGL_CHECK_OBJECT(disp, Mode, m, ret) + +#define _EGL_CHECK_DISPLAY(disp, ret, drv) \ + do { \ + drv = _eglCheckDisplay(disp, __FUNCTION__); \ + if (!drv) \ + RETURN_EGL_ERROR(disp, 0, ret); \ + } while (0) + +#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \ + do { \ + drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ + if (!drv) \ + RETURN_EGL_ERROR(disp, 0, ret); \ + } while (0) + +#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv) + +#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Context, context, ret, drv) + +#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv) + +#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv) + +#define _EGL_CHECK_MODE(disp, m, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) + +#define _EGL_CHECK_SYNC(disp, s, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) static INLINE _EGLDriver * @@ -169,6 +188,26 @@ _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) } +#ifdef EGL_KHR_reusable_sync + + +static INLINE _EGLDriver * +_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!s) { + _eglError(EGL_BAD_PARAMETER, msg); + return NULL; + } + return drv; +} + + +#endif /* EGL_KHR_reusable_sync */ + + #ifdef EGL_MESA_screen_surface @@ -203,20 +242,38 @@ _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) #endif /* EGL_MESA_screen_surface */ +/** + * Lookup and lock a display. + */ +static INLINE _EGLDisplay * +_eglLockDisplay(EGLDisplay display) +{ + _EGLDisplay *dpy = _eglLookupDisplay(display); + if (dpy) + _eglLockMutex(&dpy->Mutex); + return dpy; +} + + +/** + * Unlock a display. + */ +static INLINE void +_eglUnlockDisplay(_EGLDisplay *dpy) +{ + _eglUnlockMutex(&dpy->Mutex); +} + + /** * This is typically the first EGL function that an application calls. - * We initialize our global vars and create a private _EGLDisplay object. + * It associates a private _EGLDisplay object to the native display. */ EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType nativeDisplay) { - _EGLDisplay *dpy; - dpy = _eglFindDisplay(nativeDisplay); - if (!dpy) { - dpy = _eglNewDisplay(nativeDisplay); - if (dpy) - _eglLinkDisplay(dpy); - } + _EGLPlatformType plat = _eglGetNativePlatform(); + _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay); return _eglGetDisplayHandle(dpy); } @@ -228,58 +285,38 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay) EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - EGLint major_int, minor_int; + _EGLDisplay *disp = _eglLockDisplay(dpy); if (!disp) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); if (!disp->Initialized) { - _EGLDriver *drv = disp->Driver; - - if (!drv) { - _eglPreloadDrivers(); - drv = _eglMatchDriver(disp); - if (!drv) - return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); - } - - /* Initialize the particular display now */ - if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) - return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); - - disp->APImajor = major_int; - disp->APIminor = minor_int; - snprintf(disp->Version, sizeof(disp->Version), - "%d.%d (%s)", major_int, minor_int, drv->Name); + if (!_eglMatchDriver(disp, EGL_FALSE)) + RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); + _eglsnprintf(disp->Version, sizeof(disp->Version), "%d.%d (%s)", + disp->APImajor, disp->APIminor, disp->Driver->Name); /* limit to APIs supported by core */ disp->ClientAPIsMask &= _EGL_API_ALL_BITS; - - disp->Driver = drv; - disp->Initialized = EGL_TRUE; - } else { - major_int = disp->APImajor; - minor_int = disp->APIminor; } /* Update applications version of major and minor if not NULL */ if ((major != NULL) && (minor != NULL)) { - *major = major_int; - *minor = minor_int; + *major = disp->APImajor; + *minor = disp->APIminor; } - return EGL_TRUE; + RETURN_EGL_SUCCESS(disp, EGL_TRUE); } EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); if (!disp) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); if (disp->Initialized) { _EGLDriver *drv = disp->Driver; @@ -289,69 +326,21 @@ eglTerminate(EGLDisplay dpy) disp->Initialized = EGL_FALSE; } - return EGL_TRUE; + RETURN_EGL_SUCCESS(disp, EGL_TRUE); } -#define _EGL_DECLARE_DD(dpy) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckDisplay(disp, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - -#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLSurface *surf = _eglLookupSurface((surface), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckSurface(disp, surf, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - -#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLContext *context = _eglLookupContext((ctx), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckContext(disp, context, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - -#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLScreen *scrn = _eglLookupScreen((screen), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - -#define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLMode *m = _eglLookupMode((mode), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckMode(disp, m, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) { - _EGL_DECLARE_DD(dpy); - return drv->API.QueryString(drv, disp, name); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + const char *ret; + + _EGL_CHECK_DISPLAY(disp, NULL, drv); + ret = drv->API.QueryString(drv, disp, name); + + RETURN_EGL_EVAL(disp, ret); } @@ -359,8 +348,14 @@ EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - _EGL_DECLARE_DD(dpy); - return drv->API.GetConfigs(drv, disp, configs, config_size, num_config); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config); + + RETURN_EGL_EVAL(disp, ret); } @@ -368,9 +363,15 @@ EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - _EGL_DECLARE_DD(dpy); - return drv->API.ChooseConfig(drv, disp, attrib_list, configs, + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, config_size, num_config); + + RETURN_EGL_EVAL(disp, ret); } @@ -378,15 +379,15 @@ EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_FALSE; + _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv); + ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); - return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); + RETURN_EGL_EVAL(disp, ret); } @@ -394,34 +395,46 @@ EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLContext *share = _eglLookupContext(share_list, disp); _EGLDriver *drv; _EGLContext *context; + EGLContext ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_CONTEXT; - if (!share && share_list != EGL_NO_CONTEXT) { - _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - return EGL_NO_CONTEXT; + _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv); + + if (!config) { + /* config may be NULL if surfaceless */ + if (!disp->Extensions.KHR_surfaceless_gles1 && + !disp->Extensions.KHR_surfaceless_gles2 && + !disp->Extensions.KHR_surfaceless_opengl) + RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT); } + 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); - if (context) - return _eglLinkContext(context, disp); - else - return EGL_NO_CONTEXT; + ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT; + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); _eglUnlinkContext(context); - return drv->API.DestroyContext(drv, disp, context); + ret = drv->API.DestroyContext(drv, disp, context); + + RETURN_EGL_EVAL(disp, ret); } @@ -429,32 +442,45 @@ EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *context = _eglLookupContext(ctx, disp); _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); _EGLSurface *read_surf = _eglLookupSurface(read, disp); _EGLDriver *drv; + EGLBoolean ret; if (!disp) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); drv = disp->Driver; /* display is allowed to be uninitialized under certain condition */ if (!disp->Initialized) { if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || ctx != EGL_NO_CONTEXT) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); } if (!drv) - return EGL_TRUE; + RETURN_EGL_SUCCESS(disp, EGL_TRUE); if (!context && ctx != EGL_NO_CONTEXT) - return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - if ((!draw_surf && draw != EGL_NO_SURFACE) || - (!read_surf && read != EGL_NO_SURFACE)) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); + if (!draw_surf || !read_surf) { + /* surfaces may be NULL if surfaceless */ + if (!disp->Extensions.KHR_surfaceless_gles1 && + !disp->Extensions.KHR_surfaceless_gles2 && + !disp->Extensions.KHR_surfaceless_opengl) + RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); + + if ((!draw_surf && draw != EGL_NO_SURFACE) || + (!read_surf && read != EGL_NO_SURFACE)) + RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); + if (draw_surf || read_surf) + RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); + } - return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); + ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); + + RETURN_EGL_EVAL(disp, ret); } @@ -462,8 +488,15 @@ EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); - return drv->API.QueryContext(drv, disp, context, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); + ret = drv->API.QueryContext(drv, disp, context, attribute, value); + + RETURN_EGL_EVAL(disp, ret); } @@ -471,20 +504,20 @@ EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); + if (disp->Platform != _eglGetNativePlatform()) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + RETURN_EGL_EVAL(disp, ret); } @@ -492,20 +525,20 @@ EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); + if (disp->Platform != _eglGetNativePlatform()) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + RETURN_EGL_EVAL(disp, ret); } @@ -513,79 +546,118 @@ EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); _eglUnlinkSurface(surf); - return drv->API.DestroySurface(drv, disp, surf); + ret = drv->API.DestroySurface(drv, disp, surf); + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.QuerySurface(drv, disp, surf, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + ret = drv->API.QuerySurface(drv, disp, surf, attribute, value); + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.BindTexImage(drv, disp, surf, buffer); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + ret = drv->API.BindTexImage(drv, disp, surf, buffer); + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.ReleaseTexImage(drv, disp, surf, buffer); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer); + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) { + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *ctx = _eglGetCurrentContext(); _EGLSurface *surf; - _EGL_DECLARE_DD(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp) - return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); surf = ctx->DrawSurface; if (!_eglIsSurfaceLinked(surf)) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); + + ret = drv->API.SwapInterval(drv, disp, surf, interval); - return drv->API.SwapInterval(drv, disp, surf, interval); + RETURN_EGL_EVAL(disp, ret); } @@ -593,21 +665,37 @@ EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { _EGLContext *ctx = _eglGetCurrentContext(); - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); /* surface must be bound to current context in EGL 1.4 */ if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - return drv->API.SwapBuffers(drv, disp, surf); + ret = drv->API.SwapBuffers(drv, disp, surf); + + RETURN_EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.CopyBuffers(drv, disp, surf, target); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + if (disp->Platform != _eglGetNativePlatform()) + RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE); + ret = drv->API.CopyBuffers(drv, disp, surf, target); + + RETURN_EGL_EVAL(disp, ret); } @@ -617,19 +705,24 @@ eglWaitClient(void) _EGLContext *ctx = _eglGetCurrentContext(); _EGLDisplay *disp; _EGLDriver *drv; + EGLBoolean ret; if (!ctx) - return EGL_TRUE; + RETURN_EGL_SUCCESS(NULL, EGL_TRUE); + + disp = ctx->Resource.Display; + _eglLockMutex(&disp->Mutex); + /* let bad current context imply bad current surface */ if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) - return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); /* a valid current context implies an initialized current display */ - disp = ctx->Resource.Display; assert(disp->Initialized); drv = disp->Driver; + ret = drv->API.WaitClient(drv, disp, ctx); - return drv->API.WaitClient(drv, disp, ctx); + RETURN_EGL_EVAL(disp, ret); } @@ -643,7 +736,7 @@ eglWaitGL(void) EGLBoolean ret; if (api_index != es_index && _eglIsCurrentThreadDummy()) - return _eglError(EGL_BAD_ALLOC, "eglWaitGL"); + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); t->CurrentAPIIndex = es_index; ret = eglWaitClient(); @@ -661,19 +754,24 @@ eglWaitNative(EGLint engine) _EGLContext *ctx = _eglGetCurrentContext(); _EGLDisplay *disp; _EGLDriver *drv; + EGLBoolean ret; if (!ctx) - return EGL_TRUE; + RETURN_EGL_SUCCESS(NULL, EGL_TRUE); + + disp = ctx->Resource.Display; + _eglLockMutex(&disp->Mutex); + /* let bad current context imply bad current surface */ if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) - return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); /* a valid current context implies an initialized current display */ - disp = ctx->Resource.Display; assert(disp->Initialized); drv = disp->Driver; + ret = drv->API.WaitNative(drv, disp, engine); - return drv->API.WaitNative(drv, disp, engine); + RETURN_EGL_EVAL(disp, ret); } @@ -681,7 +779,11 @@ EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) { _EGLContext *ctx = _eglGetCurrentContext(); - return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; + EGLDisplay ret; + + ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; + + RETURN_EGL_SUCCESS(NULL, ret); } @@ -689,7 +791,11 @@ EGLContext EGLAPIENTRY eglGetCurrentContext(void) { _EGLContext *ctx = _eglGetCurrentContext(); - return _eglGetContextHandle(ctx); + EGLContext ret; + + ret = _eglGetContextHandle(ctx); + + RETURN_EGL_SUCCESS(NULL, ret); } @@ -697,10 +803,12 @@ EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) { _EGLContext *ctx = _eglGetCurrentContext(); + EGLint err = EGL_SUCCESS; _EGLSurface *surf; + EGLSurface ret; if (!ctx) - return EGL_NO_SURFACE; + RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE); switch (readdraw) { case EGL_DRAW: @@ -710,12 +818,14 @@ eglGetCurrentSurface(EGLint readdraw) surf = ctx->ReadSurface; break; default: - _eglError(EGL_BAD_PARAMETER, __FUNCTION__); surf = NULL; + err = EGL_BAD_PARAMETER; break; } - return _eglGetSurfaceHandle(surf); + ret = _eglGetSurfaceHandle(surf); + + RETURN_EGL_ERROR(NULL, err, ret); } @@ -737,7 +847,44 @@ eglGetProcAddress(const char *procname) const char *name; _EGLProc function; } egl_functions[] = { - /* extensions only */ + /* core functions should not be queryable, but, well... */ +#ifdef _EGL_GET_CORE_ADDRESSES + /* 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 }, +#endif /* _EGL_GET_CORE_ADDRESSES */ #ifdef EGL_MESA_screen_surface { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, @@ -752,34 +899,41 @@ eglGetProcAddress(const char *procname) { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, #endif /* EGL_MESA_screen_surface */ +#ifdef EGL_MESA_drm_display + { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, +#endif #ifdef EGL_KHR_image_base { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, #endif /* EGL_KHR_image_base */ +#ifdef EGL_NOK_swap_region + { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, +#endif +#ifdef EGL_MESA_drm_image + { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, + { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, +#endif { NULL, NULL } }; EGLint i; + _EGLProc ret; if (!procname) - return NULL; + RETURN_EGL_SUCCESS(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) - return egl_functions[i].function; + if (strcmp(egl_functions[i].name, procname) == 0) { + ret = egl_functions[i].function; + break; + } } } + if (!ret) + ret = _eglGetDriverProc(procname); - _eglPreloadDrivers(); - - /* now loop over drivers to query their procs */ - for (i = 0; i < _eglGlobal.NumDrivers; i++) { - _EGLDriver *drv = _eglGlobal.Drivers[i]; - _EGLProc p = drv->API.GetProcAddress(drv, procname); - if (p) - return p; - } - - return NULL; + RETURN_EGL_SUCCESS(NULL, ret); } @@ -795,9 +949,16 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, - modes, modes_size, num_modes); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); + ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, + modes, modes_size, num_modes); + + RETURN_EGL_EVAL(disp, ret); } @@ -805,8 +966,15 @@ EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); + ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); + + RETURN_EGL_EVAL(disp, ret); } @@ -814,8 +982,15 @@ EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_MODE(dpy, mode); - return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLMode *m = _eglLookupMode(mode, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv); + ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); + + RETURN_EGL_EVAL(disp, ret); } @@ -823,146 +998,177 @@ EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *source_context = _eglLookupContext(source, disp); _EGLContext *dest_context = _eglLookupContext(dest, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckContext(disp, source_context, __FUNCTION__); - if (!drv || !dest_context) { - if (drv) - _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - return EGL_FALSE; - } + _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv); + if (!dest_context) + RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); + + ret = drv->API.CopyContextMESA(drv, disp, + source_context, dest_context, mask); - return drv->API.CopyContextMESA(drv, disp, source_context, dest_context, - mask); + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens) { - _EGL_DECLARE_DD(dpy); - return drv->API.GetScreensMESA(drv, disp, screens, - max_screens, num_screens); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); + + RETURN_EGL_EVAL(disp, ret); } -EGLSurface +EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); _EGLSurface *surf = _eglLookupSurface(surface, disp); _EGLMode *m = _eglLookupMode(mode, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); - if (!drv) - return EGL_FALSE; + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); if (!surf && surface != EGL_NO_SURFACE) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); if (!m && mode != EGL_NO_MODE_MESA) - return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); - return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); + ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); + ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); + ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLBoolean ret; - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); - if (!drv) - return EGL_FALSE; - - if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE) - surf = NULL; - if (surface) + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); + ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); + if (ret && surface) *surface = _eglGetSurfaceHandle(surf); - return (surf != NULL); + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); _EGLDriver *drv; _EGLMode *m; + EGLBoolean ret; - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); - if (!drv) - return EGL_FALSE; - - if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE) - m = NULL; - if (mode) + _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); + ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); + if (ret && mode) *mode = m->Handle; - return (m != NULL); + RETURN_EGL_EVAL(disp, ret); } -const char * +const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) { - _EGL_DECLARE_DD_AND_MODE(dpy, mode); - return drv->API.QueryModeStringMESA(drv, disp, m); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLMode *m = _eglLookupMode(mode, disp); + _EGLDriver *drv; + const char *ret; + + _EGL_CHECK_MODE(disp, m, NULL, drv); + ret = drv->API.QueryModeStringMESA(drv, disp, m); + + RETURN_EGL_EVAL(disp, ret); } #endif /* EGL_MESA_screen_surface */ +#ifdef EGL_MESA_drm_display + +EGLDisplay EGLAPIENTRY +eglGetDRMDisplayMESA(int fd) +{ + _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) fd); + return _eglGetDisplayHandle(dpy); +} + +#endif /* EGL_MESA_drm_display */ + /** ** EGL 1.2 **/ @@ -981,58 +1187,61 @@ eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) * eglWaitNative() * See section 3.7 "Rendering Context" in the EGL specification for details. */ -EGLBoolean +EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api) { _EGLThreadInfo *t = _eglGetCurrentThread(); if (_eglIsCurrentThreadDummy()) - return _eglError(EGL_BAD_ALLOC, "eglBindAPI"); + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); if (!_eglIsApiValid(api)) - return _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); + RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); t->CurrentAPIIndex = _eglConvertApiToIndex(api); - return EGL_TRUE; + + RETURN_EGL_SUCCESS(NULL, EGL_TRUE); } /** * Return the last value set with eglBindAPI(). */ -EGLenum +EGLenum EGLAPIENTRY eglQueryAPI(void) { - /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ _EGLThreadInfo *t = _eglGetCurrentThread(); - return _eglConvertApiFromIndex(t->CurrentAPIIndex); + EGLenum ret; + + /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ + ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); + + RETURN_EGL_SUCCESS(NULL, ret); } -EGLSurface +EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, conf, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean +EGLBoolean EGLAPIENTRY eglReleaseThread(void) { /* unbind current contexts */ @@ -1045,9 +1254,14 @@ eglReleaseThread(void) _EGLContext *ctx = t->CurrentContexts[i]; if (ctx) { _EGLDisplay *disp = ctx->Resource.Display; - _EGLDriver *drv = disp->Driver; + _EGLDriver *drv; + t->CurrentAPIIndex = i; + + _eglLockMutex(&disp->Mutex); + drv = disp->Driver; (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + _eglUnlockMutex(&disp->Mutex); } } @@ -1055,7 +1269,8 @@ eglReleaseThread(void) } _eglDestroyCurrentThread(); - return EGL_TRUE; + + RETURN_EGL_SUCCESS(NULL, EGL_TRUE); } @@ -1065,47 +1280,212 @@ eglReleaseThread(void) #ifdef EGL_KHR_image_base -EGLImageKHR +EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *context = _eglLookupContext(ctx, disp); _EGLDriver *drv; _EGLImage *img; + EGLImageKHR ret; - drv = _eglCheckDisplay(disp, __FUNCTION__); - if (!drv) - return EGL_NO_IMAGE_KHR; - if (!context && ctx != EGL_NO_CONTEXT) { - _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - return EGL_NO_IMAGE_KHR; - } + _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); + if (!disp->Extensions.KHR_image_base) + RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); + if (!context && ctx != EGL_NO_CONTEXT) + RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); img = drv->API.CreateImageKHR(drv, disp, context, target, buffer, attr_list); - if (img) - return _eglLinkImage(img, disp); - else - return EGL_NO_IMAGE_KHR; + ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR; + + RETURN_EGL_EVAL(disp, ret); } -EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +EGLBoolean EGLAPIENTRY +eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img = _eglLookupImage(image, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckDisplay(disp, __FUNCTION__); - if (!drv) - return EGL_FALSE; + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + if (!disp->Extensions.KHR_image_base) + RETURN_EGL_EVAL(disp, EGL_FALSE); if (!img) - return _eglError(EGL_BAD_PARAMETER, __FUNCTION__); + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); _eglUnlinkImage(img); - return drv->API.DestroyImageKHR(drv, disp, img); + ret = drv->API.DestroyImageKHR(drv, disp, img); + + RETURN_EGL_EVAL(disp, ret); } #endif /* EGL_KHR_image_base */ + + +#ifdef EGL_KHR_reusable_sync + + +EGLSyncKHR EGLAPIENTRY +eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + _EGLSync *sync; + EGLSyncKHR ret; + + _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); + if (!disp->Extensions.KHR_reusable_sync) + RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR); + + sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list); + ret = (sync) ? _eglLinkSync(sync, disp) : EGL_NO_SYNC_KHR; + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLBoolean EGLAPIENTRY +eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + assert(disp->Extensions.KHR_reusable_sync); + + _eglUnlinkSync(s); + ret = drv->API.DestroySyncKHR(drv, disp, s); + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLint EGLAPIENTRY +eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLint ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + assert(disp->Extensions.KHR_reusable_sync); + ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout); + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLBoolean EGLAPIENTRY +eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + assert(disp->Extensions.KHR_reusable_sync); + ret = drv->API.SignalSyncKHR(drv, disp, s, mode); + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLBoolean EGLAPIENTRY +eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + assert(disp->Extensions.KHR_reusable_sync); + ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); + + RETURN_EGL_EVAL(disp, ret); +} + + +#endif /* EGL_KHR_reusable_sync */ + + +#ifdef EGL_NOK_swap_region + +EGLBoolean EGLAPIENTRY +eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, + EGLint numRects, const EGLint *rects) +{ + _EGLContext *ctx = _eglGetCurrentContext(); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); + + if (!disp->Extensions.NOK_swap_region) + RETURN_EGL_EVAL(disp, EGL_FALSE); + + /* surface must be bound to current context in EGL 1.4 */ + if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) + RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); + + ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects); + + RETURN_EGL_EVAL(disp, ret); +} + +#endif /* EGL_NOK_swap_region */ + + +#ifdef EGL_MESA_drm_image + +EGLImageKHR EGLAPIENTRY +eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + _EGLImage *img; + EGLImageKHR ret; + + _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); + if (!disp->Extensions.MESA_drm_image) + RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); + + img = drv->API.CreateDRMImageMESA(drv, disp, attr_list); + ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR; + + RETURN_EGL_EVAL(disp, ret); +} + +EGLBoolean EGLAPIENTRY +eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, + EGLint *name, EGLint *handle, EGLint *stride) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLImage *img = _eglLookupImage(image, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + assert(disp->Extensions.MESA_drm_image); + + if (!img) + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); + + ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride); + + RETURN_EGL_EVAL(disp, ret); +} + +#endif