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
= 0, minor_int
= 0;
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
);
275 /* Initialize the particular display now */
276 if (drv
&& !drv
->API
.Initialize(drv
, disp
, &major_int
, &minor_int
))
277 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
280 /* Load and initialize the first default driver that works */
281 drv
= _eglLoadDefaultDriver(disp
, &major_int
, &minor_int
);
283 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
285 disp
->APImajor
= major_int
;
286 disp
->APIminor
= minor_int
;
287 snprintf(disp
->Version
, sizeof(disp
->Version
),
288 "%d.%d (%s)", major_int
, minor_int
, drv
->Name
);
290 /* limit to APIs supported by core */
291 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
294 disp
->Initialized
= EGL_TRUE
;
296 major_int
= disp
->APImajor
;
297 minor_int
= disp
->APIminor
;
300 /* Update applications version of major and minor if not NULL */
301 if ((major
!= NULL
) && (minor
!= NULL
)) {
306 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
310 EGLBoolean EGLAPIENTRY
311 eglTerminate(EGLDisplay dpy
)
313 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
316 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
318 if (disp
->Initialized
) {
319 _EGLDriver
*drv
= disp
->Driver
;
321 drv
->API
.Terminate(drv
, disp
);
322 /* do not reset disp->Driver */
323 disp
->Initialized
= EGL_FALSE
;
326 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
330 const char * EGLAPIENTRY
331 eglQueryString(EGLDisplay dpy
, EGLint name
)
333 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
337 _EGL_CHECK_DISPLAY(disp
, NULL
, drv
);
338 ret
= drv
->API
.QueryString(drv
, disp
, name
);
340 RETURN_EGL_EVAL(disp
, ret
);
344 EGLBoolean EGLAPIENTRY
345 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
346 EGLint config_size
, EGLint
*num_config
)
348 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
352 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
353 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
355 RETURN_EGL_EVAL(disp
, ret
);
359 EGLBoolean EGLAPIENTRY
360 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
361 EGLint config_size
, EGLint
*num_config
)
363 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
367 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
368 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
369 config_size
, num_config
);
371 RETURN_EGL_EVAL(disp
, ret
);
375 EGLBoolean EGLAPIENTRY
376 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
377 EGLint attribute
, EGLint
*value
)
379 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
380 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
384 _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
, drv
);
385 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
387 RETURN_EGL_EVAL(disp
, ret
);
391 EGLContext EGLAPIENTRY
392 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
393 const EGLint
*attrib_list
)
395 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
396 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
397 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
399 _EGLContext
*context
;
402 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
, drv
);
403 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
404 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
406 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
407 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
409 RETURN_EGL_EVAL(disp
, ret
);
413 EGLBoolean EGLAPIENTRY
414 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
416 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
417 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
421 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
422 _eglUnlinkContext(context
);
423 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
425 RETURN_EGL_EVAL(disp
, ret
);
429 EGLBoolean EGLAPIENTRY
430 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
433 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
434 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
435 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
436 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
441 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
444 /* display is allowed to be uninitialized under certain condition */
445 if (!disp
->Initialized
) {
446 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
447 ctx
!= EGL_NO_CONTEXT
)
448 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
451 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
453 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
454 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
455 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
456 (!read_surf
&& read
!= EGL_NO_SURFACE
))
457 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
459 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
461 RETURN_EGL_EVAL(disp
, ret
);
465 EGLBoolean EGLAPIENTRY
466 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
467 EGLint attribute
, EGLint
*value
)
469 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
470 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
474 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
475 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
477 RETURN_EGL_EVAL(disp
, ret
);
481 EGLSurface EGLAPIENTRY
482 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
483 EGLNativeWindowType window
, const EGLint
*attrib_list
)
485 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
486 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
491 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
493 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
494 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
496 RETURN_EGL_EVAL(disp
, ret
);
500 EGLSurface EGLAPIENTRY
501 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
502 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
504 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
505 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
510 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
512 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
513 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
515 RETURN_EGL_EVAL(disp
, ret
);
519 EGLSurface EGLAPIENTRY
520 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
521 const EGLint
*attrib_list
)
523 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
524 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
529 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
531 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
532 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
534 RETURN_EGL_EVAL(disp
, ret
);
538 EGLBoolean EGLAPIENTRY
539 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
541 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
542 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
546 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
547 _eglUnlinkSurface(surf
);
548 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
550 RETURN_EGL_EVAL(disp
, ret
);
553 EGLBoolean EGLAPIENTRY
554 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
555 EGLint attribute
, EGLint
*value
)
557 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
558 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
562 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
563 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
565 RETURN_EGL_EVAL(disp
, ret
);
568 EGLBoolean EGLAPIENTRY
569 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
570 EGLint attribute
, EGLint value
)
572 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
573 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
577 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
578 ret
= drv
->API
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
580 RETURN_EGL_EVAL(disp
, ret
);
584 EGLBoolean EGLAPIENTRY
585 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
587 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
588 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
592 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
593 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
595 RETURN_EGL_EVAL(disp
, ret
);
599 EGLBoolean EGLAPIENTRY
600 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
602 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
603 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
607 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
608 ret
= drv
->API
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
610 RETURN_EGL_EVAL(disp
, ret
);
614 EGLBoolean EGLAPIENTRY
615 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
617 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
618 _EGLContext
*ctx
= _eglGetCurrentContext();
623 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
625 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
626 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
628 surf
= ctx
->DrawSurface
;
629 if (!_eglIsSurfaceLinked(surf
))
630 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
632 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
634 RETURN_EGL_EVAL(disp
, ret
);
638 EGLBoolean EGLAPIENTRY
639 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
641 _EGLContext
*ctx
= _eglGetCurrentContext();
642 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
643 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
647 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
649 /* surface must be bound to current context in EGL 1.4 */
650 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
651 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
653 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
655 RETURN_EGL_EVAL(disp
, ret
);
659 EGLBoolean EGLAPIENTRY
660 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
662 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
663 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
667 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
668 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
670 RETURN_EGL_EVAL(disp
, ret
);
674 EGLBoolean EGLAPIENTRY
677 _EGLContext
*ctx
= _eglGetCurrentContext();
683 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
685 disp
= ctx
->Resource
.Display
;
686 _eglLockMutex(&disp
->Mutex
);
688 /* let bad current context imply bad current surface */
689 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
690 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
692 /* a valid current context implies an initialized current display */
693 assert(disp
->Initialized
);
695 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
697 RETURN_EGL_EVAL(disp
, ret
);
701 EGLBoolean EGLAPIENTRY
704 #ifdef EGL_VERSION_1_2
705 _EGLThreadInfo
*t
= _eglGetCurrentThread();
706 EGLint api_index
= t
->CurrentAPIIndex
;
707 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
710 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
711 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
713 t
->CurrentAPIIndex
= es_index
;
714 ret
= eglWaitClient();
715 t
->CurrentAPIIndex
= api_index
;
718 return eglWaitClient();
723 EGLBoolean EGLAPIENTRY
724 eglWaitNative(EGLint engine
)
726 _EGLContext
*ctx
= _eglGetCurrentContext();
732 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
734 disp
= ctx
->Resource
.Display
;
735 _eglLockMutex(&disp
->Mutex
);
737 /* let bad current context imply bad current surface */
738 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
739 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
741 /* a valid current context implies an initialized current display */
742 assert(disp
->Initialized
);
744 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
746 RETURN_EGL_EVAL(disp
, ret
);
750 EGLDisplay EGLAPIENTRY
751 eglGetCurrentDisplay(void)
753 _EGLContext
*ctx
= _eglGetCurrentContext();
756 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
758 RETURN_EGL_SUCCESS(NULL
, ret
);
762 EGLContext EGLAPIENTRY
763 eglGetCurrentContext(void)
765 _EGLContext
*ctx
= _eglGetCurrentContext();
768 ret
= _eglGetContextHandle(ctx
);
770 RETURN_EGL_SUCCESS(NULL
, ret
);
774 EGLSurface EGLAPIENTRY
775 eglGetCurrentSurface(EGLint readdraw
)
777 _EGLContext
*ctx
= _eglGetCurrentContext();
778 EGLint err
= EGL_SUCCESS
;
783 RETURN_EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
787 surf
= ctx
->DrawSurface
;
790 surf
= ctx
->ReadSurface
;
794 err
= EGL_BAD_PARAMETER
;
798 ret
= _eglGetSurfaceHandle(surf
);
800 RETURN_EGL_ERROR(NULL
, err
, ret
);
807 _EGLThreadInfo
*t
= _eglGetCurrentThread();
808 EGLint e
= t
->LastError
;
809 if (!_eglIsCurrentThreadDummy())
810 t
->LastError
= EGL_SUCCESS
;
815 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
816 eglGetProcAddress(const char *procname
)
818 static const struct {
821 } egl_functions
[] = {
822 /* extensions only */
823 #ifdef EGL_MESA_screen_surface
824 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
825 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
826 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
827 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
828 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
829 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
830 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
831 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
832 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
833 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
834 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
835 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
836 #endif /* EGL_MESA_screen_surface */
837 #ifdef EGL_KHR_image_base
838 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
839 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
840 #endif /* EGL_KHR_image_base */
841 #ifdef EGL_NOK_swap_region
842 { "eglSwapBuffersRegionNOK", (_EGLProc
) eglSwapBuffersRegionNOK
},
850 RETURN_EGL_SUCCESS(NULL
, NULL
);
853 if (strncmp(procname
, "egl", 3) == 0) {
854 for (i
= 0; egl_functions
[i
].name
; i
++) {
855 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
856 ret
= egl_functions
[i
].function
;
862 RETURN_EGL_SUCCESS(NULL
, ret
);
864 _eglPreloadDrivers();
866 /* now loop over drivers to query their procs */
867 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
868 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
869 ret
= drv
->API
.GetProcAddress(drv
, procname
);
874 RETURN_EGL_SUCCESS(NULL
, ret
);
878 #ifdef EGL_MESA_screen_surface
882 * EGL_MESA_screen extension
885 EGLBoolean EGLAPIENTRY
886 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
887 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
888 EGLint modes_size
, EGLint
*num_modes
)
890 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
891 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
895 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
896 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
897 modes
, modes_size
, num_modes
);
899 RETURN_EGL_EVAL(disp
, ret
);
903 EGLBoolean EGLAPIENTRY
904 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
905 EGLint mode_size
, EGLint
*num_mode
)
907 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
908 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
912 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
913 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
915 RETURN_EGL_EVAL(disp
, ret
);
919 EGLBoolean EGLAPIENTRY
920 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
921 EGLint attribute
, EGLint
*value
)
923 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
924 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
928 _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
, drv
);
929 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
931 RETURN_EGL_EVAL(disp
, ret
);
935 EGLBoolean EGLAPIENTRY
936 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
939 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
940 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
941 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
945 _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
, drv
);
947 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
949 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
950 source_context
, dest_context
, mask
);
952 RETURN_EGL_EVAL(disp
, ret
);
957 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
958 EGLint max_screens
, EGLint
*num_screens
)
960 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
964 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
965 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
967 RETURN_EGL_EVAL(disp
, ret
);
972 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
973 const EGLint
*attrib_list
)
975 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
976 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
981 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
983 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
984 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
986 RETURN_EGL_EVAL(disp
, ret
);
991 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
992 EGLSurface surface
, EGLModeMESA mode
)
994 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
995 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
996 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
997 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1001 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1002 if (!surf
&& surface
!= EGL_NO_SURFACE
)
1003 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1004 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
1005 RETURN_EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
1007 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
1009 RETURN_EGL_EVAL(disp
, ret
);
1014 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
1016 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1017 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1021 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1022 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
1024 RETURN_EGL_EVAL(disp
, ret
);
1029 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1030 EGLint attribute
, EGLint
*value
)
1032 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1033 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1037 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1038 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
1040 RETURN_EGL_EVAL(disp
, ret
);
1045 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1046 EGLSurface
*surface
)
1048 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1049 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1054 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1055 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1057 *surface
= _eglGetSurfaceHandle(surf
);
1059 RETURN_EGL_EVAL(disp
, ret
);
1064 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1066 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1067 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1072 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1073 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1077 RETURN_EGL_EVAL(disp
, ret
);
1082 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1084 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1085 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1089 _EGL_CHECK_MODE(disp
, m
, NULL
, drv
);
1090 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1092 RETURN_EGL_EVAL(disp
, ret
);
1096 #endif /* EGL_MESA_screen_surface */
1103 #ifdef EGL_VERSION_1_2
1107 * Specify the client API to use for subsequent calls including:
1108 * eglCreateContext()
1109 * eglGetCurrentContext()
1110 * eglGetCurrentDisplay()
1111 * eglGetCurrentSurface()
1112 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1115 * See section 3.7 "Rendering Context" in the EGL specification for details.
1118 eglBindAPI(EGLenum api
)
1120 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1122 if (_eglIsCurrentThreadDummy())
1123 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1125 if (!_eglIsApiValid(api
))
1126 RETURN_EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1128 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1130 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1135 * Return the last value set with eglBindAPI().
1140 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1143 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1144 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1146 RETURN_EGL_SUCCESS(NULL
, ret
);
1151 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1152 EGLClientBuffer buffer
, EGLConfig config
,
1153 const EGLint
*attrib_list
)
1155 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1156 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1161 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
1163 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1165 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1167 RETURN_EGL_EVAL(disp
, ret
);
1172 eglReleaseThread(void)
1174 /* unbind current contexts */
1175 if (!_eglIsCurrentThreadDummy()) {
1176 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1177 EGLint api_index
= t
->CurrentAPIIndex
;
1180 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1181 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1183 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1186 t
->CurrentAPIIndex
= i
;
1188 _eglLockMutex(&disp
->Mutex
);
1190 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1191 _eglUnlockMutex(&disp
->Mutex
);
1195 t
->CurrentAPIIndex
= api_index
;
1198 _eglDestroyCurrentThread();
1200 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1204 #endif /* EGL_VERSION_1_2 */
1207 #ifdef EGL_KHR_image_base
1211 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1212 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1214 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1215 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1220 _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
, drv
);
1221 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1222 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1224 img
= drv
->API
.CreateImageKHR(drv
,
1225 disp
, context
, target
, buffer
, attr_list
);
1226 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1228 RETURN_EGL_EVAL(disp
, ret
);
1233 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1235 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1236 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1240 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
1242 RETURN_EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1244 _eglUnlinkImage(img
);
1245 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1247 RETURN_EGL_EVAL(disp
, ret
);
1251 #endif /* EGL_KHR_image_base */
1254 #ifdef EGL_NOK_swap_region
1257 eglSwapBuffersRegionNOK(EGLDisplay dpy
, EGLSurface surface
,
1258 EGLint numRects
, const EGLint
*rects
)
1260 _EGLContext
*ctx
= _eglGetCurrentContext();
1261 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1262 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
1266 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
1268 /* surface must be bound to current context in EGL 1.4 */
1269 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
1270 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1272 if (drv
->API
.SwapBuffersRegionNOK
)
1273 ret
= drv
->API
.SwapBuffersRegionNOK(drv
, disp
, surf
, numRects
, rects
);
1275 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
1277 RETURN_EGL_EVAL(disp
, ret
);
1280 #endif /* EGL_NOK_swap_region */