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