Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 VMware, Inc.
  4.  * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
  5.  * Copyright 2010-2011 LunarG, Inc.
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the
  10.  * "Software"), to deal in the Software without restriction, including
  11.  * without limitation the rights to use, copy, modify, merge, publish,
  12.  * distribute, sub license, and/or sell copies of the Software, and to
  13.  * permit persons to whom the Software is furnished to do so, subject to
  14.  * the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice (including the
  17.  * next paragraph) shall be included in all copies or substantial portions
  18.  * of the Software.
  19.  *
  20.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  23.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26.  * DEALINGS IN THE SOFTWARE.
  27.  *
  28.  **************************************************************************/
  29.  
  30.  
  31. /**
  32.  * Public EGL API entrypoints
  33.  *
  34.  * Generally, we use the EGLDisplay parameter as a key to lookup the
  35.  * appropriate device driver handle, then jump though the driver's
  36.  * dispatch table to handle the function.
  37.  *
  38.  * That allows us the option of supporting multiple, simultaneous,
  39.  * heterogeneous hardware devices in the future.
  40.  *
  41.  * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
  42.  * opaque handles. Internal objects are linked to a display to
  43.  * create the handles.
  44.  *
  45.  * For each public API entry point, the opaque handles are looked up
  46.  * before being dispatched to the drivers.  When it fails to look up
  47.  * a handle, one of
  48.  *
  49.  * EGL_BAD_DISPLAY
  50.  * EGL_BAD_CONFIG
  51.  * EGL_BAD_CONTEXT
  52.  * EGL_BAD_SURFACE
  53.  * EGL_BAD_SCREEN_MESA
  54.  * EGL_BAD_MODE_MESA
  55.  *
  56.  * is generated and the driver function is not called. An
  57.  * uninitialized EGLDisplay has no driver associated with it. When
  58.  * such display is detected,
  59.  *
  60.  * EGL_NOT_INITIALIZED
  61.  *
  62.  * is generated.
  63.  *
  64.  * Some of the entry points use current display, context, or surface
  65.  * implicitly.  For such entry points, the implicit objects are also
  66.  * checked before calling the driver function.  Other than the
  67.  * errors listed above,
  68.  *
  69.  * EGL_BAD_CURRENT_SURFACE
  70.  *
  71.  * may also be generated.
  72.  *
  73.  * Notes on naming conventions:
  74.  *
  75.  * eglFooBar    - public EGL function
  76.  * EGL_FOO_BAR  - public EGL token
  77.  * EGLDatatype  - public EGL datatype
  78.  *
  79.  * _eglFooBar   - private EGL function
  80.  * _EGLDatatype - private EGL datatype, typedef'd struct
  81.  * _egl_struct  - private EGL struct, non-typedef'd
  82.  *
  83.  */
  84.  
  85.  
  86. #include <stdio.h>
  87. #include <stdlib.h>
  88. #include <string.h>
  89. #include "c99_compat.h"
  90. #include "c11/threads.h"
  91. #include "eglcompiler.h"
  92.  
  93. #include "eglglobals.h"
  94. #include "eglcontext.h"
  95. #include "egldisplay.h"
  96. #include "egltypedefs.h"
  97. #include "eglcurrent.h"
  98. #include "egldriver.h"
  99. #include "eglsurface.h"
  100. #include "eglconfig.h"
  101. #include "eglimage.h"
  102. #include "eglsync.h"
  103. #include "eglstring.h"
  104.  
  105.  
  106. /**
  107.  * Macros to help return an API entrypoint.
  108.  *
  109.  * These macros will unlock the display and record the error code.
  110.  */
  111. #define RETURN_EGL_ERROR(disp, err, ret)        \
  112.    do {                                         \
  113.       if (disp)                                 \
  114.          _eglUnlockDisplay(disp);               \
  115.       /* EGL error codes are non-zero */        \
  116.       if (err)                                  \
  117.          _eglError(err, __func__);              \
  118.       return ret;                               \
  119.    } while (0)
  120.  
  121. #define RETURN_EGL_SUCCESS(disp, ret) \
  122.    RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
  123.  
  124. /* record EGL_SUCCESS only when ret evaluates to true */
  125. #define RETURN_EGL_EVAL(disp, ret) \
  126.    RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
  127.  
  128.  
  129. /*
  130.  * A bunch of macros and checks to simplify error checking.
  131.  */
  132.  
  133. #define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
  134.    do {                                            \
  135.       drv = _eglCheckDisplay(disp, __func__);      \
  136.       if (!drv)                                    \
  137.          RETURN_EGL_ERROR(disp, 0, ret);           \
  138.    } while (0)
  139.  
  140. #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
  141.    do {                                                   \
  142.       drv = _eglCheck ## type(disp, obj, __func__);       \
  143.       if (!drv)                                           \
  144.          RETURN_EGL_ERROR(disp, 0, ret);                  \
  145.    } while (0)
  146.  
  147. #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
  148.    _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
  149.  
  150. #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
  151.    _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
  152.  
  153. #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
  154.    _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
  155.  
  156. #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
  157.    _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
  158.  
  159.  
  160. static inline _EGLDriver *
  161. _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
  162. {
  163.    if (!disp) {
  164.       _eglError(EGL_BAD_DISPLAY, msg);
  165.       return NULL;
  166.    }
  167.    if (!disp->Initialized) {
  168.       _eglError(EGL_NOT_INITIALIZED, msg);
  169.       return NULL;
  170.    }
  171.    return disp->Driver;
  172. }
  173.  
  174.  
  175. static inline _EGLDriver *
  176. _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
  177. {
  178.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  179.    if (!drv)
  180.       return NULL;
  181.    if (!surf) {
  182.       _eglError(EGL_BAD_SURFACE, msg);
  183.       return NULL;
  184.    }
  185.    return drv;
  186. }
  187.  
  188.  
  189. static inline _EGLDriver *
  190. _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
  191. {
  192.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  193.    if (!drv)
  194.       return NULL;
  195.    if (!context) {
  196.       _eglError(EGL_BAD_CONTEXT, msg);
  197.       return NULL;
  198.    }
  199.    return drv;
  200. }
  201.  
  202.  
  203. static inline _EGLDriver *
  204. _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
  205. {
  206.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  207.    if (!drv)
  208.       return NULL;
  209.    if (!conf) {
  210.       _eglError(EGL_BAD_CONFIG, msg);
  211.       return NULL;
  212.    }
  213.    return drv;
  214. }
  215.  
  216.  
  217. static inline _EGLDriver *
  218. _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
  219. {
  220.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  221.    if (!drv)
  222.       return NULL;
  223.    if (!s) {
  224.       _eglError(EGL_BAD_PARAMETER, msg);
  225.       return NULL;
  226.    }
  227.    return drv;
  228. }
  229.  
  230.  
  231. /**
  232.  * Lookup and lock a display.
  233.  */
  234. static inline _EGLDisplay *
  235. _eglLockDisplay(EGLDisplay display)
  236. {
  237.    _EGLDisplay *dpy = _eglLookupDisplay(display);
  238.    if (dpy)
  239.       mtx_lock(&dpy->Mutex);
  240.    return dpy;
  241. }
  242.  
  243.  
  244. /**
  245.  * Unlock a display.
  246.  */
  247. static inline void
  248. _eglUnlockDisplay(_EGLDisplay *dpy)
  249. {
  250.    mtx_unlock(&dpy->Mutex);
  251. }
  252.  
  253.  
  254. /**
  255.  * This is typically the first EGL function that an application calls.
  256.  * It associates a private _EGLDisplay object to the native display.
  257.  */
  258. EGLDisplay EGLAPIENTRY
  259. eglGetDisplay(EGLNativeDisplayType nativeDisplay)
  260. {
  261.    _EGLPlatformType plat;
  262.    _EGLDisplay *dpy;
  263.    void *native_display_ptr;
  264.  
  265.    STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
  266.    native_display_ptr = (void*) nativeDisplay;
  267.  
  268.    plat = _eglGetNativePlatform(native_display_ptr);
  269.    dpy = _eglFindDisplay(plat, native_display_ptr);
  270.    return _eglGetDisplayHandle(dpy);
  271. }
  272.  
  273. static EGLDisplay EGLAPIENTRY
  274. eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
  275.                          const EGLint *attrib_list)
  276. {
  277.    _EGLDisplay *dpy;
  278.  
  279.    switch (platform) {
  280. #ifdef HAVE_X11_PLATFORM
  281.    case EGL_PLATFORM_X11_EXT:
  282.       dpy = _eglGetX11Display((Display*) native_display, attrib_list);
  283.       break;
  284. #endif
  285. #ifdef HAVE_DRM_PLATFORM
  286.    case EGL_PLATFORM_GBM_MESA:
  287.       dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
  288.                               attrib_list);
  289.       break;
  290. #endif
  291. #ifdef HAVE_WAYLAND_PLATFORM
  292.    case EGL_PLATFORM_WAYLAND_EXT:
  293.       dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
  294.                                   attrib_list);
  295.       break;
  296. #endif
  297.    default:
  298.       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
  299.    }
  300.  
  301.    return _eglGetDisplayHandle(dpy);
  302. }
  303.  
  304. /**
  305.  * Copy the extension into the string and update the string pointer.
  306.  */
  307. static EGLint
  308. _eglAppendExtension(char **str, const char *ext)
  309. {
  310.    char *s = *str;
  311.    size_t len = strlen(ext);
  312.  
  313.    if (s) {
  314.       memcpy(s, ext, len);
  315.       s[len++] = ' ';
  316.       s[len] = '\0';
  317.  
  318.       *str += len;
  319.    }
  320.    else {
  321.       len++;
  322.    }
  323.  
  324.    return (EGLint) len;
  325. }
  326.  
  327. /**
  328.  * Examine the individual extension enable/disable flags and recompute
  329.  * the driver's Extensions string.
  330.  */
  331. static void
  332. _eglCreateExtensionsString(_EGLDisplay *dpy)
  333. {
  334. #define _EGL_CHECK_EXTENSION(ext)                                          \
  335.    do {                                                                    \
  336.       if (dpy->Extensions.ext) {                                           \
  337.          _eglAppendExtension(&exts, "EGL_" #ext);                          \
  338.          assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN);  \
  339.       }                                                                    \
  340.    } while (0)
  341.  
  342.    char *exts = dpy->ExtensionsString;
  343.  
  344.    _EGL_CHECK_EXTENSION(MESA_drm_display);
  345.    _EGL_CHECK_EXTENSION(MESA_drm_image);
  346.    _EGL_CHECK_EXTENSION(MESA_configless_context);
  347.  
  348.    _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
  349.    _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
  350.  
  351.    _EGL_CHECK_EXTENSION(KHR_image_base);
  352.    _EGL_CHECK_EXTENSION(KHR_image_pixmap);
  353.    if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
  354.       _eglAppendExtension(&exts, "EGL_KHR_image");
  355.  
  356.    _EGL_CHECK_EXTENSION(KHR_vg_parent_image);
  357.    _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
  358.    _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
  359.    _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
  360.    _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
  361.    _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
  362.  
  363.    _EGL_CHECK_EXTENSION(KHR_reusable_sync);
  364.    _EGL_CHECK_EXTENSION(KHR_fence_sync);
  365.    _EGL_CHECK_EXTENSION(KHR_wait_sync);
  366.    _EGL_CHECK_EXTENSION(KHR_cl_event2);
  367.  
  368.    _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
  369.    _EGL_CHECK_EXTENSION(KHR_create_context);
  370.  
  371.    _EGL_CHECK_EXTENSION(NOK_swap_region);
  372.    _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
  373.  
  374.    _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
  375.  
  376.    _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
  377.  
  378.    _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
  379.    _EGL_CHECK_EXTENSION(EXT_buffer_age);
  380.    _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
  381.    _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
  382.  
  383.    _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
  384.  
  385.    _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
  386. #undef _EGL_CHECK_EXTENSION
  387. }
  388.  
  389. static void
  390. _eglCreateAPIsString(_EGLDisplay *dpy)
  391. {
  392.    if (dpy->ClientAPIs & EGL_OPENGL_BIT)
  393.       strcat(dpy->ClientAPIsString, "OpenGL ");
  394.  
  395.    if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT)
  396.       strcat(dpy->ClientAPIsString, "OpenGL_ES ");
  397.  
  398.    if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT)
  399.       strcat(dpy->ClientAPIsString, "OpenGL_ES2 ");
  400.  
  401.    if (dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR)
  402.       strcat(dpy->ClientAPIsString, "OpenGL_ES3 ");
  403.  
  404.    if (dpy->ClientAPIs & EGL_OPENVG_BIT)
  405.       strcat(dpy->ClientAPIsString, "OpenVG ");
  406.  
  407.    assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
  408. }
  409.  
  410.  
  411. /**
  412.  * This is typically the second EGL function that an application calls.
  413.  * Here we load/initialize the actual hardware driver.
  414.  */
  415. EGLBoolean EGLAPIENTRY
  416. eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
  417. {
  418.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  419.  
  420.    if (!disp)
  421.       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
  422.  
  423.    if (!disp->Initialized) {
  424.       if (!_eglMatchDriver(disp, EGL_FALSE))
  425.          RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
  426.  
  427.       /* limit to APIs supported by core */
  428.       disp->ClientAPIs &= _EGL_API_ALL_BITS;
  429.  
  430.       /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
  431.        * classifies it as an EGL display extension, though conceptually it's an
  432.        * EGL client extension.
  433.        *
  434.        * From the EGL_KHR_get_all_proc_addresses spec:
  435.        *
  436.        *    The EGL implementation must expose the name
  437.        *    EGL_KHR_client_get_all_proc_addresses if and only if it exposes
  438.        *    EGL_KHR_get_all_proc_addresses and supports
  439.        *    EGL_EXT_client_extensions.
  440.        *
  441.        * Mesa unconditionally exposes both client extensions mentioned above,
  442.        * so the spec requires that each EGLDisplay unconditionally expose
  443.        * EGL_KHR_get_all_proc_addresses also.
  444.        */
  445.       disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
  446.  
  447.       _eglCreateExtensionsString(disp);
  448.       _eglCreateAPIsString(disp);
  449.       _eglsnprintf(disp->VersionString, sizeof(disp->VersionString),
  450.               "%d.%d (%s)", disp->VersionMajor, disp->VersionMinor,
  451.               disp->Driver->Name);
  452.    }
  453.  
  454.    /* Update applications version of major and minor if not NULL */
  455.    if ((major != NULL) && (minor != NULL)) {
  456.       *major = disp->VersionMajor;
  457.       *minor = disp->VersionMinor;
  458.    }
  459.  
  460.    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  461. }
  462.  
  463.  
  464. EGLBoolean EGLAPIENTRY
  465. eglTerminate(EGLDisplay dpy)
  466. {
  467.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  468.  
  469.    if (!disp)
  470.       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
  471.  
  472.    if (disp->Initialized) {
  473.       _EGLDriver *drv = disp->Driver;
  474.  
  475.       drv->API.Terminate(drv, disp);
  476.       /* do not reset disp->Driver */
  477.       disp->ClientAPIsString[0] = 0;
  478.       disp->Initialized = EGL_FALSE;
  479.    }
  480.  
  481.    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  482. }
  483.  
  484.  
  485. const char * EGLAPIENTRY
  486. eglQueryString(EGLDisplay dpy, EGLint name)
  487. {
  488.    _EGLDisplay *disp;
  489.    _EGLDriver *drv;
  490.  
  491.    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
  492.       RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
  493.    }
  494.  
  495.    disp = _eglLockDisplay(dpy);
  496.    _EGL_CHECK_DISPLAY(disp, NULL, drv);
  497.  
  498.    switch (name) {
  499.    case EGL_VENDOR:
  500.       RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
  501.    case EGL_VERSION:
  502.       RETURN_EGL_SUCCESS(disp, disp->VersionString);
  503.    case EGL_EXTENSIONS:
  504.       RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
  505.    case EGL_CLIENT_APIS:
  506.       RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
  507.    default:
  508.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
  509.    }
  510. }
  511.  
  512.  
  513. EGLBoolean EGLAPIENTRY
  514. eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
  515.               EGLint config_size, EGLint *num_config)
  516. {
  517.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  518.    _EGLDriver *drv;
  519.    EGLBoolean ret;
  520.  
  521.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  522.    ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
  523.  
  524.    RETURN_EGL_EVAL(disp, ret);
  525. }
  526.  
  527.  
  528. EGLBoolean EGLAPIENTRY
  529. eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
  530.                 EGLint config_size, EGLint *num_config)
  531. {
  532.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  533.    _EGLDriver *drv;
  534.    EGLBoolean ret;
  535.  
  536.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  537.    ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
  538.                                 config_size, num_config);
  539.  
  540.    RETURN_EGL_EVAL(disp, ret);
  541. }
  542.  
  543.  
  544. EGLBoolean EGLAPIENTRY
  545. eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
  546.                    EGLint attribute, EGLint *value)
  547. {
  548.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  549.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  550.    _EGLDriver *drv;
  551.    EGLBoolean ret;
  552.  
  553.    _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
  554.    ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
  555.  
  556.    RETURN_EGL_EVAL(disp, ret);
  557. }
  558.  
  559.  
  560. EGLContext EGLAPIENTRY
  561. eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
  562.                  const EGLint *attrib_list)
  563. {
  564.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  565.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  566.    _EGLContext *share = _eglLookupContext(share_list, disp);
  567.    _EGLDriver *drv;
  568.    _EGLContext *context;
  569.    EGLContext ret;
  570.  
  571.    _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
  572.  
  573.    if (!config && !disp->Extensions.MESA_configless_context)
  574.       RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
  575.  
  576.    if (!share && share_list != EGL_NO_CONTEXT)
  577.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
  578.  
  579.    context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
  580.    ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
  581.  
  582.    RETURN_EGL_EVAL(disp, ret);
  583. }
  584.  
  585.  
  586. EGLBoolean EGLAPIENTRY
  587. eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
  588. {
  589.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  590.    _EGLContext *context = _eglLookupContext(ctx, disp);
  591.    _EGLDriver *drv;
  592.    EGLBoolean ret;
  593.  
  594.    _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
  595.    _eglUnlinkContext(context);
  596.    ret = drv->API.DestroyContext(drv, disp, context);
  597.  
  598.    RETURN_EGL_EVAL(disp, ret);
  599. }
  600.  
  601.  
  602. EGLBoolean EGLAPIENTRY
  603. eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
  604.                EGLContext ctx)
  605. {
  606.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  607.    _EGLContext *context = _eglLookupContext(ctx, disp);
  608.    _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
  609.    _EGLSurface *read_surf = _eglLookupSurface(read, disp);
  610.    _EGLDriver *drv;
  611.    EGLBoolean ret;
  612.  
  613.    if (!disp)
  614.       RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
  615.    drv = disp->Driver;
  616.  
  617.    /* display is allowed to be uninitialized under certain condition */
  618.    if (!disp->Initialized) {
  619.       if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
  620.           ctx != EGL_NO_CONTEXT)
  621.          RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
  622.    }
  623.    if (!drv)
  624.       RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  625.  
  626.    if (!context && ctx != EGL_NO_CONTEXT)
  627.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  628.    if (!draw_surf || !read_surf) {
  629.       /* From the EGL 1.4 (20130211) spec:
  630.        *
  631.        *    To release the current context without assigning a new one, set ctx
  632.        *    to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
  633.        */
  634.       if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
  635.          RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  636.  
  637.       if ((!draw_surf && draw != EGL_NO_SURFACE) ||
  638.           (!read_surf && read != EGL_NO_SURFACE))
  639.          RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  640.       if (draw_surf || read_surf)
  641.          RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
  642.    }
  643.  
  644.    ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
  645.  
  646.    RETURN_EGL_EVAL(disp, ret);
  647. }
  648.  
  649.  
  650. EGLBoolean EGLAPIENTRY
  651. eglQueryContext(EGLDisplay dpy, EGLContext ctx,
  652.                 EGLint attribute, EGLint *value)
  653. {
  654.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  655.    _EGLContext *context = _eglLookupContext(ctx, disp);
  656.    _EGLDriver *drv;
  657.    EGLBoolean ret;
  658.  
  659.    _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
  660.    ret = drv->API.QueryContext(drv, disp, context, attribute, value);
  661.  
  662.    RETURN_EGL_EVAL(disp, ret);
  663. }
  664.  
  665.  
  666. static EGLSurface
  667. _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
  668.                               void *native_window, const EGLint *attrib_list)
  669. {
  670.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  671.    _EGLDriver *drv;
  672.    _EGLSurface *surf;
  673.    EGLSurface ret;
  674.  
  675.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  676.  
  677.    if (native_window == NULL)
  678.       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  679.  
  680.    surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
  681.                                        attrib_list);
  682.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  683.  
  684.    RETURN_EGL_EVAL(disp, ret);
  685. }
  686.  
  687.  
  688. EGLSurface EGLAPIENTRY
  689. eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
  690.                        EGLNativeWindowType window, const EGLint *attrib_list)
  691. {
  692.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  693.    STATIC_ASSERT(sizeof(void*) == sizeof(window));
  694.    return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
  695.                                         attrib_list);
  696. }
  697.  
  698.  
  699. static EGLSurface EGLAPIENTRY
  700. eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
  701.                                   void *native_window,
  702.                                   const EGLint *attrib_list)
  703. {
  704.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  705.  
  706. #ifdef HAVE_X11_PLATFORM
  707.    if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
  708.       /* The `native_window` parameter for the X11 platform differs between
  709.        * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
  710.        * eglCreateWindowSurface(), the type of `native_window` is an Xlib
  711.        * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
  712.        * `Window*`.  Convert `Window*` to `Window` because that's what
  713.        * dri2_x11_create_window_surface() expects.
  714.        */
  715.       native_window = (void*) (* (Window*) native_window);
  716.    }
  717. #endif
  718.  
  719.    return _eglCreateWindowSurfaceCommon(disp, config, native_window,
  720.                                         attrib_list);
  721. }
  722.  
  723.  
  724. static EGLSurface
  725. _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
  726.                               void *native_pixmap, const EGLint *attrib_list)
  727. {
  728.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  729.    _EGLDriver *drv;
  730.    _EGLSurface *surf;
  731.    EGLSurface ret;
  732.  
  733.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  734.    surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
  735.                                        attrib_list);
  736.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  737.  
  738.    RETURN_EGL_EVAL(disp, ret);
  739. }
  740.  
  741.  
  742. EGLSurface EGLAPIENTRY
  743. eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
  744.                        EGLNativePixmapType pixmap, const EGLint *attrib_list)
  745. {
  746.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  747.    STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
  748.    return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
  749.                                          attrib_list);
  750. }
  751.  
  752. static EGLSurface EGLAPIENTRY
  753. eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
  754.                                    void *native_pixmap,
  755.                                    const EGLint *attrib_list)
  756. {
  757.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  758.  
  759. #ifdef HAVE_X11_PLATFORM
  760.       /* The `native_pixmap` parameter for the X11 platform differs between
  761.        * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
  762.        * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
  763.        * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
  764.        * `Pixmap*`.  Convert `Pixmap*` to `Pixmap` because that's what
  765.        * dri2_x11_create_pixmap_surface() expects.
  766.        */
  767.    if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
  768.       native_pixmap = (void*) (* (Pixmap*) native_pixmap);
  769.    }
  770. #endif
  771.  
  772.    return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
  773.                                         attrib_list);
  774. }
  775.  
  776.  
  777. EGLSurface EGLAPIENTRY
  778. eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
  779.                         const EGLint *attrib_list)
  780. {
  781.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  782.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  783.    _EGLDriver *drv;
  784.    _EGLSurface *surf;
  785.    EGLSurface ret;
  786.  
  787.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  788.  
  789.    surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
  790.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  791.  
  792.    RETURN_EGL_EVAL(disp, ret);
  793. }
  794.  
  795.  
  796. EGLBoolean EGLAPIENTRY
  797. eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
  798. {
  799.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  800.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  801.    _EGLDriver *drv;
  802.    EGLBoolean ret;
  803.  
  804.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  805.    _eglUnlinkSurface(surf);
  806.    ret = drv->API.DestroySurface(drv, disp, surf);
  807.  
  808.    RETURN_EGL_EVAL(disp, ret);
  809. }
  810.  
  811. EGLBoolean EGLAPIENTRY
  812. eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
  813.                 EGLint attribute, EGLint *value)
  814. {
  815.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  816.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  817.    _EGLDriver *drv;
  818.    EGLBoolean ret;
  819.  
  820.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  821.    ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
  822.  
  823.    RETURN_EGL_EVAL(disp, ret);
  824. }
  825.  
  826. EGLBoolean EGLAPIENTRY
  827. eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
  828.                  EGLint attribute, EGLint value)
  829. {
  830.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  831.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  832.    _EGLDriver *drv;
  833.    EGLBoolean ret;
  834.  
  835.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  836.    ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
  837.  
  838.    RETURN_EGL_EVAL(disp, ret);
  839. }
  840.  
  841.  
  842. EGLBoolean EGLAPIENTRY
  843. eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  844. {
  845.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  846.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  847.    _EGLDriver *drv;
  848.    EGLBoolean ret;
  849.  
  850.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  851.    ret = drv->API.BindTexImage(drv, disp, surf, buffer);
  852.  
  853.    RETURN_EGL_EVAL(disp, ret);
  854. }
  855.  
  856.  
  857. EGLBoolean EGLAPIENTRY
  858. eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  859. {
  860.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  861.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  862.    _EGLDriver *drv;
  863.    EGLBoolean ret;
  864.  
  865.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  866.    ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
  867.  
  868.    RETURN_EGL_EVAL(disp, ret);
  869. }
  870.  
  871.  
  872. EGLBoolean EGLAPIENTRY
  873. eglSwapInterval(EGLDisplay dpy, EGLint interval)
  874. {
  875.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  876.    _EGLContext *ctx = _eglGetCurrentContext();
  877.    _EGLSurface *surf;
  878.    _EGLDriver *drv;
  879.    EGLBoolean ret;
  880.  
  881.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  882.  
  883.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  884.        ctx->Resource.Display != disp)
  885.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  886.  
  887.    surf = ctx->DrawSurface;
  888.    if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
  889.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  890.  
  891.    ret = drv->API.SwapInterval(drv, disp, surf, interval);
  892.  
  893.    RETURN_EGL_EVAL(disp, ret);
  894. }
  895.  
  896.  
  897. EGLBoolean EGLAPIENTRY
  898. eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  899. {
  900.    _EGLContext *ctx = _eglGetCurrentContext();
  901.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  902.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  903.    _EGLDriver *drv;
  904.    EGLBoolean ret;
  905.  
  906.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  907.  
  908.    /* surface must be bound to current context in EGL 1.4 */
  909.    #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
  910.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  911.        surf != ctx->DrawSurface)
  912.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  913.    #endif
  914.  
  915.    ret = drv->API.SwapBuffers(drv, disp, surf);
  916.  
  917.    RETURN_EGL_EVAL(disp, ret);
  918. }
  919.  
  920.  
  921. #ifdef EGL_EXT_swap_buffers_with_damage
  922.  
  923. static EGLBoolean EGLAPIENTRY
  924. eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
  925.                             EGLint *rects, EGLint n_rects)
  926. {
  927.    _EGLContext *ctx = _eglGetCurrentContext();
  928.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  929.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  930.    _EGLDriver *drv;
  931.    EGLBoolean ret;
  932.  
  933.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  934.  
  935.    /* surface must be bound to current context in EGL 1.4 */
  936.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  937.        surf != ctx->DrawSurface)
  938.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  939.  
  940.    if ((n_rects > 0 && rects == NULL) || n_rects < 0)
  941.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  942.  
  943.    ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
  944.  
  945.    RETURN_EGL_EVAL(disp, ret);
  946. }
  947.  
  948. #endif /* EGL_EXT_swap_buffers_with_damage */
  949.  
  950. EGLBoolean EGLAPIENTRY
  951. eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
  952. {
  953.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  954.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  955.    _EGLDriver *drv;
  956.    EGLBoolean ret;
  957.    void *native_pixmap_ptr;
  958.  
  959.    STATIC_ASSERT(sizeof(void*) == sizeof(target));
  960.    native_pixmap_ptr = (void*) target;
  961.  
  962.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  963.    if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
  964.       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
  965.    ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
  966.  
  967.    RETURN_EGL_EVAL(disp, ret);
  968. }
  969.  
  970.  
  971. EGLBoolean EGLAPIENTRY
  972. eglWaitClient(void)
  973. {
  974.    _EGLContext *ctx = _eglGetCurrentContext();
  975.    _EGLDisplay *disp;
  976.    _EGLDriver *drv;
  977.    EGLBoolean ret;
  978.  
  979.    if (!ctx)
  980.       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  981.  
  982.    disp = ctx->Resource.Display;
  983.    mtx_lock(&disp->Mutex);
  984.  
  985.    /* let bad current context imply bad current surface */
  986.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  987.        _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  988.       RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  989.  
  990.    /* a valid current context implies an initialized current display */
  991.    assert(disp->Initialized);
  992.    drv = disp->Driver;
  993.    ret = drv->API.WaitClient(drv, disp, ctx);
  994.  
  995.    RETURN_EGL_EVAL(disp, ret);
  996. }
  997.  
  998.  
  999. EGLBoolean EGLAPIENTRY
  1000. eglWaitGL(void)
  1001. {
  1002.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1003.    EGLint api_index = t->CurrentAPIIndex;
  1004.    EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
  1005.    EGLBoolean ret;
  1006.  
  1007.    if (api_index != es_index && _eglIsCurrentThreadDummy())
  1008.       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  1009.  
  1010.    t->CurrentAPIIndex = es_index;
  1011.    ret = eglWaitClient();
  1012.    t->CurrentAPIIndex = api_index;
  1013.    return ret;
  1014. }
  1015.  
  1016.  
  1017. EGLBoolean EGLAPIENTRY
  1018. eglWaitNative(EGLint engine)
  1019. {
  1020.    _EGLContext *ctx = _eglGetCurrentContext();
  1021.    _EGLDisplay *disp;
  1022.    _EGLDriver *drv;
  1023.    EGLBoolean ret;
  1024.  
  1025.    if (!ctx)
  1026.       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1027.  
  1028.    disp = ctx->Resource.Display;
  1029.    mtx_lock(&disp->Mutex);
  1030.  
  1031.    /* let bad current context imply bad current surface */
  1032.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  1033.        _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  1034.       RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  1035.  
  1036.    /* a valid current context implies an initialized current display */
  1037.    assert(disp->Initialized);
  1038.    drv = disp->Driver;
  1039.    ret = drv->API.WaitNative(drv, disp, engine);
  1040.  
  1041.    RETURN_EGL_EVAL(disp, ret);
  1042. }
  1043.  
  1044.  
  1045. EGLDisplay EGLAPIENTRY
  1046. eglGetCurrentDisplay(void)
  1047. {
  1048.    _EGLContext *ctx = _eglGetCurrentContext();
  1049.    EGLDisplay ret;
  1050.  
  1051.    ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
  1052.  
  1053.    RETURN_EGL_SUCCESS(NULL, ret);
  1054. }
  1055.  
  1056.  
  1057. EGLContext EGLAPIENTRY
  1058. eglGetCurrentContext(void)
  1059. {
  1060.    _EGLContext *ctx = _eglGetCurrentContext();
  1061.    EGLContext ret;
  1062.  
  1063.    ret = _eglGetContextHandle(ctx);
  1064.  
  1065.    RETURN_EGL_SUCCESS(NULL, ret);
  1066. }
  1067.  
  1068.  
  1069. EGLSurface EGLAPIENTRY
  1070. eglGetCurrentSurface(EGLint readdraw)
  1071. {
  1072.    _EGLContext *ctx = _eglGetCurrentContext();
  1073.    EGLint err = EGL_SUCCESS;
  1074.    _EGLSurface *surf;
  1075.    EGLSurface ret;
  1076.  
  1077.    if (!ctx)
  1078.       RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
  1079.  
  1080.    switch (readdraw) {
  1081.    case EGL_DRAW:
  1082.       surf = ctx->DrawSurface;
  1083.       break;
  1084.    case EGL_READ:
  1085.       surf = ctx->ReadSurface;
  1086.       break;
  1087.    default:
  1088.       surf = NULL;
  1089.       err = EGL_BAD_PARAMETER;
  1090.       break;
  1091.    }
  1092.  
  1093.    ret = _eglGetSurfaceHandle(surf);
  1094.  
  1095.    RETURN_EGL_ERROR(NULL, err, ret);
  1096. }
  1097.  
  1098.  
  1099. EGLint EGLAPIENTRY
  1100. eglGetError(void)
  1101. {
  1102.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1103.    EGLint e = t->LastError;
  1104.    if (!_eglIsCurrentThreadDummy())
  1105.       t->LastError = EGL_SUCCESS;
  1106.    return e;
  1107. }
  1108.  
  1109.  
  1110. #ifdef EGL_MESA_drm_display
  1111.  
  1112. static EGLDisplay EGLAPIENTRY
  1113. eglGetDRMDisplayMESA(int fd)
  1114. {
  1115.    _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
  1116.    return _eglGetDisplayHandle(dpy);
  1117. }
  1118.  
  1119. #endif /* EGL_MESA_drm_display */
  1120.  
  1121. /**
  1122.  ** EGL 1.2
  1123.  **/
  1124.  
  1125. /**
  1126.  * Specify the client API to use for subsequent calls including:
  1127.  *  eglCreateContext()
  1128.  *  eglGetCurrentContext()
  1129.  *  eglGetCurrentDisplay()
  1130.  *  eglGetCurrentSurface()
  1131.  *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
  1132.  *  eglWaitClient()
  1133.  *  eglWaitNative()
  1134.  * See section 3.7 "Rendering Context" in the EGL specification for details.
  1135.  */
  1136. EGLBoolean EGLAPIENTRY
  1137. eglBindAPI(EGLenum api)
  1138. {
  1139.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1140.  
  1141.    if (_eglIsCurrentThreadDummy())
  1142.       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  1143.  
  1144.    if (!_eglIsApiValid(api))
  1145.       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
  1146.  
  1147.    t->CurrentAPIIndex = _eglConvertApiToIndex(api);
  1148.  
  1149.    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1150. }
  1151.  
  1152.  
  1153. /**
  1154.  * Return the last value set with eglBindAPI().
  1155.  */
  1156. EGLenum EGLAPIENTRY
  1157. eglQueryAPI(void)
  1158. {
  1159.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1160.    EGLenum ret;
  1161.  
  1162.    /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
  1163.    ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
  1164.  
  1165.    RETURN_EGL_SUCCESS(NULL, ret);
  1166. }
  1167.  
  1168.  
  1169. EGLSurface EGLAPIENTRY
  1170. eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
  1171.                                  EGLClientBuffer buffer, EGLConfig config,
  1172.                                  const EGLint *attrib_list)
  1173. {
  1174.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1175.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  1176.    _EGLDriver *drv;
  1177.    _EGLSurface *surf;
  1178.    EGLSurface ret;
  1179.  
  1180.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  1181.  
  1182.    surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
  1183.                                                  conf, attrib_list);
  1184.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  1185.  
  1186.    RETURN_EGL_EVAL(disp, ret);
  1187. }
  1188.  
  1189.  
  1190. EGLBoolean EGLAPIENTRY
  1191. eglReleaseThread(void)
  1192. {
  1193.    /* unbind current contexts */
  1194.    if (!_eglIsCurrentThreadDummy()) {
  1195.       _EGLThreadInfo *t = _eglGetCurrentThread();
  1196.       EGLint api_index = t->CurrentAPIIndex;
  1197.       EGLint i;
  1198.  
  1199.       for (i = 0; i < _EGL_API_NUM_APIS; i++) {
  1200.          _EGLContext *ctx = t->CurrentContexts[i];
  1201.          if (ctx) {
  1202.             _EGLDisplay *disp = ctx->Resource.Display;
  1203.             _EGLDriver *drv;
  1204.  
  1205.             t->CurrentAPIIndex = i;
  1206.  
  1207.             mtx_lock(&disp->Mutex);
  1208.             drv = disp->Driver;
  1209.             (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
  1210.             mtx_unlock(&disp->Mutex);
  1211.          }
  1212.       }
  1213.  
  1214.       t->CurrentAPIIndex = api_index;
  1215.    }
  1216.  
  1217.    _eglDestroyCurrentThread();
  1218.  
  1219.    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1220. }
  1221.  
  1222.  
  1223. static EGLImageKHR EGLAPIENTRY
  1224. eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1225.                   EGLClientBuffer buffer, const EGLint *attr_list)
  1226. {
  1227.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1228.    _EGLContext *context = _eglLookupContext(ctx, disp);
  1229.    _EGLDriver *drv;
  1230.    _EGLImage *img;
  1231.    EGLImageKHR ret;
  1232.  
  1233.    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1234.    if (!disp->Extensions.KHR_image_base)
  1235.       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1236.    if (!context && ctx != EGL_NO_CONTEXT)
  1237.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
  1238.    /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
  1239.     *  <ctx> must be EGL_NO_CONTEXT..."
  1240.     */
  1241.    if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
  1242.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
  1243.  
  1244.    img = drv->API.CreateImageKHR(drv,
  1245.          disp, context, target, buffer, attr_list);
  1246.    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1247.  
  1248.    RETURN_EGL_EVAL(disp, ret);
  1249. }
  1250.  
  1251.  
  1252. static EGLBoolean EGLAPIENTRY
  1253. eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
  1254. {
  1255.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1256.    _EGLImage *img = _eglLookupImage(image, disp);
  1257.    _EGLDriver *drv;
  1258.    EGLBoolean ret;
  1259.  
  1260.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1261.    if (!disp->Extensions.KHR_image_base)
  1262.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1263.    if (!img)
  1264.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1265.  
  1266.    _eglUnlinkImage(img);
  1267.    ret = drv->API.DestroyImageKHR(drv, disp, img);
  1268.  
  1269.    RETURN_EGL_EVAL(disp, ret);
  1270. }
  1271.  
  1272.  
  1273. static EGLSyncKHR
  1274. _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
  1275.                const EGLAttribKHR *attrib_list64, EGLBoolean is64)
  1276. {
  1277.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1278.    _EGLContext *ctx = _eglGetCurrentContext();
  1279.    _EGLDriver *drv;
  1280.    _EGLSync *sync;
  1281.    EGLSyncKHR ret;
  1282.  
  1283.    _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
  1284.  
  1285.    if (!disp->Extensions.KHR_cl_event2 && is64)
  1286.       RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
  1287.  
  1288.    /* return an error if the client API doesn't support GL_OES_EGL_sync */
  1289.    if (!ctx || ctx->Resource.Display != dpy ||
  1290.        ctx->ClientAPI != EGL_OPENGL_ES_API)
  1291.       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
  1292.  
  1293.    switch (type) {
  1294.    case EGL_SYNC_FENCE_KHR:
  1295.       if (!disp->Extensions.KHR_fence_sync)
  1296.          RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1297.       break;
  1298.    case EGL_SYNC_REUSABLE_KHR:
  1299.       if (!disp->Extensions.KHR_reusable_sync)
  1300.          RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1301.       break;
  1302.    case EGL_SYNC_CL_EVENT_KHR:
  1303.       if (!disp->Extensions.KHR_cl_event2)
  1304.          RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1305.       break;
  1306.    default:
  1307.       RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1308.    }
  1309.  
  1310.    sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
  1311.    ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
  1312.  
  1313.    RETURN_EGL_EVAL(disp, ret);
  1314. }
  1315.  
  1316.  
  1317. static EGLSyncKHR EGLAPIENTRY
  1318. eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
  1319. {
  1320.    return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE);
  1321. }
  1322.  
  1323.  
  1324. static EGLSyncKHR EGLAPIENTRY
  1325. eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list)
  1326. {
  1327.    return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE);
  1328. }
  1329.  
  1330.  
  1331. static EGLBoolean EGLAPIENTRY
  1332. eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
  1333. {
  1334.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1335.    _EGLSync *s = _eglLookupSync(sync, disp);
  1336.    _EGLDriver *drv;
  1337.    EGLBoolean ret;
  1338.  
  1339.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1340.    assert(disp->Extensions.KHR_reusable_sync ||
  1341.           disp->Extensions.KHR_fence_sync);
  1342.  
  1343.    _eglUnlinkSync(s);
  1344.    ret = drv->API.DestroySyncKHR(drv, disp, s);
  1345.  
  1346.    RETURN_EGL_EVAL(disp, ret);
  1347. }
  1348.  
  1349.  
  1350. static EGLint EGLAPIENTRY
  1351. eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
  1352. {
  1353.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1354.    _EGLSync *s = _eglLookupSync(sync, disp);
  1355.    _EGLDriver *drv;
  1356.    EGLint ret;
  1357.  
  1358.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1359.    assert(disp->Extensions.KHR_reusable_sync ||
  1360.           disp->Extensions.KHR_fence_sync);
  1361.  
  1362.    if (s->SyncStatus == EGL_SIGNALED_KHR)
  1363.       RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
  1364.  
  1365.    ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
  1366.  
  1367.    RETURN_EGL_EVAL(disp, ret);
  1368. }
  1369.  
  1370.  
  1371. static EGLint EGLAPIENTRY
  1372. eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
  1373. {
  1374.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1375.    _EGLSync *s = _eglLookupSync(sync, disp);
  1376.    _EGLContext *ctx = _eglGetCurrentContext();
  1377.    _EGLDriver *drv;
  1378.    EGLint ret;
  1379.  
  1380.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1381.    assert(disp->Extensions.KHR_wait_sync);
  1382.  
  1383.    /* return an error if the client API doesn't support GL_OES_EGL_sync */
  1384.    if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
  1385.       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
  1386.  
  1387.    /* the API doesn't allow any flags yet */
  1388.    if (flags != 0)
  1389.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1390.  
  1391.    ret = drv->API.WaitSyncKHR(drv, disp, s);
  1392.  
  1393.    RETURN_EGL_EVAL(disp, ret);
  1394. }
  1395.  
  1396.  
  1397. static EGLBoolean EGLAPIENTRY
  1398. eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
  1399. {
  1400.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1401.    _EGLSync *s = _eglLookupSync(sync, disp);
  1402.    _EGLDriver *drv;
  1403.    EGLBoolean ret;
  1404.  
  1405.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1406.    assert(disp->Extensions.KHR_reusable_sync);
  1407.    ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
  1408.  
  1409.    RETURN_EGL_EVAL(disp, ret);
  1410. }
  1411.  
  1412.  
  1413. static EGLBoolean EGLAPIENTRY
  1414. eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
  1415. {
  1416.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1417.    _EGLSync *s = _eglLookupSync(sync, disp);
  1418.    _EGLDriver *drv;
  1419.    EGLBoolean ret;
  1420.  
  1421.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1422.    assert(disp->Extensions.KHR_reusable_sync ||
  1423.           disp->Extensions.KHR_fence_sync);
  1424.    ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
  1425.  
  1426.    RETURN_EGL_EVAL(disp, ret);
  1427. }
  1428.  
  1429.  
  1430. #ifdef EGL_NOK_swap_region
  1431.  
  1432. static EGLBoolean EGLAPIENTRY
  1433. eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
  1434.                         EGLint numRects, const EGLint *rects)
  1435. {
  1436.    _EGLContext *ctx = _eglGetCurrentContext();
  1437.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1438.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1439.    _EGLDriver *drv;
  1440.    EGLBoolean ret;
  1441.  
  1442.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1443.  
  1444.    if (!disp->Extensions.NOK_swap_region)
  1445.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1446.  
  1447.    /* surface must be bound to current context in EGL 1.4 */
  1448.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  1449.        surf != ctx->DrawSurface)
  1450.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  1451.  
  1452.    ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
  1453.  
  1454.    RETURN_EGL_EVAL(disp, ret);
  1455. }
  1456.  
  1457. #endif /* EGL_NOK_swap_region */
  1458.  
  1459.  
  1460. #ifdef EGL_MESA_drm_image
  1461.  
  1462. static EGLImageKHR EGLAPIENTRY
  1463. eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
  1464. {
  1465.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1466.    _EGLDriver *drv;
  1467.    _EGLImage *img;
  1468.    EGLImageKHR ret;
  1469.  
  1470.    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1471.    if (!disp->Extensions.MESA_drm_image)
  1472.       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1473.  
  1474.    img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
  1475.    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1476.  
  1477.    RETURN_EGL_EVAL(disp, ret);
  1478. }
  1479.  
  1480. static EGLBoolean EGLAPIENTRY
  1481. eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
  1482.                       EGLint *name, EGLint *handle, EGLint *stride)
  1483. {
  1484.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1485.    _EGLImage *img = _eglLookupImage(image, disp);
  1486.    _EGLDriver *drv;
  1487.    EGLBoolean ret;
  1488.  
  1489.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1490.    assert(disp->Extensions.MESA_drm_image);
  1491.  
  1492.    if (!img)
  1493.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1494.  
  1495.    ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
  1496.  
  1497.    RETURN_EGL_EVAL(disp, ret);
  1498. }
  1499.  
  1500. #endif
  1501.  
  1502. #ifdef EGL_WL_bind_wayland_display
  1503. struct wl_display;
  1504.  
  1505. static EGLBoolean EGLAPIENTRY
  1506. eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1507. {
  1508.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1509.    _EGLDriver *drv;
  1510.    EGLBoolean ret;
  1511.  
  1512.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1513.    assert(disp->Extensions.WL_bind_wayland_display);
  1514.  
  1515.    if (!display)
  1516.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1517.  
  1518.    ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
  1519.  
  1520.    RETURN_EGL_EVAL(disp, ret);
  1521. }
  1522.  
  1523. static EGLBoolean EGLAPIENTRY
  1524. eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1525. {
  1526.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1527.    _EGLDriver *drv;
  1528.    EGLBoolean ret;
  1529.  
  1530.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1531.    assert(disp->Extensions.WL_bind_wayland_display);
  1532.  
  1533.    if (!display)
  1534.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1535.  
  1536.    ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
  1537.  
  1538.    RETURN_EGL_EVAL(disp, ret);
  1539. }
  1540.  
  1541. static EGLBoolean EGLAPIENTRY
  1542. eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
  1543.                         EGLint attribute, EGLint *value)
  1544. {
  1545.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1546.    _EGLDriver *drv;
  1547.    EGLBoolean ret;
  1548.  
  1549.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1550.    assert(disp->Extensions.WL_bind_wayland_display);
  1551.  
  1552.    if (!buffer)
  1553.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1554.  
  1555.    ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
  1556.  
  1557.    RETURN_EGL_EVAL(disp, ret);
  1558. }
  1559. #endif
  1560.  
  1561. #ifdef EGL_WL_create_wayland_buffer_from_image
  1562. static struct wl_buffer * EGLAPIENTRY
  1563. eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
  1564. {
  1565.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1566.    _EGLImage *img;
  1567.    _EGLDriver *drv;
  1568.    struct wl_buffer *ret;
  1569.  
  1570.    _EGL_CHECK_DISPLAY(disp, NULL, drv);
  1571.    assert(disp->Extensions.WL_create_wayland_buffer_from_image);
  1572.  
  1573.    img = _eglLookupImage(image, disp);
  1574.  
  1575.    if (!img)
  1576.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
  1577.  
  1578.    ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
  1579.  
  1580.    RETURN_EGL_EVAL(disp, ret);
  1581. }
  1582. #endif
  1583.  
  1584. static EGLBoolean EGLAPIENTRY
  1585. eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
  1586.                    EGLint x, EGLint y, EGLint width, EGLint height)
  1587. {
  1588.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1589.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1590.    _EGLDriver *drv;
  1591.    EGLBoolean ret;
  1592.  
  1593.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1594.  
  1595.    if (!disp->Extensions.NV_post_sub_buffer)
  1596.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1597.  
  1598.    ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
  1599.  
  1600.    RETURN_EGL_EVAL(disp, ret);
  1601. }
  1602.  
  1603. static EGLBoolean EGLAPIENTRY
  1604. eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
  1605.                          EGLuint64KHR *ust, EGLuint64KHR *msc,
  1606.                          EGLuint64KHR *sbc)
  1607. {
  1608.    _EGLDisplay *disp = _eglLockDisplay(display);
  1609.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1610.    _EGLDriver *drv;
  1611.    EGLBoolean ret;
  1612.  
  1613.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1614.    if (!disp->Extensions.CHROMIUM_sync_control)
  1615.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1616.  
  1617.    if (!ust || !msc || !sbc)
  1618.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1619.  
  1620.    ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
  1621.  
  1622.    RETURN_EGL_EVAL(disp, ret);
  1623. }
  1624.  
  1625. #ifdef EGL_MESA_image_dma_buf_export
  1626. static EGLBoolean EGLAPIENTRY
  1627. eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
  1628.                               EGLint *fourcc, EGLint *nplanes,
  1629.                               EGLuint64KHR *modifiers)
  1630. {
  1631.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1632.    _EGLImage *img = _eglLookupImage(image, disp);
  1633.    _EGLDriver *drv;
  1634.    EGLBoolean ret;
  1635.  
  1636.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1637.    assert(disp->Extensions.MESA_image_dma_buf_export);
  1638.  
  1639.    if (!img)
  1640.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1641.  
  1642.    ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
  1643.                                              modifiers);
  1644.  
  1645.    RETURN_EGL_EVAL(disp, ret);
  1646. }
  1647.  
  1648. static EGLBoolean EGLAPIENTRY
  1649. eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image,
  1650.                          int *fds, EGLint *strides, EGLint *offsets)
  1651. {
  1652.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1653.    _EGLImage *img = _eglLookupImage(image, disp);
  1654.    _EGLDriver *drv;
  1655.    EGLBoolean ret;
  1656.  
  1657.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1658.    assert(disp->Extensions.MESA_image_dma_buf_export);
  1659.  
  1660.    if (!img)
  1661.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1662.  
  1663.    ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
  1664.  
  1665.    RETURN_EGL_EVAL(disp, ret);
  1666. }
  1667. #endif
  1668.  
  1669. __eglMustCastToProperFunctionPointerType EGLAPIENTRY
  1670. eglGetProcAddress(const char *procname)
  1671. {
  1672.    static const struct {
  1673.       const char *name;
  1674.       _EGLProc function;
  1675.    } egl_functions[] = {
  1676.       /* core functions queryable in the presence of
  1677.        * EGL_KHR_get_all_proc_addresses or EGL 1.5
  1678.        */
  1679.       /* alphabetical order */
  1680.       { "eglBindAPI", (_EGLProc) eglBindAPI },
  1681.       { "eglBindTexImage", (_EGLProc) eglBindTexImage },
  1682.       { "eglChooseConfig", (_EGLProc) eglChooseConfig },
  1683.       { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
  1684.       { "eglCreateContext", (_EGLProc) eglCreateContext },
  1685.       { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
  1686.       { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
  1687.       { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
  1688.       { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
  1689.       { "eglDestroyContext", (_EGLProc) eglDestroyContext },
  1690.       { "eglDestroySurface", (_EGLProc) eglDestroySurface },
  1691.       { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
  1692.       { "eglGetConfigs", (_EGLProc) eglGetConfigs },
  1693.       { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
  1694.       { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
  1695.       { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
  1696.       { "eglGetDisplay", (_EGLProc) eglGetDisplay },
  1697.       { "eglGetError", (_EGLProc) eglGetError },
  1698.       { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
  1699.       { "eglInitialize", (_EGLProc) eglInitialize },
  1700.       { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
  1701.       { "eglQueryAPI", (_EGLProc) eglQueryAPI },
  1702.       { "eglQueryContext", (_EGLProc) eglQueryContext },
  1703.       { "eglQueryString", (_EGLProc) eglQueryString },
  1704.       { "eglQuerySurface", (_EGLProc) eglQuerySurface },
  1705.       { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
  1706.       { "eglReleaseThread", (_EGLProc) eglReleaseThread },
  1707.       { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
  1708.       { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
  1709.       { "eglSwapInterval", (_EGLProc) eglSwapInterval },
  1710.       { "eglTerminate", (_EGLProc) eglTerminate },
  1711.       { "eglWaitClient", (_EGLProc) eglWaitClient },
  1712.       { "eglWaitGL", (_EGLProc) eglWaitGL },
  1713.       { "eglWaitNative", (_EGLProc) eglWaitNative },
  1714. #ifdef EGL_MESA_drm_display
  1715.       { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
  1716. #endif
  1717.       { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
  1718.       { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
  1719.       { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
  1720.       { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
  1721.       { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
  1722.       { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
  1723.       { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
  1724.       { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
  1725.       { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
  1726. #ifdef EGL_NOK_swap_region
  1727.       { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
  1728. #endif
  1729. #ifdef EGL_MESA_drm_image
  1730.       { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
  1731.       { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
  1732. #endif
  1733. #ifdef EGL_WL_bind_wayland_display
  1734.       { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
  1735.       { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
  1736.       { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
  1737. #endif
  1738. #ifdef EGL_WL_create_wayland_buffer_from_image
  1739.       { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
  1740. #endif
  1741.       { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
  1742. #ifdef EGL_EXT_swap_buffers_with_damage
  1743.       { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
  1744. #endif
  1745.       { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
  1746.       { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
  1747.       { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
  1748.       { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
  1749. #ifdef EGL_MESA_image_dma_buf_export
  1750.       { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
  1751.       { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
  1752. #endif
  1753.       { NULL, NULL }
  1754.    };
  1755.    EGLint i;
  1756.    _EGLProc ret;
  1757.  
  1758.    if (!procname)
  1759.       RETURN_EGL_SUCCESS(NULL, NULL);
  1760.  
  1761.    ret = NULL;
  1762.    if (strncmp(procname, "egl", 3) == 0) {
  1763.       for (i = 0; egl_functions[i].name; i++) {
  1764.          if (strcmp(egl_functions[i].name, procname) == 0) {
  1765.             ret = egl_functions[i].function;
  1766.             break;
  1767.          }
  1768.       }
  1769.    }
  1770.    if (!ret)
  1771.       ret = _eglGetDriverProc(procname);
  1772.  
  1773.    RETURN_EGL_SUCCESS(NULL, ret);
  1774. }
  1775.