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 implemented with 32-bit unsigned integers.
13 * It's up to the driver function or fallback function to look up the
14 * handle and get an object.
15 * By using opaque handles, we leave open the possibility of having
16 * indirect rendering in the future, like GLX.
19 * Notes on naming conventions:
21 * eglFooBar - public EGL function
22 * EGL_FOO_BAR - public EGL token
23 * EGLDatatype - public EGL datatype
25 * _eglFooBar - private EGL function
26 * _EGLDatatype - private EGL datatype, typedef'd struct
27 * _egl_struct - private EGL struct, non-typedef'd
36 #include "eglcontext.h"
37 #include "egldisplay.h"
38 #include "egltypedefs.h"
39 #include "eglglobals.h"
40 #include "egldriver.h"
41 #include "eglsurface.h"
46 * This is typically the first EGL function that an application calls.
47 * We initialize our global vars and create a private _EGLDisplay object.
49 EGLDisplay EGLAPIENTRY
50 eglGetDisplay(NativeDisplayType nativeDisplay
)
53 dpy
= _eglFindDisplay(nativeDisplay
);
55 dpy
= _eglNewDisplay(nativeDisplay
);
59 return _eglGetDisplayHandle(dpy
);
64 * This is typically the second EGL function that an application calls.
65 * Here we load/initialize the actual hardware driver.
67 EGLBoolean EGLAPIENTRY
68 eglInitialize(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
)
70 EGLint major_int
, minor_int
;
74 _EGLDisplay
*dpyPriv
= _eglLookupDisplay(dpy
);
78 dpyPriv
->Driver
= _eglOpenDriver(dpyPriv
,
81 if (!dpyPriv
->Driver
) {
84 /* Initialize the particular driver now */
85 retVal
= dpyPriv
->Driver
->API
.Initialize(dpyPriv
->Driver
, dpy
,
86 &major_int
, &minor_int
);
88 dpyPriv
->Driver
->APImajor
= major_int
;
89 dpyPriv
->Driver
->APIminor
= minor_int
;
90 snprintf(dpyPriv
->Driver
->Version
, sizeof(dpyPriv
->Driver
->Version
),
91 "%d.%d (%s)", major_int
, minor_int
, dpyPriv
->Driver
->Name
);
93 /* Update applications version of major and minor if not NULL */
94 if((major
!= NULL
) && (minor
!= NULL
))
106 EGLBoolean EGLAPIENTRY
107 eglTerminate(EGLDisplay dpy
)
109 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
111 return _eglCloseDriver(drv
, dpy
);
117 const char * EGLAPIENTRY
118 eglQueryString(EGLDisplay dpy
, EGLint name
)
120 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
122 return drv
->API
.QueryString(drv
, dpy
, name
);
128 EGLBoolean EGLAPIENTRY
129 eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
, EGLint config_size
, EGLint
*num_config
)
131 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
132 /* XXX check drv for null in remaining functions */
133 return drv
->API
.GetConfigs(drv
, dpy
, configs
, config_size
, num_config
);
137 EGLBoolean EGLAPIENTRY
138 eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
, EGLint config_size
, EGLint
*num_config
)
140 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
141 return drv
->API
.ChooseConfig(drv
, dpy
, attrib_list
, configs
, config_size
, num_config
);
145 EGLBoolean EGLAPIENTRY
146 eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
, EGLint attribute
, EGLint
*value
)
148 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
149 return drv
->API
.GetConfigAttrib(drv
, dpy
, config
, attribute
, value
);
153 EGLContext EGLAPIENTRY
154 eglCreateContext(EGLDisplay dpy
, EGLConfig config
, EGLContext share_list
, const EGLint
*attrib_list
)
156 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
157 return drv
->API
.CreateContext(drv
, dpy
, config
, share_list
, attrib_list
);
161 EGLBoolean EGLAPIENTRY
162 eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
164 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
165 return drv
->API
.DestroyContext(drv
, dpy
, ctx
);
169 EGLBoolean EGLAPIENTRY
170 eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
, EGLContext ctx
)
172 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
173 return drv
->API
.MakeCurrent(drv
, dpy
, draw
, read
, ctx
);
177 EGLBoolean EGLAPIENTRY
178 eglQueryContext(EGLDisplay dpy
, EGLContext ctx
, EGLint attribute
, EGLint
*value
)
180 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
181 return drv
->API
.QueryContext(drv
, dpy
, ctx
, attribute
, value
);
185 EGLSurface EGLAPIENTRY
186 eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
, NativeWindowType window
, const EGLint
*attrib_list
)
188 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
189 return drv
->API
.CreateWindowSurface(drv
, dpy
, config
, window
, attrib_list
);
193 EGLSurface EGLAPIENTRY
194 eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
, NativePixmapType pixmap
, const EGLint
*attrib_list
)
196 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
197 return drv
->API
.CreatePixmapSurface(drv
, dpy
, config
, pixmap
, attrib_list
);
201 EGLSurface EGLAPIENTRY
202 eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
, const EGLint
*attrib_list
)
204 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
205 return drv
->API
.CreatePbufferSurface(drv
, dpy
, config
, attrib_list
);
209 EGLBoolean EGLAPIENTRY
210 eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
212 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
213 return drv
->API
.DestroySurface(drv
, dpy
, surface
);
217 EGLBoolean EGLAPIENTRY
218 eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
, EGLint attribute
, EGLint
*value
)
220 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
221 return drv
->API
.QuerySurface(drv
, dpy
, surface
, attribute
, value
);
225 EGLBoolean EGLAPIENTRY
226 eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
, EGLint attribute
, EGLint value
)
228 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
229 return drv
->API
.SurfaceAttrib(drv
, dpy
, surface
, attribute
, value
);
233 EGLBoolean EGLAPIENTRY
234 eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
236 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
237 return drv
->API
.BindTexImage(drv
, dpy
, surface
, buffer
);
241 EGLBoolean EGLAPIENTRY
242 eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
244 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
245 return drv
->API
.ReleaseTexImage(drv
, dpy
, surface
, buffer
);
249 EGLBoolean EGLAPIENTRY
250 eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
252 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
253 return drv
->API
.SwapInterval(drv
, dpy
, interval
);
257 EGLBoolean EGLAPIENTRY
258 eglSwapBuffers(EGLDisplay dpy
, EGLSurface draw
)
260 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
261 return drv
->API
.SwapBuffers(drv
, dpy
, draw
);
265 EGLBoolean EGLAPIENTRY
266 eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
, NativePixmapType target
)
268 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
269 return drv
->API
.CopyBuffers(drv
, dpy
, surface
, target
);
273 EGLBoolean EGLAPIENTRY
276 EGLDisplay dpy
= eglGetCurrentDisplay();
277 if (dpy
!= EGL_NO_DISPLAY
) {
278 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
279 return drv
->API
.WaitGL(drv
, dpy
);
286 EGLBoolean EGLAPIENTRY
287 eglWaitNative(EGLint engine
)
289 EGLDisplay dpy
= eglGetCurrentDisplay();
290 if (dpy
!= EGL_NO_DISPLAY
) {
291 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
292 return drv
->API
.WaitNative(drv
, dpy
, engine
);
299 EGLDisplay EGLAPIENTRY
300 eglGetCurrentDisplay(void)
302 _EGLDisplay
*dpy
= _eglGetCurrentDisplay();
303 return _eglGetDisplayHandle(dpy
);
307 EGLContext EGLAPIENTRY
308 eglGetCurrentContext(void)
310 _EGLContext
*ctx
= _eglGetCurrentContext();
311 return _eglGetContextHandle(ctx
);
315 EGLSurface EGLAPIENTRY
316 eglGetCurrentSurface(EGLint readdraw
)
318 _EGLSurface
*s
= _eglGetCurrentSurface(readdraw
);
319 return _eglGetSurfaceHandle(s
);
326 _EGLThreadInfo
*t
= _eglGetCurrentThread();
327 EGLint e
= t
->LastError
;
328 if (!_eglIsCurrentThreadDummy())
329 t
->LastError
= EGL_SUCCESS
;
334 void (* EGLAPIENTRY
eglGetProcAddress(const char *procname
))()
336 typedef void (*genericFunc
)();
337 struct name_function
{
341 static struct name_function egl_functions
[] = {
342 /* alphabetical order */
343 { "eglBindTexImage", (_EGLProc
) eglBindTexImage
},
344 { "eglChooseConfig", (_EGLProc
) eglChooseConfig
},
345 { "eglCopyBuffers", (_EGLProc
) eglCopyBuffers
},
346 { "eglCreateContext", (_EGLProc
) eglCreateContext
},
347 { "eglCreatePbufferSurface", (_EGLProc
) eglCreatePbufferSurface
},
348 { "eglCreatePixmapSurface", (_EGLProc
) eglCreatePixmapSurface
},
349 { "eglCreateWindowSurface", (_EGLProc
) eglCreateWindowSurface
},
350 { "eglDestroyContext", (_EGLProc
) eglDestroyContext
},
351 { "eglDestroySurface", (_EGLProc
) eglDestroySurface
},
352 { "eglGetConfigAttrib", (_EGLProc
) eglGetConfigAttrib
},
353 { "eglGetConfigs", (_EGLProc
) eglGetConfigs
},
354 { "eglGetCurrentContext", (_EGLProc
) eglGetCurrentContext
},
355 { "eglGetCurrentDisplay", (_EGLProc
) eglGetCurrentDisplay
},
356 { "eglGetCurrentSurface", (_EGLProc
) eglGetCurrentSurface
},
357 { "eglGetDisplay", (_EGLProc
) eglGetDisplay
},
358 { "eglGetError", (_EGLProc
) eglGetError
},
359 { "eglGetProcAddress", (_EGLProc
) eglGetProcAddress
},
360 { "eglInitialize", (_EGLProc
) eglInitialize
},
361 { "eglMakeCurrent", (_EGLProc
) eglMakeCurrent
},
362 { "eglQueryContext", (_EGLProc
) eglQueryContext
},
363 { "eglQueryString", (_EGLProc
) eglQueryString
},
364 { "eglQuerySurface", (_EGLProc
) eglQuerySurface
},
365 { "eglReleaseTexImage", (_EGLProc
) eglReleaseTexImage
},
366 { "eglSurfaceAttrib", (_EGLProc
) eglSurfaceAttrib
},
367 { "eglSwapBuffers", (_EGLProc
) eglSwapBuffers
},
368 { "eglSwapInterval", (_EGLProc
) eglSwapInterval
},
369 { "eglTerminate", (_EGLProc
) eglTerminate
},
370 { "eglWaitGL", (_EGLProc
) eglWaitGL
},
371 { "eglWaitNative", (_EGLProc
) eglWaitNative
},
373 #ifdef EGL_MESA_screen_surface
374 { "eglChooseModeMESA", (_EGLProc
) eglChooseModeMESA
},
375 { "eglGetModesMESA", (_EGLProc
) eglGetModesMESA
},
376 { "eglGetModeAttribMESA", (_EGLProc
) eglGetModeAttribMESA
},
377 { "eglCopyContextMESA", (_EGLProc
) eglCopyContextMESA
},
378 { "eglGetScreensMESA", (_EGLProc
) eglGetScreensMESA
},
379 { "eglCreateScreenSurfaceMESA", (_EGLProc
) eglCreateScreenSurfaceMESA
},
380 { "eglShowScreenSurfaceMESA", (_EGLProc
) eglShowScreenSurfaceMESA
},
381 { "eglScreenPositionMESA", (_EGLProc
) eglScreenPositionMESA
},
382 { "eglQueryScreenMESA", (_EGLProc
) eglQueryScreenMESA
},
383 { "eglQueryScreenSurfaceMESA", (_EGLProc
) eglQueryScreenSurfaceMESA
},
384 { "eglQueryScreenModeMESA", (_EGLProc
) eglQueryScreenModeMESA
},
385 { "eglQueryModeStringMESA", (_EGLProc
) eglQueryModeStringMESA
},
386 #endif /* EGL_MESA_screen_surface */
387 #ifdef EGL_VERSION_1_2
388 { "eglBindAPI", (_EGLProc
) eglBindAPI
},
389 { "eglCreatePbufferFromClientBuffer", (_EGLProc
) eglCreatePbufferFromClientBuffer
},
390 { "eglQueryAPI", (_EGLProc
) eglQueryAPI
},
391 { "eglReleaseThread", (_EGLProc
) eglReleaseThread
},
392 { "eglWaitClient", (_EGLProc
) eglWaitClient
},
393 #endif /* EGL_VERSION_1_2 */
397 for (i
= 0; egl_functions
[i
].name
; i
++) {
398 if (strcmp(egl_functions
[i
].name
, procname
) == 0) {
399 return (genericFunc
) egl_functions
[i
].function
;
403 /* now loop over drivers to query their procs */
404 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
405 _EGLProc p
= _eglGlobal
.Drivers
[i
]->API
.GetProcAddress(procname
);
415 * EGL_MESA_screen extension
418 EGLBoolean EGLAPIENTRY
419 eglChooseModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
,
420 const EGLint
*attrib_list
, EGLModeMESA
*modes
,
421 EGLint modes_size
, EGLint
*num_modes
)
423 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
425 return drv
->API
.ChooseModeMESA(drv
, dpy
, screen
, attrib_list
, modes
, modes_size
, num_modes
);
431 EGLBoolean EGLAPIENTRY
432 eglGetModesMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*modes
, EGLint mode_size
, EGLint
*num_mode
)
434 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
436 return drv
->API
.GetModesMESA(drv
, dpy
, screen
, modes
, mode_size
, num_mode
);
442 EGLBoolean EGLAPIENTRY
443 eglGetModeAttribMESA(EGLDisplay dpy
, EGLModeMESA mode
, EGLint attribute
, EGLint
*value
)
445 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
447 return drv
->API
.GetModeAttribMESA(drv
, dpy
, mode
, attribute
, value
);
453 EGLBoolean EGLAPIENTRY
454 eglCopyContextMESA(EGLDisplay dpy
, EGLContext source
, EGLContext dest
, EGLint mask
)
456 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
458 return drv
->API
.CopyContextMESA(drv
, dpy
, source
, dest
, mask
);
465 eglGetScreensMESA(EGLDisplay dpy
, EGLScreenMESA
*screens
, EGLint max_screens
, EGLint
*num_screens
)
467 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
469 return drv
->API
.GetScreensMESA(drv
, dpy
, screens
, max_screens
, num_screens
);
476 eglCreateScreenSurfaceMESA(EGLDisplay dpy
, EGLConfig config
, const EGLint
*attrib_list
)
478 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
479 return drv
->API
.CreateScreenSurfaceMESA(drv
, dpy
, config
, attrib_list
);
484 eglShowScreenSurfaceMESA(EGLDisplay dpy
, EGLint screen
, EGLSurface surface
, EGLModeMESA mode
)
486 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
487 return drv
->API
.ShowScreenSurfaceMESA(drv
, dpy
, screen
, surface
, mode
);
492 eglScreenPositionMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLint x
, EGLint y
)
494 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
495 return drv
->API
.ScreenPositionMESA(drv
, dpy
, screen
, x
, y
);
500 eglQueryScreenMESA( EGLDisplay dpy
, EGLScreenMESA screen
, EGLint attribute
, EGLint
*value
)
502 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
503 return drv
->API
.QueryScreenMESA(drv
, dpy
, screen
, attribute
, value
);
508 eglQueryScreenSurfaceMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLSurface
*surface
)
510 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
511 return drv
->API
.QueryScreenSurfaceMESA(drv
, dpy
, screen
, surface
);
516 eglQueryScreenModeMESA(EGLDisplay dpy
, EGLScreenMESA screen
, EGLModeMESA
*mode
)
518 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
519 return drv
->API
.QueryScreenModeMESA(drv
, dpy
, screen
, mode
);
524 eglQueryModeStringMESA(EGLDisplay dpy
, EGLModeMESA mode
)
526 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
527 return drv
->API
.QueryModeStringMESA(drv
, dpy
, mode
);
535 #ifdef EGL_VERSION_1_2
539 * Specify the client API to use for subsequent calls including:
541 * eglGetCurrentContext()
542 * eglGetCurrentDisplay()
543 * eglGetCurrentSurface()
544 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
547 * See section 3.7 "Rendering Context" in the EGL specification for details.
550 eglBindAPI(EGLenum api
)
552 _EGLThreadInfo
*t
= _eglGetCurrentThread();
554 if (_eglIsCurrentThreadDummy())
555 return _eglError(EGL_BAD_ALLOC
, "eglBindAPI");
557 if (!_eglIsApiValid(api
))
558 return _eglError(EGL_BAD_PARAMETER
, "eglBindAPI");
561 #ifdef EGL_VERSION_1_4
563 if (_eglGlobal
.ClientAPIsMask
& EGL_OPENGL_BIT
) {
564 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
567 _eglError(EGL_BAD_PARAMETER
, "eglBindAPI");
570 case EGL_OPENGL_ES_API
:
571 if (_eglGlobal
.ClientAPIsMask
& (EGL_OPENGL_ES_BIT
| EGL_OPENGL_ES2_BIT
)) {
572 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
575 _eglError(EGL_BAD_PARAMETER
, "eglBindAPI");
578 if (_eglGlobal
.ClientAPIsMask
& EGL_OPENVG_BIT
) {
579 t
->CurrentAPIIndex
= _eglConvertApiToIndex(api
);
582 _eglError(EGL_BAD_PARAMETER
, "eglBindAPI");
592 * Return the last value set with eglBindAPI().
597 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
598 _EGLThreadInfo
*t
= _eglGetCurrentThread();
599 return _eglConvertApiFromIndex(t
->CurrentAPIIndex
);
604 eglCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
605 EGLClientBuffer buffer
, EGLConfig config
,
606 const EGLint
*attrib_list
)
608 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
609 return drv
->API
.CreatePbufferFromClientBuffer(drv
, dpy
, buftype
, buffer
,
610 config
, attrib_list
);
615 eglReleaseThread(void)
619 if (_eglIsCurrentThreadDummy())
622 dpy
= eglGetCurrentDisplay();
624 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
626 (void) drv
->API
.MakeCurrent(drv
, dpy
, EGL_NO_SURFACE
,
627 EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
629 _eglDestroyCurrentThread();
637 EGLDisplay dpy
= eglGetCurrentDisplay();
638 if (dpy
!= EGL_NO_DISPLAY
) {
639 _EGLDriver
*drv
= _eglLookupDriver(dpy
);
640 return drv
->API
.WaitClient(drv
, dpy
);
646 #endif /* EGL_VERSION_1_2 */