Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  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.  
  90. #include "eglcontext.h"
  91. #include "egldisplay.h"
  92. #include "egltypedefs.h"
  93. #include "eglcurrent.h"
  94. #include "egldriver.h"
  95. #include "eglsurface.h"
  96. #include "eglconfig.h"
  97. #include "eglscreen.h"
  98. #include "eglmode.h"
  99. #include "eglimage.h"
  100. #include "eglsync.h"
  101.  
  102.  
  103. /**
  104.  * Macros to help return an API entrypoint.
  105.  *
  106.  * These macros will unlock the display and record the error code.
  107.  */
  108. #define RETURN_EGL_ERROR(disp, err, ret)        \
  109.    do {                                         \
  110.       if (disp)                                 \
  111.          _eglUnlockDisplay(disp);               \
  112.       /* EGL error codes are non-zero */        \
  113.       if (err)                                  \
  114.          _eglError(err, __FUNCTION__);          \
  115.       return ret;                               \
  116.    } while (0)
  117.  
  118. #define RETURN_EGL_SUCCESS(disp, ret) \
  119.    RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
  120.  
  121. /* record EGL_SUCCESS only when ret evaluates to true */
  122. #define RETURN_EGL_EVAL(disp, ret) \
  123.    RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
  124.  
  125.  
  126. /*
  127.  * A bunch of macros and checks to simplify error checking.
  128.  */
  129.  
  130. #define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
  131.    do {                                            \
  132.       drv = _eglCheckDisplay(disp, __FUNCTION__);  \
  133.       if (!drv)                                    \
  134.          RETURN_EGL_ERROR(disp, 0, ret);           \
  135.    } while (0)
  136.  
  137. #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
  138.    do {                                                   \
  139.       drv = _eglCheck ## type(disp, obj, __FUNCTION__);   \
  140.       if (!drv)                                           \
  141.          RETURN_EGL_ERROR(disp, 0, ret);                  \
  142.    } while (0)
  143.  
  144. #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
  145.    _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
  146.  
  147. #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
  148.    _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
  149.  
  150. #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
  151.    _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
  152.  
  153. #define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
  154.    _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
  155.  
  156. #define _EGL_CHECK_MODE(disp, m, ret, drv) \
  157.    _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
  158.  
  159. #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
  160.    _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
  161.  
  162.  
  163. static INLINE _EGLDriver *
  164. _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
  165. {
  166.    if (!disp) {
  167.       _eglError(EGL_BAD_DISPLAY, msg);
  168.       return NULL;
  169.    }
  170.    if (!disp->Initialized) {
  171.       _eglError(EGL_NOT_INITIALIZED, msg);
  172.       return NULL;
  173.    }
  174.    return disp->Driver;
  175. }
  176.  
  177.  
  178. static INLINE _EGLDriver *
  179. _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
  180. {
  181.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  182.    if (!drv)
  183.       return NULL;
  184.    if (!surf) {
  185.       _eglError(EGL_BAD_SURFACE, msg);
  186.       return NULL;
  187.    }
  188.    return drv;
  189. }
  190.  
  191.  
  192. static INLINE _EGLDriver *
  193. _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
  194. {
  195.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  196.    if (!drv)
  197.       return NULL;
  198.    if (!context) {
  199.       _eglError(EGL_BAD_CONTEXT, msg);
  200.       return NULL;
  201.    }
  202.    return drv;
  203. }
  204.  
  205.  
  206. static INLINE _EGLDriver *
  207. _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
  208. {
  209.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  210.    if (!drv)
  211.       return NULL;
  212.    if (!conf) {
  213.       _eglError(EGL_BAD_CONFIG, msg);
  214.       return NULL;
  215.    }
  216.    return drv;
  217. }
  218.  
  219.  
  220. static INLINE _EGLDriver *
  221. _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
  222. {
  223.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  224.    if (!drv)
  225.       return NULL;
  226.    if (!s) {
  227.       _eglError(EGL_BAD_PARAMETER, msg);
  228.       return NULL;
  229.    }
  230.    return drv;
  231. }
  232.  
  233.  
  234. #ifdef EGL_MESA_screen_surface
  235.  
  236.  
  237. static INLINE _EGLDriver *
  238. _eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
  239. {
  240.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  241.    if (!drv)
  242.       return NULL;
  243.    if (!scrn) {
  244.       _eglError(EGL_BAD_SCREEN_MESA, msg);
  245.       return NULL;
  246.    }
  247.    return drv;
  248. }
  249.  
  250.  
  251. static INLINE _EGLDriver *
  252. _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
  253. {
  254.    _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  255.    if (!drv)
  256.       return NULL;
  257.    if (!m) {
  258.       _eglError(EGL_BAD_MODE_MESA, msg);
  259.       return NULL;
  260.    }
  261.    return drv;
  262. }
  263.  
  264.  
  265. #endif /* EGL_MESA_screen_surface */
  266.  
  267.  
  268. /**
  269.  * Lookup and lock a display.
  270.  */
  271. static INLINE _EGLDisplay *
  272. _eglLockDisplay(EGLDisplay display)
  273. {
  274.    _EGLDisplay *dpy = _eglLookupDisplay(display);
  275.    if (dpy)
  276.       _eglLockMutex(&dpy->Mutex);
  277.    return dpy;
  278. }
  279.  
  280.  
  281. /**
  282.  * Unlock a display.
  283.  */
  284. static INLINE void
  285. _eglUnlockDisplay(_EGLDisplay *dpy)
  286. {
  287.    _eglUnlockMutex(&dpy->Mutex);
  288. }
  289.  
  290.  
  291. /**
  292.  * This is typically the first EGL function that an application calls.
  293.  * It associates a private _EGLDisplay object to the native display.
  294.  */
  295. EGLDisplay EGLAPIENTRY
  296. eglGetDisplay(EGLNativeDisplayType nativeDisplay)
  297. {
  298.    _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay);
  299.    _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
  300.    return _eglGetDisplayHandle(dpy);
  301. }
  302.  
  303.  
  304. /**
  305.  * This is typically the second EGL function that an application calls.
  306.  * Here we load/initialize the actual hardware driver.
  307.  */
  308. EGLBoolean EGLAPIENTRY
  309. eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
  310. {
  311.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  312.  
  313.    if (!disp)
  314.       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
  315.  
  316.    if (!disp->Initialized) {
  317.       if (!_eglMatchDriver(disp, EGL_FALSE))
  318.          RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
  319.  
  320.       /* limit to APIs supported by core */
  321.       disp->ClientAPIs &= _EGL_API_ALL_BITS;
  322.    }
  323.  
  324.    /* Update applications version of major and minor if not NULL */
  325.    if ((major != NULL) && (minor != NULL)) {
  326.       *major = disp->VersionMajor;
  327.       *minor = disp->VersionMinor;
  328.    }
  329.  
  330.    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  331. }
  332.  
  333.  
  334. EGLBoolean EGLAPIENTRY
  335. eglTerminate(EGLDisplay dpy)
  336. {
  337.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  338.  
  339.    if (!disp)
  340.       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
  341.  
  342.    if (disp->Initialized) {
  343.       _EGLDriver *drv = disp->Driver;
  344.  
  345.       drv->API.Terminate(drv, disp);
  346.       /* do not reset disp->Driver */
  347.       disp->Initialized = EGL_FALSE;
  348.    }
  349.  
  350.    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  351. }
  352.  
  353.  
  354. const char * EGLAPIENTRY
  355. eglQueryString(EGLDisplay dpy, EGLint name)
  356. {
  357.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  358.    _EGLDriver *drv;
  359.    const char *ret;
  360.  
  361.    _EGL_CHECK_DISPLAY(disp, NULL, drv);
  362.    ret = drv->API.QueryString(drv, disp, name);
  363.  
  364.    RETURN_EGL_EVAL(disp, ret);
  365. }
  366.  
  367.  
  368. EGLBoolean EGLAPIENTRY
  369. eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
  370.               EGLint config_size, EGLint *num_config)
  371. {
  372.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  373.    _EGLDriver *drv;
  374.    EGLBoolean ret;
  375.  
  376.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  377.    ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
  378.  
  379.    RETURN_EGL_EVAL(disp, ret);
  380. }
  381.  
  382.  
  383. EGLBoolean EGLAPIENTRY
  384. eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
  385.                 EGLint config_size, EGLint *num_config)
  386. {
  387.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  388.    _EGLDriver *drv;
  389.    EGLBoolean ret;
  390.  
  391.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  392.    ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
  393.                                 config_size, num_config);
  394.  
  395.    RETURN_EGL_EVAL(disp, ret);
  396. }
  397.  
  398.  
  399. EGLBoolean EGLAPIENTRY
  400. eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
  401.                    EGLint attribute, EGLint *value)
  402. {
  403.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  404.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  405.    _EGLDriver *drv;
  406.    EGLBoolean ret;
  407.  
  408.    _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
  409.    ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
  410.  
  411.    RETURN_EGL_EVAL(disp, ret);
  412. }
  413.  
  414.  
  415. EGLContext EGLAPIENTRY
  416. eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
  417.                  const EGLint *attrib_list)
  418. {
  419.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  420.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  421.    _EGLContext *share = _eglLookupContext(share_list, disp);
  422.    _EGLDriver *drv;
  423.    _EGLContext *context;
  424.    EGLContext ret;
  425.  
  426.    _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
  427.  
  428.    if (!config) {
  429.       /* config may be NULL if surfaceless */
  430.       if (!disp->Extensions.KHR_surfaceless_context)
  431.          RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
  432.    }
  433.  
  434.    if (!share && share_list != EGL_NO_CONTEXT)
  435.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
  436.  
  437.    context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
  438.    ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
  439.  
  440.    RETURN_EGL_EVAL(disp, ret);
  441. }
  442.  
  443.  
  444. EGLBoolean EGLAPIENTRY
  445. eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
  446. {
  447.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  448.    _EGLContext *context = _eglLookupContext(ctx, disp);
  449.    _EGLDriver *drv;
  450.    EGLBoolean ret;
  451.  
  452.    _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
  453.    _eglUnlinkContext(context);
  454.    ret = drv->API.DestroyContext(drv, disp, context);
  455.  
  456.    RETURN_EGL_EVAL(disp, ret);
  457. }
  458.  
  459.  
  460. EGLBoolean EGLAPIENTRY
  461. eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
  462.                EGLContext ctx)
  463. {
  464.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  465.    _EGLContext *context = _eglLookupContext(ctx, disp);
  466.    _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
  467.    _EGLSurface *read_surf = _eglLookupSurface(read, disp);
  468.    _EGLDriver *drv;
  469.    EGLBoolean ret;
  470.  
  471.    if (!disp)
  472.       RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
  473.    drv = disp->Driver;
  474.  
  475.    /* display is allowed to be uninitialized under certain condition */
  476.    if (!disp->Initialized) {
  477.       if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
  478.           ctx != EGL_NO_CONTEXT)
  479.          RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
  480.    }
  481.    if (!drv)
  482.       RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  483.  
  484.    if (!context && ctx != EGL_NO_CONTEXT)
  485.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  486.    if (!draw_surf || !read_surf) {
  487.       /* surfaces may be NULL if surfaceless */
  488.       if (!disp->Extensions.KHR_surfaceless_context)
  489.          RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  490.  
  491.       if ((!draw_surf && draw != EGL_NO_SURFACE) ||
  492.           (!read_surf && read != EGL_NO_SURFACE))
  493.          RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  494.       if (draw_surf || read_surf)
  495.          RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
  496.    }
  497.  
  498.    ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
  499.  
  500.    RETURN_EGL_EVAL(disp, ret);
  501. }
  502.  
  503.  
  504. EGLBoolean EGLAPIENTRY
  505. eglQueryContext(EGLDisplay dpy, EGLContext ctx,
  506.                 EGLint attribute, EGLint *value)
  507. {
  508.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  509.    _EGLContext *context = _eglLookupContext(ctx, disp);
  510.    _EGLDriver *drv;
  511.    EGLBoolean ret;
  512.  
  513.    _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
  514.    ret = drv->API.QueryContext(drv, disp, context, attribute, value);
  515.  
  516.    RETURN_EGL_EVAL(disp, ret);
  517. }
  518.  
  519.  
  520. EGLSurface EGLAPIENTRY
  521. eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
  522.                        EGLNativeWindowType window, const EGLint *attrib_list)
  523. {
  524.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  525.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  526.    _EGLDriver *drv;
  527.    _EGLSurface *surf;
  528.    EGLSurface ret;
  529.  
  530.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  531.    if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
  532.       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  533.  
  534.    surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
  535.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  536.  
  537.    RETURN_EGL_EVAL(disp, ret);
  538. }
  539.  
  540.  
  541. EGLSurface EGLAPIENTRY
  542. eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
  543.                        EGLNativePixmapType pixmap, const EGLint *attrib_list)
  544. {
  545.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  546.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  547.    _EGLDriver *drv;
  548.    _EGLSurface *surf;
  549.    EGLSurface ret;
  550.  
  551.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  552.    if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
  553.       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
  554.  
  555.    surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
  556.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  557.  
  558.    RETURN_EGL_EVAL(disp, ret);
  559. }
  560.  
  561.  
  562. EGLSurface EGLAPIENTRY
  563. eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
  564.                         const EGLint *attrib_list)
  565. {
  566.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  567.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  568.    _EGLDriver *drv;
  569.    _EGLSurface *surf;
  570.    EGLSurface ret;
  571.  
  572.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  573.  
  574.    surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
  575.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  576.  
  577.    RETURN_EGL_EVAL(disp, ret);
  578. }
  579.  
  580.  
  581. EGLBoolean EGLAPIENTRY
  582. eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
  583. {
  584.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  585.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  586.    _EGLDriver *drv;
  587.    EGLBoolean ret;
  588.  
  589.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  590.    _eglUnlinkSurface(surf);
  591.    ret = drv->API.DestroySurface(drv, disp, surf);
  592.  
  593.    RETURN_EGL_EVAL(disp, ret);
  594. }
  595.  
  596. EGLBoolean EGLAPIENTRY
  597. eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
  598.                 EGLint attribute, EGLint *value)
  599. {
  600.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  601.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  602.    _EGLDriver *drv;
  603.    EGLBoolean ret;
  604.  
  605.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  606.    ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
  607.  
  608.    RETURN_EGL_EVAL(disp, ret);
  609. }
  610.  
  611. EGLBoolean EGLAPIENTRY
  612. eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
  613.                  EGLint attribute, EGLint value)
  614. {
  615.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  616.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  617.    _EGLDriver *drv;
  618.    EGLBoolean ret;
  619.  
  620.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  621.    ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
  622.  
  623.    RETURN_EGL_EVAL(disp, ret);
  624. }
  625.  
  626.  
  627. EGLBoolean EGLAPIENTRY
  628. eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  629. {
  630.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  631.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  632.    _EGLDriver *drv;
  633.    EGLBoolean ret;
  634.  
  635.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  636.    ret = drv->API.BindTexImage(drv, disp, surf, buffer);
  637.  
  638.    RETURN_EGL_EVAL(disp, ret);
  639. }
  640.  
  641.  
  642. EGLBoolean EGLAPIENTRY
  643. eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  644. {
  645.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  646.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  647.    _EGLDriver *drv;
  648.    EGLBoolean ret;
  649.  
  650.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  651.    ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
  652.  
  653.    RETURN_EGL_EVAL(disp, ret);
  654. }
  655.  
  656.  
  657. EGLBoolean EGLAPIENTRY
  658. eglSwapInterval(EGLDisplay dpy, EGLint interval)
  659. {
  660.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  661.    _EGLContext *ctx = _eglGetCurrentContext();
  662.    _EGLSurface *surf;
  663.    _EGLDriver *drv;
  664.    EGLBoolean ret;
  665.  
  666.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  667.  
  668.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  669.        ctx->Resource.Display != disp)
  670.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  671.  
  672.    surf = ctx->DrawSurface;
  673.    if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
  674.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  675.  
  676.    ret = drv->API.SwapInterval(drv, disp, surf, interval);
  677.  
  678.    RETURN_EGL_EVAL(disp, ret);
  679. }
  680.  
  681.  
  682. EGLBoolean EGLAPIENTRY
  683. eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  684. {
  685.    _EGLContext *ctx = _eglGetCurrentContext();
  686.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  687.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  688.    _EGLDriver *drv;
  689.    EGLBoolean ret;
  690.  
  691.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  692.  
  693.    /* surface must be bound to current context in EGL 1.4 */
  694.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  695.        surf != ctx->DrawSurface)
  696.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  697.  
  698.    ret = drv->API.SwapBuffers(drv, disp, surf);
  699.  
  700.    RETURN_EGL_EVAL(disp, ret);
  701. }
  702.  
  703.  
  704. #ifdef EGL_EXT_swap_buffers_with_damage
  705.  
  706. EGLBoolean EGLAPIENTRY
  707. eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
  708.                             EGLint *rects, EGLint n_rects)
  709. {
  710.    _EGLContext *ctx = _eglGetCurrentContext();
  711.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  712.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  713.    _EGLDriver *drv;
  714.    EGLBoolean ret;
  715.  
  716.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  717.  
  718.    /* surface must be bound to current context in EGL 1.4 */
  719.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  720.        surf != ctx->DrawSurface)
  721.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  722.  
  723.    if ((n_rects > 0 && rects == NULL) || n_rects < 0)
  724.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  725.  
  726.    ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
  727.  
  728.    RETURN_EGL_EVAL(disp, ret);
  729. }
  730.  
  731. #endif /* EGL_EXT_swap_buffers_with_damage */
  732.  
  733. EGLBoolean EGLAPIENTRY
  734. eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
  735. {
  736.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  737.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  738.    _EGLDriver *drv;
  739.    EGLBoolean ret;
  740.  
  741.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  742.    if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
  743.       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
  744.    ret = drv->API.CopyBuffers(drv, disp, surf, target);
  745.  
  746.    RETURN_EGL_EVAL(disp, ret);
  747. }
  748.  
  749.  
  750. EGLBoolean EGLAPIENTRY
  751. eglWaitClient(void)
  752. {
  753.    _EGLContext *ctx = _eglGetCurrentContext();
  754.    _EGLDisplay *disp;
  755.    _EGLDriver *drv;
  756.    EGLBoolean ret;
  757.  
  758.    if (!ctx)
  759.       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  760.  
  761.    disp = ctx->Resource.Display;
  762.    _eglLockMutex(&disp->Mutex);
  763.  
  764.    /* let bad current context imply bad current surface */
  765.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  766.        _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  767.       RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  768.  
  769.    /* a valid current context implies an initialized current display */
  770.    assert(disp->Initialized);
  771.    drv = disp->Driver;
  772.    ret = drv->API.WaitClient(drv, disp, ctx);
  773.  
  774.    RETURN_EGL_EVAL(disp, ret);
  775. }
  776.  
  777.  
  778. EGLBoolean EGLAPIENTRY
  779. eglWaitGL(void)
  780. {
  781.    _EGLThreadInfo *t = _eglGetCurrentThread();
  782.    EGLint api_index = t->CurrentAPIIndex;
  783.    EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
  784.    EGLBoolean ret;
  785.  
  786.    if (api_index != es_index && _eglIsCurrentThreadDummy())
  787.       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  788.  
  789.    t->CurrentAPIIndex = es_index;
  790.    ret = eglWaitClient();
  791.    t->CurrentAPIIndex = api_index;
  792.    return ret;
  793. }
  794.  
  795.  
  796. EGLBoolean EGLAPIENTRY
  797. eglWaitNative(EGLint engine)
  798. {
  799.    _EGLContext *ctx = _eglGetCurrentContext();
  800.    _EGLDisplay *disp;
  801.    _EGLDriver *drv;
  802.    EGLBoolean ret;
  803.  
  804.    if (!ctx)
  805.       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  806.  
  807.    disp = ctx->Resource.Display;
  808.    _eglLockMutex(&disp->Mutex);
  809.  
  810.    /* let bad current context imply bad current surface */
  811.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  812.        _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  813.       RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  814.  
  815.    /* a valid current context implies an initialized current display */
  816.    assert(disp->Initialized);
  817.    drv = disp->Driver;
  818.    ret = drv->API.WaitNative(drv, disp, engine);
  819.  
  820.    RETURN_EGL_EVAL(disp, ret);
  821. }
  822.  
  823.  
  824. EGLDisplay EGLAPIENTRY
  825. eglGetCurrentDisplay(void)
  826. {
  827.    _EGLContext *ctx = _eglGetCurrentContext();
  828.    EGLDisplay ret;
  829.  
  830.    ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
  831.  
  832.    RETURN_EGL_SUCCESS(NULL, ret);
  833. }
  834.  
  835.  
  836. EGLContext EGLAPIENTRY
  837. eglGetCurrentContext(void)
  838. {
  839.    _EGLContext *ctx = _eglGetCurrentContext();
  840.    EGLContext ret;
  841.  
  842.    ret = _eglGetContextHandle(ctx);
  843.  
  844.    RETURN_EGL_SUCCESS(NULL, ret);
  845. }
  846.  
  847.  
  848. EGLSurface EGLAPIENTRY
  849. eglGetCurrentSurface(EGLint readdraw)
  850. {
  851.    _EGLContext *ctx = _eglGetCurrentContext();
  852.    EGLint err = EGL_SUCCESS;
  853.    _EGLSurface *surf;
  854.    EGLSurface ret;
  855.  
  856.    if (!ctx)
  857.       RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
  858.  
  859.    switch (readdraw) {
  860.    case EGL_DRAW:
  861.       surf = ctx->DrawSurface;
  862.       break;
  863.    case EGL_READ:
  864.       surf = ctx->ReadSurface;
  865.       break;
  866.    default:
  867.       surf = NULL;
  868.       err = EGL_BAD_PARAMETER;
  869.       break;
  870.    }
  871.  
  872.    ret = _eglGetSurfaceHandle(surf);
  873.  
  874.    RETURN_EGL_ERROR(NULL, err, ret);
  875. }
  876.  
  877.  
  878. EGLint EGLAPIENTRY
  879. eglGetError(void)
  880. {
  881.    _EGLThreadInfo *t = _eglGetCurrentThread();
  882.    EGLint e = t->LastError;
  883.    if (!_eglIsCurrentThreadDummy())
  884.       t->LastError = EGL_SUCCESS;
  885.    return e;
  886. }
  887.  
  888.  
  889. __eglMustCastToProperFunctionPointerType EGLAPIENTRY
  890. eglGetProcAddress(const char *procname)
  891. {
  892.    static const struct {
  893.       const char *name;
  894.       _EGLProc function;
  895.    } egl_functions[] = {
  896.       /* core functions should not be queryable, but, well... */
  897. #ifdef _EGL_GET_CORE_ADDRESSES
  898.       /* alphabetical order */
  899.       { "eglBindAPI", (_EGLProc) eglBindAPI },
  900.       { "eglBindTexImage", (_EGLProc) eglBindTexImage },
  901.       { "eglChooseConfig", (_EGLProc) eglChooseConfig },
  902.       { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
  903.       { "eglCreateContext", (_EGLProc) eglCreateContext },
  904.       { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
  905.       { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
  906.       { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
  907.       { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
  908.       { "eglDestroyContext", (_EGLProc) eglDestroyContext },
  909.       { "eglDestroySurface", (_EGLProc) eglDestroySurface },
  910.       { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
  911.       { "eglGetConfigs", (_EGLProc) eglGetConfigs },
  912.       { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
  913.       { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
  914.       { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
  915.       { "eglGetDisplay", (_EGLProc) eglGetDisplay },
  916.       { "eglGetError", (_EGLProc) eglGetError },
  917.       { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
  918.       { "eglInitialize", (_EGLProc) eglInitialize },
  919.       { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
  920.       { "eglQueryAPI", (_EGLProc) eglQueryAPI },
  921.       { "eglQueryContext", (_EGLProc) eglQueryContext },
  922.       { "eglQueryString", (_EGLProc) eglQueryString },
  923.       { "eglQuerySurface", (_EGLProc) eglQuerySurface },
  924.       { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
  925.       { "eglReleaseThread", (_EGLProc) eglReleaseThread },
  926.       { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
  927.       { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
  928.       { "eglSwapInterval", (_EGLProc) eglSwapInterval },
  929.       { "eglTerminate", (_EGLProc) eglTerminate },
  930.       { "eglWaitClient", (_EGLProc) eglWaitClient },
  931.       { "eglWaitGL", (_EGLProc) eglWaitGL },
  932.       { "eglWaitNative", (_EGLProc) eglWaitNative },
  933. #endif /* _EGL_GET_CORE_ADDRESSES */
  934. #ifdef EGL_MESA_screen_surface
  935.       { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
  936.       { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
  937.       { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
  938.       { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
  939.       { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
  940.       { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
  941.       { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
  942.       { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
  943.       { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
  944.       { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
  945.       { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
  946.       { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
  947. #endif /* EGL_MESA_screen_surface */
  948. #ifdef EGL_MESA_drm_display
  949.       { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
  950. #endif
  951.       { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
  952.       { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
  953.       { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
  954.       { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
  955.       { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
  956.       { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
  957.       { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
  958. #ifdef EGL_NOK_swap_region
  959.       { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
  960. #endif
  961. #ifdef EGL_MESA_drm_image
  962.       { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
  963.       { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
  964. #endif
  965. #ifdef EGL_WL_bind_wayland_display
  966.       { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
  967.       { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
  968.       { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
  969. #endif
  970.       { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
  971. #ifdef EGL_EXT_swap_buffers_with_damage
  972.       { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
  973. #endif
  974.       { NULL, NULL }
  975.    };
  976.    EGLint i;
  977.    _EGLProc ret;
  978.  
  979.    if (!procname)
  980.       RETURN_EGL_SUCCESS(NULL, NULL);
  981.  
  982.    ret = NULL;
  983.    if (strncmp(procname, "egl", 3) == 0) {
  984.       for (i = 0; egl_functions[i].name; i++) {
  985.          if (strcmp(egl_functions[i].name, procname) == 0) {
  986.             ret = egl_functions[i].function;
  987.             break;
  988.          }
  989.       }
  990.    }
  991.    if (!ret)
  992.       ret = _eglGetDriverProc(procname);
  993.  
  994.    RETURN_EGL_SUCCESS(NULL, ret);
  995. }
  996.  
  997.  
  998. #ifdef EGL_MESA_screen_surface
  999.  
  1000.  
  1001. /*
  1002.  * EGL_MESA_screen extension
  1003.  */
  1004.  
  1005. EGLBoolean EGLAPIENTRY
  1006. eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
  1007.                   const EGLint *attrib_list, EGLModeMESA *modes,
  1008.                   EGLint modes_size, EGLint *num_modes)
  1009. {
  1010.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1011.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1012.    _EGLDriver *drv;
  1013.    EGLBoolean ret;
  1014.  
  1015.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1016.    ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
  1017.          modes, modes_size, num_modes);
  1018.  
  1019.    RETURN_EGL_EVAL(disp, ret);
  1020. }
  1021.  
  1022.  
  1023. EGLBoolean EGLAPIENTRY
  1024. eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
  1025.                 EGLint mode_size, EGLint *num_mode)
  1026. {
  1027.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1028.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1029.    _EGLDriver *drv;
  1030.    EGLBoolean ret;
  1031.  
  1032.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1033.    ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
  1034.  
  1035.    RETURN_EGL_EVAL(disp, ret);
  1036. }
  1037.  
  1038.  
  1039. EGLBoolean EGLAPIENTRY
  1040. eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
  1041.                      EGLint attribute, EGLint *value)
  1042. {
  1043.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1044.    _EGLMode *m = _eglLookupMode(mode, disp);
  1045.    _EGLDriver *drv;
  1046.    EGLBoolean ret;
  1047.  
  1048.    _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
  1049.    ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
  1050.  
  1051.    RETURN_EGL_EVAL(disp, ret);
  1052. }
  1053.  
  1054.  
  1055. EGLBoolean EGLAPIENTRY
  1056. eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
  1057.                    EGLint mask)
  1058. {
  1059.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1060.    _EGLContext *source_context = _eglLookupContext(source, disp);
  1061.    _EGLContext *dest_context = _eglLookupContext(dest, disp);
  1062.    _EGLDriver *drv;
  1063.    EGLBoolean ret;
  1064.  
  1065.    _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
  1066.    if (!dest_context)
  1067.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  1068.  
  1069.    ret = drv->API.CopyContextMESA(drv, disp,
  1070.          source_context, dest_context, mask);
  1071.  
  1072.    RETURN_EGL_EVAL(disp, ret);
  1073. }
  1074.  
  1075.  
  1076. EGLBoolean EGLAPIENTRY
  1077. eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
  1078.                   EGLint max_screens, EGLint *num_screens)
  1079. {
  1080.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1081.    _EGLDriver *drv;
  1082.    EGLBoolean ret;
  1083.  
  1084.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1085.    ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
  1086.  
  1087.    RETURN_EGL_EVAL(disp, ret);
  1088. }
  1089.  
  1090.  
  1091. EGLSurface EGLAPIENTRY
  1092. eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
  1093.                            const EGLint *attrib_list)
  1094. {
  1095.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1096.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  1097.    _EGLDriver *drv;
  1098.    _EGLSurface *surf;
  1099.    EGLSurface ret;
  1100.  
  1101.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  1102.  
  1103.    surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
  1104.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  1105.  
  1106.    RETURN_EGL_EVAL(disp, ret);
  1107. }
  1108.  
  1109.  
  1110. EGLBoolean EGLAPIENTRY
  1111. eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
  1112.                          EGLSurface surface, EGLModeMESA mode)
  1113. {
  1114.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1115.    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
  1116.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1117.    _EGLMode *m = _eglLookupMode(mode, disp);
  1118.    _EGLDriver *drv;
  1119.    EGLBoolean ret;
  1120.  
  1121.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1122.    if (!surf && surface != EGL_NO_SURFACE)
  1123.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  1124.    if (!m && mode != EGL_NO_MODE_MESA)
  1125.       RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
  1126.  
  1127.    ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
  1128.  
  1129.    RETURN_EGL_EVAL(disp, ret);
  1130. }
  1131.  
  1132.  
  1133. EGLBoolean EGLAPIENTRY
  1134. eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
  1135. {
  1136.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1137.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1138.    _EGLDriver *drv;
  1139.    EGLBoolean ret;
  1140.  
  1141.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1142.    ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
  1143.  
  1144.    RETURN_EGL_EVAL(disp, ret);
  1145. }
  1146.  
  1147.  
  1148. EGLBoolean EGLAPIENTRY
  1149. eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
  1150.                    EGLint attribute, EGLint *value)
  1151. {
  1152.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1153.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1154.    _EGLDriver *drv;
  1155.    EGLBoolean ret;
  1156.  
  1157.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1158.    ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
  1159.  
  1160.    RETURN_EGL_EVAL(disp, ret);
  1161. }
  1162.  
  1163.  
  1164. EGLBoolean EGLAPIENTRY
  1165. eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
  1166.                           EGLSurface *surface)
  1167. {
  1168.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1169.    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
  1170.    _EGLDriver *drv;
  1171.    _EGLSurface *surf;
  1172.    EGLBoolean ret;
  1173.  
  1174.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1175.    ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
  1176.    if (ret && surface)
  1177.       *surface = _eglGetSurfaceHandle(surf);
  1178.  
  1179.    RETURN_EGL_EVAL(disp, ret);
  1180. }
  1181.  
  1182.  
  1183. EGLBoolean EGLAPIENTRY
  1184. eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
  1185. {
  1186.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1187.    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
  1188.    _EGLDriver *drv;
  1189.    _EGLMode *m;
  1190.    EGLBoolean ret;
  1191.  
  1192.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1193.    ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
  1194.    if (ret && mode)
  1195.       *mode = m->Handle;
  1196.  
  1197.    RETURN_EGL_EVAL(disp, ret);
  1198. }
  1199.  
  1200.  
  1201. const char * EGLAPIENTRY
  1202. eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
  1203. {
  1204.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1205.    _EGLMode *m = _eglLookupMode(mode, disp);
  1206.    _EGLDriver *drv;
  1207.    const char *ret;
  1208.  
  1209.    _EGL_CHECK_MODE(disp, m, NULL, drv);
  1210.    ret = drv->API.QueryModeStringMESA(drv, disp, m);
  1211.  
  1212.    RETURN_EGL_EVAL(disp, ret);
  1213. }
  1214.  
  1215.  
  1216. #endif /* EGL_MESA_screen_surface */
  1217.  
  1218.  
  1219. #ifdef EGL_MESA_drm_display
  1220.  
  1221. EGLDisplay EGLAPIENTRY
  1222. eglGetDRMDisplayMESA(int fd)
  1223. {
  1224.    _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
  1225.    return _eglGetDisplayHandle(dpy);
  1226. }
  1227.  
  1228. #endif /* EGL_MESA_drm_display */
  1229.  
  1230. /**
  1231.  ** EGL 1.2
  1232.  **/
  1233.  
  1234. /**
  1235.  * Specify the client API to use for subsequent calls including:
  1236.  *  eglCreateContext()
  1237.  *  eglGetCurrentContext()
  1238.  *  eglGetCurrentDisplay()
  1239.  *  eglGetCurrentSurface()
  1240.  *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
  1241.  *  eglWaitClient()
  1242.  *  eglWaitNative()
  1243.  * See section 3.7 "Rendering Context" in the EGL specification for details.
  1244.  */
  1245. EGLBoolean EGLAPIENTRY
  1246. eglBindAPI(EGLenum api)
  1247. {
  1248.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1249.  
  1250.    if (_eglIsCurrentThreadDummy())
  1251.       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  1252.  
  1253.    if (!_eglIsApiValid(api))
  1254.       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
  1255.  
  1256.    t->CurrentAPIIndex = _eglConvertApiToIndex(api);
  1257.  
  1258.    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1259. }
  1260.  
  1261.  
  1262. /**
  1263.  * Return the last value set with eglBindAPI().
  1264.  */
  1265. EGLenum EGLAPIENTRY
  1266. eglQueryAPI(void)
  1267. {
  1268.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1269.    EGLenum ret;
  1270.  
  1271.    /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
  1272.    ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
  1273.  
  1274.    RETURN_EGL_SUCCESS(NULL, ret);
  1275. }
  1276.  
  1277.  
  1278. EGLSurface EGLAPIENTRY
  1279. eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
  1280.                                  EGLClientBuffer buffer, EGLConfig config,
  1281.                                  const EGLint *attrib_list)
  1282. {
  1283.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1284.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  1285.    _EGLDriver *drv;
  1286.    _EGLSurface *surf;
  1287.    EGLSurface ret;
  1288.  
  1289.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  1290.  
  1291.    surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
  1292.                                                  conf, attrib_list);
  1293.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  1294.  
  1295.    RETURN_EGL_EVAL(disp, ret);
  1296. }
  1297.  
  1298.  
  1299. EGLBoolean EGLAPIENTRY
  1300. eglReleaseThread(void)
  1301. {
  1302.    /* unbind current contexts */
  1303.    if (!_eglIsCurrentThreadDummy()) {
  1304.       _EGLThreadInfo *t = _eglGetCurrentThread();
  1305.       EGLint api_index = t->CurrentAPIIndex;
  1306.       EGLint i;
  1307.  
  1308.       for (i = 0; i < _EGL_API_NUM_APIS; i++) {
  1309.          _EGLContext *ctx = t->CurrentContexts[i];
  1310.          if (ctx) {
  1311.             _EGLDisplay *disp = ctx->Resource.Display;
  1312.             _EGLDriver *drv;
  1313.  
  1314.             t->CurrentAPIIndex = i;
  1315.  
  1316.             _eglLockMutex(&disp->Mutex);
  1317.             drv = disp->Driver;
  1318.             (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
  1319.             _eglUnlockMutex(&disp->Mutex);
  1320.          }
  1321.       }
  1322.  
  1323.       t->CurrentAPIIndex = api_index;
  1324.    }
  1325.  
  1326.    _eglDestroyCurrentThread();
  1327.  
  1328.    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1329. }
  1330.  
  1331.  
  1332. EGLImageKHR EGLAPIENTRY
  1333. eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1334.                   EGLClientBuffer buffer, const EGLint *attr_list)
  1335. {
  1336.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1337.    _EGLContext *context = _eglLookupContext(ctx, disp);
  1338.    _EGLDriver *drv;
  1339.    _EGLImage *img;
  1340.    EGLImageKHR ret;
  1341.  
  1342.    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1343.    if (!disp->Extensions.KHR_image_base)
  1344.       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1345.    if (!context && ctx != EGL_NO_CONTEXT)
  1346.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
  1347.  
  1348.    img = drv->API.CreateImageKHR(drv,
  1349.          disp, context, target, buffer, attr_list);
  1350.    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1351.  
  1352.    RETURN_EGL_EVAL(disp, ret);
  1353. }
  1354.  
  1355.  
  1356. EGLBoolean EGLAPIENTRY
  1357. eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
  1358. {
  1359.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1360.    _EGLImage *img = _eglLookupImage(image, disp);
  1361.    _EGLDriver *drv;
  1362.    EGLBoolean ret;
  1363.  
  1364.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1365.    if (!disp->Extensions.KHR_image_base)
  1366.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1367.    if (!img)
  1368.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1369.  
  1370.    _eglUnlinkImage(img);
  1371.    ret = drv->API.DestroyImageKHR(drv, disp, img);
  1372.  
  1373.    RETURN_EGL_EVAL(disp, ret);
  1374. }
  1375.  
  1376.  
  1377. EGLSyncKHR EGLAPIENTRY
  1378. eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
  1379. {
  1380.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1381.    _EGLDriver *drv;
  1382.    _EGLSync *sync;
  1383.    EGLSyncKHR ret;
  1384.  
  1385.    _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
  1386.    if (!disp->Extensions.KHR_reusable_sync)
  1387.       RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
  1388.  
  1389.    sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
  1390.    ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
  1391.  
  1392.    RETURN_EGL_EVAL(disp, ret);
  1393. }
  1394.  
  1395.  
  1396. EGLBoolean EGLAPIENTRY
  1397. eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
  1398. {
  1399.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1400.    _EGLSync *s = _eglLookupSync(sync, disp);
  1401.    _EGLDriver *drv;
  1402.    EGLBoolean ret;
  1403.  
  1404.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1405.    assert(disp->Extensions.KHR_reusable_sync);
  1406.  
  1407.    _eglUnlinkSync(s);
  1408.    ret = drv->API.DestroySyncKHR(drv, disp, s);
  1409.  
  1410.    RETURN_EGL_EVAL(disp, ret);
  1411. }
  1412.  
  1413.  
  1414. EGLint EGLAPIENTRY
  1415. eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
  1416. {
  1417.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1418.    _EGLSync *s = _eglLookupSync(sync, disp);
  1419.    _EGLDriver *drv;
  1420.    EGLint ret;
  1421.  
  1422.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1423.    assert(disp->Extensions.KHR_reusable_sync);
  1424.    ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
  1425.  
  1426.    RETURN_EGL_EVAL(disp, ret);
  1427. }
  1428.  
  1429.  
  1430. EGLBoolean EGLAPIENTRY
  1431. eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
  1432. {
  1433.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1434.    _EGLSync *s = _eglLookupSync(sync, disp);
  1435.    _EGLDriver *drv;
  1436.    EGLBoolean ret;
  1437.  
  1438.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1439.    assert(disp->Extensions.KHR_reusable_sync);
  1440.    ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
  1441.  
  1442.    RETURN_EGL_EVAL(disp, ret);
  1443. }
  1444.  
  1445.  
  1446. EGLBoolean EGLAPIENTRY
  1447. eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
  1448. {
  1449.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1450.    _EGLSync *s = _eglLookupSync(sync, disp);
  1451.    _EGLDriver *drv;
  1452.    EGLBoolean ret;
  1453.  
  1454.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1455.    assert(disp->Extensions.KHR_reusable_sync);
  1456.    ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
  1457.  
  1458.    RETURN_EGL_EVAL(disp, ret);
  1459. }
  1460.  
  1461.  
  1462. #ifdef EGL_NOK_swap_region
  1463.  
  1464. EGLBoolean EGLAPIENTRY
  1465. eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
  1466.                         EGLint numRects, const EGLint *rects)
  1467. {
  1468.    _EGLContext *ctx = _eglGetCurrentContext();
  1469.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1470.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1471.    _EGLDriver *drv;
  1472.    EGLBoolean ret;
  1473.  
  1474.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1475.  
  1476.    if (!disp->Extensions.NOK_swap_region)
  1477.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1478.  
  1479.    /* surface must be bound to current context in EGL 1.4 */
  1480.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  1481.        surf != ctx->DrawSurface)
  1482.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  1483.  
  1484.    ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
  1485.  
  1486.    RETURN_EGL_EVAL(disp, ret);
  1487. }
  1488.  
  1489. #endif /* EGL_NOK_swap_region */
  1490.  
  1491.  
  1492. #ifdef EGL_MESA_drm_image
  1493.  
  1494. EGLImageKHR EGLAPIENTRY
  1495. eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
  1496. {
  1497.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1498.    _EGLDriver *drv;
  1499.    _EGLImage *img;
  1500.    EGLImageKHR ret;
  1501.  
  1502.    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1503.    if (!disp->Extensions.MESA_drm_image)
  1504.       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1505.  
  1506.    img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
  1507.    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1508.  
  1509.    RETURN_EGL_EVAL(disp, ret);
  1510. }
  1511.  
  1512. EGLBoolean EGLAPIENTRY
  1513. eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
  1514.                       EGLint *name, EGLint *handle, EGLint *stride)
  1515. {
  1516.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1517.    _EGLImage *img = _eglLookupImage(image, disp);
  1518.    _EGLDriver *drv;
  1519.    EGLBoolean ret;
  1520.  
  1521.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1522.    assert(disp->Extensions.MESA_drm_image);
  1523.  
  1524.    if (!img)
  1525.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1526.  
  1527.    ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
  1528.  
  1529.    RETURN_EGL_EVAL(disp, ret);
  1530. }
  1531.  
  1532. #endif
  1533.  
  1534. #ifdef EGL_WL_bind_wayland_display
  1535. struct wl_display;
  1536.  
  1537. EGLBoolean EGLAPIENTRY
  1538. eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1539. {
  1540.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1541.    _EGLDriver *drv;
  1542.    EGLBoolean ret;
  1543.  
  1544.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1545.    assert(disp->Extensions.WL_bind_wayland_display);
  1546.  
  1547.    if (!display)
  1548.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1549.  
  1550.    ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
  1551.  
  1552.    RETURN_EGL_EVAL(disp, ret);
  1553. }
  1554.  
  1555. EGLBoolean EGLAPIENTRY
  1556. eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1557. {
  1558.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1559.    _EGLDriver *drv;
  1560.    EGLBoolean ret;
  1561.  
  1562.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1563.    assert(disp->Extensions.WL_bind_wayland_display);
  1564.  
  1565.    if (!display)
  1566.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1567.  
  1568.    ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
  1569.  
  1570.    RETURN_EGL_EVAL(disp, ret);
  1571. }
  1572.  
  1573. EGLBoolean EGLAPIENTRY
  1574. eglQueryWaylandBufferWL(EGLDisplay dpy,struct wl_buffer *buffer,
  1575.                         EGLint attribute, EGLint *value)
  1576. {
  1577.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1578.    _EGLDriver *drv;
  1579.    EGLBoolean ret;
  1580.  
  1581.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1582.    assert(disp->Extensions.WL_bind_wayland_display);
  1583.  
  1584.    if (!buffer)
  1585.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1586.  
  1587.    ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
  1588.  
  1589.    RETURN_EGL_EVAL(disp, ret);
  1590. }
  1591. #endif
  1592.  
  1593.  
  1594. EGLBoolean EGLAPIENTRY
  1595. eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
  1596.                    EGLint x, EGLint y, EGLint width, EGLint height)
  1597. {
  1598.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1599.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1600.    _EGLDriver *drv;
  1601.    EGLBoolean ret;
  1602.  
  1603.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1604.  
  1605.    if (!disp->Extensions.NV_post_sub_buffer)
  1606.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1607.  
  1608.    ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
  1609.  
  1610.    RETURN_EGL_EVAL(disp, ret);
  1611. }
  1612.  
  1613. int atexit(void (*func)(void))
  1614. {
  1615.     return 0;
  1616. };
  1617.