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 "eglcurrent.h"
65 #include "egldriver.h"
66 #include "eglsurface.h"
67 #include "eglconfig.h"
68 #include "eglscreen.h"
74 * Macros to help return an API entrypoint.
76 * These macros will unlock the display and record the error code.
78 #define RETURN_EGL_ERROR(disp, err, ret) \
81 _eglUnlockDisplay(disp); \
82 /* EGL error codes are non-zero */ \
84 _eglError(err, __FUNCTION__); \
88 #define RETURN_EGL_SUCCESS(disp, ret) \
89 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
91 /* record EGL_SUCCESS only when ret evaluates to true */
92 #define RETURN_EGL_EVAL(disp, ret) \
93 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
97 * A bunch of macros and checks to simplify error checking.
100 #define _EGL_CHECK_DISPLAY(disp, ret, drv) \
102 drv = _eglCheckDisplay(disp, __FUNCTION__); \
104 RETURN_EGL_ERROR(disp, 0, ret); \
107 #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
109 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \
111 RETURN_EGL_ERROR(disp, 0, ret); \
114 #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
115 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
117 #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
118 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
120 #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
121 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
123 #define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
124 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
126 #define _EGL_CHECK_MODE(disp, m, ret, drv) \
127 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
131 static INLINE _EGLDriver
*
132 _eglCheckDisplay(_EGLDisplay
*disp
, const char *msg
)
135 _eglError(EGL_BAD_DISPLAY
, msg
);
138 if (!disp
->Initialized
) {
139 _eglError(EGL_NOT_INITIALIZED
, msg
);
146 static INLINE _EGLDriver
*
147 _eglCheckSurface(_EGLDisplay
*disp
, _EGLSurface
*surf
, const char *msg
)
149 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
153 _eglError(EGL_BAD_SURFACE
, msg
);
160 static INLINE _EGLDriver
*
161 _eglCheckContext(_EGLDisplay
*disp
, _EGLContext
*context
, const char *msg
)
163 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
167 _eglError(EGL_BAD_CONTEXT
, msg
);
174 static INLINE _EGLDriver
*
175 _eglCheckConfig(_EGLDisplay
*disp
, _EGLConfig
*conf
, const char *msg
)
177 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
181 _eglError(EGL_BAD_CONFIG
, msg
);
188 #ifdef EGL_MESA_screen_surface
191 static INLINE _EGLDriver
*
192 _eglCheckScreen(_EGLDisplay
*disp
, _EGLScreen
*scrn
, const char *msg
)
194 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
198 _eglError(EGL_BAD_SCREEN_MESA
, msg
);
205 static INLINE _EGLDriver
*
206 _eglCheckMode(_EGLDisplay
*disp
, _EGLMode
*m
, const char *msg
)
208 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
212 _eglError(EGL_BAD_MODE_MESA
, msg
);
219 #endif /* EGL_MESA_screen_surface */
223 * Lookup and lock a display.
225 static INLINE _EGLDisplay
*
226 _eglLockDisplay(EGLDisplay display
)
228 _EGLDisplay
*dpy
= _eglLookupDisplay(display
);
230 _eglLockMutex(&dpy
->Mutex
);
239 _eglUnlockDisplay(_EGLDisplay
*dpy
)
241 _eglUnlockMutex(&dpy
->Mutex
);
246 * This is typically the first EGL function that an application calls.
247 * It associates a private _EGLDisplay object to the native display.
249 EGLDisplay EGLAPIENTRY
250 eglGetDisplay(EGLNativeDisplayType nativeDisplay
)
252 _EGLPlatformType plat
= _eglGetNativePlatform();
253 _EGLDisplay
*dpy
= _eglFindDisplay(plat
, (void *) nativeDisplay
);
254 return _eglGetDisplayHandle(dpy
);
259 * This is typically the second EGL function that an application calls.
260 * Here we load/initialize the actual hardware driver.
262 EGLBoolean EGLAPIENTRY
263 eglInitialize(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
)
265 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
268 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
270 if (!disp
->Initialized
) {
271 if (!_eglMatchDriver(disp
, EGL_FALSE
))
272 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
274 _eglsnprintf(disp
->Version
, sizeof(disp
->Version
), "%d.%d (%s)",
275 disp
->APImajor
, disp
->APIminor
, disp
->Driver
->Name
);
276 /* limit to APIs supported by core */
277 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
280 /* Update applications version of major and minor if not NULL */
281 if ((major
!= NULL
) && (minor
!= NULL
)) {
282 *major
= disp
->APImajor
;
283 *minor
= disp
->APIminor
;
286 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
290 EGLBoolean EGLAPIENTRY
291 eglTerminate(EGLDisplay dpy
)
293 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
296 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
298 if (disp
->Initialized
) {
299 _EGLDriver
*drv
= disp
->Driver
;
301 drv
->API
.Terminate(drv
, disp
);
302 /* do not reset disp->Driver */
303 disp
->Initialized
= EGL_FALSE
;
306 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
310 const char * EGLAPIENTRY
311 eglQueryString(EGLDisplay dpy
, EGLint name
)
313 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
317 _EGL_CHECK_DISPLAY(disp
, NULL
, drv
);
318 ret
= drv
->API
.QueryString(drv
, disp
, name
);
320 RETURN_EGL_EVAL(disp
, ret
);
324 EGLBoolean EGLAPIENTRY
325 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
326 EGLint config_size
, EGLint
*num_config
)
328 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
332 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
333 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
335 RETURN_EGL_EVAL(disp
, ret
);
339 EGLBoolean EGLAPIENTRY
340 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
341 EGLint config_size
, EGLint
*num_config
)
343 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
347 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
348 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
349 config_size
, num_config
);
351 RETURN_EGL_EVAL(disp
, ret
);
355 EGLBoolean EGLAPIENTRY
356 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
357 EGLint attribute
, EGLint
*value
)
359 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
360 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
364 _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
, drv
);
365 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
367 RETURN_EGL_EVAL(disp
, ret
);
371 EGLContext EGLAPIENTRY
372 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
373 const EGLint
*attrib_list
)
375 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
376 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
377 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
379 _EGLContext
*context
;
383 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
, drv
);
385 drv
= _eglCheckDisplay(disp
, __FUNCTION__
);
387 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
388 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
390 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
391 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
393 RETURN_EGL_EVAL(disp
, ret
);
397 EGLBoolean EGLAPIENTRY
398 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
400 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
401 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
405 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
406 _eglUnlinkContext(context
);
407 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
409 RETURN_EGL_EVAL(disp
, ret
);
413 EGLBoolean EGLAPIENTRY
414 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
417 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
418 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
419 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
420 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
425 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
428 /* display is allowed to be uninitialized under certain condition */
429 if (!disp
->Initialized
) {
430 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
431 ctx
!= EGL_NO_CONTEXT
)
432 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
435 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
437 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
438 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
439 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
440 (!read_surf
&& read
!= EGL_NO_SURFACE
))
441 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
443 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
445 RETURN_EGL_EVAL(disp
, ret
);
449 EGLBoolean EGLAPIENTRY
450 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
451 EGLint attribute
, EGLint
*value
)
453 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
454 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
458 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
459 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
461 RETURN_EGL_EVAL(disp
, ret
);
465 EGLSurface EGLAPIENTRY
466 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
467 EGLNativeWindowType window
, const EGLint
*attrib_list
)
469 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
470 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
475 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
476 if (disp
->Platform
!= _eglGetNativePlatform())
477 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_WINDOW
, EGL_NO_SURFACE
);
479 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
480 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
482 RETURN_EGL_EVAL(disp
, ret
);
486 EGLSurface EGLAPIENTRY
487 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
488 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
490 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
491 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
496 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
497 if (disp
->Platform
!= _eglGetNativePlatform())
498 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_PIXMAP
, EGL_NO_SURFACE
);
500 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
501 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
503 RETURN_EGL_EVAL(disp
, ret
);
507 EGLSurface EGLAPIENTRY
508 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
509 const EGLint
*attrib_list
)
511 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
512 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
517 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
519 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
520 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
522 RETURN_EGL_EVAL(disp
, ret
);
526 EGLBoolean EGLAPIENTRY
527 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
529 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
530 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
534 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
535 _eglUnlinkSurface(surf
);
536 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
538 RETURN_EGL_EVAL(disp
, ret
);
541 EGLBoolean EGLAPIENTRY
542 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
543 EGLint attribute
, EGLint
*value
)
545 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
546 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
550 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
551 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
553 RETURN_EGL_EVAL(disp
, ret
);
556 EGLBoolean EGLAPIENTRY
557 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
558 EGLint attribute
, EGLint value
)
560 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
561 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
565 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
566 ret
= drv
->API
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
568 RETURN_EGL_EVAL(disp
, ret
);
572 EGLBoolean EGLAPIENTRY
573 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
575 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
576 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
580 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
581 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
583 RETURN_EGL_EVAL(disp
, ret
);
587 EGLBoolean EGLAPIENTRY
588 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
590 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
591 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
595 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
596 ret
= drv
->API
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
598 RETURN_EGL_EVAL(disp
, ret
);
602 EGLBoolean EGLAPIENTRY
603 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
605 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
606 _EGLContext
*ctx
= _eglGetCurrentContext();
611 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
613 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
614 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
616 surf
= ctx
->DrawSurface
;
617 if (!_eglIsSurfaceLinked(surf
))
618 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
620 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
622 RETURN_EGL_EVAL(disp
, ret
);
626 EGLBoolean EGLAPIENTRY
627 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
629 _EGLContext
*ctx
= _eglGetCurrentContext();
630 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
631 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
635 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
637 /* surface must be bound to current context in EGL 1.4 */
638 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
639 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
641 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
643 RETURN_EGL_EVAL(disp
, ret
);
647 EGLBoolean EGLAPIENTRY
648 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
650 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
651 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
655 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
656 if (disp
->Platform
!= _eglGetNativePlatform())
657 RETURN_EGL_ERROR(disp
, EGL_BAD_NATIVE_PIXMAP
, EGL_FALSE
);
658 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
660 RETURN_EGL_EVAL(disp
, ret
);
664 EGLBoolean EGLAPIENTRY
667 _EGLContext
*ctx
= _eglGetCurrentContext();
673 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
675 disp
= ctx
->Resource
.Display
;
676 _eglLockMutex(&disp
->Mutex
);
678 /* let bad current context imply bad current surface */
679 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
680 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
682 /* a valid current context implies an initialized current display */
683 assert(disp
->Initialized
);
685 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
687 RETURN_EGL_EVAL(disp
, ret
);
691 EGLBoolean EGLAPIENTRY
694 #ifdef EGL_VERSION_1_2
695 _EGLThreadInfo
*t
= _eglGetCurrentThread();
696 EGLint api_index
= t
->CurrentAPIIndex
;
697 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
700 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
701 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
703 t
->CurrentAPIIndex
= es_index
;
704 ret
= eglWaitClient();
705 t
->CurrentAPIIndex
= api_index
;
708 return eglWaitClient();
713 EGLBoolean EGLAPIENTRY
714 eglWaitNative(EGLint engine
)
716 _EGLContext
*ctx
= _eglGetCurrentContext();
722 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
724 disp
= ctx
->Resource
.Display
;
725 _eglLockMutex(&disp
->Mutex
);
727 /* let bad current context imply bad current surface */
728 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
729 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
731 /* a valid current context implies an initialized current display */
732 assert(disp
->Initialized
);
734 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
736 RETURN_EGL_EVAL(disp
, ret
);
740 EGLDisplay EGLAPIENTRY
741 eglGetCurrentDisplay(void)
743 _EGLContext
*ctx
= _eglGetCurrentContext();
746 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
748 RETURN_EGL_SUCCESS(NULL
, ret
);
752 EGLContext EGLAPIENTRY
753 eglGetCurrentContext(void)
755 _EGLContext
*ctx
= _eglGetCurrentContext();
758 ret
= _eglGetContextHandle(ctx
);
760 RETURN_EGL_SUCCESS(NULL
, ret
);
764 EGLSurface EGLAPIENTRY
765 eglGetCurrentSurface(EGLint readdraw
)
767 _EGLContext
*ctx
= _eglGetCurrentContext();
768 EGLint err
= EGL_SUCCESS
;
773 RETURN_EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
777 surf
= ctx
->DrawSurface
;
780 surf
= ctx
->ReadSurface
;
784 err
= EGL_BAD_PARAMETER
;
788 ret
= _eglGetSurfaceHandle(surf
);
790 RETURN_EGL_ERROR(NULL
, err
, ret
);
797 _EGLThreadInfo
*t
= _eglGetCurrentThread();
798 EGLint e
= t
->LastError
;
799 if (!_eglIsCurrentThreadDummy())
800 t
->LastError
= EGL_SUCCESS
;
805 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
806 eglGetProcAddress(const char *procname
)
808 static const struct {
811 } egl_functions
[] = {
812 /* extensions only */
813 #ifdef EGL_MESA_screen_surface
814 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
815 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
816 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
817 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
818 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
819 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
820 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
821 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
822 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
823 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
824 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
825 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
826 #endif /* EGL_MESA_screen_surface */
827 #ifdef EGL_MESA_drm_display
828 { "eglGetDRMDisplayMESA", (_EGLProc
) eglGetDRMDisplayMESA
},
830 #ifdef EGL_KHR_image_base
831 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
832 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
833 #endif /* EGL_KHR_image_base */
834 #ifdef EGL_NOK_swap_region
835 { "eglSwapBuffersRegionNOK", (_EGLProc
) eglSwapBuffersRegionNOK
},
843 RETURN_EGL_SUCCESS(NULL
, NULL
);
846 if (strncmp(procname
, "egl", 3) == 0) {
847 for (i
= 0; egl_functions
[i
].name
; i
++) {
848 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
849 ret
= egl_functions
[i
].function
;
855 ret
= _eglGetDriverProc(procname
);
857 RETURN_EGL_SUCCESS(NULL
, ret
);
861 #ifdef EGL_MESA_screen_surface
865 * EGL_MESA_screen extension
868 EGLBoolean EGLAPIENTRY
869 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
870 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
871 EGLint modes_size
, EGLint
*num_modes
)
873 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
874 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
878 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
879 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
880 modes
, modes_size
, num_modes
);
882 RETURN_EGL_EVAL(disp
, ret
);
886 EGLBoolean EGLAPIENTRY
887 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
888 EGLint mode_size
, EGLint
*num_mode
)
890 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
891 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
895 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
896 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
898 RETURN_EGL_EVAL(disp
, ret
);
902 EGLBoolean EGLAPIENTRY
903 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
904 EGLint attribute
, EGLint
*value
)
906 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
907 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
911 _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
, drv
);
912 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
914 RETURN_EGL_EVAL(disp
, ret
);
918 EGLBoolean EGLAPIENTRY
919 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
922 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
923 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
924 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
928 _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
, drv
);
930 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
932 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
933 source_context
, dest_context
, mask
);
935 RETURN_EGL_EVAL(disp
, ret
);
939 EGLBoolean EGLAPIENTRY
940 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
941 EGLint max_screens
, EGLint
*num_screens
)
943 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
947 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
948 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
950 RETURN_EGL_EVAL(disp
, ret
);
954 EGLSurface EGLAPIENTRY
955 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
956 const EGLint
*attrib_list
)
958 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
959 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
964 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
966 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
967 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
969 RETURN_EGL_EVAL(disp
, ret
);
973 EGLBoolean EGLAPIENTRY
974 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
975 EGLSurface surface
, EGLModeMESA mode
)
977 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
978 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
979 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
980 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
984 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
985 if (!surf
&& surface
!= EGL_NO_SURFACE
)
986 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
987 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
988 RETURN_EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
990 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
992 RETURN_EGL_EVAL(disp
, ret
);
996 EGLBoolean EGLAPIENTRY
997 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
999 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1000 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1004 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1005 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
1007 RETURN_EGL_EVAL(disp
, ret
);
1011 EGLBoolean EGLAPIENTRY
1012 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1013 EGLint attribute
, EGLint
*value
)
1015 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1016 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1020 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1021 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
1023 RETURN_EGL_EVAL(disp
, ret
);
1027 EGLBoolean EGLAPIENTRY
1028 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1029 EGLSurface
*surface
)
1031 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1032 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1037 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1038 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1040 *surface
= _eglGetSurfaceHandle(surf
);
1042 RETURN_EGL_EVAL(disp
, ret
);
1046 EGLBoolean EGLAPIENTRY
1047 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1049 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1050 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1055 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1056 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1060 RETURN_EGL_EVAL(disp
, ret
);
1064 const char * EGLAPIENTRY
1065 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1067 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1068 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1072 _EGL_CHECK_MODE(disp
, m
, NULL
, drv
);
1073 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1075 RETURN_EGL_EVAL(disp
, ret
);
1079 #endif /* EGL_MESA_screen_surface */
1082 #ifdef EGL_MESA_drm_display
1084 EGLDisplay EGLAPIENTRY
1085 eglGetDRMDisplayMESA(int fd
)
1087 _EGLDisplay
*dpy
= _eglFindDisplay(_EGL_PLATFORM_DRM
, (void *) fd
);
1088 return _eglGetDisplayHandle(dpy
);
1091 #endif /* EGL_MESA_drm_display */
1097 #ifdef EGL_VERSION_1_2
1101 * Specify the client API to use for subsequent calls including:
1102 * eglCreateContext()
1103 * eglGetCurrentContext()
1104 * eglGetCurrentDisplay()
1105 * eglGetCurrentSurface()
1106 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1109 * See section 3.7 "Rendering Context" in the EGL specification for details.
1111 EGLBoolean EGLAPIENTRY
1112 eglBindAPI(EGLenum api
)
1114 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1116 if (_eglIsCurrentThreadDummy())
1117 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1119 if (!_eglIsApiValid(api
))
1120 RETURN_EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1122 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1124 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1129 * Return the last value set with eglBindAPI().
1134 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1137 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1138 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1140 RETURN_EGL_SUCCESS(NULL
, ret
);
1144 EGLSurface EGLAPIENTRY
1145 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1146 EGLClientBuffer buffer
, EGLConfig config
,
1147 const EGLint
*attrib_list
)
1149 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1150 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1155 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
1157 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1159 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1161 RETURN_EGL_EVAL(disp
, ret
);
1165 EGLBoolean EGLAPIENTRY
1166 eglReleaseThread(void)
1168 /* unbind current contexts */
1169 if (!_eglIsCurrentThreadDummy()) {
1170 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1171 EGLint api_index
= t
->CurrentAPIIndex
;
1174 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1175 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1177 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1180 t
->CurrentAPIIndex
= i
;
1182 _eglLockMutex(&disp
->Mutex
);
1184 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1185 _eglUnlockMutex(&disp
->Mutex
);
1189 t
->CurrentAPIIndex
= api_index
;
1192 _eglDestroyCurrentThread();
1194 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1198 #endif /* EGL_VERSION_1_2 */
1201 #ifdef EGL_KHR_image_base
1204 EGLImageKHR EGLAPIENTRY
1205 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1206 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1208 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1209 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1214 _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
, drv
);
1215 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1216 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1218 img
= drv
->API
.CreateImageKHR(drv
,
1219 disp
, context
, target
, buffer
, attr_list
);
1220 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1222 RETURN_EGL_EVAL(disp
, ret
);
1226 EGLBoolean EGLAPIENTRY
1227 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1229 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1230 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1234 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
1236 RETURN_EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1238 _eglUnlinkImage(img
);
1239 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1241 RETURN_EGL_EVAL(disp
, ret
);
1245 #endif /* EGL_KHR_image_base */
1248 #ifdef EGL_NOK_swap_region
1250 EGLBoolean EGLAPIENTRY
1251 eglSwapBuffersRegionNOK(EGLDisplay dpy
, EGLSurface surface
,
1252 EGLint numRects
, const EGLint
*rects
)
1254 _EGLContext
*ctx
= _eglGetCurrentContext();
1255 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1256 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
1260 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
1262 /* surface must be bound to current context in EGL 1.4 */
1263 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
1264 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1266 if (drv
->API
.SwapBuffersRegionNOK
)
1267 ret
= drv
->API
.SwapBuffersRegionNOK(drv
, disp
, surf
, numRects
, rects
);
1269 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
1271 RETURN_EGL_EVAL(disp
, ret
);
1274 #endif /* EGL_NOK_swap_region */