2 * Public EGL API entrypoints
4 * Generally, we use the EGLDisplay parameter as a key to lookup the
5 * appropriate device driver handle, then jump though the driver's
6 * dispatch table to handle the function.
8 * That allows us the option of supporting multiple, simultaneous,
9 * heterogeneous hardware devices in the future.
11 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
12 * opaque handles. Internal objects are linked to a display to
15 * For each public API entry point, the opaque handles are looked up
16 * before being dispatched to the drivers. When it fails to look up
26 * is generated and the driver function is not called. An
27 * uninitialized EGLDisplay has no driver associated with it. When
28 * such display is detected,
34 * Some of the entry points use current display, context, or surface
35 * implicitly. For such entry points, the implicit objects are also
36 * checked before calling the driver function. Other than the
37 * errors listed above,
39 * EGL_BAD_CURRENT_SURFACE
41 * may also be generated.
43 * Notes on naming conventions:
45 * eglFooBar - public EGL function
46 * EGL_FOO_BAR - public EGL token
47 * EGLDatatype - public EGL datatype
49 * _eglFooBar - private EGL function
50 * _EGLDatatype - private EGL datatype, typedef'd struct
51 * _egl_struct - private EGL struct, non-typedef'd
59 #include "eglcontext.h"
60 #include "egldisplay.h"
61 #include "egltypedefs.h"
62 #include "eglglobals.h"
63 #include "eglcurrent.h"
64 #include "egldriver.h"
65 #include "eglsurface.h"
66 #include "eglconfig.h"
67 #include "eglscreen.h"
73 * Macros to help return an API entrypoint.
75 #define _EGL_ERROR(disp, err, ret) \
77 /* EGL error codes are non-zero */ \
79 _eglError(err, __FUNCTION__); \
82 #define _EGL_SUCCESS(disp, ret) _EGL_ERROR(disp, EGL_SUCCESS, ret)
83 /* record EGL_SUCCESS only when ret evaluates to true */
84 #define _EGL_EVAL(disp, ret) _EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
88 * A bunch of macros and checks to simplify error checking.
90 #define _EGL_CHECK_DISPLAY(disp, ret) \
92 _EGLDriver *__drv = _eglCheckDisplay(disp, __FUNCTION__); \
94 return _EGL_ERROR(disp, 0, ret); \
99 #define _EGL_CHECK_OBJECT(disp, type, obj, ret) \
101 _EGLDriver *__drv = _eglCheck ## type(disp, obj, __FUNCTION__); \
103 return _EGL_ERROR(disp, 0, ret); \
106 #define _EGL_CHECK_SURFACE(disp, surf, ret) \
107 _EGL_CHECK_OBJECT(disp, Surface, surf, ret)
108 #define _EGL_CHECK_CONTEXT(disp, context, ret) \
109 _EGL_CHECK_OBJECT(disp, Context, context, ret)
110 #define _EGL_CHECK_CONFIG(disp, conf, ret) \
111 _EGL_CHECK_OBJECT(disp, Config, conf, ret)
112 #define _EGL_CHECK_SCREEN(disp, scrn, ret) \
113 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret)
114 #define _EGL_CHECK_MODE(disp, m, ret) \
115 _EGL_CHECK_OBJECT(disp, Mode, m, ret)
118 static INLINE _EGLDriver
*
119 _eglCheckDisplay(_EGLDisplay
*disp
, const char *msg
)
122 _eglError(EGL_BAD_DISPLAY
, msg
);
125 if (!disp
->Initialized
) {
126 _eglError(EGL_NOT_INITIALIZED
, msg
);
133 static INLINE _EGLDriver
*
134 _eglCheckSurface(_EGLDisplay
*disp
, _EGLSurface
*surf
, const char *msg
)
136 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
140 _eglError(EGL_BAD_SURFACE
, msg
);
147 static INLINE _EGLDriver
*
148 _eglCheckContext(_EGLDisplay
*disp
, _EGLContext
*context
, const char *msg
)
150 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
154 _eglError(EGL_BAD_CONTEXT
, msg
);
161 static INLINE _EGLDriver
*
162 _eglCheckConfig(_EGLDisplay
*disp
, _EGLConfig
*conf
, const char *msg
)
164 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
168 _eglError(EGL_BAD_CONFIG
, msg
);
175 #ifdef EGL_MESA_screen_surface
178 static INLINE _EGLDriver
*
179 _eglCheckScreen(_EGLDisplay
*disp
, _EGLScreen
*scrn
, const char *msg
)
181 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
185 _eglError(EGL_BAD_SCREEN_MESA
, msg
);
192 static INLINE _EGLDriver
*
193 _eglCheckMode(_EGLDisplay
*disp
, _EGLMode
*m
, const char *msg
)
195 _EGLDriver
*drv
= _eglCheckDisplay(disp
, msg
);
199 _eglError(EGL_BAD_MODE_MESA
, msg
);
206 #endif /* EGL_MESA_screen_surface */
210 * This is typically the first EGL function that an application calls.
211 * It associates a private _EGLDisplay object to the native display.
213 EGLDisplay EGLAPIENTRY
214 eglGetDisplay(EGLNativeDisplayType nativeDisplay
)
216 _EGLDisplay
*dpy
= _eglFindDisplay(nativeDisplay
);
217 return _eglGetDisplayHandle(dpy
);
222 * This is typically the second EGL function that an application calls.
223 * Here we load/initialize the actual hardware driver.
225 EGLBoolean EGLAPIENTRY
226 eglInitialize(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
)
228 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
229 EGLint major_int
, minor_int
;
232 return _EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
234 if (!disp
->Initialized
) {
235 _EGLDriver
*drv
= disp
->Driver
;
238 _eglPreloadDrivers();
239 drv
= _eglMatchDriver(disp
);
241 return _EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
244 /* Initialize the particular display now */
245 if (!drv
->API
.Initialize(drv
, disp
, &major_int
, &minor_int
))
246 return _EGL_ERROR(disp
, EGL_NOT_INITIALIZED
, EGL_FALSE
);
248 disp
->APImajor
= major_int
;
249 disp
->APIminor
= minor_int
;
250 snprintf(disp
->Version
, sizeof(disp
->Version
),
251 "%d.%d (%s)", major_int
, minor_int
, drv
->Name
);
253 /* limit to APIs supported by core */
254 disp
->ClientAPIsMask
&= _EGL_API_ALL_BITS
;
257 disp
->Initialized
= EGL_TRUE
;
259 major_int
= disp
->APImajor
;
260 minor_int
= disp
->APIminor
;
263 /* Update applications version of major and minor if not NULL */
264 if ((major
!= NULL
) && (minor
!= NULL
)) {
269 return _EGL_SUCCESS(disp
, EGL_TRUE
);
273 EGLBoolean EGLAPIENTRY
274 eglTerminate(EGLDisplay dpy
)
276 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
279 return _EGL_ERROR(NULL
, EGL_BAD_DISPLAY
, EGL_FALSE
);
281 if (disp
->Initialized
) {
282 _EGLDriver
*drv
= disp
->Driver
;
284 drv
->API
.Terminate(drv
, disp
);
285 /* do not reset disp->Driver */
286 disp
->Initialized
= EGL_FALSE
;
289 return _EGL_SUCCESS(disp
, EGL_TRUE
);
293 const char * EGLAPIENTRY
294 eglQueryString(EGLDisplay dpy
, EGLint name
)
296 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
300 drv
= _EGL_CHECK_DISPLAY(disp
, NULL
);
301 ret
= drv
->API
.QueryString(drv
, disp
, name
);
303 return _EGL_EVAL(disp
, ret
);
307 EGLBoolean EGLAPIENTRY
308 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
309 EGLint config_size
, EGLint
*num_config
)
311 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
315 drv
= _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
);
316 ret
= drv
->API
.GetConfigs(drv
, disp
, configs
, config_size
, num_config
);
318 return _EGL_EVAL(disp
, ret
);
322 EGLBoolean EGLAPIENTRY
323 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
,
324 EGLint config_size
, EGLint
*num_config
)
326 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
330 drv
= _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
);
331 ret
= drv
->API
.ChooseConfig(drv
, disp
, attrib_list
, configs
,
332 config_size
, num_config
);
334 return _EGL_EVAL(disp
, ret
);
338 EGLBoolean EGLAPIENTRY
339 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
340 EGLint attribute
, EGLint
*value
)
342 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
343 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
347 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_FALSE
);
348 ret
= drv
->API
.GetConfigAttrib(drv
, disp
, conf
, attribute
, value
);
350 return _EGL_EVAL(disp
, ret
);
354 EGLContext EGLAPIENTRY
355 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
,
356 const EGLint
*attrib_list
)
358 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
359 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
360 _EGLContext
*share
= _eglLookupContext(share_list
, disp
);
362 _EGLContext
*context
;
365 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_CONTEXT
);
366 if (!share
&& share_list
!= EGL_NO_CONTEXT
)
367 return _EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_CONTEXT
);
369 context
= drv
->API
.CreateContext(drv
, disp
, conf
, share
, attrib_list
);
370 ret
= (context
) ? _eglLinkContext(context
, disp
) : EGL_NO_CONTEXT
;
372 return _EGL_EVAL(disp
, ret
);
376 EGLBoolean EGLAPIENTRY
377 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
379 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
380 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
384 drv
= _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
);
385 _eglUnlinkContext(context
);
386 ret
= drv
->API
.DestroyContext(drv
, disp
, context
);
388 return _EGL_EVAL(disp
, ret
);
392 EGLBoolean EGLAPIENTRY
393 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
396 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
397 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
398 _EGLSurface
*draw_surf
= _eglLookupSurface(draw
, disp
);
399 _EGLSurface
*read_surf
= _eglLookupSurface(read
, disp
);
404 return _EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
407 /* display is allowed to be uninitialized under certain condition */
408 if (!disp
->Initialized
) {
409 if (draw
!= EGL_NO_SURFACE
|| read
!= EGL_NO_SURFACE
||
410 ctx
!= EGL_NO_CONTEXT
)
411 return _EGL_ERROR(disp
, EGL_BAD_DISPLAY
, EGL_FALSE
);
414 return _EGL_SUCCESS(disp
, EGL_TRUE
);
416 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
417 return _EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
418 if ((!draw_surf
&& draw
!= EGL_NO_SURFACE
) ||
419 (!read_surf
&& read
!= EGL_NO_SURFACE
))
420 return _EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
422 ret
= drv
->API
.MakeCurrent(drv
, disp
, draw_surf
, read_surf
, context
);
424 return _EGL_EVAL(disp
, ret
);
428 EGLBoolean EGLAPIENTRY
429 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
430 EGLint attribute
, EGLint
*value
)
432 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
433 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
437 drv
= _EGL_CHECK_CONTEXT(disp
, context
, EGL_FALSE
);
438 ret
= drv
->API
.QueryContext(drv
, disp
, context
, attribute
, value
);
440 return _EGL_EVAL(disp
, ret
);
444 EGLSurface EGLAPIENTRY
445 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
446 EGLNativeWindowType window
, const EGLint
*attrib_list
)
448 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
449 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
454 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
);
456 surf
= drv
->API
.CreateWindowSurface(drv
, disp
, conf
, window
, attrib_list
);
457 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
459 return _EGL_EVAL(disp
, ret
);
463 EGLSurface EGLAPIENTRY
464 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
465 EGLNativePixmapType pixmap
, const EGLint
*attrib_list
)
467 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
468 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
473 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
);
475 surf
= drv
->API
.CreatePixmapSurface(drv
, disp
, conf
, pixmap
, attrib_list
);
476 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
478 return _EGL_EVAL(disp
, ret
);
482 EGLSurface EGLAPIENTRY
483 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
484 const EGLint
*attrib_list
)
486 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
487 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
492 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
);
494 surf
= drv
->API
.CreatePbufferSurface(drv
, disp
, conf
, attrib_list
);
495 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
497 return _EGL_EVAL(disp
, ret
);
501 EGLBoolean EGLAPIENTRY
502 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
504 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
505 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
509 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
510 _eglUnlinkSurface(surf
);
511 ret
= drv
->API
.DestroySurface(drv
, disp
, surf
);
513 return _EGL_EVAL(disp
, ret
);
516 EGLBoolean EGLAPIENTRY
517 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
518 EGLint attribute
, EGLint
*value
)
520 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
521 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
525 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
526 ret
= drv
->API
.QuerySurface(drv
, disp
, surf
, attribute
, value
);
528 return _EGL_EVAL(disp
, ret
);
531 EGLBoolean EGLAPIENTRY
532 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
533 EGLint attribute
, EGLint value
)
535 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
536 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
540 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
541 ret
= drv
->API
.SurfaceAttrib(drv
, disp
, surf
, attribute
, value
);
543 return _EGL_EVAL(disp
, ret
);
547 EGLBoolean EGLAPIENTRY
548 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
550 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
551 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
555 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
556 ret
= drv
->API
.BindTexImage(drv
, disp
, surf
, buffer
);
558 return _EGL_EVAL(disp
, ret
);
562 EGLBoolean EGLAPIENTRY
563 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
565 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
566 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
570 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
571 ret
= drv
->API
.ReleaseTexImage(drv
, disp
, surf
, buffer
);
573 return _EGL_EVAL(disp
, ret
);
577 EGLBoolean EGLAPIENTRY
578 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
580 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
581 _EGLContext
*ctx
= _eglGetCurrentContext();
586 drv
= _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
);
588 if (!ctx
|| !_eglIsContextLinked(ctx
) || ctx
->Resource
.Display
!= disp
)
589 return _EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
591 surf
= ctx
->DrawSurface
;
592 if (!_eglIsSurfaceLinked(surf
))
593 return _EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
595 ret
= drv
->API
.SwapInterval(drv
, disp
, surf
, interval
);
597 return _EGL_EVAL(disp
, ret
);
601 EGLBoolean EGLAPIENTRY
602 eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
604 _EGLContext
*ctx
= _eglGetCurrentContext();
605 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
606 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
610 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
612 /* surface must be bound to current context in EGL 1.4 */
613 if (!ctx
|| !_eglIsContextLinked(ctx
) || surf
!= ctx
->DrawSurface
)
614 return _EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
616 ret
= drv
->API
.SwapBuffers(drv
, disp
, surf
);
618 return _EGL_EVAL(disp
, ret
);
622 EGLBoolean EGLAPIENTRY
623 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, EGLNativePixmapType target
)
625 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
626 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
630 drv
= _EGL_CHECK_SURFACE(disp
, surf
, EGL_FALSE
);
631 ret
= drv
->API
.CopyBuffers(drv
, disp
, surf
, target
);
633 return _EGL_EVAL(disp
, ret
);
637 EGLBoolean EGLAPIENTRY
640 _EGLContext
*ctx
= _eglGetCurrentContext();
646 return _EGL_SUCCESS(NULL
, EGL_TRUE
);
647 /* let bad current context imply bad current surface */
648 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
649 return _EGL_ERROR(NULL
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
651 disp
= ctx
->Resource
.Display
;
653 /* a valid current context implies an initialized current display */
654 assert(disp
->Initialized
);
656 ret
= drv
->API
.WaitClient(drv
, disp
, ctx
);
658 return _EGL_EVAL(NULL
, ret
);
662 EGLBoolean EGLAPIENTRY
665 #ifdef EGL_VERSION_1_2
666 _EGLThreadInfo
*t
= _eglGetCurrentThread();
667 EGLint api_index
= t
->CurrentAPIIndex
;
668 EGLint es_index
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
671 if (api_index
!= es_index
&& _eglIsCurrentThreadDummy())
672 return _EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
674 t
->CurrentAPIIndex
= es_index
;
675 ret
= eglWaitClient();
676 t
->CurrentAPIIndex
= api_index
;
679 return eglWaitClient();
684 EGLBoolean EGLAPIENTRY
685 eglWaitNative(EGLint engine
)
687 _EGLContext
*ctx
= _eglGetCurrentContext();
693 return _EGL_SUCCESS(NULL
, EGL_TRUE
);
695 /* let bad current context imply bad current surface */
696 if (!_eglIsContextLinked(ctx
) || !_eglIsSurfaceLinked(ctx
->DrawSurface
))
697 return _EGL_ERROR(NULL
, EGL_BAD_CURRENT_SURFACE
, EGL_FALSE
);
699 disp
= ctx
->Resource
.Display
;
701 /* a valid current context implies an initialized current display */
702 assert(disp
->Initialized
);
704 ret
= drv
->API
.WaitNative(drv
, disp
, engine
);
706 return _EGL_EVAL(NULL
, ret
);
710 EGLDisplay EGLAPIENTRY
711 eglGetCurrentDisplay(void)
713 _EGLContext
*ctx
= _eglGetCurrentContext();
716 ret
= (ctx
) ? _eglGetDisplayHandle(ctx
->Resource
.Display
) : EGL_NO_DISPLAY
;
718 return _EGL_SUCCESS(NULL
, ret
);
722 EGLContext EGLAPIENTRY
723 eglGetCurrentContext(void)
725 _EGLContext
*ctx
= _eglGetCurrentContext();
728 ret
= _eglGetContextHandle(ctx
);
730 return _EGL_SUCCESS(NULL
, ret
);
734 EGLSurface EGLAPIENTRY
735 eglGetCurrentSurface(EGLint readdraw
)
737 _EGLContext
*ctx
= _eglGetCurrentContext();
738 EGLint err
= EGL_SUCCESS
;
743 return _EGL_SUCCESS(NULL
, EGL_NO_SURFACE
);
747 surf
= ctx
->DrawSurface
;
750 surf
= ctx
->ReadSurface
;
754 err
= EGL_BAD_PARAMETER
;
758 ret
= _eglGetSurfaceHandle(surf
);
760 return _EGL_ERROR(NULL
, err
, ret
);
767 _EGLThreadInfo
*t
= _eglGetCurrentThread();
768 EGLint e
= t
->LastError
;
769 if (!_eglIsCurrentThreadDummy())
770 t
->LastError
= EGL_SUCCESS
;
775 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
776 eglGetProcAddress(const char *procname
)
778 static const struct {
781 } egl_functions
[] = {
782 /* extensions only */
783 #ifdef EGL_MESA_screen_surface
784 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
785 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
786 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
787 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
788 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
789 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
790 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
791 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
792 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
793 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
794 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
795 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
796 #endif /* EGL_MESA_screen_surface */
797 #ifdef EGL_KHR_image_base
798 { "eglCreateImageKHR", (_EGLProc
) eglCreateImageKHR
},
799 { "eglDestroyImageKHR", (_EGLProc
) eglDestroyImageKHR
},
800 #endif /* EGL_KHR_image_base */
807 return _EGL_SUCCESS(NULL
, NULL
);
810 if (strncmp(procname
, "egl", 3) == 0) {
811 for (i
= 0; egl_functions
[i
].name
; i
++) {
812 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
813 ret
= egl_functions
[i
].function
;
819 return _EGL_SUCCESS(NULL
, ret
);
821 _eglPreloadDrivers();
823 /* now loop over drivers to query their procs */
824 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
825 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
826 ret
= drv
->API
.GetProcAddress(drv
, procname
);
831 return _EGL_SUCCESS(NULL
, ret
);
835 #ifdef EGL_MESA_screen_surface
839 * EGL_MESA_screen extension
842 EGLBoolean EGLAPIENTRY
843 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
844 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
845 EGLint modes_size
, EGLint
*num_modes
)
847 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
848 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
852 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
853 ret
= drv
->API
.ChooseModeMESA(drv
, disp
, scrn
, attrib_list
,
854 modes
, modes_size
, num_modes
);
856 return _EGL_EVAL(disp
, ret
);
860 EGLBoolean EGLAPIENTRY
861 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
,
862 EGLint mode_size
, EGLint
*num_mode
)
864 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
865 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
869 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
870 ret
= drv
->API
.GetModesMESA(drv
, disp
, scrn
, modes
, mode_size
, num_mode
);
872 return _EGL_EVAL(disp
, ret
);
876 EGLBoolean EGLAPIENTRY
877 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
,
878 EGLint attribute
, EGLint
*value
)
880 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
881 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
885 drv
= _EGL_CHECK_MODE(disp
, m
, EGL_FALSE
);
886 ret
= drv
->API
.GetModeAttribMESA(drv
, disp
, m
, attribute
, value
);
888 return _EGL_EVAL(disp
, ret
);
892 EGLBoolean EGLAPIENTRY
893 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
,
896 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
897 _EGLContext
*source_context
= _eglLookupContext(source
, disp
);
898 _EGLContext
*dest_context
= _eglLookupContext(dest
, disp
);
902 drv
= _EGL_CHECK_CONTEXT(disp
, source_context
, EGL_FALSE
);
904 return _EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_FALSE
);
906 ret
= drv
->API
.CopyContextMESA(drv
, disp
,
907 source_context
, dest_context
, mask
);
909 return _EGL_EVAL(disp
, ret
);
914 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
,
915 EGLint max_screens
, EGLint
*num_screens
)
917 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
921 drv
= _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
);
922 ret
= drv
->API
.GetScreensMESA(drv
, disp
, screens
, max_screens
, num_screens
);
924 return _EGL_EVAL(disp
, ret
);
929 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
,
930 const EGLint
*attrib_list
)
932 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
933 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
938 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
);
940 surf
= drv
->API
.CreateScreenSurfaceMESA(drv
, disp
, conf
, attrib_list
);
941 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
943 return _EGL_EVAL(disp
, ret
);
948 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
,
949 EGLSurface surface
, EGLModeMESA mode
)
951 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
952 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
953 _EGLSurface
*surf
= _eglLookupSurface(surface
, disp
);
954 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
958 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
959 if (!surf
&& surface
!= EGL_NO_SURFACE
)
960 return _EGL_ERROR(disp
, EGL_BAD_SURFACE
, EGL_FALSE
);
961 if (!m
&& mode
!= EGL_NO_MODE_MESA
)
962 return _EGL_ERROR(disp
, EGL_BAD_MODE_MESA
, EGL_FALSE
);
964 ret
= drv
->API
.ShowScreenSurfaceMESA(drv
, disp
, scrn
, surf
, m
);
966 return _EGL_EVAL(disp
, ret
);
971 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
973 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
974 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
978 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
979 ret
= drv
->API
.ScreenPositionMESA(drv
, disp
, scrn
, x
, y
);
981 return _EGL_EVAL(disp
, ret
);
986 eglQueryScreenMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
987 EGLint attribute
, EGLint
*value
)
989 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
990 _EGLScreen
*scrn
= _eglLookupScreen(screen
, disp
);
994 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
995 ret
= drv
->API
.QueryScreenMESA(drv
, disp
, scrn
, attribute
, value
);
997 return _EGL_EVAL(disp
, ret
);
1002 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
1003 EGLSurface
*surface
)
1005 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
1006 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1011 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
1012 ret
= drv
->API
.QueryScreenSurfaceMESA(drv
, disp
, scrn
, &surf
);
1014 *surface
= _eglGetSurfaceHandle(surf
);
1016 return _EGL_EVAL(disp
, ret
);
1021 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
1023 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
1024 _EGLScreen
*scrn
= _eglLookupScreen((EGLScreenMESA
) screen
, disp
);
1029 drv
= _EGL_CHECK_SCREEN(disp
, scrn
, EGL_FALSE
);
1030 ret
= drv
->API
.QueryScreenModeMESA(drv
, disp
, scrn
, &m
);
1034 return _EGL_EVAL(disp
, ret
);
1039 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
1041 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
1042 _EGLMode
*m
= _eglLookupMode(mode
, disp
);
1046 drv
= _EGL_CHECK_MODE(disp
, m
, NULL
);
1047 ret
= drv
->API
.QueryModeStringMESA(drv
, disp
, m
);
1049 return _EGL_EVAL(disp
, ret
);
1053 #endif /* EGL_MESA_screen_surface */
1060 #ifdef EGL_VERSION_1_2
1064 * Specify the client API to use for subsequent calls including:
1065 * eglCreateContext()
1066 * eglGetCurrentContext()
1067 * eglGetCurrentDisplay()
1068 * eglGetCurrentSurface()
1069 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1072 * See section 3.7 "Rendering Context" in the EGL specification for details.
1075 eglBindAPI(EGLenum api
)
1077 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1079 if (_eglIsCurrentThreadDummy())
1080 return _EGL_ERROR(NULL
, EGL_BAD_ALLOC
, EGL_FALSE
);
1082 if (!_eglIsApiValid(api
))
1083 return _EGL_ERROR(NULL
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1085 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
1087 return _EGL_SUCCESS(NULL
, EGL_TRUE
);
1092 * Return the last value set with eglBindAPI().
1097 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1100 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1101 ret
= _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
1103 return _EGL_SUCCESS(NULL
, ret
);
1108 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
1109 EGLClientBuffer buffer
, EGLConfig config
,
1110 const EGLint
*attrib_list
)
1112 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
1113 _EGLConfig
*conf
= _eglLookupConfig(config
, disp
);
1118 drv
= _EGL_CHECK_CONFIG(disp
, conf
, EGL_NO_SURFACE
);
1120 surf
= drv
->API
.CreatePbufferFromClientBuffer(drv
, disp
, buftype
, buffer
,
1122 ret
= (surf
) ? _eglLinkSurface(surf
, disp
) : EGL_NO_SURFACE
;
1124 return _EGL_EVAL(disp
, ret
);
1129 eglReleaseThread(void)
1131 /* unbind current contexts */
1132 if (!_eglIsCurrentThreadDummy()) {
1133 _EGLThreadInfo
*t
= _eglGetCurrentThread();
1134 EGLint api_index
= t
->CurrentAPIIndex
;
1137 for (i
= 0; i
< _EGL_API_NUM_APIS
; i
++) {
1138 _EGLContext
*ctx
= t
->CurrentContexts
[i
];
1140 _EGLDisplay
*disp
= ctx
->Resource
.Display
;
1141 _EGLDriver
*drv
= disp
->Driver
;
1142 t
->CurrentAPIIndex
= i
;
1143 (void) drv
->API
.MakeCurrent(drv
, disp
, NULL
, NULL
, NULL
);
1147 t
->CurrentAPIIndex
= api_index
;
1150 _eglDestroyCurrentThread();
1152 return _EGL_SUCCESS(NULL
, EGL_TRUE
);
1156 #endif /* EGL_VERSION_1_2 */
1159 #ifdef EGL_KHR_image_base
1163 eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
1164 EGLClientBuffer buffer
, const EGLint
*attr_list
)
1166 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
1167 _EGLContext
*context
= _eglLookupContext(ctx
, disp
);
1172 drv
= _EGL_CHECK_DISPLAY(disp
, EGL_NO_IMAGE_KHR
);
1173 if (!context
&& ctx
!= EGL_NO_CONTEXT
)
1174 return _EGL_ERROR(disp
, EGL_BAD_CONTEXT
, EGL_NO_IMAGE_KHR
);
1176 img
= drv
->API
.CreateImageKHR(drv
,
1177 disp
, context
, target
, buffer
, attr_list
);
1178 ret
= (img
) ? _eglLinkImage(img
, disp
) : EGL_NO_IMAGE_KHR
;
1180 return _EGL_EVAL(disp
, ret
);
1185 eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
1187 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
1188 _EGLImage
*img
= _eglLookupImage(image
, disp
);
1192 drv
= _EGL_CHECK_DISPLAY(disp
, EGL_FALSE
);
1194 return _EGL_ERROR(disp
, EGL_BAD_PARAMETER
, EGL_FALSE
);
1196 _eglUnlinkImage(img
);
1197 ret
= drv
->API
.DestroyImageKHR(drv
, disp
, img
);
1199 return _EGL_EVAL(disp
, ret
);
1203 #endif /* EGL_KHR_image_base */