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
60 #include "eglstring.h"
61 #include "eglcontext.h"
62 #include "egldisplay.h"
63 #include "egltypedefs.h"
64 #include "eglglobals.h"
65 #include "eglcurrent.h"
66 #include "egldriver.h"
67 #include "eglsurface.h"
68 #include "eglconfig.h"
69 #include "eglscreen.h"
75 * Macros to help return an API entrypoint.
77 * These macros will unlock the display and record the error code.
79 #define RETURN_EGL_ERROR(disp, err, ret) \
82 _eglUnlockDisplay(disp); \
83 /* EGL error codes are non-zero */ \
85 _eglError(err, __FUNCTION__); \
89 #define RETURN_EGL_SUCCESS(disp, ret) \
90 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
92 /* record EGL_SUCCESS only when ret evaluates to true */
93 #define RETURN_EGL_EVAL(disp, ret) \
94 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
98 * A bunch of macros and checks to simplify error checking.
101 #define _EGL_CHECK_DISPLAY(disp, ret, drv) \
103 drv = _eglCheckDisplay(disp, __FUNCTION__); \
105 RETURN_EGL_ERROR(disp, 0, ret); \
108 #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
110 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \
112 RETURN_EGL_ERROR(disp, 0, ret); \
115 #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
116 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
118 #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
119 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
121 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
122 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
124 #define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
125 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
127 #define _EGL_CHECK_MODE(disp, m, ret, drv) \
128 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
132 static INLINE _EGLDriver
*
133 _eglCheckDisplay(_EGLDisplay
*disp
, const char *msg
)
136 _eglError(EGL_BAD_DISPLAY
, msg
);
139 if (!disp
->Initialized
) {
140 _eglError(EGL_NOT_INITIALIZED
, msg
);
147 static INLINE _EGLDriver
*
148 _eglCheckSurface(_EGLDisplay
*disp
, _EGLSurface
*surf
, const char *msg
)
150 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
154 _eglError(EGL_BAD_SURFACE
, msg
);
161 static INLINE _EGLDriver
*
162 _eglCheckContext(_EGLDisplay
*disp
, _EGLContext
*context
, const char *msg
)
164 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
168 _eglError(EGL_BAD_CONTEXT
, msg
);
175 static INLINE _EGLDriver
*
176 _eglCheckConfig(_EGLDisplay
*disp
, _EGLConfig
*conf
, const char *msg
)
178 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
182 _eglError(EGL_BAD_CONFIG
, msg
);
189 #ifdef EGL_MESA_screen_surface
192 static INLINE _EGLDriver
*
193 _eglCheckScreen(_EGLDisplay
*disp
, _EGLScreen
*scrn
, const char *msg
)
195 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
199 _eglError(EGL_BAD_SCREEN_MESA
, msg
);
206 static INLINE _EGLDriver
*
207 _eglCheckMode(_EGLDisplay
*disp
, _EGLMode
*m
, const char *msg
)
209 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
213 _eglError(EGL_BAD_MODE_MESA
, msg
);
220 #endif /* EGL_MESA_screen_surface */
224 * Lookup and lock a display.
226 static INLINE _EGLDisplay
*
227 _eglLockDisplay(EGLDisplay display
)
229 _EGLDisplay
*dpy
= _eglLookupDisplay(display
);
231 _eglLockMutex(&dpy
->Mutex
);
240 _eglUnlockDisplay(_EGLDisplay
*dpy
)
242 _eglUnlockMutex(&dpy
->Mutex
);
247 * This is typically the first EGL function that an application calls.
248 * It associates a private _EGLDisplay object to the native display.
250 EGLDisplay EGLAPIENTRY
251 eglGetDisplay(EGLNativeDisplayType nativeDisplay
)
253 _EGLPlatformType plat
= _eglGetNativePlatform();
254 _EGLDisplay
*dpy
= _eglFindDisplay(plat
, (void *) nativeDisplay
);
255 return _eglGetDisplayHandle(dpy
);
260 * This is typically the second EGL function that an application calls.
261 * Here we load/initialize the actual hardware driver.
263 EGLBoolean EGLAPIENTRY
264 eglInitialize(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
)
266 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
267 EGLint major_int
= 0, minor_int
= 0;
270 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
272 if (!disp
->Initialized
) {
273 _EGLDriver
*drv
= disp
->Driver
;
276 _eglPreloadDrivers();
277 drv
= _eglMatchDriver(disp
);
278 /* Initialize the particular display now */
279 if (drv
&& !drv
->API
.Initialize(drv
, disp
, &major_int
, &minor_int
))
280 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
283 /* Load and initialize the first default driver that works */
284 drv
= _eglLoadDefaultDriver(disp
, &major_int
, &minor_int
);
286 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
288 disp
->APImajor
= major_int
;
289 disp
->APIminor
= minor_int
;
290 _eglsnprintf(disp
->Version
, sizeof(disp
->Version
),
291 "%d.%d (%s)", major_int
, minor_int
, drv
->Name
);
293 /* limit to APIs supported by core */
294 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
297 disp
->Initialized
= EGL_TRUE
;
299 major_int
= disp
->APImajor
;
300 minor_int
= disp
->APIminor
;
303 /* Update applications version of major and minor if not NULL */
304 if ((major
!= NULL
) && (minor
!= NULL
)) {
309 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
313 EGLBoolean EGLAPIENTRY
314 eglTerminate(EGLDisplay dpy
)
316 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
319 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
321 if (disp
->Initialized
) {
322 _EGLDriver
*drv
= disp
->Driver
;
324 drv
->API
.Terminate(drv
, disp
);
325 /* do not reset disp->Driver */
326 disp
->Initialized
= EGL_FALSE
;
329 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
333 const char * EGLAPIENTRY
334 eglQueryString(EGLDisplay dpy
, EGLint name
)
336 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
340 _EGL_CHECK_DISPLAY(disp
, NULL
, drv
);
341 ret
= drv
->API
.QueryString(drv
, disp
, name
);
343 RETURN_EGL_EVAL(disp
, ret
);
347 EGLBoolean EGLAPIENTRY
348 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
349 EGLint config_size
, EGLint
*num_config
)
351 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
355 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
356 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
358 RETURN_EGL_EVAL(disp
, ret
);
362 EGLBoolean EGLAPIENTRY
363 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
364 EGLint config_size
, EGLint
*num_config
)
366 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
370 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
371 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
372 config_size
, num_config
);
374 RETURN_EGL_EVAL(disp
, ret
);
378 EGLBoolean EGLAPIENTRY
379 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
380 EGLint attribute
, EGLint
*value
)
382 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
383 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
387 _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
, drv
);
388 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
390 RETURN_EGL_EVAL(disp
, ret
);
394 EGLContext EGLAPIENTRY
395 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
396 const EGLint
*attrib_list
)
398 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
399 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
400 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
402 _EGLContext
*context
;
405 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
, drv
);
406 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
407 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
409 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
410 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
412 RETURN_EGL_EVAL(disp
, ret
);
416 EGLBoolean EGLAPIENTRY
417 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
419 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
420 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
424 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
425 _eglUnlinkContext(context
);
426 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
428 RETURN_EGL_EVAL(disp
, ret
);
432 EGLBoolean EGLAPIENTRY
433 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
436 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
437 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
438 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
439 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
444 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
447 /* display is allowed to be uninitialized under certain condition */
448 if (!disp
->Initialized
) {
449 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
450 ctx
!= EGL_NO_CONTEXT
)
451 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
454 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
456 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
457 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
458 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
459 (!read_surf
&& read
!= EGL_NO_SURFACE
))
460 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
462 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
464 RETURN_EGL_EVAL(disp
, ret
);
468 EGLBoolean EGLAPIENTRY
469 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
470 EGLint attribute
, EGLint
*value
)
472 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
473 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
477 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
478 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
480 RETURN_EGL_EVAL(disp
, ret
);
484 EGLSurface EGLAPIENTRY
485 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
486 EGLNativeWindowType window
, const EGLint
*attrib_list
)
488 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
489 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
494 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
495 if (disp
->Platform
!= _eglGetNativePlatform())
496 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_WINDOW
, EGL_NO_SURFACE
);
498 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
499 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
501 RETURN_EGL_EVAL(disp
, ret
);
505 EGLSurface EGLAPIENTRY
506 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
507 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
509 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
510 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
515 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
516 if (disp
->Platform
!= _eglGetNativePlatform())
517 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_PIXMAP
, EGL_NO_SURFACE
);
519 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
520 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
522 RETURN_EGL_EVAL(disp
, ret
);
526 EGLSurface EGLAPIENTRY
527 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
528 const EGLint
*attrib_list
)
530 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
531 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
536 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
538 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
539 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
541 RETURN_EGL_EVAL(disp
, ret
);
545 EGLBoolean EGLAPIENTRY
546 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
548 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
549 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
553 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
554 _eglUnlinkSurface(surf
);
555 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
557 RETURN_EGL_EVAL(disp
, ret
);
560 EGLBoolean EGLAPIENTRY
561 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
562 EGLint attribute
, EGLint
*value
)
564 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
565 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
569 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
570 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
572 RETURN_EGL_EVAL(disp
, ret
);
575 EGLBoolean EGLAPIENTRY
576 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
577 EGLint attribute
, EGLint value
)
579 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
580 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
584 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
585 ret
= drv
->API
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
587 RETURN_EGL_EVAL(disp
, ret
);
591 EGLBoolean EGLAPIENTRY
592 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
594 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
595 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
599 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
600 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
602 RETURN_EGL_EVAL(disp
, ret
);
606 EGLBoolean EGLAPIENTRY
607 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
609 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
610 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
614 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
615 ret
= drv
->API
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
617 RETURN_EGL_EVAL(disp
, ret
);
621 EGLBoolean EGLAPIENTRY
622 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
624 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
625 _EGLContext
*ctx
= _eglGetCurrentContext();
630 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
632 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
633 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
635 surf
= ctx
->DrawSurface
;
636 if (!_eglIsSurfaceLinked(surf
))
637 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
639 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
641 RETURN_EGL_EVAL(disp
, ret
);
645 EGLBoolean EGLAPIENTRY
646 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
648 _EGLContext
*ctx
= _eglGetCurrentContext();
649 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
650 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
654 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
656 /* surface must be bound to current context in EGL 1.4 */
657 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
658 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
660 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
662 RETURN_EGL_EVAL(disp
, ret
);
666 EGLBoolean EGLAPIENTRY
667 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
669 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
670 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
674 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
675 if (disp
->Platform
!= _eglGetNativePlatform())
676 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_PIXMAP
, EGL_FALSE
);
677 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
679 RETURN_EGL_EVAL(disp
, ret
);
683 EGLBoolean EGLAPIENTRY
686 _EGLContext
*ctx
= _eglGetCurrentContext();
692 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
694 disp
= ctx
->Resource
.Display
;
695 _eglLockMutex(&disp
->Mutex
);
697 /* let bad current context imply bad current surface */
698 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
699 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
701 /* a valid current context implies an initialized current display */
702 assert(disp
->Initialized
);
704 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
706 RETURN_EGL_EVAL(disp
, ret
);
710 EGLBoolean EGLAPIENTRY
713 #ifdef EGL_VERSION_1_2
714 _EGLThreadInfo
*t
= _eglGetCurrentThread();
715 EGLint api_index
= t
->CurrentAPIIndex
;
716 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
719 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
720 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
722 t
->CurrentAPIIndex
= es_index
;
723 ret
= eglWaitClient();
724 t
->CurrentAPIIndex
= api_index
;
727 return eglWaitClient();
732 EGLBoolean EGLAPIENTRY
733 eglWaitNative(EGLint engine
)
735 _EGLContext
*ctx
= _eglGetCurrentContext();
741 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
743 disp
= ctx
->Resource
.Display
;
744 _eglLockMutex(&disp
->Mutex
);
746 /* let bad current context imply bad current surface */
747 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
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
);
753 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
755 RETURN_EGL_EVAL(disp
, ret
);
759 EGLDisplay EGLAPIENTRY
760 eglGetCurrentDisplay(void)
762 _EGLContext
*ctx
= _eglGetCurrentContext();
765 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
767 RETURN_EGL_SUCCESS(NULL
, ret
);
771 EGLContext EGLAPIENTRY
772 eglGetCurrentContext(void)
774 _EGLContext
*ctx
= _eglGetCurrentContext();
777 ret
= _eglGetContextHandle(ctx
);
779 RETURN_EGL_SUCCESS(NULL
, ret
);
783 EGLSurface EGLAPIENTRY
784 eglGetCurrentSurface(EGLint readdraw
)
786 _EGLContext
*ctx
= _eglGetCurrentContext();
787 EGLint err
= EGL_SUCCESS
;
792 RETURN_EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
796 surf
= ctx
->DrawSurface
;
799 surf
= ctx
->ReadSurface
;
803 err
= EGL_BAD_PARAMETER
;
807 ret
= _eglGetSurfaceHandle(surf
);
809 RETURN_EGL_ERROR(NULL
, err
, ret
);
816 _EGLThreadInfo
*t
= _eglGetCurrentThread();
817 EGLint e
= t
->LastError
;
818 if (!_eglIsCurrentThreadDummy())
819 t
->LastError
= EGL_SUCCESS
;
824 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
825 eglGetProcAddress(const char *procname
)
827 static const struct {
830 } egl_functions
[] = {
831 /* extensions only */
832 #ifdef EGL_MESA_screen_surface
833 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
834 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
835 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
836 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
837 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
838 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
839 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
840 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
841 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
842 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
843 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
844 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
845 #endif /* EGL_MESA_screen_surface */
846 #ifdef EGL_MESA_drm_display
847 { "eglGetDRMDisplayMESA", (_EGLProc
) eglGetDRMDisplayMESA
},
849 #ifdef EGL_KHR_image_base
850 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
851 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
852 #endif /* EGL_KHR_image_base */
853 #ifdef EGL_NOK_swap_region
854 { "eglSwapBuffersRegionNOK", (_EGLProc
) eglSwapBuffersRegionNOK
},
862 RETURN_EGL_SUCCESS(NULL
, NULL
);
865 if (strncmp(procname
, "egl", 3) == 0) {
866 for (i
= 0; egl_functions
[i
].name
; i
++) {
867 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
868 ret
= egl_functions
[i
].function
;
874 RETURN_EGL_SUCCESS(NULL
, ret
);
876 _eglPreloadDrivers();
878 /* now loop over drivers to query their procs */
879 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
880 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
881 ret
= drv
->API
.GetProcAddress(drv
, procname
);
886 RETURN_EGL_SUCCESS(NULL
, ret
);
890 #ifdef EGL_MESA_screen_surface
894 * EGL_MESA_screen extension
897 EGLBoolean EGLAPIENTRY
898 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
899 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
900 EGLint modes_size
, EGLint
*num_modes
)
902 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
903 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
907 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
908 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
909 modes
, modes_size
, num_modes
);
911 RETURN_EGL_EVAL(disp
, ret
);
915 EGLBoolean EGLAPIENTRY
916 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
917 EGLint mode_size
, EGLint
*num_mode
)
919 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
920 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
924 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
925 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
927 RETURN_EGL_EVAL(disp
, ret
);
931 EGLBoolean EGLAPIENTRY
932 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
933 EGLint attribute
, EGLint
*value
)
935 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
936 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
940 _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
, drv
);
941 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
943 RETURN_EGL_EVAL(disp
, ret
);
947 EGLBoolean EGLAPIENTRY
948 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
951 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
952 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
953 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
957 _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
, drv
);
959 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
961 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
962 source_context
, dest_context
, mask
);
964 RETURN_EGL_EVAL(disp
, ret
);
969 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
970 EGLint max_screens
, EGLint
*num_screens
)
972 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
976 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
977 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
979 RETURN_EGL_EVAL(disp
, ret
);
984 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
985 const EGLint
*attrib_list
)
987 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
988 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
993 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
995 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
996 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
998 RETURN_EGL_EVAL(disp
, ret
);
1003 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
1004 EGLSurface surface
, EGLModeMESA mode
)
1006 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1007 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1008 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
1009 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1013 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1014 if (!surf
&& surface
!= EGL_NO_SURFACE
)
1015 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1016 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
1017 RETURN_EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
1019 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
1021 RETURN_EGL_EVAL(disp
, ret
);
1026 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
1028 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1029 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1033 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1034 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
1036 RETURN_EGL_EVAL(disp
, ret
);
1041 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1042 EGLint attribute
, EGLint
*value
)
1044 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1045 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1049 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1050 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
1052 RETURN_EGL_EVAL(disp
, ret
);
1057 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1058 EGLSurface
*surface
)
1060 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1061 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1066 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1067 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1069 *surface
= _eglGetSurfaceHandle(surf
);
1071 RETURN_EGL_EVAL(disp
, ret
);
1076 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1078 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1079 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1084 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1085 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1089 RETURN_EGL_EVAL(disp
, ret
);
1094 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1096 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1097 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1101 _EGL_CHECK_MODE(disp
, m
, NULL
, drv
);
1102 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1104 RETURN_EGL_EVAL(disp
, ret
);
1108 #endif /* EGL_MESA_screen_surface */
1111 #ifdef EGL_MESA_drm_display
1113 EGLDisplay EGLAPIENTRY
1114 eglGetDRMDisplayMESA(int fd
)
1116 _EGLDisplay
*dpy
= _eglFindDisplay(_EGL_PLATFORM_DRM
, (void *) fd
);
1117 return _eglGetDisplayHandle(dpy
);
1120 #endif /* EGL_MESA_drm_display */
1126 #ifdef EGL_VERSION_1_2
1130 * Specify the client API to use for subsequent calls including:
1131 * eglCreateContext()
1132 * eglGetCurrentContext()
1133 * eglGetCurrentDisplay()
1134 * eglGetCurrentSurface()
1135 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1138 * See section 3.7 "Rendering Context" in the EGL specification for details.
1141 eglBindAPI(EGLenum api
)
1143 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1145 if (_eglIsCurrentThreadDummy())
1146 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1148 if (!_eglIsApiValid(api
))
1149 RETURN_EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1151 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1153 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1158 * Return the last value set with eglBindAPI().
1163 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1166 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1167 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1169 RETURN_EGL_SUCCESS(NULL
, ret
);
1174 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1175 EGLClientBuffer buffer
, EGLConfig config
,
1176 const EGLint
*attrib_list
)
1178 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1179 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1184 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
1186 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1188 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1190 RETURN_EGL_EVAL(disp
, ret
);
1195 eglReleaseThread(void)
1197 /* unbind current contexts */
1198 if (!_eglIsCurrentThreadDummy()) {
1199 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1200 EGLint api_index
= t
->CurrentAPIIndex
;
1203 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1204 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1206 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1209 t
->CurrentAPIIndex
= i
;
1211 _eglLockMutex(&disp
->Mutex
);
1213 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1214 _eglUnlockMutex(&disp
->Mutex
);
1218 t
->CurrentAPIIndex
= api_index
;
1221 _eglDestroyCurrentThread();
1223 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1227 #endif /* EGL_VERSION_1_2 */
1230 #ifdef EGL_KHR_image_base
1234 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1235 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1237 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1238 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1243 _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
, drv
);
1244 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1245 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1247 img
= drv
->API
.CreateImageKHR(drv
,
1248 disp
, context
, target
, buffer
, attr_list
);
1249 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1251 RETURN_EGL_EVAL(disp
, ret
);
1256 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1258 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1259 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1263 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
1265 RETURN_EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1267 _eglUnlinkImage(img
);
1268 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1270 RETURN_EGL_EVAL(disp
, ret
);
1274 #endif /* EGL_KHR_image_base */
1277 #ifdef EGL_NOK_swap_region
1280 eglSwapBuffersRegionNOK(EGLDisplay dpy
, EGLSurface surface
,
1281 EGLint numRects
, const EGLint
*rects
)
1283 _EGLContext
*ctx
= _eglGetCurrentContext();
1284 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1285 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
1289 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
1291 /* surface must be bound to current context in EGL 1.4 */
1292 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
1293 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1295 if (drv
->API
.SwapBuffersRegionNOK
)
1296 ret
= drv
->API
.SwapBuffersRegionNOK(drv
, disp
, surf
, numRects
, rects
);
1298 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
1300 RETURN_EGL_EVAL(disp
, ret
);
1303 #endif /* EGL_NOK_swap_region */