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 _EGLDisplay
*dpy
= _eglFindDisplay(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
);
266 EGLint major_int
= 0, minor_int
= 0;
269 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
271 if (!disp
->Initialized
) {
272 _EGLDriver
*drv
= disp
->Driver
;
275 _eglPreloadDrivers();
276 drv
= _eglMatchDriver(disp
);
277 /* Initialize the particular display now */
278 if (drv
&& !drv
->API
.Initialize(drv
, disp
, &major_int
, &minor_int
))
279 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
282 /* Load and initialize the first default driver that works */
283 drv
= _eglLoadDefaultDriver(disp
, &major_int
, &minor_int
);
285 RETURN_EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
287 disp
->APImajor
= major_int
;
288 disp
->APIminor
= minor_int
;
289 _eglsnprintf(disp
->Version
, sizeof(disp
->Version
),
290 "%d.%d (%s)", major_int
, minor_int
, drv
->Name
);
292 /* limit to APIs supported by core */
293 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
296 disp
->Initialized
= EGL_TRUE
;
298 major_int
= disp
->APImajor
;
299 minor_int
= disp
->APIminor
;
302 /* Update applications version of major and minor if not NULL */
303 if ((major
!= NULL
) && (minor
!= NULL
)) {
308 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
312 EGLBoolean EGLAPIENTRY
313 eglTerminate(EGLDisplay dpy
)
315 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
318 RETURN_EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
320 if (disp
->Initialized
) {
321 _EGLDriver
*drv
= disp
->Driver
;
323 drv
->API
.Terminate(drv
, disp
);
324 /* do not reset disp->Driver */
325 disp
->Initialized
= EGL_FALSE
;
328 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
332 const char * EGLAPIENTRY
333 eglQueryString(EGLDisplay dpy
, EGLint name
)
335 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
339 _EGL_CHECK_DISPLAY(disp
, NULL
, drv
);
340 ret
= drv
->API
.QueryString(drv
, disp
, name
);
342 RETURN_EGL_EVAL(disp
, ret
);
346 EGLBoolean EGLAPIENTRY
347 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
348 EGLint config_size
, EGLint
*num_config
)
350 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
354 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
355 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
357 RETURN_EGL_EVAL(disp
, ret
);
361 EGLBoolean EGLAPIENTRY
362 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
363 EGLint config_size
, EGLint
*num_config
)
365 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
369 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
370 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
371 config_size
, num_config
);
373 RETURN_EGL_EVAL(disp
, ret
);
377 EGLBoolean EGLAPIENTRY
378 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
379 EGLint attribute
, EGLint
*value
)
381 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
382 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
386 _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
, drv
);
387 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
389 RETURN_EGL_EVAL(disp
, ret
);
393 EGLContext EGLAPIENTRY
394 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
395 const EGLint
*attrib_list
)
397 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
398 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
399 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
401 _EGLContext
*context
;
404 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
, drv
);
405 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
406 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
408 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
409 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
411 RETURN_EGL_EVAL(disp
, ret
);
415 EGLBoolean EGLAPIENTRY
416 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
418 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
419 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
423 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
424 _eglUnlinkContext(context
);
425 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
427 RETURN_EGL_EVAL(disp
, ret
);
431 EGLBoolean EGLAPIENTRY
432 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
435 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
436 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
437 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
438 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
443 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
446 /* display is allowed to be uninitialized under certain condition */
447 if (!disp
->Initialized
) {
448 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
449 ctx
!= EGL_NO_CONTEXT
)
450 RETURN_EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
453 RETURN_EGL_SUCCESS(disp
, EGL_TRUE
);
455 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
456 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
457 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
458 (!read_surf
&& read
!= EGL_NO_SURFACE
))
459 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
461 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
463 RETURN_EGL_EVAL(disp
, ret
);
467 EGLBoolean EGLAPIENTRY
468 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
469 EGLint attribute
, EGLint
*value
)
471 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
472 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
476 _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
, drv
);
477 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
479 RETURN_EGL_EVAL(disp
, ret
);
483 EGLSurface EGLAPIENTRY
484 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
485 EGLNativeWindowType window
, 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
);
495 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
496 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
498 RETURN_EGL_EVAL(disp
, ret
);
502 EGLSurface EGLAPIENTRY
503 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
504 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
506 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
507 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
512 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
514 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
515 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
517 RETURN_EGL_EVAL(disp
, ret
);
521 EGLSurface EGLAPIENTRY
522 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
523 const EGLint
*attrib_list
)
525 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
526 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
531 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
533 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
534 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
536 RETURN_EGL_EVAL(disp
, ret
);
540 EGLBoolean EGLAPIENTRY
541 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
543 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
544 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
548 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
549 _eglUnlinkSurface(surf
);
550 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
552 RETURN_EGL_EVAL(disp
, ret
);
555 EGLBoolean EGLAPIENTRY
556 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
557 EGLint attribute
, EGLint
*value
)
559 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
560 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
564 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
565 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
567 RETURN_EGL_EVAL(disp
, ret
);
570 EGLBoolean EGLAPIENTRY
571 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
572 EGLint attribute
, EGLint value
)
574 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
575 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
579 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
580 ret
= drv
->API
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
582 RETURN_EGL_EVAL(disp
, ret
);
586 EGLBoolean EGLAPIENTRY
587 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
589 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
590 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
594 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
595 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
597 RETURN_EGL_EVAL(disp
, ret
);
601 EGLBoolean EGLAPIENTRY
602 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
604 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
605 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
609 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
610 ret
= drv
->API
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
612 RETURN_EGL_EVAL(disp
, ret
);
616 EGLBoolean EGLAPIENTRY
617 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
619 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
620 _EGLContext
*ctx
= _eglGetCurrentContext();
625 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
627 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
628 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
630 surf
= ctx
->DrawSurface
;
631 if (!_eglIsSurfaceLinked(surf
))
632 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
634 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
636 RETURN_EGL_EVAL(disp
, ret
);
640 EGLBoolean EGLAPIENTRY
641 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
643 _EGLContext
*ctx
= _eglGetCurrentContext();
644 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
645 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
649 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
651 /* surface must be bound to current context in EGL 1.4 */
652 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
653 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
655 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
657 RETURN_EGL_EVAL(disp
, ret
);
661 EGLBoolean EGLAPIENTRY
662 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
664 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
665 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
669 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
670 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
672 RETURN_EGL_EVAL(disp
, ret
);
676 EGLBoolean EGLAPIENTRY
679 _EGLContext
*ctx
= _eglGetCurrentContext();
685 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
687 disp
= ctx
->Resource
.Display
;
688 _eglLockMutex(&disp
->Mutex
);
690 /* let bad current context imply bad current surface */
691 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
692 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
694 /* a valid current context implies an initialized current display */
695 assert(disp
->Initialized
);
697 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
699 RETURN_EGL_EVAL(disp
, ret
);
703 EGLBoolean EGLAPIENTRY
706 #ifdef EGL_VERSION_1_2
707 _EGLThreadInfo
*t
= _eglGetCurrentThread();
708 EGLint api_index
= t
->CurrentAPIIndex
;
709 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
712 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
713 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
715 t
->CurrentAPIIndex
= es_index
;
716 ret
= eglWaitClient();
717 t
->CurrentAPIIndex
= api_index
;
720 return eglWaitClient();
725 EGLBoolean EGLAPIENTRY
726 eglWaitNative(EGLint engine
)
728 _EGLContext
*ctx
= _eglGetCurrentContext();
734 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
736 disp
= ctx
->Resource
.Display
;
737 _eglLockMutex(&disp
->Mutex
);
739 /* let bad current context imply bad current surface */
740 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
741 RETURN_EGL_ERROR(disp
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
743 /* a valid current context implies an initialized current display */
744 assert(disp
->Initialized
);
746 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
748 RETURN_EGL_EVAL(disp
, ret
);
752 EGLDisplay EGLAPIENTRY
753 eglGetCurrentDisplay(void)
755 _EGLContext
*ctx
= _eglGetCurrentContext();
758 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
760 RETURN_EGL_SUCCESS(NULL
, ret
);
764 EGLContext EGLAPIENTRY
765 eglGetCurrentContext(void)
767 _EGLContext
*ctx
= _eglGetCurrentContext();
770 ret
= _eglGetContextHandle(ctx
);
772 RETURN_EGL_SUCCESS(NULL
, ret
);
776 EGLSurface EGLAPIENTRY
777 eglGetCurrentSurface(EGLint readdraw
)
779 _EGLContext
*ctx
= _eglGetCurrentContext();
780 EGLint err
= EGL_SUCCESS
;
785 RETURN_EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
789 surf
= ctx
->DrawSurface
;
792 surf
= ctx
->ReadSurface
;
796 err
= EGL_BAD_PARAMETER
;
800 ret
= _eglGetSurfaceHandle(surf
);
802 RETURN_EGL_ERROR(NULL
, err
, ret
);
809 _EGLThreadInfo
*t
= _eglGetCurrentThread();
810 EGLint e
= t
->LastError
;
811 if (!_eglIsCurrentThreadDummy())
812 t
->LastError
= EGL_SUCCESS
;
817 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
818 eglGetProcAddress(const char *procname
)
820 static const struct {
823 } egl_functions
[] = {
824 /* extensions only */
825 #ifdef EGL_MESA_screen_surface
826 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
827 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
828 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
829 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
830 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
831 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
832 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
833 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
834 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
835 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
836 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
837 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
838 #endif /* EGL_MESA_screen_surface */
839 #ifdef EGL_KHR_image_base
840 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
841 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
842 #endif /* EGL_KHR_image_base */
843 #ifdef EGL_NOK_swap_region
844 { "eglSwapBuffersRegionNOK", (_EGLProc
) eglSwapBuffersRegionNOK
},
852 RETURN_EGL_SUCCESS(NULL
, NULL
);
855 if (strncmp(procname
, "egl", 3) == 0) {
856 for (i
= 0; egl_functions
[i
].name
; i
++) {
857 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
858 ret
= egl_functions
[i
].function
;
864 RETURN_EGL_SUCCESS(NULL
, ret
);
866 _eglPreloadDrivers();
868 /* now loop over drivers to query their procs */
869 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
870 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
871 ret
= drv
->API
.GetProcAddress(drv
, procname
);
876 RETURN_EGL_SUCCESS(NULL
, ret
);
880 #ifdef EGL_MESA_screen_surface
884 * EGL_MESA_screen extension
887 EGLBoolean EGLAPIENTRY
888 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
889 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
890 EGLint modes_size
, EGLint
*num_modes
)
892 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
893 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
897 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
898 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
899 modes
, modes_size
, num_modes
);
901 RETURN_EGL_EVAL(disp
, ret
);
905 EGLBoolean EGLAPIENTRY
906 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
907 EGLint mode_size
, EGLint
*num_mode
)
909 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
910 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
914 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
915 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
917 RETURN_EGL_EVAL(disp
, ret
);
921 EGLBoolean EGLAPIENTRY
922 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
923 EGLint attribute
, EGLint
*value
)
925 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
926 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
930 _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
, drv
);
931 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
933 RETURN_EGL_EVAL(disp
, ret
);
937 EGLBoolean EGLAPIENTRY
938 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
941 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
942 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
943 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
947 _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
, drv
);
949 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
951 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
952 source_context
, dest_context
, mask
);
954 RETURN_EGL_EVAL(disp
, ret
);
959 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
960 EGLint max_screens
, EGLint
*num_screens
)
962 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
966 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
967 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
969 RETURN_EGL_EVAL(disp
, ret
);
974 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
975 const EGLint
*attrib_list
)
977 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
978 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
983 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
985 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
986 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
988 RETURN_EGL_EVAL(disp
, ret
);
993 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
994 EGLSurface surface
, EGLModeMESA mode
)
996 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
997 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
998 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
999 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1003 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1004 if (!surf
&& surface
!= EGL_NO_SURFACE
)
1005 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1006 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
1007 RETURN_EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
1009 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
1011 RETURN_EGL_EVAL(disp
, ret
);
1016 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
1018 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1019 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1023 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1024 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
1026 RETURN_EGL_EVAL(disp
, ret
);
1031 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1032 EGLint attribute
, EGLint
*value
)
1034 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1035 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
1039 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1040 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
1042 RETURN_EGL_EVAL(disp
, ret
);
1047 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1048 EGLSurface
*surface
)
1050 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1051 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1056 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1057 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1059 *surface
= _eglGetSurfaceHandle(surf
);
1061 RETURN_EGL_EVAL(disp
, ret
);
1066 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1068 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1069 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1074 _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
, drv
);
1075 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1079 RETURN_EGL_EVAL(disp
, ret
);
1084 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1086 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1087 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1091 _EGL_CHECK_MODE(disp
, m
, NULL
, drv
);
1092 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1094 RETURN_EGL_EVAL(disp
, ret
);
1098 #endif /* EGL_MESA_screen_surface */
1105 #ifdef EGL_VERSION_1_2
1109 * Specify the client API to use for subsequent calls including:
1110 * eglCreateContext()
1111 * eglGetCurrentContext()
1112 * eglGetCurrentDisplay()
1113 * eglGetCurrentSurface()
1114 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1117 * See section 3.7 "Rendering Context" in the EGL specification for details.
1120 eglBindAPI(EGLenum api
)
1122 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1124 if (_eglIsCurrentThreadDummy())
1125 RETURN_EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1127 if (!_eglIsApiValid(api
))
1128 RETURN_EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1130 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1132 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1137 * Return the last value set with eglBindAPI().
1142 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1145 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1146 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1148 RETURN_EGL_SUCCESS(NULL
, ret
);
1153 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1154 EGLClientBuffer buffer
, EGLConfig config
,
1155 const EGLint
*attrib_list
)
1157 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1158 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1163 _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
, drv
);
1165 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1167 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1169 RETURN_EGL_EVAL(disp
, ret
);
1174 eglReleaseThread(void)
1176 /* unbind current contexts */
1177 if (!_eglIsCurrentThreadDummy()) {
1178 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1179 EGLint api_index
= t
->CurrentAPIIndex
;
1182 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1183 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1185 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1188 t
->CurrentAPIIndex
= i
;
1190 _eglLockMutex(&disp
->Mutex
);
1192 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1193 _eglUnlockMutex(&disp
->Mutex
);
1197 t
->CurrentAPIIndex
= api_index
;
1200 _eglDestroyCurrentThread();
1202 RETURN_EGL_SUCCESS(NULL
, EGL_TRUE
);
1206 #endif /* EGL_VERSION_1_2 */
1209 #ifdef EGL_KHR_image_base
1213 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1214 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1216 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1217 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1222 _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
, drv
);
1223 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1224 RETURN_EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1226 img
= drv
->API
.CreateImageKHR(drv
,
1227 disp
, context
, target
, buffer
, attr_list
);
1228 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1230 RETURN_EGL_EVAL(disp
, ret
);
1235 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1237 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1238 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1242 _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
, drv
);
1244 RETURN_EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1246 _eglUnlinkImage(img
);
1247 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1249 RETURN_EGL_EVAL(disp
, ret
);
1253 #endif /* EGL_KHR_image_base */
1256 #ifdef EGL_NOK_swap_region
1259 eglSwapBuffersRegionNOK(EGLDisplay dpy
, EGLSurface surface
,
1260 EGLint numRects
, const EGLint
*rects
)
1262 _EGLContext
*ctx
= _eglGetCurrentContext();
1263 _EGLDisplay
*disp
= _eglLockDisplay(dpy
);
1264 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
1268 _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
, drv
);
1270 /* surface must be bound to current context in EGL 1.4 */
1271 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
1272 RETURN_EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
1274 if (drv
->API
.SwapBuffersRegionNOK
)
1275 ret
= drv
->API
.SwapBuffersRegionNOK(drv
, disp
, surf
, numRects
, rects
);
1277 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
1279 RETURN_EGL_EVAL(disp
, ret
);
1282 #endif /* EGL_NOK_swap_region */