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.  
  576.    printf("%s surface: %p\n", __FUNCTION__, surf);
  577.  
  578.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  579.  
  580.    RETURN_EGL_EVAL(disp, ret);
  581. }
  582.  
  583.  
  584. EGLBoolean EGLAPIENTRY
  585. eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
  586. {
  587.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  588.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  589.    _EGLDriver *drv;
  590.    EGLBoolean ret;
  591.  
  592.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  593.    _eglUnlinkSurface(surf);
  594.    ret = drv->API.DestroySurface(drv, disp, surf);
  595.  
  596.    RETURN_EGL_EVAL(disp, ret);
  597. }
  598.  
  599. EGLBoolean EGLAPIENTRY
  600. eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
  601.                 EGLint attribute, EGLint *value)
  602. {
  603.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  604.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  605.    _EGLDriver *drv;
  606.    EGLBoolean ret;
  607.  
  608.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  609.    ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
  610.  
  611.    RETURN_EGL_EVAL(disp, ret);
  612. }
  613.  
  614. EGLBoolean EGLAPIENTRY
  615. eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
  616.                  EGLint attribute, EGLint value)
  617. {
  618.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  619.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  620.    _EGLDriver *drv;
  621.    EGLBoolean ret;
  622.  
  623.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  624.    ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
  625.  
  626.    RETURN_EGL_EVAL(disp, ret);
  627. }
  628.  
  629.  
  630. EGLBoolean EGLAPIENTRY
  631. eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  632. {
  633.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  634.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  635.    _EGLDriver *drv;
  636.    EGLBoolean ret;
  637.  
  638.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  639.    ret = drv->API.BindTexImage(drv, disp, surf, buffer);
  640.  
  641.    RETURN_EGL_EVAL(disp, ret);
  642. }
  643.  
  644.  
  645. EGLBoolean EGLAPIENTRY
  646. eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  647. {
  648.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  649.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  650.    _EGLDriver *drv;
  651.    EGLBoolean ret;
  652.  
  653.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  654.    ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
  655.  
  656.    RETURN_EGL_EVAL(disp, ret);
  657. }
  658.  
  659.  
  660. EGLBoolean EGLAPIENTRY
  661. eglSwapInterval(EGLDisplay dpy, EGLint interval)
  662. {
  663.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  664.    _EGLContext *ctx = _eglGetCurrentContext();
  665.    _EGLSurface *surf;
  666.    _EGLDriver *drv;
  667.    EGLBoolean ret;
  668.  
  669.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  670.  
  671.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  672.        ctx->Resource.Display != disp)
  673.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  674.  
  675.    surf = ctx->DrawSurface;
  676.    if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
  677.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  678.  
  679.    ret = drv->API.SwapInterval(drv, disp, surf, interval);
  680.  
  681.    RETURN_EGL_EVAL(disp, ret);
  682. }
  683.  
  684.  
  685. EGLBoolean EGLAPIENTRY
  686. eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  687. {
  688.    _EGLContext *ctx = _eglGetCurrentContext();
  689.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  690.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  691.    _EGLDriver *drv;
  692.    EGLBoolean ret;
  693.  
  694.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  695.  
  696.    /* surface must be bound to current context in EGL 1.4 */
  697.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  698.        surf != ctx->DrawSurface)
  699.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  700.  
  701.    ret = drv->API.SwapBuffers(drv, disp, surf);
  702.  
  703.    RETURN_EGL_EVAL(disp, ret);
  704. }
  705.  
  706.  
  707. #ifdef EGL_EXT_swap_buffers_with_damage
  708.  
  709. EGLBoolean EGLAPIENTRY
  710. eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
  711.                             EGLint *rects, EGLint n_rects)
  712. {
  713.    _EGLContext *ctx = _eglGetCurrentContext();
  714.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  715.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  716.    _EGLDriver *drv;
  717.    EGLBoolean ret;
  718.  
  719.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  720.  
  721.    /* surface must be bound to current context in EGL 1.4 */
  722.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  723.        surf != ctx->DrawSurface)
  724.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  725.  
  726.    if ((n_rects > 0 && rects == NULL) || n_rects < 0)
  727.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  728.  
  729.    ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
  730.  
  731.    RETURN_EGL_EVAL(disp, ret);
  732. }
  733.  
  734. #endif /* EGL_EXT_swap_buffers_with_damage */
  735.  
  736. EGLBoolean EGLAPIENTRY
  737. eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
  738. {
  739.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  740.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  741.    _EGLDriver *drv;
  742.    EGLBoolean ret;
  743.  
  744.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  745.    if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
  746.       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
  747.    ret = drv->API.CopyBuffers(drv, disp, surf, target);
  748.  
  749.    RETURN_EGL_EVAL(disp, ret);
  750. }
  751.  
  752.  
  753. EGLBoolean EGLAPIENTRY
  754. eglWaitClient(void)
  755. {
  756.    _EGLContext *ctx = _eglGetCurrentContext();
  757.    _EGLDisplay *disp;
  758.    _EGLDriver *drv;
  759.    EGLBoolean ret;
  760.  
  761.    if (!ctx)
  762.       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  763.  
  764.    disp = ctx->Resource.Display;
  765.    _eglLockMutex(&disp->Mutex);
  766.  
  767.    /* let bad current context imply bad current surface */
  768.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  769.        _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  770.       RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  771.  
  772.    /* a valid current context implies an initialized current display */
  773.    assert(disp->Initialized);
  774.    drv = disp->Driver;
  775.    ret = drv->API.WaitClient(drv, disp, ctx);
  776.  
  777.    RETURN_EGL_EVAL(disp, ret);
  778. }
  779.  
  780.  
  781. EGLBoolean EGLAPIENTRY
  782. eglWaitGL(void)
  783. {
  784.    _EGLThreadInfo *t = _eglGetCurrentThread();
  785.    EGLint api_index = t->CurrentAPIIndex;
  786.    EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
  787.    EGLBoolean ret;
  788.  
  789.    if (api_index != es_index && _eglIsCurrentThreadDummy())
  790.       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  791.  
  792.    t->CurrentAPIIndex = es_index;
  793.    ret = eglWaitClient();
  794.    t->CurrentAPIIndex = api_index;
  795.    return ret;
  796. }
  797.  
  798.  
  799. EGLBoolean EGLAPIENTRY
  800. eglWaitNative(EGLint engine)
  801. {
  802.    _EGLContext *ctx = _eglGetCurrentContext();
  803.    _EGLDisplay *disp;
  804.    _EGLDriver *drv;
  805.    EGLBoolean ret;
  806.  
  807.    if (!ctx)
  808.       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  809.  
  810.    disp = ctx->Resource.Display;
  811.    _eglLockMutex(&disp->Mutex);
  812.  
  813.    /* let bad current context imply bad current surface */
  814.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  815.        _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  816.       RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  817.  
  818.    /* a valid current context implies an initialized current display */
  819.    assert(disp->Initialized);
  820.    drv = disp->Driver;
  821.    ret = drv->API.WaitNative(drv, disp, engine);
  822.  
  823.    RETURN_EGL_EVAL(disp, ret);
  824. }
  825.  
  826.  
  827. EGLDisplay EGLAPIENTRY
  828. eglGetCurrentDisplay(void)
  829. {
  830.    _EGLContext *ctx = _eglGetCurrentContext();
  831.    EGLDisplay ret;
  832.  
  833.    ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
  834.  
  835.    RETURN_EGL_SUCCESS(NULL, ret);
  836. }
  837.  
  838.  
  839. EGLContext EGLAPIENTRY
  840. eglGetCurrentContext(void)
  841. {
  842.    _EGLContext *ctx = _eglGetCurrentContext();
  843.    EGLContext ret;
  844.  
  845.    ret = _eglGetContextHandle(ctx);
  846.  
  847.    RETURN_EGL_SUCCESS(NULL, ret);
  848. }
  849.  
  850.  
  851. EGLSurface EGLAPIENTRY
  852. eglGetCurrentSurface(EGLint readdraw)
  853. {
  854.    _EGLContext *ctx = _eglGetCurrentContext();
  855.    EGLint err = EGL_SUCCESS;
  856.    _EGLSurface *surf;
  857.    EGLSurface ret;
  858.  
  859.    if (!ctx)
  860.       RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
  861.  
  862.    switch (readdraw) {
  863.    case EGL_DRAW:
  864.       surf = ctx->DrawSurface;
  865.       break;
  866.    case EGL_READ:
  867.       surf = ctx->ReadSurface;
  868.       break;
  869.    default:
  870.       surf = NULL;
  871.       err = EGL_BAD_PARAMETER;
  872.       break;
  873.    }
  874.  
  875.    ret = _eglGetSurfaceHandle(surf);
  876.  
  877.    RETURN_EGL_ERROR(NULL, err, ret);
  878. }
  879.  
  880.  
  881. EGLint EGLAPIENTRY
  882. eglGetError(void)
  883. {
  884.    _EGLThreadInfo *t = _eglGetCurrentThread();
  885.    EGLint e = t->LastError;
  886.    if (!_eglIsCurrentThreadDummy())
  887.       t->LastError = EGL_SUCCESS;
  888.    return e;
  889. }
  890.  
  891.  
  892. __eglMustCastToProperFunctionPointerType EGLAPIENTRY
  893. eglGetProcAddress(const char *procname)
  894. {
  895.    static const struct {
  896.       const char *name;
  897.       _EGLProc function;
  898.    } egl_functions[] = {
  899.       /* core functions should not be queryable, but, well... */
  900. #ifdef _EGL_GET_CORE_ADDRESSES
  901.       /* alphabetical order */
  902.       { "eglBindAPI", (_EGLProc) eglBindAPI },
  903.       { "eglBindTexImage", (_EGLProc) eglBindTexImage },
  904.       { "eglChooseConfig", (_EGLProc) eglChooseConfig },
  905.       { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
  906.       { "eglCreateContext", (_EGLProc) eglCreateContext },
  907.       { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
  908.       { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
  909.       { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
  910.       { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
  911.       { "eglDestroyContext", (_EGLProc) eglDestroyContext },
  912.       { "eglDestroySurface", (_EGLProc) eglDestroySurface },
  913.       { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
  914.       { "eglGetConfigs", (_EGLProc) eglGetConfigs },
  915.       { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
  916.       { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
  917.       { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
  918.       { "eglGetDisplay", (_EGLProc) eglGetDisplay },
  919.       { "eglGetError", (_EGLProc) eglGetError },
  920.       { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
  921.       { "eglInitialize", (_EGLProc) eglInitialize },
  922.       { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
  923.       { "eglQueryAPI", (_EGLProc) eglQueryAPI },
  924.       { "eglQueryContext", (_EGLProc) eglQueryContext },
  925.       { "eglQueryString", (_EGLProc) eglQueryString },
  926.       { "eglQuerySurface", (_EGLProc) eglQuerySurface },
  927.       { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
  928.       { "eglReleaseThread", (_EGLProc) eglReleaseThread },
  929.       { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
  930.       { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
  931.       { "eglSwapInterval", (_EGLProc) eglSwapInterval },
  932.       { "eglTerminate", (_EGLProc) eglTerminate },
  933.       { "eglWaitClient", (_EGLProc) eglWaitClient },
  934.       { "eglWaitGL", (_EGLProc) eglWaitGL },
  935.       { "eglWaitNative", (_EGLProc) eglWaitNative },
  936. #endif /* _EGL_GET_CORE_ADDRESSES */
  937. #ifdef EGL_MESA_screen_surface
  938.       { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
  939.       { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
  940.       { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
  941.       { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
  942.       { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
  943.       { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
  944.       { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
  945.       { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
  946.       { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
  947.       { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
  948.       { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
  949.       { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
  950. #endif /* EGL_MESA_screen_surface */
  951. #ifdef EGL_MESA_drm_display
  952.       { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
  953. #endif
  954.       { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
  955.       { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
  956.       { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
  957.       { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
  958.       { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
  959.       { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
  960.       { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
  961. #ifdef EGL_NOK_swap_region
  962.       { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
  963. #endif
  964. #ifdef EGL_MESA_drm_image
  965.       { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
  966.       { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
  967. #endif
  968. #ifdef EGL_WL_bind_wayland_display
  969.       { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
  970.       { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
  971.       { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
  972. #endif
  973.       { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
  974. #ifdef EGL_EXT_swap_buffers_with_damage
  975.       { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
  976. #endif
  977.       { NULL, NULL }
  978.    };
  979.    EGLint i;
  980.    _EGLProc ret;
  981.  
  982.    if (!procname)
  983.       RETURN_EGL_SUCCESS(NULL, NULL);
  984.  
  985.    ret = NULL;
  986.    if (strncmp(procname, "egl", 3) == 0) {
  987.       for (i = 0; egl_functions[i].name; i++) {
  988.          if (strcmp(egl_functions[i].name, procname) == 0) {
  989.             ret = egl_functions[i].function;
  990.             break;
  991.          }
  992.       }
  993.    }
  994.    if (!ret)
  995.       ret = _eglGetDriverProc(procname);
  996.  
  997.    RETURN_EGL_SUCCESS(NULL, ret);
  998. }
  999.  
  1000.  
  1001. #ifdef EGL_MESA_screen_surface
  1002.  
  1003.  
  1004. /*
  1005.  * EGL_MESA_screen extension
  1006.  */
  1007.  
  1008. EGLBoolean EGLAPIENTRY
  1009. eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
  1010.                   const EGLint *attrib_list, EGLModeMESA *modes,
  1011.                   EGLint modes_size, EGLint *num_modes)
  1012. {
  1013.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1014.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1015.    _EGLDriver *drv;
  1016.    EGLBoolean ret;
  1017.  
  1018.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1019.    ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
  1020.          modes, modes_size, num_modes);
  1021.  
  1022.    RETURN_EGL_EVAL(disp, ret);
  1023. }
  1024.  
  1025.  
  1026. EGLBoolean EGLAPIENTRY
  1027. eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
  1028.                 EGLint mode_size, EGLint *num_mode)
  1029. {
  1030.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1031.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1032.    _EGLDriver *drv;
  1033.    EGLBoolean ret;
  1034.  
  1035.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1036.    ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
  1037.  
  1038.    RETURN_EGL_EVAL(disp, ret);
  1039. }
  1040.  
  1041.  
  1042. EGLBoolean EGLAPIENTRY
  1043. eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
  1044.                      EGLint attribute, EGLint *value)
  1045. {
  1046.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1047.    _EGLMode *m = _eglLookupMode(mode, disp);
  1048.    _EGLDriver *drv;
  1049.    EGLBoolean ret;
  1050.  
  1051.    _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
  1052.    ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
  1053.  
  1054.    RETURN_EGL_EVAL(disp, ret);
  1055. }
  1056.  
  1057.  
  1058. EGLBoolean EGLAPIENTRY
  1059. eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
  1060.                    EGLint mask)
  1061. {
  1062.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1063.    _EGLContext *source_context = _eglLookupContext(source, disp);
  1064.    _EGLContext *dest_context = _eglLookupContext(dest, disp);
  1065.    _EGLDriver *drv;
  1066.    EGLBoolean ret;
  1067.  
  1068.    _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
  1069.    if (!dest_context)
  1070.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  1071.  
  1072.    ret = drv->API.CopyContextMESA(drv, disp,
  1073.          source_context, dest_context, mask);
  1074.  
  1075.    RETURN_EGL_EVAL(disp, ret);
  1076. }
  1077.  
  1078.  
  1079. EGLBoolean EGLAPIENTRY
  1080. eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
  1081.                   EGLint max_screens, EGLint *num_screens)
  1082. {
  1083.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1084.    _EGLDriver *drv;
  1085.    EGLBoolean ret;
  1086.  
  1087.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1088.    ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
  1089.  
  1090.    RETURN_EGL_EVAL(disp, ret);
  1091. }
  1092.  
  1093.  
  1094. EGLSurface EGLAPIENTRY
  1095. eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
  1096.                            const EGLint *attrib_list)
  1097. {
  1098.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1099.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  1100.    _EGLDriver *drv;
  1101.    _EGLSurface *surf;
  1102.    EGLSurface ret;
  1103.  
  1104.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  1105.  
  1106.    surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
  1107.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  1108.  
  1109.    RETURN_EGL_EVAL(disp, ret);
  1110. }
  1111.  
  1112.  
  1113. EGLBoolean EGLAPIENTRY
  1114. eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
  1115.                          EGLSurface surface, EGLModeMESA mode)
  1116. {
  1117.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1118.    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
  1119.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1120.    _EGLMode *m = _eglLookupMode(mode, disp);
  1121.    _EGLDriver *drv;
  1122.    EGLBoolean ret;
  1123.  
  1124.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1125.    if (!surf && surface != EGL_NO_SURFACE)
  1126.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  1127.    if (!m && mode != EGL_NO_MODE_MESA)
  1128.       RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
  1129.  
  1130.    ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
  1131.  
  1132.    RETURN_EGL_EVAL(disp, ret);
  1133. }
  1134.  
  1135.  
  1136. EGLBoolean EGLAPIENTRY
  1137. eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
  1138. {
  1139.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1140.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1141.    _EGLDriver *drv;
  1142.    EGLBoolean ret;
  1143.  
  1144.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1145.    ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
  1146.  
  1147.    RETURN_EGL_EVAL(disp, ret);
  1148. }
  1149.  
  1150.  
  1151. EGLBoolean EGLAPIENTRY
  1152. eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
  1153.                    EGLint attribute, EGLint *value)
  1154. {
  1155.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1156.    _EGLScreen *scrn = _eglLookupScreen(screen, disp);
  1157.    _EGLDriver *drv;
  1158.    EGLBoolean ret;
  1159.  
  1160.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1161.    ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
  1162.  
  1163.    RETURN_EGL_EVAL(disp, ret);
  1164. }
  1165.  
  1166.  
  1167. EGLBoolean EGLAPIENTRY
  1168. eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
  1169.                           EGLSurface *surface)
  1170. {
  1171.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1172.    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
  1173.    _EGLDriver *drv;
  1174.    _EGLSurface *surf;
  1175.    EGLBoolean ret;
  1176.  
  1177.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1178.    ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
  1179.    if (ret && surface)
  1180.       *surface = _eglGetSurfaceHandle(surf);
  1181.  
  1182.    RETURN_EGL_EVAL(disp, ret);
  1183. }
  1184.  
  1185.  
  1186. EGLBoolean EGLAPIENTRY
  1187. eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
  1188. {
  1189.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1190.    _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
  1191.    _EGLDriver *drv;
  1192.    _EGLMode *m;
  1193.    EGLBoolean ret;
  1194.  
  1195.    _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
  1196.    ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
  1197.    if (ret && mode)
  1198.       *mode = m->Handle;
  1199.  
  1200.    RETURN_EGL_EVAL(disp, ret);
  1201. }
  1202.  
  1203.  
  1204. const char * EGLAPIENTRY
  1205. eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
  1206. {
  1207.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1208.    _EGLMode *m = _eglLookupMode(mode, disp);
  1209.    _EGLDriver *drv;
  1210.    const char *ret;
  1211.  
  1212.    _EGL_CHECK_MODE(disp, m, NULL, drv);
  1213.    ret = drv->API.QueryModeStringMESA(drv, disp, m);
  1214.  
  1215.    RETURN_EGL_EVAL(disp, ret);
  1216. }
  1217.  
  1218.  
  1219. #endif /* EGL_MESA_screen_surface */
  1220.  
  1221.  
  1222. #ifdef EGL_MESA_drm_display
  1223.  
  1224. EGLDisplay EGLAPIENTRY
  1225. eglGetDRMDisplayMESA(int fd)
  1226. {
  1227.    _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
  1228.    return _eglGetDisplayHandle(dpy);
  1229. }
  1230.  
  1231. #endif /* EGL_MESA_drm_display */
  1232.  
  1233. /**
  1234.  ** EGL 1.2
  1235.  **/
  1236.  
  1237. /**
  1238.  * Specify the client API to use for subsequent calls including:
  1239.  *  eglCreateContext()
  1240.  *  eglGetCurrentContext()
  1241.  *  eglGetCurrentDisplay()
  1242.  *  eglGetCurrentSurface()
  1243.  *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
  1244.  *  eglWaitClient()
  1245.  *  eglWaitNative()
  1246.  * See section 3.7 "Rendering Context" in the EGL specification for details.
  1247.  */
  1248. EGLBoolean EGLAPIENTRY
  1249. eglBindAPI(EGLenum api)
  1250. {
  1251.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1252.  
  1253.    if (_eglIsCurrentThreadDummy())
  1254.       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  1255.  
  1256.    if (!_eglIsApiValid(api))
  1257.       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
  1258.  
  1259.    t->CurrentAPIIndex = _eglConvertApiToIndex(api);
  1260.  
  1261.    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1262. }
  1263.  
  1264.  
  1265. /**
  1266.  * Return the last value set with eglBindAPI().
  1267.  */
  1268. EGLenum EGLAPIENTRY
  1269. eglQueryAPI(void)
  1270. {
  1271.    _EGLThreadInfo *t = _eglGetCurrentThread();
  1272.    EGLenum ret;
  1273.  
  1274.    /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
  1275.    ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
  1276.  
  1277.    RETURN_EGL_SUCCESS(NULL, ret);
  1278. }
  1279.  
  1280.  
  1281. EGLSurface EGLAPIENTRY
  1282. eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
  1283.                                  EGLClientBuffer buffer, EGLConfig config,
  1284.                                  const EGLint *attrib_list)
  1285. {
  1286.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1287.    _EGLConfig *conf = _eglLookupConfig(config, disp);
  1288.    _EGLDriver *drv;
  1289.    _EGLSurface *surf;
  1290.    EGLSurface ret;
  1291.  
  1292.    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  1293.  
  1294.    surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
  1295.                                                  conf, attrib_list);
  1296.    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  1297.  
  1298.    RETURN_EGL_EVAL(disp, ret);
  1299. }
  1300.  
  1301.  
  1302. EGLBoolean EGLAPIENTRY
  1303. eglReleaseThread(void)
  1304. {
  1305.    /* unbind current contexts */
  1306.    if (!_eglIsCurrentThreadDummy()) {
  1307.       _EGLThreadInfo *t = _eglGetCurrentThread();
  1308.       EGLint api_index = t->CurrentAPIIndex;
  1309.       EGLint i;
  1310.  
  1311.       for (i = 0; i < _EGL_API_NUM_APIS; i++) {
  1312.          _EGLContext *ctx = t->CurrentContexts[i];
  1313.          if (ctx) {
  1314.             _EGLDisplay *disp = ctx->Resource.Display;
  1315.             _EGLDriver *drv;
  1316.  
  1317.             t->CurrentAPIIndex = i;
  1318.  
  1319.             _eglLockMutex(&disp->Mutex);
  1320.             drv = disp->Driver;
  1321.             (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
  1322.             _eglUnlockMutex(&disp->Mutex);
  1323.          }
  1324.       }
  1325.  
  1326.       t->CurrentAPIIndex = api_index;
  1327.    }
  1328.  
  1329.    _eglDestroyCurrentThread();
  1330.  
  1331.    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  1332. }
  1333.  
  1334.  
  1335. EGLImageKHR EGLAPIENTRY
  1336. eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  1337.                   EGLClientBuffer buffer, const EGLint *attr_list)
  1338. {
  1339.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1340.    _EGLContext *context = _eglLookupContext(ctx, disp);
  1341.    _EGLDriver *drv;
  1342.    _EGLImage *img;
  1343.    EGLImageKHR ret;
  1344.  
  1345.    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1346.    if (!disp->Extensions.KHR_image_base)
  1347.       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1348.    if (!context && ctx != EGL_NO_CONTEXT)
  1349.       RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
  1350.  
  1351.    img = drv->API.CreateImageKHR(drv,
  1352.          disp, context, target, buffer, attr_list);
  1353.    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1354.  
  1355.    RETURN_EGL_EVAL(disp, ret);
  1356. }
  1357.  
  1358.  
  1359. EGLBoolean EGLAPIENTRY
  1360. eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
  1361. {
  1362.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1363.    _EGLImage *img = _eglLookupImage(image, disp);
  1364.    _EGLDriver *drv;
  1365.    EGLBoolean ret;
  1366.  
  1367.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1368.    if (!disp->Extensions.KHR_image_base)
  1369.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1370.    if (!img)
  1371.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1372.  
  1373.    _eglUnlinkImage(img);
  1374.    ret = drv->API.DestroyImageKHR(drv, disp, img);
  1375.  
  1376.    RETURN_EGL_EVAL(disp, ret);
  1377. }
  1378.  
  1379.  
  1380. EGLSyncKHR EGLAPIENTRY
  1381. eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
  1382. {
  1383.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1384.    _EGLDriver *drv;
  1385.    _EGLSync *sync;
  1386.    EGLSyncKHR ret;
  1387.  
  1388.    _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
  1389.    if (!disp->Extensions.KHR_reusable_sync)
  1390.       RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
  1391.  
  1392.    sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
  1393.    ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
  1394.  
  1395.    RETURN_EGL_EVAL(disp, ret);
  1396. }
  1397.  
  1398.  
  1399. EGLBoolean EGLAPIENTRY
  1400. eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
  1401. {
  1402.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1403.    _EGLSync *s = _eglLookupSync(sync, disp);
  1404.    _EGLDriver *drv;
  1405.    EGLBoolean ret;
  1406.  
  1407.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1408.    assert(disp->Extensions.KHR_reusable_sync);
  1409.  
  1410.    _eglUnlinkSync(s);
  1411.    ret = drv->API.DestroySyncKHR(drv, disp, s);
  1412.  
  1413.    RETURN_EGL_EVAL(disp, ret);
  1414. }
  1415.  
  1416.  
  1417. EGLint EGLAPIENTRY
  1418. eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
  1419. {
  1420.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1421.    _EGLSync *s = _eglLookupSync(sync, disp);
  1422.    _EGLDriver *drv;
  1423.    EGLint ret;
  1424.  
  1425.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1426.    assert(disp->Extensions.KHR_reusable_sync);
  1427.    ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
  1428.  
  1429.    RETURN_EGL_EVAL(disp, ret);
  1430. }
  1431.  
  1432.  
  1433. EGLBoolean EGLAPIENTRY
  1434. eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
  1435. {
  1436.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1437.    _EGLSync *s = _eglLookupSync(sync, disp);
  1438.    _EGLDriver *drv;
  1439.    EGLBoolean ret;
  1440.  
  1441.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1442.    assert(disp->Extensions.KHR_reusable_sync);
  1443.    ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
  1444.  
  1445.    RETURN_EGL_EVAL(disp, ret);
  1446. }
  1447.  
  1448.  
  1449. EGLBoolean EGLAPIENTRY
  1450. eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
  1451. {
  1452.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1453.    _EGLSync *s = _eglLookupSync(sync, disp);
  1454.    _EGLDriver *drv;
  1455.    EGLBoolean ret;
  1456.  
  1457.    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1458.    assert(disp->Extensions.KHR_reusable_sync);
  1459.    ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
  1460.  
  1461.    RETURN_EGL_EVAL(disp, ret);
  1462. }
  1463.  
  1464.  
  1465. #ifdef EGL_NOK_swap_region
  1466.  
  1467. EGLBoolean EGLAPIENTRY
  1468. eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
  1469.                         EGLint numRects, const EGLint *rects)
  1470. {
  1471.    _EGLContext *ctx = _eglGetCurrentContext();
  1472.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1473.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1474.    _EGLDriver *drv;
  1475.    EGLBoolean ret;
  1476.  
  1477.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1478.  
  1479.    if (!disp->Extensions.NOK_swap_region)
  1480.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1481.  
  1482.    /* surface must be bound to current context in EGL 1.4 */
  1483.    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  1484.        surf != ctx->DrawSurface)
  1485.       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  1486.  
  1487.    ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
  1488.  
  1489.    RETURN_EGL_EVAL(disp, ret);
  1490. }
  1491.  
  1492. #endif /* EGL_NOK_swap_region */
  1493.  
  1494.  
  1495. #ifdef EGL_MESA_drm_image
  1496.  
  1497. EGLImageKHR EGLAPIENTRY
  1498. eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
  1499. {
  1500.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1501.    _EGLDriver *drv;
  1502.    _EGLImage *img;
  1503.    EGLImageKHR ret;
  1504.  
  1505.    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1506.    if (!disp->Extensions.MESA_drm_image)
  1507.       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1508.  
  1509.    img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
  1510.    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1511.  
  1512.    RETURN_EGL_EVAL(disp, ret);
  1513. }
  1514.  
  1515. EGLBoolean EGLAPIENTRY
  1516. eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
  1517.                       EGLint *name, EGLint *handle, EGLint *stride)
  1518. {
  1519.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1520.    _EGLImage *img = _eglLookupImage(image, disp);
  1521.    _EGLDriver *drv;
  1522.    EGLBoolean ret;
  1523.  
  1524.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1525.    assert(disp->Extensions.MESA_drm_image);
  1526.  
  1527.    if (!img)
  1528.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1529.  
  1530.    ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
  1531.  
  1532.    RETURN_EGL_EVAL(disp, ret);
  1533. }
  1534.  
  1535. #endif
  1536.  
  1537. #ifdef EGL_WL_bind_wayland_display
  1538. struct wl_display;
  1539.  
  1540. EGLBoolean EGLAPIENTRY
  1541. eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1542. {
  1543.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1544.    _EGLDriver *drv;
  1545.    EGLBoolean ret;
  1546.  
  1547.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1548.    assert(disp->Extensions.WL_bind_wayland_display);
  1549.  
  1550.    if (!display)
  1551.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1552.  
  1553.    ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
  1554.  
  1555.    RETURN_EGL_EVAL(disp, ret);
  1556. }
  1557.  
  1558. EGLBoolean EGLAPIENTRY
  1559. eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1560. {
  1561.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1562.    _EGLDriver *drv;
  1563.    EGLBoolean ret;
  1564.  
  1565.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1566.    assert(disp->Extensions.WL_bind_wayland_display);
  1567.  
  1568.    if (!display)
  1569.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1570.  
  1571.    ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
  1572.  
  1573.    RETURN_EGL_EVAL(disp, ret);
  1574. }
  1575.  
  1576. EGLBoolean EGLAPIENTRY
  1577. eglQueryWaylandBufferWL(EGLDisplay dpy,struct wl_buffer *buffer,
  1578.                         EGLint attribute, EGLint *value)
  1579. {
  1580.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1581.    _EGLDriver *drv;
  1582.    EGLBoolean ret;
  1583.  
  1584.    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1585.    assert(disp->Extensions.WL_bind_wayland_display);
  1586.  
  1587.    if (!buffer)
  1588.       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1589.  
  1590.    ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
  1591.  
  1592.    RETURN_EGL_EVAL(disp, ret);
  1593. }
  1594. #endif
  1595.  
  1596.  
  1597. EGLBoolean EGLAPIENTRY
  1598. eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
  1599.                    EGLint x, EGLint y, EGLint width, EGLint height)
  1600. {
  1601.    _EGLDisplay *disp = _eglLockDisplay(dpy);
  1602.    _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1603.    _EGLDriver *drv;
  1604.    EGLBoolean ret;
  1605.  
  1606.    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1607.  
  1608.    if (!disp->Extensions.NV_post_sub_buffer)
  1609.       RETURN_EGL_EVAL(disp, EGL_FALSE);
  1610.  
  1611.    ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
  1612.  
  1613.    RETURN_EGL_EVAL(disp, ret);
  1614. }
  1615.