2 * Public EGL API entrypoints
4 * Generally, we use the EGLDisplay parameter as a key to lookup the
5 * appropriate device driver handle, then jump though the driver's
6 * dispatch table to handle the function.
8 * That allows us the option of supporting multiple, simultaneous,
9 * heterogeneous hardware devices in the future.
11 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
12 * opaque handles. Internal objects are linked to a display to
15 * For each public API entry point, the opaque handles are looked up
16 * before being dispatched to the drivers. When it fails to look up
26 * is generated and the driver function is not called. An
27 * uninitialized EGLDisplay has no driver associated with it. When
28 * such display is detected,
34 * Some of the entry points use current display, context, or surface
35 * implicitly. For such entry points, the implicit objects are also
36 * checked before calling the driver function. Other than the
37 * errors listed above,
39 * EGL_BAD_CURRENT_SURFACE
41 * may also be generated.
43 * Notes on naming conventions:
45 * eglFooBar - public EGL function
46 * EGL_FOO_BAR - public EGL token
47 * EGLDatatype - public EGL datatype
49 * _eglFooBar - private EGL function
50 * _EGLDatatype - private EGL datatype, typedef'd struct
51 * _egl_struct - private EGL struct, non-typedef'd
59 #include "eglcontext.h"
60 #include "egldisplay.h"
61 #include "egltypedefs.h"
62 #include "eglglobals.h"
63 #include "eglcurrent.h"
64 #include "egldriver.h"
65 #include "eglsurface.h"
66 #include "eglconfig.h"
67 #include "eglscreen.h"
73 * Macros to help return an API entrypoint.
75 * These macros will unlock the display and record the error code.
77 #define RETURN_EGL_ERROR(disp, err, ret) \
80 _eglUnlockDisplay(disp); \
81 /* EGL error codes are non-zero */ \
83 _eglError(err, __FUNCTION__); \
87 #define RETURN_EGL_SUCCESS(disp, ret) \
88 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
90 /* record EGL_SUCCESS only when ret evaluates to true */
91 #define RETURN_EGL_EVAL(disp, ret) \
92 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
96 * A bunch of macros and checks to simplify error checking.
99 #define _EGL_CHECK_DISPLAY(disp, ret, drv) \
101 drv = _eglCheckDisplay(disp, __FUNCTION__); \
103 RETURN_EGL_ERROR(disp, 0, ret); \
106 #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
108 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \
110 RETURN_EGL_ERROR(disp, 0, ret); \
113 #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
114 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
116 #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
117 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
119 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
120 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
122 #define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
123 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
125 #define _EGL_CHECK_MODE(disp, m, ret, drv) \
126 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
130 static INLINE _EGLDriver
*
131 _eglCheckDisplay(_EGLDisplay
*disp
, const char *msg
)
134 _eglError(EGL_BAD_DISPLAY
, msg
);
137 if (!disp
->Initialized
) {
138 _eglError(EGL_NOT_INITIALIZED
, msg
);
145 static INLINE _EGLDriver
*
146 _eglCheckSurface(_EGLDisplay
*disp
, _EGLSurface
*surf
, const char *msg
)
148 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
152 _eglError(EGL_BAD_SURFACE
, msg
);
159 static INLINE _EGLDriver
*
160 _eglCheckContext(_EGLDisplay
*disp
, _EGLContext
*context
, const char *msg
)
162 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
166 _eglError(EGL_BAD_CONTEXT
, msg
);
173 static INLINE _EGLDriver
*
174 _eglCheckConfig(_EGLDisplay
*disp
, _EGLConfig
*conf
, const char *msg
)
176 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
180 _eglError(EGL_BAD_CONFIG
, msg
);
187 #ifdef EGL_MESA_screen_surface
190 static INLINE _EGLDriver
*
191 _eglCheckScreen(_EGLDisplay
*disp
, _EGLScreen
*scrn
, const char *msg
)
193 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
197 _eglError(EGL_BAD_SCREEN_MESA
, msg
);
204 static INLINE _EGLDriver
*
205 _eglCheckMode(_EGLDisplay
*disp
, _EGLMode
*m
, const char *msg
)
207 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
211 _eglError(EGL_BAD_MODE_MESA
, msg
);
218 #endif /* EGL_MESA_screen_surface */
222 * Lookup and lock a display.
224 static INLINE _EGLDisplay
*
225 _eglLockDisplay(EGLDisplay display
)
227 _EGLDisplay
*dpy
= _eglLookupDisplay(display
);
229 _eglLockMutex(&dpy
->Mutex
);
238 _eglUnlockDisplay(_EGLDisplay
*dpy
)
240 _eglUnlockMutex(&dpy
->Mutex
);
245 * This is typically the first EGL function that an application calls.
246 * It associates a private _EGLDisplay object to the native display.
248 EGLDisplay EGLAPIENTRY
249 eglGetDisplay(EGLNativeDisplayType nativeDisplay
)
251 _EGLDisplay
*dpy
= _eglFindDisplay(nativeDisplay
);
252 return _eglGetDisplayHandle(dpy
);
257 * This is typically the second EGL function that an application calls.
258 * Here we load/initialize the actual hardware driver.
260 EGLBoolean EGLAPIENTRY
261 eglInitialize(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
)
263 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
264 EGLint major_int
, minor_int
;
267 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
269 if (!disp
->Initialized
) {
270 _EGLDriver
*drv
= disp
->Driver
;
273 _eglPreloadDrivers();
274 drv
= _eglMatchDriver(disp
);
276 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
279 /* Initialize the particular display now */
280 if (!drv
->API
.Initialize(drv
, disp
, &major_int
, &minor_int
))
281 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
283 disp
->APImajor
= major_int
;
284 disp
->APIminor
= minor_int
;
285 snprintf(disp
->Version
, sizeof(disp
->Version
),
286 "%d.%d (%s)", major_int
, minor_int
, drv
->Name
);
288 /* limit to APIs supported by core */
289 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
292 disp
->Initialized
= EGL_TRUE
;
294 major_int
= disp
->APImajor
;
295 minor_int
= disp
->APIminor
;
298 /* Update applications version of major and minor if not NULL */
299 if ((major
!= NULL
) && (minor
!= NULL
)) {
304 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
308 EGLBoolean EGLAPIENTRY
309 eglTerminate(EGLDisplay dpy
)
311 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
314 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
316 if (disp
->Initialized
) {
317 _EGLDriver
*drv
= disp
->Driver
;
319 drv
->API
.Terminate(drv
, disp
);
320 /* do not reset disp->Driver */
321 disp
->Initialized
= EGL_FALSE
;
324 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
328 const char * EGLAPIENTRY
329 eglQueryString(EGLDisplay dpy
, EGLint name
)
331 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
335 _EGL_CHECK_DISPLAY(disp
, NULL
, drv
);
336 ret
= drv
->API
.QueryString(drv
, disp
, name
);
338 RETURN_EGL_EVAL(disp
, ret
);
342 EGLBoolean EGLAPIENTRY
343 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
344 EGLint config_size
, EGLint
*num_config
)
346 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
350 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
351 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
353 RETURN_EGL_EVAL(disp
, ret
);
357 EGLBoolean EGLAPIENTRY
358 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
359 EGLint config_size
, EGLint
*num_config
)
361 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
365 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
366 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
367 config_size
, num_config
);
369 RETURN_EGL_EVAL(disp
, ret
);
373 EGLBoolean EGLAPIENTRY
374 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
375 EGLint attribute
, EGLint
*value
)
377 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
378 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
382 _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
, drv
);
383 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
385 RETURN_EGL_EVAL(disp
, ret
);
389 EGLContext EGLAPIENTRY
390 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
391 const EGLint
*attrib_list
)
393 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
394 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
395 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
397 _EGLContext
*context
;
400 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
, drv
);
401 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
402 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
404 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
405 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
407 RETURN_EGL_EVAL(disp
, ret
);
411 EGLBoolean EGLAPIENTRY
412 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
414 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
415 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
419 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
420 _eglUnlinkContext(context
);
421 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
423 RETURN_EGL_EVAL(disp
, ret
);
427 EGLBoolean EGLAPIENTRY
428 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
431 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
432 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
433 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
434 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
439 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
442 /* display is allowed to be uninitialized under certain condition */
443 if (!disp
->Initialized
) {
444 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
445 ctx
!= EGL_NO_CONTEXT
)
446 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
449 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
451 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
452 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
453 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
454 (!read_surf
&& read
!= EGL_NO_SURFACE
))
455 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
457 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
459 RETURN_EGL_EVAL(disp
, ret
);
463 EGLBoolean EGLAPIENTRY
464 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
465 EGLint attribute
, EGLint
*value
)
467 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
468 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
472 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
473 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
475 RETURN_EGL_EVAL(disp
, ret
);
479 EGLSurface EGLAPIENTRY
480 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
481 EGLNativeWindowType window
, const EGLint
*attrib_list
)
483 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
484 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
489 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
491 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
492 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
494 RETURN_EGL_EVAL(disp
, ret
);
498 EGLSurface EGLAPIENTRY
499 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
500 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
502 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
503 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
508 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
510 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
511 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
513 RETURN_EGL_EVAL(disp
, ret
);
517 EGLSurface EGLAPIENTRY
518 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
519 const EGLint
*attrib_list
)
521 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
522 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
527 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
529 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
530 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
532 RETURN_EGL_EVAL(disp
, ret
);
536 EGLBoolean EGLAPIENTRY
537 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
539 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
540 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
544 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
545 _eglUnlinkSurface(surf
);
546 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
548 RETURN_EGL_EVAL(disp
, ret
);
551 EGLBoolean EGLAPIENTRY
552 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
553 EGLint attribute
, EGLint
*value
)
555 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
556 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
560 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
561 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
563 RETURN_EGL_EVAL(disp
, ret
);
566 EGLBoolean EGLAPIENTRY
567 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
568 EGLint attribute
, EGLint value
)
570 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
571 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
575 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
576 ret
= drv
->API
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
578 RETURN_EGL_EVAL(disp
, ret
);
582 EGLBoolean EGLAPIENTRY
583 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
585 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
586 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
590 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
591 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
593 RETURN_EGL_EVAL(disp
, ret
);
597 EGLBoolean EGLAPIENTRY
598 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
600 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
601 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
605 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
606 ret
= drv
->API
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
608 RETURN_EGL_EVAL(disp
, ret
);
612 EGLBoolean EGLAPIENTRY
613 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
615 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
616 _EGLContext
*ctx
= _eglGetCurrentContext();
621 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
623 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
624 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
626 surf
= ctx
->DrawSurface
;
627 if (!_eglIsSurfaceLinked(surf
))
628 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
630 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
632 RETURN_EGL_EVAL(disp
, ret
);
636 EGLBoolean EGLAPIENTRY
637 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
639 _EGLContext
*ctx
= _eglGetCurrentContext();
640 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
641 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
645 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
647 /* surface must be bound to current context in EGL 1.4 */
648 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
649 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
651 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
653 RETURN_EGL_EVAL(disp
, ret
);
657 EGLBoolean EGLAPIENTRY
658 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
660 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
661 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
665 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
666 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
668 RETURN_EGL_EVAL(disp
, ret
);
672 EGLBoolean EGLAPIENTRY
675 _EGLContext
*ctx
= _eglGetCurrentContext();
681 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
683 disp
= ctx
->Resource
.Display
;
684 _eglLockMutex(&disp
->Mutex
);
686 /* let bad current context imply bad current surface */
687 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
688 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
690 /* a valid current context implies an initialized current display */
691 assert(disp
->Initialized
);
693 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
695 RETURN_EGL_EVAL(disp
, ret
);
699 EGLBoolean EGLAPIENTRY
702 #ifdef EGL_VERSION_1_2
703 _EGLThreadInfo
*t
= _eglGetCurrentThread();
704 EGLint api_index
= t
->CurrentAPIIndex
;
705 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
708 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
709 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
711 t
->CurrentAPIIndex
= es_index
;
712 ret
= eglWaitClient();
713 t
->CurrentAPIIndex
= api_index
;
716 return eglWaitClient();
721 EGLBoolean EGLAPIENTRY
722 eglWaitNative(EGLint engine
)
724 _EGLContext
*ctx
= _eglGetCurrentContext();
730 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
732 disp
= ctx
->Resource
.Display
;
733 _eglLockMutex(&disp
->Mutex
);
735 /* let bad current context imply bad current surface */
736 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
737 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
739 /* a valid current context implies an initialized current display */
740 assert(disp
->Initialized
);
742 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
744 RETURN_EGL_EVAL(disp
, ret
);
748 EGLDisplay EGLAPIENTRY
749 eglGetCurrentDisplay(void)
751 _EGLContext
*ctx
= _eglGetCurrentContext();
754 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
756 RETURN_EGL_SUCCESS(NULL
, ret
);
760 EGLContext EGLAPIENTRY
761 eglGetCurrentContext(void)
763 _EGLContext
*ctx
= _eglGetCurrentContext();
766 ret
= _eglGetContextHandle(ctx
);
768 RETURN_EGL_SUCCESS(NULL
, ret
);
772 EGLSurface EGLAPIENTRY
773 eglGetCurrentSurface(EGLint readdraw
)
775 _EGLContext
*ctx
= _eglGetCurrentContext();
776 EGLint err
= EGL_SUCCESS
;
781 RETURN_EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
785 surf
= ctx
->DrawSurface
;
788 surf
= ctx
->ReadSurface
;
792 err
= EGL_BAD_PARAMETER
;
796 ret
= _eglGetSurfaceHandle(surf
);
798 RETURN_EGL_ERROR(NULL
, err
, ret
);
805 _EGLThreadInfo
*t
= _eglGetCurrentThread();
806 EGLint e
= t
->LastError
;
807 if (!_eglIsCurrentThreadDummy())
808 t
->LastError
= EGL_SUCCESS
;
813 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
814 eglGetProcAddress(const char *procname
)
816 static const struct {
819 } egl_functions
[] = {
820 /* extensions only */
821 #ifdef EGL_MESA_screen_surface
822 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
823 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
824 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
825 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
826 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
827 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
828 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
829 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
830 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
831 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
832 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
833 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
834 #endif /* EGL_MESA_screen_surface */
835 #ifdef EGL_KHR_image_base
836 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
837 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
838 #endif /* EGL_KHR_image_base */
845 RETURN_EGL_SUCCESS(NULL
, NULL
);
848 if (strncmp(procname
, "egl", 3) == 0) {
849 for (i
= 0; egl_functions
[i
].name
; i
++) {
850 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
851 ret
= egl_functions
[i
].function
;
857 RETURN_EGL_SUCCESS(NULL
, ret
);
859 _eglPreloadDrivers();
861 /* now loop over drivers to query their procs */
862 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
863 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
864 ret
= drv
->API
.GetProcAddress(drv
, procname
);
869 RETURN_EGL_SUCCESS(NULL
, ret
);
873 #ifdef EGL_MESA_screen_surface
877 * EGL_MESA_screen extension
880 EGLBoolean EGLAPIENTRY
881 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
882 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
883 EGLint modes_size
, EGLint
*num_modes
)
885 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
886 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
890 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
891 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
892 modes
, modes_size
, num_modes
);
894 RETURN_EGL_EVAL(disp
, ret
);
898 EGLBoolean EGLAPIENTRY
899 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
900 EGLint mode_size
, EGLint
*num_mode
)
902 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
903 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
907 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
908 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
910 RETURN_EGL_EVAL(disp
, ret
);
914 EGLBoolean EGLAPIENTRY
915 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
916 EGLint attribute
, EGLint
*value
)
918 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
919 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
923 _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
, drv
);
924 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
926 RETURN_EGL_EVAL(disp
, ret
);
930 EGLBoolean EGLAPIENTRY
931 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
934 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
935 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
936 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
940 _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
, drv
);
942 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
944 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
945 source_context
, dest_context
, mask
);
947 RETURN_EGL_EVAL(disp
, ret
);
952 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
953 EGLint max_screens
, EGLint
*num_screens
)
955 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
959 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
960 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
962 RETURN_EGL_EVAL(disp
, ret
);
967 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
968 const EGLint
*attrib_list
)
970 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
971 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
976 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
978 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
979 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
981 RETURN_EGL_EVAL(disp
, ret
);
986 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
987 EGLSurface surface
, EGLModeMESA mode
)
989 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
990 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
991 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
992 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
996 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
997 if (!surf
&& surface
!= EGL_NO_SURFACE
)
998 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
999 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
1000 RETURN_EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
1002 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
1004 RETURN_EGL_EVAL(disp
, ret
);
1009 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
1011 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1012 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1016 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1017 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
1019 RETURN_EGL_EVAL(disp
, ret
);
1024 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1025 EGLint attribute
, EGLint
*value
)
1027 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1028 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1032 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1033 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
1035 RETURN_EGL_EVAL(disp
, ret
);
1040 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1041 EGLSurface
*surface
)
1043 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1044 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1049 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1050 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1052 *surface
= _eglGetSurfaceHandle(surf
);
1054 RETURN_EGL_EVAL(disp
, ret
);
1059 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1061 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1062 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1067 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1068 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1072 RETURN_EGL_EVAL(disp
, ret
);
1077 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1079 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1080 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1084 _EGL_CHECK_MODE(disp
, m
, NULL
, drv
);
1085 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1087 RETURN_EGL_EVAL(disp
, ret
);
1091 #endif /* EGL_MESA_screen_surface */
1098 #ifdef EGL_VERSION_1_2
1102 * Specify the client API to use for subsequent calls including:
1103 * eglCreateContext()
1104 * eglGetCurrentContext()
1105 * eglGetCurrentDisplay()
1106 * eglGetCurrentSurface()
1107 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1110 * See section 3.7 "Rendering Context" in the EGL specification for details.
1113 eglBindAPI(EGLenum api
)
1115 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1117 if (_eglIsCurrentThreadDummy())
1118 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1120 if (!_eglIsApiValid(api
))
1121 RETURN_EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1123 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1125 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1130 * Return the last value set with eglBindAPI().
1135 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1138 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1139 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1141 RETURN_EGL_SUCCESS(NULL
, ret
);
1146 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1147 EGLClientBuffer buffer
, EGLConfig config
,
1148 const EGLint
*attrib_list
)
1150 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1151 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1156 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
1158 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1160 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1162 RETURN_EGL_EVAL(disp
, ret
);
1167 eglReleaseThread(void)
1169 /* unbind current contexts */
1170 if (!_eglIsCurrentThreadDummy()) {
1171 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1172 EGLint api_index
= t
->CurrentAPIIndex
;
1175 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1176 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1178 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1181 t
->CurrentAPIIndex
= i
;
1183 _eglLockMutex(&disp
->Mutex
);
1185 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1186 _eglUnlockMutex(&disp
->Mutex
);
1190 t
->CurrentAPIIndex
= api_index
;
1193 _eglDestroyCurrentThread();
1195 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1199 #endif /* EGL_VERSION_1_2 */
1202 #ifdef EGL_KHR_image_base
1206 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1207 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1209 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1210 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1215 _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
, drv
);
1216 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1217 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1219 img
= drv
->API
.CreateImageKHR(drv
,
1220 disp
, context
, target
, buffer
, attr_list
);
1221 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1223 RETURN_EGL_EVAL(disp
, ret
);
1228 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1230 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1231 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1235 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
1237 RETURN_EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1239 _eglUnlinkImage(img
);
1240 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1242 RETURN_EGL_EVAL(disp
, ret
);
1246 #endif /* EGL_KHR_image_base */