Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / mesa / src / egl / main / eglapi.c
blob0ba7794e2c920d8f5142eed918ff1ff0270eba1b
1 /**************************************************************************
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.
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:
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.
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.
28 **************************************************************************/
31 /**
32 * Public EGL API entrypoints
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.
38 * That allows us the option of supporting multiple, simultaneous,
39 * heterogeneous hardware devices in the future.
41 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
42 * opaque handles. Internal objects are linked to a display to
43 * create the handles.
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
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
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,
60 * EGL_NOT_INITIALIZED
62 * is generated.
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,
69 * EGL_BAD_CURRENT_SURFACE
71 * may also be generated.
73 * Notes on naming conventions:
75 * eglFooBar - public EGL function
76 * EGL_FOO_BAR - public EGL token
77 * EGLDatatype - public EGL datatype
79 * _eglFooBar - private EGL function
80 * _EGLDatatype - private EGL datatype, typedef'd struct
81 * _egl_struct - private EGL struct, non-typedef'd
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <string.h>
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"
104 * Macros to help return an API entrypoint.
106 * These macros will unlock the display and record the error code.
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)
118 #define RETURN_EGL_SUCCESS(disp, ret) \
119 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
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)
127 * A bunch of macros and checks to simplify error checking.
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)
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)
144 #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
145 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
147 #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
148 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
150 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
151 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
153 #define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
154 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
156 #define _EGL_CHECK_MODE(disp, m, ret, drv) \
157 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
159 #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
160 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
163 static INLINE _EGLDriver *
164 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
166 if (!disp) {
167 _eglError(EGL_BAD_DISPLAY, msg);
168 return NULL;
170 if (!disp->Initialized) {
171 _eglError(EGL_NOT_INITIALIZED, msg);
172 return NULL;
174 return disp->Driver;
178 static INLINE _EGLDriver *
179 _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
181 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
182 if (!drv)
183 return NULL;
184 if (!surf) {
185 _eglError(EGL_BAD_SURFACE, msg);
186 return NULL;
188 return drv;
192 static INLINE _EGLDriver *
193 _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
195 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
196 if (!drv)
197 return NULL;
198 if (!context) {
199 _eglError(EGL_BAD_CONTEXT, msg);
200 return NULL;
202 return drv;
206 static INLINE _EGLDriver *
207 _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
209 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
210 if (!drv)
211 return NULL;
212 if (!conf) {
213 _eglError(EGL_BAD_CONFIG, msg);
214 return NULL;
216 return drv;
220 #ifdef EGL_KHR_reusable_sync
223 static INLINE _EGLDriver *
224 _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
226 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
227 if (!drv)
228 return NULL;
229 if (!s) {
230 _eglError(EGL_BAD_PARAMETER, msg);
231 return NULL;
233 return drv;
237 #endif /* EGL_KHR_reusable_sync */
240 #ifdef EGL_MESA_screen_surface
243 static INLINE _EGLDriver *
244 _eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
246 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
247 if (!drv)
248 return NULL;
249 if (!scrn) {
250 _eglError(EGL_BAD_SCREEN_MESA, msg);
251 return NULL;
253 return drv;
257 static INLINE _EGLDriver *
258 _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
260 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
261 if (!drv)
262 return NULL;
263 if (!m) {
264 _eglError(EGL_BAD_MODE_MESA, msg);
265 return NULL;
267 return drv;
271 #endif /* EGL_MESA_screen_surface */
275 * Lookup and lock a display.
277 static INLINE _EGLDisplay *
278 _eglLockDisplay(EGLDisplay display)
280 _EGLDisplay *dpy = _eglLookupDisplay(display);
281 if (dpy)
282 _eglLockMutex(&dpy->Mutex);
283 return dpy;
288 * Unlock a display.
290 static INLINE void
291 _eglUnlockDisplay(_EGLDisplay *dpy)
293 _eglUnlockMutex(&dpy->Mutex);
298 * This is typically the first EGL function that an application calls.
299 * It associates a private _EGLDisplay object to the native display.
301 EGLDisplay EGLAPIENTRY
302 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
304 _EGLPlatformType plat = _eglGetNativePlatform();
305 _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
306 return _eglGetDisplayHandle(dpy);
311 * This is typically the second EGL function that an application calls.
312 * Here we load/initialize the actual hardware driver.
314 EGLBoolean EGLAPIENTRY
315 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
317 _EGLDisplay *disp = _eglLockDisplay(dpy);
319 if (!disp)
320 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
322 if (!disp->Initialized) {
323 if (!_eglMatchDriver(disp, EGL_FALSE))
324 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
326 /* limit to APIs supported by core */
327 disp->ClientAPIs &= _EGL_API_ALL_BITS;
330 /* Update applications version of major and minor if not NULL */
331 if ((major != NULL) && (minor != NULL)) {
332 *major = disp->VersionMajor;
333 *minor = disp->VersionMinor;
336 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
340 EGLBoolean EGLAPIENTRY
341 eglTerminate(EGLDisplay dpy)
343 _EGLDisplay *disp = _eglLockDisplay(dpy);
345 if (!disp)
346 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
348 if (disp->Initialized) {
349 _EGLDriver *drv = disp->Driver;
351 drv->API.Terminate(drv, disp);
352 /* do not reset disp->Driver */
353 disp->Initialized = EGL_FALSE;
356 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
360 const char * EGLAPIENTRY
361 eglQueryString(EGLDisplay dpy, EGLint name)
363 _EGLDisplay *disp = _eglLockDisplay(dpy);
364 _EGLDriver *drv;
365 const char *ret;
367 _EGL_CHECK_DISPLAY(disp, NULL, drv);
368 ret = drv->API.QueryString(drv, disp, name);
370 RETURN_EGL_EVAL(disp, ret);
374 EGLBoolean EGLAPIENTRY
375 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
376 EGLint config_size, EGLint *num_config)
378 _EGLDisplay *disp = _eglLockDisplay(dpy);
379 _EGLDriver *drv;
380 EGLBoolean ret;
382 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
383 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
385 RETURN_EGL_EVAL(disp, ret);
389 EGLBoolean EGLAPIENTRY
390 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
391 EGLint config_size, EGLint *num_config)
393 _EGLDisplay *disp = _eglLockDisplay(dpy);
394 _EGLDriver *drv;
395 EGLBoolean ret;
397 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
398 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
399 config_size, num_config);
401 RETURN_EGL_EVAL(disp, ret);
405 EGLBoolean EGLAPIENTRY
406 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
407 EGLint attribute, EGLint *value)
409 _EGLDisplay *disp = _eglLockDisplay(dpy);
410 _EGLConfig *conf = _eglLookupConfig(config, disp);
411 _EGLDriver *drv;
412 EGLBoolean ret;
414 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
415 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
417 RETURN_EGL_EVAL(disp, ret);
421 EGLContext EGLAPIENTRY
422 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
423 const EGLint *attrib_list)
425 _EGLDisplay *disp = _eglLockDisplay(dpy);
426 _EGLConfig *conf = _eglLookupConfig(config, disp);
427 _EGLContext *share = _eglLookupContext(share_list, disp);
428 _EGLDriver *drv;
429 _EGLContext *context;
430 EGLContext ret;
432 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
434 if (!config) {
435 /* config may be NULL if surfaceless */
436 if (!disp->Extensions.KHR_surfaceless_gles1 &&
437 !disp->Extensions.KHR_surfaceless_gles2 &&
438 !disp->Extensions.KHR_surfaceless_opengl)
439 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
442 if (!share && share_list != EGL_NO_CONTEXT)
443 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
445 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
446 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
448 RETURN_EGL_EVAL(disp, ret);
452 EGLBoolean EGLAPIENTRY
453 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
455 _EGLDisplay *disp = _eglLockDisplay(dpy);
456 _EGLContext *context = _eglLookupContext(ctx, disp);
457 _EGLDriver *drv;
458 EGLBoolean ret;
460 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
461 _eglUnlinkContext(context);
462 ret = drv->API.DestroyContext(drv, disp, context);
464 RETURN_EGL_EVAL(disp, ret);
468 EGLBoolean EGLAPIENTRY
469 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
470 EGLContext ctx)
472 _EGLDisplay *disp = _eglLockDisplay(dpy);
473 _EGLContext *context = _eglLookupContext(ctx, disp);
474 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
475 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
476 _EGLDriver *drv;
477 EGLBoolean ret;
479 if (!disp)
480 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
481 drv = disp->Driver;
483 /* display is allowed to be uninitialized under certain condition */
484 if (!disp->Initialized) {
485 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
486 ctx != EGL_NO_CONTEXT)
487 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
489 if (!drv)
490 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
492 if (!context && ctx != EGL_NO_CONTEXT)
493 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
494 if (!draw_surf || !read_surf) {
495 /* surfaces may be NULL if surfaceless */
496 if (!disp->Extensions.KHR_surfaceless_gles1 &&
497 !disp->Extensions.KHR_surfaceless_gles2 &&
498 !disp->Extensions.KHR_surfaceless_opengl)
499 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
501 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
502 (!read_surf && read != EGL_NO_SURFACE))
503 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
504 if (draw_surf || read_surf)
505 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
508 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
510 RETURN_EGL_EVAL(disp, ret);
514 EGLBoolean EGLAPIENTRY
515 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
516 EGLint attribute, EGLint *value)
518 _EGLDisplay *disp = _eglLockDisplay(dpy);
519 _EGLContext *context = _eglLookupContext(ctx, disp);
520 _EGLDriver *drv;
521 EGLBoolean ret;
523 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
524 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
526 RETURN_EGL_EVAL(disp, ret);
530 EGLSurface EGLAPIENTRY
531 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
532 EGLNativeWindowType window, const EGLint *attrib_list)
534 _EGLDisplay *disp = _eglLockDisplay(dpy);
535 _EGLConfig *conf = _eglLookupConfig(config, disp);
536 _EGLDriver *drv;
537 _EGLSurface *surf;
538 EGLSurface ret;
540 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
541 if (disp->Platform != _eglGetNativePlatform())
542 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
544 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
545 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
547 RETURN_EGL_EVAL(disp, ret);
551 EGLSurface EGLAPIENTRY
552 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
553 EGLNativePixmapType pixmap, const EGLint *attrib_list)
555 _EGLDisplay *disp = _eglLockDisplay(dpy);
556 _EGLConfig *conf = _eglLookupConfig(config, disp);
557 _EGLDriver *drv;
558 _EGLSurface *surf;
559 EGLSurface ret;
561 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
562 if (disp->Platform != _eglGetNativePlatform())
563 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
565 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
566 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
568 RETURN_EGL_EVAL(disp, ret);
572 EGLSurface EGLAPIENTRY
573 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
574 const EGLint *attrib_list)
576 _EGLDisplay *disp = _eglLockDisplay(dpy);
577 _EGLConfig *conf = _eglLookupConfig(config, disp);
578 _EGLDriver *drv;
579 _EGLSurface *surf;
580 EGLSurface ret;
582 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
584 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
585 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
587 RETURN_EGL_EVAL(disp, ret);
591 EGLBoolean EGLAPIENTRY
592 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
594 _EGLDisplay *disp = _eglLockDisplay(dpy);
595 _EGLSurface *surf = _eglLookupSurface(surface, disp);
596 _EGLDriver *drv;
597 EGLBoolean ret;
599 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
600 _eglUnlinkSurface(surf);
601 ret = drv->API.DestroySurface(drv, disp, surf);
603 RETURN_EGL_EVAL(disp, ret);
606 EGLBoolean EGLAPIENTRY
607 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
608 EGLint attribute, EGLint *value)
610 _EGLDisplay *disp = _eglLockDisplay(dpy);
611 _EGLSurface *surf = _eglLookupSurface(surface, disp);
612 _EGLDriver *drv;
613 EGLBoolean ret;
615 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
616 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
618 RETURN_EGL_EVAL(disp, ret);
621 EGLBoolean EGLAPIENTRY
622 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
623 EGLint attribute, EGLint value)
625 _EGLDisplay *disp = _eglLockDisplay(dpy);
626 _EGLSurface *surf = _eglLookupSurface(surface, disp);
627 _EGLDriver *drv;
628 EGLBoolean ret;
630 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
631 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
633 RETURN_EGL_EVAL(disp, ret);
637 EGLBoolean EGLAPIENTRY
638 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
640 _EGLDisplay *disp = _eglLockDisplay(dpy);
641 _EGLSurface *surf = _eglLookupSurface(surface, disp);
642 _EGLDriver *drv;
643 EGLBoolean ret;
645 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
646 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
648 RETURN_EGL_EVAL(disp, ret);
652 EGLBoolean EGLAPIENTRY
653 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
655 _EGLDisplay *disp = _eglLockDisplay(dpy);
656 _EGLSurface *surf = _eglLookupSurface(surface, disp);
657 _EGLDriver *drv;
658 EGLBoolean ret;
660 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
661 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
663 RETURN_EGL_EVAL(disp, ret);
667 EGLBoolean EGLAPIENTRY
668 eglSwapInterval(EGLDisplay dpy, EGLint interval)
670 _EGLDisplay *disp = _eglLockDisplay(dpy);
671 _EGLContext *ctx = _eglGetCurrentContext();
672 _EGLSurface *surf;
673 _EGLDriver *drv;
674 EGLBoolean ret;
676 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
678 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
679 ctx->Resource.Display != disp)
680 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
682 surf = ctx->DrawSurface;
683 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
684 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
686 ret = drv->API.SwapInterval(drv, disp, surf, interval);
688 RETURN_EGL_EVAL(disp, ret);
692 EGLBoolean EGLAPIENTRY
693 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
695 _EGLContext *ctx = _eglGetCurrentContext();
696 _EGLDisplay *disp = _eglLockDisplay(dpy);
697 _EGLSurface *surf = _eglLookupSurface(surface, disp);
698 _EGLDriver *drv;
699 EGLBoolean ret;
701 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
703 /* surface must be bound to current context in EGL 1.4 */
704 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
705 surf != ctx->DrawSurface)
706 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
708 ret = drv->API.SwapBuffers(drv, disp, surf);
710 RETURN_EGL_EVAL(disp, ret);
714 EGLBoolean EGLAPIENTRY
715 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
717 _EGLDisplay *disp = _eglLockDisplay(dpy);
718 _EGLSurface *surf = _eglLookupSurface(surface, disp);
719 _EGLDriver *drv;
720 EGLBoolean ret;
722 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
723 if (disp->Platform != _eglGetNativePlatform())
724 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
725 ret = drv->API.CopyBuffers(drv, disp, surf, target);
727 RETURN_EGL_EVAL(disp, ret);
731 EGLBoolean EGLAPIENTRY
732 eglWaitClient(void)
734 _EGLContext *ctx = _eglGetCurrentContext();
735 _EGLDisplay *disp;
736 _EGLDriver *drv;
737 EGLBoolean ret;
739 if (!ctx)
740 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
742 disp = ctx->Resource.Display;
743 _eglLockMutex(&disp->Mutex);
745 /* let bad current context imply bad current surface */
746 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
747 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
748 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
750 /* a valid current context implies an initialized current display */
751 assert(disp->Initialized);
752 drv = disp->Driver;
753 ret = drv->API.WaitClient(drv, disp, ctx);
755 RETURN_EGL_EVAL(disp, ret);
759 EGLBoolean EGLAPIENTRY
760 eglWaitGL(void)
762 #ifdef EGL_VERSION_1_2
763 _EGLThreadInfo *t = _eglGetCurrentThread();
764 EGLint api_index = t->CurrentAPIIndex;
765 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
766 EGLBoolean ret;
768 if (api_index != es_index && _eglIsCurrentThreadDummy())
769 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
771 t->CurrentAPIIndex = es_index;
772 ret = eglWaitClient();
773 t->CurrentAPIIndex = api_index;
774 return ret;
775 #else
776 return eglWaitClient();
777 #endif
781 EGLBoolean EGLAPIENTRY
782 eglWaitNative(EGLint engine)
784 _EGLContext *ctx = _eglGetCurrentContext();
785 _EGLDisplay *disp;
786 _EGLDriver *drv;
787 EGLBoolean ret;
789 if (!ctx)
790 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
792 disp = ctx->Resource.Display;
793 _eglLockMutex(&disp->Mutex);
795 /* let bad current context imply bad current surface */
796 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
797 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
798 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
800 /* a valid current context implies an initialized current display */
801 assert(disp->Initialized);
802 drv = disp->Driver;
803 ret = drv->API.WaitNative(drv, disp, engine);
805 RETURN_EGL_EVAL(disp, ret);
809 EGLDisplay EGLAPIENTRY
810 eglGetCurrentDisplay(void)
812 _EGLContext *ctx = _eglGetCurrentContext();
813 EGLDisplay ret;
815 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
817 RETURN_EGL_SUCCESS(NULL, ret);
821 EGLContext EGLAPIENTRY
822 eglGetCurrentContext(void)
824 _EGLContext *ctx = _eglGetCurrentContext();
825 EGLContext ret;
827 ret = _eglGetContextHandle(ctx);
829 RETURN_EGL_SUCCESS(NULL, ret);
833 EGLSurface EGLAPIENTRY
834 eglGetCurrentSurface(EGLint readdraw)
836 _EGLContext *ctx = _eglGetCurrentContext();
837 EGLint err = EGL_SUCCESS;
838 _EGLSurface *surf;
839 EGLSurface ret;
841 if (!ctx)
842 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
844 switch (readdraw) {
845 case EGL_DRAW:
846 surf = ctx->DrawSurface;
847 break;
848 case EGL_READ:
849 surf = ctx->ReadSurface;
850 break;
851 default:
852 surf = NULL;
853 err = EGL_BAD_PARAMETER;
854 break;
857 ret = _eglGetSurfaceHandle(surf);
859 RETURN_EGL_ERROR(NULL, err, ret);
863 EGLint EGLAPIENTRY
864 eglGetError(void)
866 _EGLThreadInfo *t = _eglGetCurrentThread();
867 EGLint e = t->LastError;
868 if (!_eglIsCurrentThreadDummy())
869 t->LastError = EGL_SUCCESS;
870 return e;
874 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
875 eglGetProcAddress(const char *procname)
877 static const struct {
878 const char *name;
879 _EGLProc function;
880 } egl_functions[] = {
881 /* core functions should not be queryable, but, well... */
882 #ifdef _EGL_GET_CORE_ADDRESSES
883 /* alphabetical order */
884 { "eglBindAPI", (_EGLProc) eglBindAPI },
885 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
886 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
887 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
888 { "eglCreateContext", (_EGLProc) eglCreateContext },
889 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
890 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
891 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
892 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
893 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
894 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
895 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
896 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
897 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
898 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
899 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
900 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
901 { "eglGetError", (_EGLProc) eglGetError },
902 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
903 { "eglInitialize", (_EGLProc) eglInitialize },
904 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
905 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
906 { "eglQueryContext", (_EGLProc) eglQueryContext },
907 { "eglQueryString", (_EGLProc) eglQueryString },
908 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
909 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
910 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
911 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
912 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
913 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
914 { "eglTerminate", (_EGLProc) eglTerminate },
915 { "eglWaitClient", (_EGLProc) eglWaitClient },
916 { "eglWaitGL", (_EGLProc) eglWaitGL },
917 { "eglWaitNative", (_EGLProc) eglWaitNative },
918 #endif /* _EGL_GET_CORE_ADDRESSES */
919 #ifdef EGL_MESA_screen_surface
920 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
921 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
922 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
923 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
924 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
925 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
926 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
927 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
928 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
929 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
930 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
931 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
932 #endif /* EGL_MESA_screen_surface */
933 #ifdef EGL_MESA_drm_display
934 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
935 #endif
936 #ifdef EGL_KHR_image_base
937 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
938 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
939 #endif /* EGL_KHR_image_base */
940 #ifdef EGL_NOK_swap_region
941 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
942 #endif
943 #ifdef EGL_MESA_drm_image
944 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
945 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
946 #endif
947 #ifdef EGL_WL_bind_wayland_display
948 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
949 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
950 #endif
951 { NULL, NULL }
953 EGLint i;
954 _EGLProc ret;
956 if (!procname)
957 RETURN_EGL_SUCCESS(NULL, NULL);
959 ret = NULL;
960 if (strncmp(procname, "egl", 3) == 0) {
961 for (i = 0; egl_functions[i].name; i++) {
962 if (strcmp(egl_functions[i].name, procname) == 0) {
963 ret = egl_functions[i].function;
964 break;
968 if (!ret)
969 ret = _eglGetDriverProc(procname);
971 RETURN_EGL_SUCCESS(NULL, ret);
975 #ifdef EGL_MESA_screen_surface
979 * EGL_MESA_screen extension
982 EGLBoolean EGLAPIENTRY
983 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
984 const EGLint *attrib_list, EGLModeMESA *modes,
985 EGLint modes_size, EGLint *num_modes)
987 _EGLDisplay *disp = _eglLockDisplay(dpy);
988 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
989 _EGLDriver *drv;
990 EGLBoolean ret;
992 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
993 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
994 modes, modes_size, num_modes);
996 RETURN_EGL_EVAL(disp, ret);
1000 EGLBoolean EGLAPIENTRY
1001 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
1002 EGLint mode_size, EGLint *num_mode)
1004 _EGLDisplay *disp = _eglLockDisplay(dpy);
1005 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1006 _EGLDriver *drv;
1007 EGLBoolean ret;
1009 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1010 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
1012 RETURN_EGL_EVAL(disp, ret);
1016 EGLBoolean EGLAPIENTRY
1017 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
1018 EGLint attribute, EGLint *value)
1020 _EGLDisplay *disp = _eglLockDisplay(dpy);
1021 _EGLMode *m = _eglLookupMode(mode, disp);
1022 _EGLDriver *drv;
1023 EGLBoolean ret;
1025 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
1026 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
1028 RETURN_EGL_EVAL(disp, ret);
1032 EGLBoolean EGLAPIENTRY
1033 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
1034 EGLint mask)
1036 _EGLDisplay *disp = _eglLockDisplay(dpy);
1037 _EGLContext *source_context = _eglLookupContext(source, disp);
1038 _EGLContext *dest_context = _eglLookupContext(dest, disp);
1039 _EGLDriver *drv;
1040 EGLBoolean ret;
1042 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
1043 if (!dest_context)
1044 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
1046 ret = drv->API.CopyContextMESA(drv, disp,
1047 source_context, dest_context, mask);
1049 RETURN_EGL_EVAL(disp, ret);
1053 EGLBoolean EGLAPIENTRY
1054 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
1055 EGLint max_screens, EGLint *num_screens)
1057 _EGLDisplay *disp = _eglLockDisplay(dpy);
1058 _EGLDriver *drv;
1059 EGLBoolean ret;
1061 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1062 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
1064 RETURN_EGL_EVAL(disp, ret);
1068 EGLSurface EGLAPIENTRY
1069 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
1070 const EGLint *attrib_list)
1072 _EGLDisplay *disp = _eglLockDisplay(dpy);
1073 _EGLConfig *conf = _eglLookupConfig(config, disp);
1074 _EGLDriver *drv;
1075 _EGLSurface *surf;
1076 EGLSurface ret;
1078 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1080 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
1081 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1083 RETURN_EGL_EVAL(disp, ret);
1087 EGLBoolean EGLAPIENTRY
1088 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
1089 EGLSurface surface, EGLModeMESA mode)
1091 _EGLDisplay *disp = _eglLockDisplay(dpy);
1092 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1093 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1094 _EGLMode *m = _eglLookupMode(mode, disp);
1095 _EGLDriver *drv;
1096 EGLBoolean ret;
1098 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1099 if (!surf && surface != EGL_NO_SURFACE)
1100 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1101 if (!m && mode != EGL_NO_MODE_MESA)
1102 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
1104 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
1106 RETURN_EGL_EVAL(disp, ret);
1110 EGLBoolean EGLAPIENTRY
1111 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
1113 _EGLDisplay *disp = _eglLockDisplay(dpy);
1114 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1115 _EGLDriver *drv;
1116 EGLBoolean ret;
1118 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1119 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1121 RETURN_EGL_EVAL(disp, ret);
1125 EGLBoolean EGLAPIENTRY
1126 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1127 EGLint attribute, EGLint *value)
1129 _EGLDisplay *disp = _eglLockDisplay(dpy);
1130 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1131 _EGLDriver *drv;
1132 EGLBoolean ret;
1134 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1135 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1137 RETURN_EGL_EVAL(disp, ret);
1141 EGLBoolean EGLAPIENTRY
1142 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1143 EGLSurface *surface)
1145 _EGLDisplay *disp = _eglLockDisplay(dpy);
1146 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1147 _EGLDriver *drv;
1148 _EGLSurface *surf;
1149 EGLBoolean ret;
1151 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1152 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1153 if (ret && surface)
1154 *surface = _eglGetSurfaceHandle(surf);
1156 RETURN_EGL_EVAL(disp, ret);
1160 EGLBoolean EGLAPIENTRY
1161 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1163 _EGLDisplay *disp = _eglLockDisplay(dpy);
1164 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1165 _EGLDriver *drv;
1166 _EGLMode *m;
1167 EGLBoolean ret;
1169 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1170 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1171 if (ret && mode)
1172 *mode = m->Handle;
1174 RETURN_EGL_EVAL(disp, ret);
1178 const char * EGLAPIENTRY
1179 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1181 _EGLDisplay *disp = _eglLockDisplay(dpy);
1182 _EGLMode *m = _eglLookupMode(mode, disp);
1183 _EGLDriver *drv;
1184 const char *ret;
1186 _EGL_CHECK_MODE(disp, m, NULL, drv);
1187 ret = drv->API.QueryModeStringMESA(drv, disp, m);
1189 RETURN_EGL_EVAL(disp, ret);
1193 #endif /* EGL_MESA_screen_surface */
1196 #ifdef EGL_MESA_drm_display
1198 EGLDisplay EGLAPIENTRY
1199 eglGetDRMDisplayMESA(int fd)
1201 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
1202 return _eglGetDisplayHandle(dpy);
1205 #endif /* EGL_MESA_drm_display */
1208 ** EGL 1.2
1211 #ifdef EGL_VERSION_1_2
1215 * Specify the client API to use for subsequent calls including:
1216 * eglCreateContext()
1217 * eglGetCurrentContext()
1218 * eglGetCurrentDisplay()
1219 * eglGetCurrentSurface()
1220 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1221 * eglWaitClient()
1222 * eglWaitNative()
1223 * See section 3.7 "Rendering Context" in the EGL specification for details.
1225 EGLBoolean EGLAPIENTRY
1226 eglBindAPI(EGLenum api)
1228 _EGLThreadInfo *t = _eglGetCurrentThread();
1230 if (_eglIsCurrentThreadDummy())
1231 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1233 if (!_eglIsApiValid(api))
1234 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1236 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1238 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1243 * Return the last value set with eglBindAPI().
1245 EGLenum EGLAPIENTRY
1246 eglQueryAPI(void)
1248 _EGLThreadInfo *t = _eglGetCurrentThread();
1249 EGLenum ret;
1251 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1252 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1254 RETURN_EGL_SUCCESS(NULL, ret);
1258 EGLSurface EGLAPIENTRY
1259 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1260 EGLClientBuffer buffer, EGLConfig config,
1261 const EGLint *attrib_list)
1263 _EGLDisplay *disp = _eglLockDisplay(dpy);
1264 _EGLConfig *conf = _eglLookupConfig(config, disp);
1265 _EGLDriver *drv;
1266 _EGLSurface *surf;
1267 EGLSurface ret;
1269 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1271 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1272 conf, attrib_list);
1273 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1275 RETURN_EGL_EVAL(disp, ret);
1279 EGLBoolean EGLAPIENTRY
1280 eglReleaseThread(void)
1282 /* unbind current contexts */
1283 if (!_eglIsCurrentThreadDummy()) {
1284 _EGLThreadInfo *t = _eglGetCurrentThread();
1285 EGLint api_index = t->CurrentAPIIndex;
1286 EGLint i;
1288 for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1289 _EGLContext *ctx = t->CurrentContexts[i];
1290 if (ctx) {
1291 _EGLDisplay *disp = ctx->Resource.Display;
1292 _EGLDriver *drv;
1294 t->CurrentAPIIndex = i;
1296 _eglLockMutex(&disp->Mutex);
1297 drv = disp->Driver;
1298 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1299 _eglUnlockMutex(&disp->Mutex);
1303 t->CurrentAPIIndex = api_index;
1306 _eglDestroyCurrentThread();
1308 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1312 #endif /* EGL_VERSION_1_2 */
1315 #ifdef EGL_KHR_image_base
1318 EGLImageKHR EGLAPIENTRY
1319 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1320 EGLClientBuffer buffer, const EGLint *attr_list)
1322 _EGLDisplay *disp = _eglLockDisplay(dpy);
1323 _EGLContext *context = _eglLookupContext(ctx, disp);
1324 _EGLDriver *drv;
1325 _EGLImage *img;
1326 EGLImageKHR ret;
1328 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1329 if (!disp->Extensions.KHR_image_base)
1330 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1331 if (!context && ctx != EGL_NO_CONTEXT)
1332 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1334 img = drv->API.CreateImageKHR(drv,
1335 disp, context, target, buffer, attr_list);
1336 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1338 RETURN_EGL_EVAL(disp, ret);
1342 EGLBoolean EGLAPIENTRY
1343 eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1345 _EGLDisplay *disp = _eglLockDisplay(dpy);
1346 _EGLImage *img = _eglLookupImage(image, disp);
1347 _EGLDriver *drv;
1348 EGLBoolean ret;
1350 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1351 if (!disp->Extensions.KHR_image_base)
1352 RETURN_EGL_EVAL(disp, EGL_FALSE);
1353 if (!img)
1354 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1356 _eglUnlinkImage(img);
1357 ret = drv->API.DestroyImageKHR(drv, disp, img);
1359 RETURN_EGL_EVAL(disp, ret);
1363 #endif /* EGL_KHR_image_base */
1366 #ifdef EGL_KHR_reusable_sync
1369 EGLSyncKHR EGLAPIENTRY
1370 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1372 _EGLDisplay *disp = _eglLockDisplay(dpy);
1373 _EGLDriver *drv;
1374 _EGLSync *sync;
1375 EGLSyncKHR ret;
1377 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1378 if (!disp->Extensions.KHR_reusable_sync)
1379 RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
1381 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
1382 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1384 RETURN_EGL_EVAL(disp, ret);
1388 EGLBoolean EGLAPIENTRY
1389 eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1391 _EGLDisplay *disp = _eglLockDisplay(dpy);
1392 _EGLSync *s = _eglLookupSync(sync, disp);
1393 _EGLDriver *drv;
1394 EGLBoolean ret;
1396 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1397 assert(disp->Extensions.KHR_reusable_sync);
1399 _eglUnlinkSync(s);
1400 ret = drv->API.DestroySyncKHR(drv, disp, s);
1402 RETURN_EGL_EVAL(disp, ret);
1406 EGLint EGLAPIENTRY
1407 eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1409 _EGLDisplay *disp = _eglLockDisplay(dpy);
1410 _EGLSync *s = _eglLookupSync(sync, disp);
1411 _EGLDriver *drv;
1412 EGLint ret;
1414 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1415 assert(disp->Extensions.KHR_reusable_sync);
1416 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1418 RETURN_EGL_EVAL(disp, ret);
1422 EGLBoolean EGLAPIENTRY
1423 eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1425 _EGLDisplay *disp = _eglLockDisplay(dpy);
1426 _EGLSync *s = _eglLookupSync(sync, disp);
1427 _EGLDriver *drv;
1428 EGLBoolean ret;
1430 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1431 assert(disp->Extensions.KHR_reusable_sync);
1432 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1434 RETURN_EGL_EVAL(disp, ret);
1438 EGLBoolean EGLAPIENTRY
1439 eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1441 _EGLDisplay *disp = _eglLockDisplay(dpy);
1442 _EGLSync *s = _eglLookupSync(sync, disp);
1443 _EGLDriver *drv;
1444 EGLBoolean ret;
1446 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1447 assert(disp->Extensions.KHR_reusable_sync);
1448 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1450 RETURN_EGL_EVAL(disp, ret);
1454 #endif /* EGL_KHR_reusable_sync */
1457 #ifdef EGL_NOK_swap_region
1459 EGLBoolean EGLAPIENTRY
1460 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1461 EGLint numRects, const EGLint *rects)
1463 _EGLContext *ctx = _eglGetCurrentContext();
1464 _EGLDisplay *disp = _eglLockDisplay(dpy);
1465 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1466 _EGLDriver *drv;
1467 EGLBoolean ret;
1469 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1471 if (!disp->Extensions.NOK_swap_region)
1472 RETURN_EGL_EVAL(disp, EGL_FALSE);
1474 /* surface must be bound to current context in EGL 1.4 */
1475 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1476 surf != ctx->DrawSurface)
1477 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1479 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1481 RETURN_EGL_EVAL(disp, ret);
1484 #endif /* EGL_NOK_swap_region */
1487 #ifdef EGL_MESA_drm_image
1489 EGLImageKHR EGLAPIENTRY
1490 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1492 _EGLDisplay *disp = _eglLockDisplay(dpy);
1493 _EGLDriver *drv;
1494 _EGLImage *img;
1495 EGLImageKHR ret;
1497 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1498 if (!disp->Extensions.MESA_drm_image)
1499 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1501 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1502 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1504 RETURN_EGL_EVAL(disp, ret);
1507 EGLBoolean EGLAPIENTRY
1508 eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
1509 EGLint *name, EGLint *handle, EGLint *stride)
1511 _EGLDisplay *disp = _eglLockDisplay(dpy);
1512 _EGLImage *img = _eglLookupImage(image, disp);
1513 _EGLDriver *drv;
1514 EGLBoolean ret;
1516 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1517 assert(disp->Extensions.MESA_drm_image);
1519 if (!img)
1520 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1522 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1524 RETURN_EGL_EVAL(disp, ret);
1527 #endif
1529 #ifdef EGL_WL_bind_wayland_display
1530 struct wl_display;
1532 EGLBoolean EGLAPIENTRY
1533 eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1535 _EGLDisplay *disp = _eglLockDisplay(dpy);
1536 _EGLDriver *drv;
1537 EGLBoolean ret;
1539 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1540 assert(disp->Extensions.WL_bind_wayland_display);
1542 if (!display)
1543 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1545 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1547 RETURN_EGL_EVAL(disp, ret);
1550 EGLBoolean EGLAPIENTRY
1551 eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1553 _EGLDisplay *disp = _eglLockDisplay(dpy);
1554 _EGLDriver *drv;
1555 EGLBoolean ret;
1557 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1558 assert(disp->Extensions.WL_bind_wayland_display);
1560 if (!display)
1561 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1563 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1565 RETURN_EGL_EVAL(disp, ret);
1567 #endif