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
);
269 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
271 if (!disp
->Initialized
) {
272 if (!_eglMatchDriver(disp
, EGL_FALSE
))
273 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
275 _eglsnprintf(disp
->Version
, sizeof(disp
->Version
), "%d.%d (%s)",
276 disp
->APImajor
, disp
->APIminor
, disp
->Driver
->Name
);
277 /* limit to APIs supported by core */
278 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
281 /* Update applications version of major and minor if not NULL */
282 if ((major
!= NULL
) && (minor
!= NULL
)) {
283 *major
= disp
->APImajor
;
284 *minor
= disp
->APIminor
;
287 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
291 EGLBoolean EGLAPIENTRY
292 eglTerminate(EGLDisplay dpy
)
294 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
297 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
299 if (disp
->Initialized
) {
300 _EGLDriver
*drv
= disp
->Driver
;
302 drv
->API
.Terminate(drv
, disp
);
303 /* do not reset disp->Driver */
304 disp
->Initialized
= EGL_FALSE
;
307 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
311 const char * EGLAPIENTRY
312 eglQueryString(EGLDisplay dpy
, EGLint name
)
314 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
318 _EGL_CHECK_DISPLAY(disp
, NULL
, drv
);
319 ret
= drv
->API
.QueryString(drv
, disp
, name
);
321 RETURN_EGL_EVAL(disp
, ret
);
325 EGLBoolean EGLAPIENTRY
326 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
327 EGLint config_size
, EGLint
*num_config
)
329 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
333 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
334 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
336 RETURN_EGL_EVAL(disp
, ret
);
340 EGLBoolean EGLAPIENTRY
341 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
342 EGLint config_size
, EGLint
*num_config
)
344 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
348 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
349 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
350 config_size
, num_config
);
352 RETURN_EGL_EVAL(disp
, ret
);
356 EGLBoolean EGLAPIENTRY
357 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
358 EGLint attribute
, EGLint
*value
)
360 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
361 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
365 _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
, drv
);
366 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
368 RETURN_EGL_EVAL(disp
, ret
);
372 EGLContext EGLAPIENTRY
373 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
374 const EGLint
*attrib_list
)
376 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
377 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
378 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
380 _EGLContext
*context
;
383 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
, drv
);
384 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
385 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
387 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
388 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
390 RETURN_EGL_EVAL(disp
, ret
);
394 EGLBoolean EGLAPIENTRY
395 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
397 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
398 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
402 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
403 _eglUnlinkContext(context
);
404 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
406 RETURN_EGL_EVAL(disp
, ret
);
410 EGLBoolean EGLAPIENTRY
411 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
414 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
415 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
416 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
417 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
422 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
425 /* display is allowed to be uninitialized under certain condition */
426 if (!disp
->Initialized
) {
427 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
428 ctx
!= EGL_NO_CONTEXT
)
429 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
432 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
434 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
435 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
436 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
437 (!read_surf
&& read
!= EGL_NO_SURFACE
))
438 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
440 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
442 RETURN_EGL_EVAL(disp
, ret
);
446 EGLBoolean EGLAPIENTRY
447 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
448 EGLint attribute
, EGLint
*value
)
450 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
451 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
455 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
456 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
458 RETURN_EGL_EVAL(disp
, ret
);
462 EGLSurface EGLAPIENTRY
463 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
464 EGLNativeWindowType window
, const EGLint
*attrib_list
)
466 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
467 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
472 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
473 if (disp
->Platform
!= _eglGetNativePlatform())
474 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_WINDOW
, EGL_NO_SURFACE
);
476 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
477 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
479 RETURN_EGL_EVAL(disp
, ret
);
483 EGLSurface EGLAPIENTRY
484 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
485 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
487 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
488 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
493 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
494 if (disp
->Platform
!= _eglGetNativePlatform())
495 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_PIXMAP
, EGL_NO_SURFACE
);
497 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
498 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
500 RETURN_EGL_EVAL(disp
, ret
);
504 EGLSurface EGLAPIENTRY
505 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
506 const EGLint
*attrib_list
)
508 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
509 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
514 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
516 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
517 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
519 RETURN_EGL_EVAL(disp
, ret
);
523 EGLBoolean EGLAPIENTRY
524 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
526 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
527 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
531 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
532 _eglUnlinkSurface(surf
);
533 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
535 RETURN_EGL_EVAL(disp
, ret
);
538 EGLBoolean EGLAPIENTRY
539 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
540 EGLint attribute
, EGLint
*value
)
542 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
543 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
547 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
548 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
550 RETURN_EGL_EVAL(disp
, ret
);
553 EGLBoolean EGLAPIENTRY
554 eglSurfaceAttrib(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
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
565 RETURN_EGL_EVAL(disp
, ret
);
569 EGLBoolean EGLAPIENTRY
570 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
572 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
573 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
577 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
578 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
580 RETURN_EGL_EVAL(disp
, ret
);
584 EGLBoolean EGLAPIENTRY
585 eglReleaseTexImage(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
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
595 RETURN_EGL_EVAL(disp
, ret
);
599 EGLBoolean EGLAPIENTRY
600 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
602 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
603 _EGLContext
*ctx
= _eglGetCurrentContext();
608 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
610 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
611 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
613 surf
= ctx
->DrawSurface
;
614 if (!_eglIsSurfaceLinked(surf
))
615 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
617 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
619 RETURN_EGL_EVAL(disp
, ret
);
623 EGLBoolean EGLAPIENTRY
624 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
626 _EGLContext
*ctx
= _eglGetCurrentContext();
627 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
628 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
632 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
634 /* surface must be bound to current context in EGL 1.4 */
635 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
636 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
638 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
640 RETURN_EGL_EVAL(disp
, ret
);
644 EGLBoolean EGLAPIENTRY
645 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
647 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
648 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
652 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
653 if (disp
->Platform
!= _eglGetNativePlatform())
654 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_PIXMAP
, EGL_FALSE
);
655 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
657 RETURN_EGL_EVAL(disp
, ret
);
661 EGLBoolean EGLAPIENTRY
664 _EGLContext
*ctx
= _eglGetCurrentContext();
670 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
672 disp
= ctx
->Resource
.Display
;
673 _eglLockMutex(&disp
->Mutex
);
675 /* let bad current context imply bad current surface */
676 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
677 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
679 /* a valid current context implies an initialized current display */
680 assert(disp
->Initialized
);
682 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
684 RETURN_EGL_EVAL(disp
, ret
);
688 EGLBoolean EGLAPIENTRY
691 #ifdef EGL_VERSION_1_2
692 _EGLThreadInfo
*t
= _eglGetCurrentThread();
693 EGLint api_index
= t
->CurrentAPIIndex
;
694 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
697 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
698 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
700 t
->CurrentAPIIndex
= es_index
;
701 ret
= eglWaitClient();
702 t
->CurrentAPIIndex
= api_index
;
705 return eglWaitClient();
710 EGLBoolean EGLAPIENTRY
711 eglWaitNative(EGLint engine
)
713 _EGLContext
*ctx
= _eglGetCurrentContext();
719 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
721 disp
= ctx
->Resource
.Display
;
722 _eglLockMutex(&disp
->Mutex
);
724 /* let bad current context imply bad current surface */
725 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
726 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
728 /* a valid current context implies an initialized current display */
729 assert(disp
->Initialized
);
731 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
733 RETURN_EGL_EVAL(disp
, ret
);
737 EGLDisplay EGLAPIENTRY
738 eglGetCurrentDisplay(void)
740 _EGLContext
*ctx
= _eglGetCurrentContext();
743 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
745 RETURN_EGL_SUCCESS(NULL
, ret
);
749 EGLContext EGLAPIENTRY
750 eglGetCurrentContext(void)
752 _EGLContext
*ctx
= _eglGetCurrentContext();
755 ret
= _eglGetContextHandle(ctx
);
757 RETURN_EGL_SUCCESS(NULL
, ret
);
761 EGLSurface EGLAPIENTRY
762 eglGetCurrentSurface(EGLint readdraw
)
764 _EGLContext
*ctx
= _eglGetCurrentContext();
765 EGLint err
= EGL_SUCCESS
;
770 RETURN_EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
774 surf
= ctx
->DrawSurface
;
777 surf
= ctx
->ReadSurface
;
781 err
= EGL_BAD_PARAMETER
;
785 ret
= _eglGetSurfaceHandle(surf
);
787 RETURN_EGL_ERROR(NULL
, err
, ret
);
794 _EGLThreadInfo
*t
= _eglGetCurrentThread();
795 EGLint e
= t
->LastError
;
796 if (!_eglIsCurrentThreadDummy())
797 t
->LastError
= EGL_SUCCESS
;
802 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
803 eglGetProcAddress(const char *procname
)
805 static const struct {
808 } egl_functions
[] = {
809 /* extensions only */
810 #ifdef EGL_MESA_screen_surface
811 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
812 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
813 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
814 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
815 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
816 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
817 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
818 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
819 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
820 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
821 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
822 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
823 #endif /* EGL_MESA_screen_surface */
824 #ifdef EGL_MESA_drm_display
825 { "eglGetDRMDisplayMESA", (_EGLProc
) eglGetDRMDisplayMESA
},
827 #ifdef EGL_KHR_image_base
828 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
829 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
830 #endif /* EGL_KHR_image_base */
831 #ifdef EGL_NOK_swap_region
832 { "eglSwapBuffersRegionNOK", (_EGLProc
) eglSwapBuffersRegionNOK
},
840 RETURN_EGL_SUCCESS(NULL
, NULL
);
843 if (strncmp(procname
, "egl", 3) == 0) {
844 for (i
= 0; egl_functions
[i
].name
; i
++) {
845 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
846 ret
= egl_functions
[i
].function
;
852 ret
= _eglGetDriverProc(procname
);
854 RETURN_EGL_SUCCESS(NULL
, ret
);
858 #ifdef EGL_MESA_screen_surface
862 * EGL_MESA_screen extension
865 EGLBoolean EGLAPIENTRY
866 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
867 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
868 EGLint modes_size
, EGLint
*num_modes
)
870 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
871 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
875 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
876 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
877 modes
, modes_size
, num_modes
);
879 RETURN_EGL_EVAL(disp
, ret
);
883 EGLBoolean EGLAPIENTRY
884 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
885 EGLint mode_size
, EGLint
*num_mode
)
887 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
888 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
892 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
893 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
895 RETURN_EGL_EVAL(disp
, ret
);
899 EGLBoolean EGLAPIENTRY
900 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
901 EGLint attribute
, EGLint
*value
)
903 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
904 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
908 _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
, drv
);
909 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
911 RETURN_EGL_EVAL(disp
, ret
);
915 EGLBoolean EGLAPIENTRY
916 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
919 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
920 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
921 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
925 _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
, drv
);
927 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
929 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
930 source_context
, dest_context
, mask
);
932 RETURN_EGL_EVAL(disp
, ret
);
936 EGLBoolean EGLAPIENTRY
937 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
938 EGLint max_screens
, EGLint
*num_screens
)
940 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
944 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
945 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
947 RETURN_EGL_EVAL(disp
, ret
);
951 EGLSurface EGLAPIENTRY
952 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
953 const EGLint
*attrib_list
)
955 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
956 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
961 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
963 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
964 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
966 RETURN_EGL_EVAL(disp
, ret
);
970 EGLBoolean EGLAPIENTRY
971 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
972 EGLSurface surface
, EGLModeMESA mode
)
974 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
975 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
976 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
977 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
981 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
982 if (!surf
&& surface
!= EGL_NO_SURFACE
)
983 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
984 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
985 RETURN_EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
987 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
989 RETURN_EGL_EVAL(disp
, ret
);
993 EGLBoolean EGLAPIENTRY
994 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
996 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
997 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1001 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1002 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
1004 RETURN_EGL_EVAL(disp
, ret
);
1008 EGLBoolean EGLAPIENTRY
1009 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1010 EGLint attribute
, EGLint
*value
)
1012 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1013 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1017 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1018 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
1020 RETURN_EGL_EVAL(disp
, ret
);
1024 EGLBoolean EGLAPIENTRY
1025 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1026 EGLSurface
*surface
)
1028 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1029 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1034 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1035 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1037 *surface
= _eglGetSurfaceHandle(surf
);
1039 RETURN_EGL_EVAL(disp
, ret
);
1043 EGLBoolean EGLAPIENTRY
1044 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1046 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1047 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1052 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1053 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1057 RETURN_EGL_EVAL(disp
, ret
);
1061 const char * EGLAPIENTRY
1062 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1064 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1065 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1069 _EGL_CHECK_MODE(disp
, m
, NULL
, drv
);
1070 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1072 RETURN_EGL_EVAL(disp
, ret
);
1076 #endif /* EGL_MESA_screen_surface */
1079 #ifdef EGL_MESA_drm_display
1081 EGLDisplay EGLAPIENTRY
1082 eglGetDRMDisplayMESA(int fd
)
1084 _EGLDisplay
*dpy
= _eglFindDisplay(_EGL_PLATFORM_DRM
, (void *) fd
);
1085 return _eglGetDisplayHandle(dpy
);
1088 #endif /* EGL_MESA_drm_display */
1094 #ifdef EGL_VERSION_1_2
1098 * Specify the client API to use for subsequent calls including:
1099 * eglCreateContext()
1100 * eglGetCurrentContext()
1101 * eglGetCurrentDisplay()
1102 * eglGetCurrentSurface()
1103 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1106 * See section 3.7 "Rendering Context" in the EGL specification for details.
1108 EGLBoolean EGLAPIENTRY
1109 eglBindAPI(EGLenum api
)
1111 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1113 if (_eglIsCurrentThreadDummy())
1114 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1116 if (!_eglIsApiValid(api
))
1117 RETURN_EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1119 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1121 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1126 * Return the last value set with eglBindAPI().
1131 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1134 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1135 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1137 RETURN_EGL_SUCCESS(NULL
, ret
);
1141 EGLSurface EGLAPIENTRY
1142 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1143 EGLClientBuffer buffer
, EGLConfig config
,
1144 const EGLint
*attrib_list
)
1146 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1147 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1152 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
1154 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1156 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1158 RETURN_EGL_EVAL(disp
, ret
);
1162 EGLBoolean EGLAPIENTRY
1163 eglReleaseThread(void)
1165 /* unbind current contexts */
1166 if (!_eglIsCurrentThreadDummy()) {
1167 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1168 EGLint api_index
= t
->CurrentAPIIndex
;
1171 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1172 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1174 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1177 t
->CurrentAPIIndex
= i
;
1179 _eglLockMutex(&disp
->Mutex
);
1181 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1182 _eglUnlockMutex(&disp
->Mutex
);
1186 t
->CurrentAPIIndex
= api_index
;
1189 _eglDestroyCurrentThread();
1191 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1195 #endif /* EGL_VERSION_1_2 */
1198 #ifdef EGL_KHR_image_base
1201 EGLImageKHR EGLAPIENTRY
1202 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1203 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1205 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1206 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1211 _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
, drv
);
1212 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1213 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1215 img
= drv
->API
.CreateImageKHR(drv
,
1216 disp
, context
, target
, buffer
, attr_list
);
1217 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1219 RETURN_EGL_EVAL(disp
, ret
);
1223 EGLBoolean EGLAPIENTRY
1224 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1226 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1227 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1231 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
1233 RETURN_EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1235 _eglUnlinkImage(img
);
1236 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1238 RETURN_EGL_EVAL(disp
, ret
);
1242 #endif /* EGL_KHR_image_base */
1245 #ifdef EGL_NOK_swap_region
1247 EGLBoolean EGLAPIENTRY
1248 eglSwapBuffersRegionNOK(EGLDisplay dpy
, EGLSurface surface
,
1249 EGLint numRects
, const EGLint
*rects
)
1251 _EGLContext
*ctx
= _eglGetCurrentContext();
1252 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1253 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
1257 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
1259 /* surface must be bound to current context in EGL 1.4 */
1260 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
1261 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1263 if (drv
->API
.SwapBuffersRegionNOK
)
1264 ret
= drv
->API
.SwapBuffersRegionNOK(drv
, disp
, surf
, numRects
, rects
);
1266 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
1268 RETURN_EGL_EVAL(disp
, ret
);
1271 #endif /* EGL_NOK_swap_region */