eglapi.c revision ff318c45ec1fafd0d825a8da5556d2d1e69ff7da
1/**
2 * Public EGL API entrypoints
3 *
4 * Generally, we use the EGLDisplay parameter as a key to lookup the
5 * appropriate device driver handle, then jump though the driver's
6 * dispatch table to handle the function.
7 *
8 * That allows us the option of supporting multiple, simultaneous,
9 * heterogeneous hardware devices in the future.
10 *
11 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
12 * opaque handles. Internal objects are linked to a display to
13 * create the handles.
14 *
15 * For each public API entry point, the opaque handles are looked up
16 * before being dispatched to the drivers.  When it fails to look up
17 * a handle, one of
18 *
19 * EGL_BAD_DISPLAY
20 * EGL_BAD_CONFIG
21 * EGL_BAD_CONTEXT
22 * EGL_BAD_SURFACE
23 * EGL_BAD_SCREEN_MESA
24 * EGL_BAD_MODE_MESA
25 *
26 * is generated and the driver function is not called. An
27 * uninitialized EGLDisplay has no driver associated with it. When
28 * such display is detected,
29 *
30 * EGL_NOT_INITIALIZED
31 *
32 * is generated.
33 *
34 * Some of the entry points use current display, context, or surface
35 * implicitly.  For such entry points, the implicit objects are also
36 * checked before calling the driver function.  Other than the
37 * errors listed above,
38 *
39 * EGL_BAD_CURRENT_SURFACE
40 *
41 * may also be generated.
42 *
43 * Notes on naming conventions:
44 *
45 * eglFooBar    - public EGL function
46 * EGL_FOO_BAR  - public EGL token
47 * EGLDatatype  - public EGL datatype
48 *
49 * _eglFooBar   - private EGL function
50 * _EGLDatatype - private EGL datatype, typedef'd struct
51 * _egl_struct  - private EGL struct, non-typedef'd
52 *
53 */
54
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59
60#include "eglstring.h"
61#include "eglcontext.h"
62#include "egldisplay.h"
63#include "egltypedefs.h"
64#include "eglcurrent.h"
65#include "egldriver.h"
66#include "eglsurface.h"
67#include "eglconfig.h"
68#include "eglscreen.h"
69#include "eglmode.h"
70#include "eglimage.h"
71
72
73/**
74 * Macros to help return an API entrypoint.
75 *
76 * These macros will unlock the display and record the error code.
77 */
78#define RETURN_EGL_ERROR(disp, err, ret)        \
79   do {                                         \
80      if (disp)                                 \
81         _eglUnlockDisplay(disp);               \
82      /* EGL error codes are non-zero */        \
83      if (err)                                  \
84         _eglError(err, __FUNCTION__);          \
85      return ret;                               \
86   } while (0)
87
88#define RETURN_EGL_SUCCESS(disp, ret) \
89   RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
90
91/* record EGL_SUCCESS only when ret evaluates to true */
92#define RETURN_EGL_EVAL(disp, ret) \
93   RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
94
95
96/*
97 * A bunch of macros and checks to simplify error checking.
98 */
99
100#define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
101   do {                                            \
102      drv = _eglCheckDisplay(disp, __FUNCTION__);  \
103      if (!drv)                                    \
104         RETURN_EGL_ERROR(disp, 0, ret);           \
105   } while (0)
106
107#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
108   do {                                                   \
109      drv = _eglCheck ## type(disp, obj, __FUNCTION__);   \
110      if (!drv)                                           \
111         RETURN_EGL_ERROR(disp, 0, ret);                  \
112   } while (0)
113
114#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
115   _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
116
117#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
118   _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
119
120#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
121   _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
122
123#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
124   _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
125
126#define _EGL_CHECK_MODE(disp, m, ret, drv) \
127   _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
128
129
130
131static INLINE _EGLDriver *
132_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
133{
134   if (!disp) {
135      _eglError(EGL_BAD_DISPLAY, msg);
136      return NULL;
137   }
138   if (!disp->Initialized) {
139      _eglError(EGL_NOT_INITIALIZED, msg);
140      return NULL;
141   }
142   return disp->Driver;
143}
144
145
146static INLINE _EGLDriver *
147_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
148{
149   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
150   if (!drv)
151      return NULL;
152   if (!surf) {
153      _eglError(EGL_BAD_SURFACE, msg);
154      return NULL;
155   }
156   return drv;
157}
158
159
160static INLINE _EGLDriver *
161_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
162{
163   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
164   if (!drv)
165      return NULL;
166   if (!context) {
167      _eglError(EGL_BAD_CONTEXT, msg);
168      return NULL;
169   }
170   return drv;
171}
172
173
174static INLINE _EGLDriver *
175_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
176{
177   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
178   if (!drv)
179      return NULL;
180   if (!conf) {
181      _eglError(EGL_BAD_CONFIG, msg);
182      return NULL;
183   }
184   return drv;
185}
186
187
188#ifdef EGL_MESA_screen_surface
189
190
191static INLINE _EGLDriver *
192_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
193{
194   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
195   if (!drv)
196      return NULL;
197   if (!scrn) {
198      _eglError(EGL_BAD_SCREEN_MESA, msg);
199      return NULL;
200   }
201   return drv;
202}
203
204
205static INLINE _EGLDriver *
206_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
207{
208   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
209   if (!drv)
210      return NULL;
211   if (!m) {
212      _eglError(EGL_BAD_MODE_MESA, msg);
213      return NULL;
214   }
215   return drv;
216}
217
218
219#endif /* EGL_MESA_screen_surface */
220
221
222/**
223 * Lookup and lock a display.
224 */
225static INLINE _EGLDisplay *
226_eglLockDisplay(EGLDisplay display)
227{
228   _EGLDisplay *dpy = _eglLookupDisplay(display);
229   if (dpy)
230      _eglLockMutex(&dpy->Mutex);
231   return dpy;
232}
233
234
235/**
236 * Unlock a display.
237 */
238static INLINE void
239_eglUnlockDisplay(_EGLDisplay *dpy)
240{
241   _eglUnlockMutex(&dpy->Mutex);
242}
243
244
245/**
246 * This is typically the first EGL function that an application calls.
247 * It associates a private _EGLDisplay object to the native display.
248 */
249EGLDisplay EGLAPIENTRY
250eglGetDisplay(EGLNativeDisplayType nativeDisplay)
251{
252   _EGLPlatformType plat = _eglGetNativePlatform();
253   _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
254   return _eglGetDisplayHandle(dpy);
255}
256
257
258/**
259 * This is typically the second EGL function that an application calls.
260 * Here we load/initialize the actual hardware driver.
261 */
262EGLBoolean EGLAPIENTRY
263eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
264{
265   _EGLDisplay *disp = _eglLockDisplay(dpy);
266
267   if (!disp)
268      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
269
270   if (!disp->Initialized) {
271      if (!_eglMatchDriver(disp, EGL_FALSE))
272         RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
273
274      _eglsnprintf(disp->Version, sizeof(disp->Version), "%d.%d (%s)",
275            disp->APImajor, disp->APIminor, disp->Driver->Name);
276      /* limit to APIs supported by core */
277      disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
278   }
279
280   /* Update applications version of major and minor if not NULL */
281   if ((major != NULL) && (minor != NULL)) {
282      *major = disp->APImajor;
283      *minor = disp->APIminor;
284   }
285
286   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
287}
288
289
290EGLBoolean EGLAPIENTRY
291eglTerminate(EGLDisplay dpy)
292{
293   _EGLDisplay *disp = _eglLockDisplay(dpy);
294
295   if (!disp)
296      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
297
298   if (disp->Initialized) {
299      _EGLDriver *drv = disp->Driver;
300
301      drv->API.Terminate(drv, disp);
302      /* do not reset disp->Driver */
303      disp->Initialized = EGL_FALSE;
304   }
305
306   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
307}
308
309
310const char * EGLAPIENTRY
311eglQueryString(EGLDisplay dpy, EGLint name)
312{
313   _EGLDisplay *disp = _eglLockDisplay(dpy);
314   _EGLDriver *drv;
315   const char *ret;
316
317   _EGL_CHECK_DISPLAY(disp, NULL, drv);
318   ret = drv->API.QueryString(drv, disp, name);
319
320   RETURN_EGL_EVAL(disp, ret);
321}
322
323
324EGLBoolean EGLAPIENTRY
325eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
326              EGLint config_size, EGLint *num_config)
327{
328   _EGLDisplay *disp = _eglLockDisplay(dpy);
329   _EGLDriver *drv;
330   EGLBoolean ret;
331
332   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
333   ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
334
335   RETURN_EGL_EVAL(disp, ret);
336}
337
338
339EGLBoolean EGLAPIENTRY
340eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
341                EGLint config_size, EGLint *num_config)
342{
343   _EGLDisplay *disp = _eglLockDisplay(dpy);
344   _EGLDriver *drv;
345   EGLBoolean ret;
346
347   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
348   ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
349                                config_size, num_config);
350
351   RETURN_EGL_EVAL(disp, ret);
352}
353
354
355EGLBoolean EGLAPIENTRY
356eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
357                   EGLint attribute, EGLint *value)
358{
359   _EGLDisplay *disp = _eglLockDisplay(dpy);
360   _EGLConfig *conf = _eglLookupConfig(config, disp);
361   _EGLDriver *drv;
362   EGLBoolean ret;
363
364   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
365   ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
366
367   RETURN_EGL_EVAL(disp, ret);
368}
369
370
371EGLContext EGLAPIENTRY
372eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
373                 const EGLint *attrib_list)
374{
375   _EGLDisplay *disp = _eglLockDisplay(dpy);
376   _EGLConfig *conf = _eglLookupConfig(config, disp);
377   _EGLContext *share = _eglLookupContext(share_list, disp);
378   _EGLDriver *drv;
379   _EGLContext *context;
380   EGLContext ret;
381
382   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
383   if (!share && share_list != EGL_NO_CONTEXT)
384      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
385
386   context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
387   ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT;
388
389   RETURN_EGL_EVAL(disp, ret);
390}
391
392
393EGLBoolean EGLAPIENTRY
394eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
395{
396   _EGLDisplay *disp = _eglLockDisplay(dpy);
397   _EGLContext *context = _eglLookupContext(ctx, disp);
398   _EGLDriver *drv;
399   EGLBoolean ret;
400
401   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
402   _eglUnlinkContext(context);
403   ret = drv->API.DestroyContext(drv, disp, context);
404
405   RETURN_EGL_EVAL(disp, ret);
406}
407
408
409EGLBoolean EGLAPIENTRY
410eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
411               EGLContext ctx)
412{
413   _EGLDisplay *disp = _eglLockDisplay(dpy);
414   _EGLContext *context = _eglLookupContext(ctx, disp);
415   _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
416   _EGLSurface *read_surf = _eglLookupSurface(read, disp);
417   _EGLDriver *drv;
418   EGLBoolean ret;
419
420   if (!disp)
421      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
422   drv = disp->Driver;
423
424   /* display is allowed to be uninitialized under certain condition */
425   if (!disp->Initialized) {
426      if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
427          ctx != EGL_NO_CONTEXT)
428         RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
429   }
430   if (!drv)
431      RETURN_EGL_SUCCESS(disp, EGL_TRUE);
432
433   if (!context && ctx != EGL_NO_CONTEXT)
434      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
435   if ((!draw_surf && draw != EGL_NO_SURFACE) ||
436       (!read_surf && read != EGL_NO_SURFACE))
437      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
438
439   ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
440
441   RETURN_EGL_EVAL(disp, ret);
442}
443
444
445EGLBoolean EGLAPIENTRY
446eglQueryContext(EGLDisplay dpy, EGLContext ctx,
447                EGLint attribute, EGLint *value)
448{
449   _EGLDisplay *disp = _eglLockDisplay(dpy);
450   _EGLContext *context = _eglLookupContext(ctx, disp);
451   _EGLDriver *drv;
452   EGLBoolean ret;
453
454   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
455   ret = drv->API.QueryContext(drv, disp, context, attribute, value);
456
457   RETURN_EGL_EVAL(disp, ret);
458}
459
460
461EGLSurface EGLAPIENTRY
462eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
463                       EGLNativeWindowType window, const EGLint *attrib_list)
464{
465   _EGLDisplay *disp = _eglLockDisplay(dpy);
466   _EGLConfig *conf = _eglLookupConfig(config, disp);
467   _EGLDriver *drv;
468   _EGLSurface *surf;
469   EGLSurface ret;
470
471   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
472   if (disp->Platform != _eglGetNativePlatform())
473      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
474
475   surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
476   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
477
478   RETURN_EGL_EVAL(disp, ret);
479}
480
481
482EGLSurface EGLAPIENTRY
483eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
484                       EGLNativePixmapType pixmap, const EGLint *attrib_list)
485{
486   _EGLDisplay *disp = _eglLockDisplay(dpy);
487   _EGLConfig *conf = _eglLookupConfig(config, disp);
488   _EGLDriver *drv;
489   _EGLSurface *surf;
490   EGLSurface ret;
491
492   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
493   if (disp->Platform != _eglGetNativePlatform())
494      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
495
496   surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
497   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
498
499   RETURN_EGL_EVAL(disp, ret);
500}
501
502
503EGLSurface EGLAPIENTRY
504eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
505                        const EGLint *attrib_list)
506{
507   _EGLDisplay *disp = _eglLockDisplay(dpy);
508   _EGLConfig *conf = _eglLookupConfig(config, disp);
509   _EGLDriver *drv;
510   _EGLSurface *surf;
511   EGLSurface ret;
512
513   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
514
515   surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
516   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
517
518   RETURN_EGL_EVAL(disp, ret);
519}
520
521
522EGLBoolean EGLAPIENTRY
523eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
524{
525   _EGLDisplay *disp = _eglLockDisplay(dpy);
526   _EGLSurface *surf = _eglLookupSurface(surface, disp);
527   _EGLDriver *drv;
528   EGLBoolean ret;
529
530   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
531   _eglUnlinkSurface(surf);
532   ret = drv->API.DestroySurface(drv, disp, surf);
533
534   RETURN_EGL_EVAL(disp, ret);
535}
536
537EGLBoolean EGLAPIENTRY
538eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
539                EGLint attribute, EGLint *value)
540{
541   _EGLDisplay *disp = _eglLockDisplay(dpy);
542   _EGLSurface *surf = _eglLookupSurface(surface, disp);
543   _EGLDriver *drv;
544   EGLBoolean ret;
545
546   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
547   ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
548
549   RETURN_EGL_EVAL(disp, ret);
550}
551
552EGLBoolean EGLAPIENTRY
553eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
554                 EGLint attribute, EGLint value)
555{
556   _EGLDisplay *disp = _eglLockDisplay(dpy);
557   _EGLSurface *surf = _eglLookupSurface(surface, disp);
558   _EGLDriver *drv;
559   EGLBoolean ret;
560
561   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
562   ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
563
564   RETURN_EGL_EVAL(disp, ret);
565}
566
567
568EGLBoolean EGLAPIENTRY
569eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
570{
571   _EGLDisplay *disp = _eglLockDisplay(dpy);
572   _EGLSurface *surf = _eglLookupSurface(surface, disp);
573   _EGLDriver *drv;
574   EGLBoolean ret;
575
576   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
577   ret = drv->API.BindTexImage(drv, disp, surf, buffer);
578
579   RETURN_EGL_EVAL(disp, ret);
580}
581
582
583EGLBoolean EGLAPIENTRY
584eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
585{
586   _EGLDisplay *disp = _eglLockDisplay(dpy);
587   _EGLSurface *surf = _eglLookupSurface(surface, disp);
588   _EGLDriver *drv;
589   EGLBoolean ret;
590
591   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
592   ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
593
594   RETURN_EGL_EVAL(disp, ret);
595}
596
597
598EGLBoolean EGLAPIENTRY
599eglSwapInterval(EGLDisplay dpy, EGLint interval)
600{
601   _EGLDisplay *disp = _eglLockDisplay(dpy);
602   _EGLContext *ctx = _eglGetCurrentContext();
603   _EGLSurface *surf;
604   _EGLDriver *drv;
605   EGLBoolean ret;
606
607   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
608
609   if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
610      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
611
612   surf = ctx->DrawSurface;
613   if (!_eglIsSurfaceLinked(surf))
614      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
615
616   ret = drv->API.SwapInterval(drv, disp, surf, interval);
617
618   RETURN_EGL_EVAL(disp, ret);
619}
620
621
622EGLBoolean EGLAPIENTRY
623eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
624{
625   _EGLContext *ctx = _eglGetCurrentContext();
626   _EGLDisplay *disp = _eglLockDisplay(dpy);
627   _EGLSurface *surf = _eglLookupSurface(surface, disp);
628   _EGLDriver *drv;
629   EGLBoolean ret;
630
631   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
632
633   /* surface must be bound to current context in EGL 1.4 */
634   if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
635      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
636
637   ret = drv->API.SwapBuffers(drv, disp, surf);
638
639   RETURN_EGL_EVAL(disp, ret);
640}
641
642
643EGLBoolean EGLAPIENTRY
644eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
645{
646   _EGLDisplay *disp = _eglLockDisplay(dpy);
647   _EGLSurface *surf = _eglLookupSurface(surface, disp);
648   _EGLDriver *drv;
649   EGLBoolean ret;
650
651   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
652   if (disp->Platform != _eglGetNativePlatform())
653      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
654   ret = drv->API.CopyBuffers(drv, disp, surf, target);
655
656   RETURN_EGL_EVAL(disp, ret);
657}
658
659
660EGLBoolean EGLAPIENTRY
661eglWaitClient(void)
662{
663   _EGLContext *ctx = _eglGetCurrentContext();
664   _EGLDisplay *disp;
665   _EGLDriver *drv;
666   EGLBoolean ret;
667
668   if (!ctx)
669      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
670
671   disp = ctx->Resource.Display;
672   _eglLockMutex(&disp->Mutex);
673
674   /* let bad current context imply bad current surface */
675   if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
676      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
677
678   /* a valid current context implies an initialized current display */
679   assert(disp->Initialized);
680   drv = disp->Driver;
681   ret = drv->API.WaitClient(drv, disp, ctx);
682
683   RETURN_EGL_EVAL(disp, ret);
684}
685
686
687EGLBoolean EGLAPIENTRY
688eglWaitGL(void)
689{
690#ifdef EGL_VERSION_1_2
691   _EGLThreadInfo *t = _eglGetCurrentThread();
692   EGLint api_index = t->CurrentAPIIndex;
693   EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
694   EGLBoolean ret;
695
696   if (api_index != es_index && _eglIsCurrentThreadDummy())
697      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
698
699   t->CurrentAPIIndex = es_index;
700   ret = eglWaitClient();
701   t->CurrentAPIIndex = api_index;
702   return ret;
703#else
704   return eglWaitClient();
705#endif
706}
707
708
709EGLBoolean EGLAPIENTRY
710eglWaitNative(EGLint engine)
711{
712   _EGLContext *ctx = _eglGetCurrentContext();
713   _EGLDisplay *disp;
714   _EGLDriver *drv;
715   EGLBoolean ret;
716
717   if (!ctx)
718      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
719
720   disp = ctx->Resource.Display;
721   _eglLockMutex(&disp->Mutex);
722
723   /* let bad current context imply bad current surface */
724   if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
725      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
726
727   /* a valid current context implies an initialized current display */
728   assert(disp->Initialized);
729   drv = disp->Driver;
730   ret = drv->API.WaitNative(drv, disp, engine);
731
732   RETURN_EGL_EVAL(disp, ret);
733}
734
735
736EGLDisplay EGLAPIENTRY
737eglGetCurrentDisplay(void)
738{
739   _EGLContext *ctx = _eglGetCurrentContext();
740   EGLDisplay ret;
741
742   ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
743
744   RETURN_EGL_SUCCESS(NULL, ret);
745}
746
747
748EGLContext EGLAPIENTRY
749eglGetCurrentContext(void)
750{
751   _EGLContext *ctx = _eglGetCurrentContext();
752   EGLContext ret;
753
754   ret = _eglGetContextHandle(ctx);
755
756   RETURN_EGL_SUCCESS(NULL, ret);
757}
758
759
760EGLSurface EGLAPIENTRY
761eglGetCurrentSurface(EGLint readdraw)
762{
763   _EGLContext *ctx = _eglGetCurrentContext();
764   EGLint err = EGL_SUCCESS;
765   _EGLSurface *surf;
766   EGLSurface ret;
767
768   if (!ctx)
769      RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
770
771   switch (readdraw) {
772   case EGL_DRAW:
773      surf = ctx->DrawSurface;
774      break;
775   case EGL_READ:
776      surf = ctx->ReadSurface;
777      break;
778   default:
779      surf = NULL;
780      err = EGL_BAD_PARAMETER;
781      break;
782   }
783
784   ret = _eglGetSurfaceHandle(surf);
785
786   RETURN_EGL_ERROR(NULL, err, ret);
787}
788
789
790EGLint EGLAPIENTRY
791eglGetError(void)
792{
793   _EGLThreadInfo *t = _eglGetCurrentThread();
794   EGLint e = t->LastError;
795   if (!_eglIsCurrentThreadDummy())
796      t->LastError = EGL_SUCCESS;
797   return e;
798}
799
800
801__eglMustCastToProperFunctionPointerType EGLAPIENTRY
802eglGetProcAddress(const char *procname)
803{
804   static const struct {
805      const char *name;
806      _EGLProc function;
807   } egl_functions[] = {
808      /* extensions only */
809#ifdef EGL_MESA_screen_surface
810      { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
811      { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
812      { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
813      { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
814      { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
815      { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
816      { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
817      { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
818      { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
819      { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
820      { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
821      { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
822#endif /* EGL_MESA_screen_surface */
823#ifdef EGL_MESA_drm_display
824      { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
825#endif
826#ifdef EGL_KHR_image_base
827      { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
828      { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
829#endif /* EGL_KHR_image_base */
830#ifdef EGL_NOK_swap_region
831      { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
832#endif
833      { NULL, NULL }
834   };
835   EGLint i;
836   _EGLProc ret;
837
838   if (!procname)
839      RETURN_EGL_SUCCESS(NULL, NULL);
840
841   ret = NULL;
842   if (strncmp(procname, "egl", 3) == 0) {
843      for (i = 0; egl_functions[i].name; i++) {
844         if (strcmp(egl_functions[i].name, procname) == 0) {
845            ret = egl_functions[i].function;
846            break;
847         }
848      }
849   }
850   if (!ret)
851      ret = _eglGetDriverProc(procname);
852
853   RETURN_EGL_SUCCESS(NULL, ret);
854}
855
856
857#ifdef EGL_MESA_screen_surface
858
859
860/*
861 * EGL_MESA_screen extension
862 */
863
864EGLBoolean EGLAPIENTRY
865eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
866                  const EGLint *attrib_list, EGLModeMESA *modes,
867                  EGLint modes_size, EGLint *num_modes)
868{
869   _EGLDisplay *disp = _eglLockDisplay(dpy);
870   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
871   _EGLDriver *drv;
872   EGLBoolean ret;
873
874   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
875   ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
876         modes, modes_size, num_modes);
877
878   RETURN_EGL_EVAL(disp, ret);
879}
880
881
882EGLBoolean EGLAPIENTRY
883eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
884                EGLint mode_size, EGLint *num_mode)
885{
886   _EGLDisplay *disp = _eglLockDisplay(dpy);
887   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
888   _EGLDriver *drv;
889   EGLBoolean ret;
890
891   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
892   ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
893
894   RETURN_EGL_EVAL(disp, ret);
895}
896
897
898EGLBoolean EGLAPIENTRY
899eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
900                     EGLint attribute, EGLint *value)
901{
902   _EGLDisplay *disp = _eglLockDisplay(dpy);
903   _EGLMode *m = _eglLookupMode(mode, disp);
904   _EGLDriver *drv;
905   EGLBoolean ret;
906
907   _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
908   ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
909
910   RETURN_EGL_EVAL(disp, ret);
911}
912
913
914EGLBoolean EGLAPIENTRY
915eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
916                   EGLint mask)
917{
918   _EGLDisplay *disp = _eglLockDisplay(dpy);
919   _EGLContext *source_context = _eglLookupContext(source, disp);
920   _EGLContext *dest_context = _eglLookupContext(dest, disp);
921   _EGLDriver *drv;
922   EGLBoolean ret;
923
924   _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
925   if (!dest_context)
926      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
927
928   ret = drv->API.CopyContextMESA(drv, disp,
929         source_context, dest_context, mask);
930
931   RETURN_EGL_EVAL(disp, ret);
932}
933
934
935EGLBoolean EGLAPIENTRY
936eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
937                  EGLint max_screens, EGLint *num_screens)
938{
939   _EGLDisplay *disp = _eglLockDisplay(dpy);
940   _EGLDriver *drv;
941   EGLBoolean ret;
942
943   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
944   ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
945
946   RETURN_EGL_EVAL(disp, ret);
947}
948
949
950EGLSurface EGLAPIENTRY
951eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
952                           const EGLint *attrib_list)
953{
954   _EGLDisplay *disp = _eglLockDisplay(dpy);
955   _EGLConfig *conf = _eglLookupConfig(config, disp);
956   _EGLDriver *drv;
957   _EGLSurface *surf;
958   EGLSurface ret;
959
960   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
961
962   surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
963   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
964
965   RETURN_EGL_EVAL(disp, ret);
966}
967
968
969EGLBoolean EGLAPIENTRY
970eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
971                         EGLSurface surface, EGLModeMESA mode)
972{
973   _EGLDisplay *disp = _eglLockDisplay(dpy);
974   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
975   _EGLSurface *surf = _eglLookupSurface(surface, disp);
976   _EGLMode *m = _eglLookupMode(mode, disp);
977   _EGLDriver *drv;
978   EGLBoolean ret;
979
980   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
981   if (!surf && surface != EGL_NO_SURFACE)
982      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
983   if (!m && mode != EGL_NO_MODE_MESA)
984      RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
985
986   ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
987
988   RETURN_EGL_EVAL(disp, ret);
989}
990
991
992EGLBoolean EGLAPIENTRY
993eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
994{
995   _EGLDisplay *disp = _eglLockDisplay(dpy);
996   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
997   _EGLDriver *drv;
998   EGLBoolean ret;
999
1000   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1001   ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1002
1003   RETURN_EGL_EVAL(disp, ret);
1004}
1005
1006
1007EGLBoolean EGLAPIENTRY
1008eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1009                   EGLint attribute, EGLint *value)
1010{
1011   _EGLDisplay *disp = _eglLockDisplay(dpy);
1012   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1013   _EGLDriver *drv;
1014   EGLBoolean ret;
1015
1016   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1017   ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1018
1019   RETURN_EGL_EVAL(disp, ret);
1020}
1021
1022
1023EGLBoolean EGLAPIENTRY
1024eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1025                          EGLSurface *surface)
1026{
1027   _EGLDisplay *disp = _eglLockDisplay(dpy);
1028   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1029   _EGLDriver *drv;
1030   _EGLSurface *surf;
1031   EGLBoolean ret;
1032
1033   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1034   ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1035   if (ret && surface)
1036      *surface = _eglGetSurfaceHandle(surf);
1037
1038   RETURN_EGL_EVAL(disp, ret);
1039}
1040
1041
1042EGLBoolean EGLAPIENTRY
1043eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1044{
1045   _EGLDisplay *disp = _eglLockDisplay(dpy);
1046   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1047   _EGLDriver *drv;
1048   _EGLMode *m;
1049   EGLBoolean ret;
1050
1051   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1052   ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1053   if (ret && mode)
1054      *mode = m->Handle;
1055
1056   RETURN_EGL_EVAL(disp, ret);
1057}
1058
1059
1060const char * EGLAPIENTRY
1061eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1062{
1063   _EGLDisplay *disp = _eglLockDisplay(dpy);
1064   _EGLMode *m = _eglLookupMode(mode, disp);
1065   _EGLDriver *drv;
1066   const char *ret;
1067
1068   _EGL_CHECK_MODE(disp, m, NULL, drv);
1069   ret = drv->API.QueryModeStringMESA(drv, disp, m);
1070
1071   RETURN_EGL_EVAL(disp, ret);
1072}
1073
1074
1075#endif /* EGL_MESA_screen_surface */
1076
1077
1078#ifdef EGL_MESA_drm_display
1079
1080EGLDisplay EGLAPIENTRY
1081eglGetDRMDisplayMESA(int fd)
1082{
1083   _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) fd);
1084   return _eglGetDisplayHandle(dpy);
1085}
1086
1087#endif /* EGL_MESA_drm_display */
1088
1089/**
1090 ** EGL 1.2
1091 **/
1092
1093#ifdef EGL_VERSION_1_2
1094
1095
1096/**
1097 * Specify the client API to use for subsequent calls including:
1098 *  eglCreateContext()
1099 *  eglGetCurrentContext()
1100 *  eglGetCurrentDisplay()
1101 *  eglGetCurrentSurface()
1102 *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1103 *  eglWaitClient()
1104 *  eglWaitNative()
1105 * See section 3.7 "Rendering Context" in the EGL specification for details.
1106 */
1107EGLBoolean EGLAPIENTRY
1108eglBindAPI(EGLenum api)
1109{
1110   _EGLThreadInfo *t = _eglGetCurrentThread();
1111
1112   if (_eglIsCurrentThreadDummy())
1113      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1114
1115   if (!_eglIsApiValid(api))
1116      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1117
1118   t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1119
1120   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1121}
1122
1123
1124/**
1125 * Return the last value set with eglBindAPI().
1126 */
1127EGLenum EGLAPIENTRY
1128eglQueryAPI(void)
1129{
1130   _EGLThreadInfo *t = _eglGetCurrentThread();
1131   EGLenum ret;
1132
1133   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1134   ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1135
1136   RETURN_EGL_SUCCESS(NULL, ret);
1137}
1138
1139
1140EGLSurface EGLAPIENTRY
1141eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1142                                 EGLClientBuffer buffer, EGLConfig config,
1143                                 const EGLint *attrib_list)
1144{
1145   _EGLDisplay *disp = _eglLockDisplay(dpy);
1146   _EGLConfig *conf = _eglLookupConfig(config, disp);
1147   _EGLDriver *drv;
1148   _EGLSurface *surf;
1149   EGLSurface ret;
1150
1151   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1152
1153   surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1154                                                 conf, attrib_list);
1155   ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
1156
1157   RETURN_EGL_EVAL(disp, ret);
1158}
1159
1160
1161EGLBoolean EGLAPIENTRY
1162eglReleaseThread(void)
1163{
1164   /* unbind current contexts */
1165   if (!_eglIsCurrentThreadDummy()) {
1166      _EGLThreadInfo *t = _eglGetCurrentThread();
1167      EGLint api_index = t->CurrentAPIIndex;
1168      EGLint i;
1169
1170      for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1171         _EGLContext *ctx = t->CurrentContexts[i];
1172         if (ctx) {
1173            _EGLDisplay *disp = ctx->Resource.Display;
1174            _EGLDriver *drv;
1175
1176            t->CurrentAPIIndex = i;
1177
1178            _eglLockMutex(&disp->Mutex);
1179            drv = disp->Driver;
1180            (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1181            _eglUnlockMutex(&disp->Mutex);
1182         }
1183      }
1184
1185      t->CurrentAPIIndex = api_index;
1186   }
1187
1188   _eglDestroyCurrentThread();
1189
1190   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1191}
1192
1193
1194#endif /* EGL_VERSION_1_2 */
1195
1196
1197#ifdef EGL_KHR_image_base
1198
1199
1200EGLImageKHR EGLAPIENTRY
1201eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1202                  EGLClientBuffer buffer, const EGLint *attr_list)
1203{
1204   _EGLDisplay *disp = _eglLockDisplay(dpy);
1205   _EGLContext *context = _eglLookupContext(ctx, disp);
1206   _EGLDriver *drv;
1207   _EGLImage *img;
1208   EGLImageKHR ret;
1209
1210   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1211   if (!context && ctx != EGL_NO_CONTEXT)
1212      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1213
1214   img = drv->API.CreateImageKHR(drv,
1215         disp, context, target, buffer, attr_list);
1216   ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
1217
1218   RETURN_EGL_EVAL(disp, ret);
1219}
1220
1221
1222EGLBoolean EGLAPIENTRY
1223eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1224{
1225   _EGLDisplay *disp = _eglLockDisplay(dpy);
1226   _EGLImage *img = _eglLookupImage(image, disp);
1227   _EGLDriver *drv;
1228   EGLBoolean ret;
1229
1230   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1231   if (!img)
1232      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1233
1234   _eglUnlinkImage(img);
1235   ret = drv->API.DestroyImageKHR(drv, disp, img);
1236
1237   RETURN_EGL_EVAL(disp, ret);
1238}
1239
1240
1241#endif /* EGL_KHR_image_base */
1242
1243
1244#ifdef EGL_NOK_swap_region
1245
1246EGLBoolean EGLAPIENTRY
1247eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1248			EGLint numRects, const EGLint *rects)
1249{
1250   _EGLContext *ctx = _eglGetCurrentContext();
1251   _EGLDisplay *disp = _eglLockDisplay(dpy);
1252   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1253   _EGLDriver *drv;
1254   EGLBoolean ret;
1255
1256   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1257
1258   /* surface must be bound to current context in EGL 1.4 */
1259   if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
1260      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1261
1262   if (drv->API.SwapBuffersRegionNOK)
1263      ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1264   else
1265      ret = drv->API.SwapBuffers(drv, disp, surf);
1266
1267   RETURN_EGL_EVAL(disp, ret);
1268}
1269
1270#endif /* EGL_NOK_swap_region */
1271