eglapi.c revision b2006a40eb22899d38cd31691640555228e36975
1/** 2 * Public EGL API entrypoints 3 * 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. 7 * 8 * That allows us the option of supporting multiple, simultaneous, 9 * heterogeneous hardware devices in the future. 10 * 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. 17 * 18 * 19 * Notes on naming conventions: 20 * 21 * eglFooBar - public EGL function 22 * EGL_FOO_BAR - public EGL token 23 * EGLDatatype - public EGL datatype 24 * 25 * _eglFooBar - private EGL function 26 * _EGLDatatype - private EGL datatype, typedef'd struct 27 * _egl_struct - private EGL struct, non-typedef'd 28 * 29 */ 30 31 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <string.h> 36#include "eglcontext.h" 37#include "egldisplay.h" 38#include "egltypedefs.h" 39#include "eglglobals.h" 40#include "egldriver.h" 41#include "eglsurface.h" 42 43 44 45/** 46 * NOTE: displayName is treated as a string in _eglChooseDriver()!!! 47 * This will probably change! 48 * See _eglChooseDriver() for details! 49 */ 50EGLDisplay APIENTRY 51eglGetDisplay(NativeDisplayType displayName) 52{ 53 _EGLDisplay *dpy; 54 _eglInitGlobals(); 55 dpy = _eglNewDisplay(displayName); 56 if (dpy) 57 return dpy->Handle; 58 else 59 return EGL_NO_DISPLAY; 60} 61 62 63EGLBoolean APIENTRY 64eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 65{ 66 if (dpy) { 67 _EGLDriver *drv = _eglChooseDriver(dpy); 68 if (drv) 69 return drv->API.Initialize(drv, dpy, major, minor); 70 } 71 return EGL_FALSE; 72} 73 74 75EGLBoolean APIENTRY 76eglTerminate(EGLDisplay dpy) 77{ 78 _EGLDriver *drv = _eglLookupDriver(dpy); 79 if (drv) 80 return _eglCloseDriver(drv, dpy); 81 else 82 return EGL_FALSE; 83} 84 85 86const char * APIENTRY 87eglQueryString(EGLDisplay dpy, EGLint name) 88{ 89 _EGLDriver *drv = _eglLookupDriver(dpy); 90 if (drv) 91 return drv->API.QueryString(drv, dpy, name); 92 else 93 return NULL; 94} 95 96 97EGLBoolean APIENTRY 98eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) 99{ 100 _EGLDriver *drv = _eglLookupDriver(dpy); 101 /* XXX check drv for null in remaining functions */ 102 return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config); 103} 104 105 106EGLBoolean APIENTRY 107eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) 108{ 109 _EGLDriver *drv = _eglLookupDriver(dpy); 110 return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config); 111} 112 113 114EGLBoolean APIENTRY 115eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) 116{ 117 _EGLDriver *drv = _eglLookupDriver(dpy); 118 return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value); 119} 120 121 122EGLContext APIENTRY 123eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) 124{ 125 _EGLDriver *drv = _eglLookupDriver(dpy); 126 return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list); 127} 128 129 130EGLBoolean APIENTRY 131eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 132{ 133 _EGLDriver *drv = _eglLookupDriver(dpy); 134 return drv->API.DestroyContext(drv, dpy, ctx); 135} 136 137 138EGLBoolean APIENTRY 139eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) 140{ 141 _EGLDriver *drv = _eglLookupDriver(dpy); 142 return drv->API.MakeCurrent(drv, dpy, draw, read, ctx); 143} 144 145 146EGLBoolean APIENTRY 147eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) 148{ 149 _EGLDriver *drv = _eglLookupDriver(dpy); 150 return drv->API.QueryContext(drv, dpy, ctx, attribute, value); 151} 152 153 154EGLSurface APIENTRY 155eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) 156{ 157 _EGLDriver *drv = _eglLookupDriver(dpy); 158 return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list); 159} 160 161 162EGLSurface APIENTRY 163eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) 164{ 165 _EGLDriver *drv = _eglLookupDriver(dpy); 166 return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list); 167} 168 169 170EGLSurface APIENTRY 171eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) 172{ 173 _EGLDriver *drv = _eglLookupDriver(dpy); 174 return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list); 175} 176 177 178EGLBoolean APIENTRY 179eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 180{ 181 _EGLDriver *drv = _eglLookupDriver(dpy); 182 return drv->API.DestroySurface(drv, dpy, surface); 183} 184 185 186EGLBoolean APIENTRY 187eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) 188{ 189 _EGLDriver *drv = _eglLookupDriver(dpy); 190 return drv->API.QuerySurface(drv, dpy, surface, attribute, value); 191} 192 193 194EGLBoolean APIENTRY 195eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) 196{ 197 _EGLDriver *drv = _eglLookupDriver(dpy); 198 return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value); 199} 200 201 202EGLBoolean APIENTRY 203eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 204{ 205 _EGLDriver *drv = _eglLookupDriver(dpy); 206 return drv->API.BindTexImage(drv, dpy, surface, buffer); 207} 208 209 210EGLBoolean APIENTRY 211eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 212{ 213 _EGLDriver *drv = _eglLookupDriver(dpy); 214 return drv->API.ReleaseTexImage(drv, dpy, surface, buffer); 215} 216 217 218EGLBoolean APIENTRY 219eglSwapInterval(EGLDisplay dpy, EGLint interval) 220{ 221 _EGLDriver *drv = _eglLookupDriver(dpy); 222 return drv->API.SwapInterval(drv, dpy, interval); 223} 224 225 226EGLBoolean APIENTRY 227eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) 228{ 229 _EGLDriver *drv = _eglLookupDriver(dpy); 230 return drv->API.SwapBuffers(drv, dpy, draw); 231} 232 233 234EGLBoolean APIENTRY 235eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) 236{ 237 _EGLDriver *drv = _eglLookupDriver(dpy); 238 return drv->API.CopyBuffers(drv, dpy, surface, target); 239} 240 241 242EGLBoolean APIENTRY 243eglWaitGL(void) 244{ 245 EGLDisplay dpy = eglGetCurrentDisplay(); 246 if (dpy != EGL_NO_DISPLAY) { 247 _EGLDriver *drv = _eglLookupDriver(dpy); 248 return drv->API.WaitGL(drv, dpy); 249 } 250 else 251 return EGL_FALSE; 252} 253 254 255EGLBoolean APIENTRY 256eglWaitNative(EGLint engine) 257{ 258 EGLDisplay dpy = eglGetCurrentDisplay(); 259 if (dpy != EGL_NO_DISPLAY) { 260 _EGLDriver *drv = _eglLookupDriver(dpy); 261 return drv->API.WaitNative(drv, dpy, engine); 262 } 263 else 264 return EGL_FALSE; 265} 266 267 268EGLDisplay APIENTRY 269eglGetCurrentDisplay(void) 270{ 271 _EGLDisplay *dpy = _eglGetCurrentDisplay(); 272 if (dpy) 273 return dpy->Handle; 274 else 275 return EGL_NO_DISPLAY; 276} 277 278 279EGLContext APIENTRY 280eglGetCurrentContext(void) 281{ 282 _EGLContext *ctx = _eglGetCurrentContext(); 283 if (ctx) 284 return ctx->Handle; 285 else 286 return EGL_NO_CONTEXT; 287} 288 289 290EGLSurface APIENTRY 291eglGetCurrentSurface(EGLint readdraw) 292{ 293 _EGLSurface *s = _eglGetCurrentSurface(readdraw); 294 if (s) 295 return s->Handle; 296 else 297 return EGL_NO_SURFACE; 298} 299 300 301EGLint APIENTRY 302eglGetError(void) 303{ 304 _EGLThreadInfo *t = _eglGetCurrentThread(); 305 EGLint e = t->LastError; 306 t->LastError = EGL_SUCCESS; 307 return e; 308} 309 310 311void (* APIENTRY eglGetProcAddress(const char *procname))() 312{ 313 typedef void (*genericFunc)(); 314 struct name_function { 315 const char *name; 316 _EGLProc function; 317 }; 318 static struct name_function egl_functions[] = { 319 /* alphabetical order */ 320 { "eglBindTexImage", (_EGLProc) eglBindTexImage }, 321 { "eglChooseConfig", (_EGLProc) eglChooseConfig }, 322 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, 323 { "eglCreateContext", (_EGLProc) eglCreateContext }, 324 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, 325 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, 326 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, 327 { "eglDestroyContext", (_EGLProc) eglDestroyContext }, 328 { "eglDestroySurface", (_EGLProc) eglDestroySurface }, 329 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, 330 { "eglGetConfigs", (_EGLProc) eglGetConfigs }, 331 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, 332 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, 333 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, 334 { "eglGetDisplay", (_EGLProc) eglGetDisplay }, 335 { "eglGetError", (_EGLProc) eglGetError }, 336 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, 337 { "eglInitialize", (_EGLProc) eglInitialize }, 338 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, 339 { "eglQueryContext", (_EGLProc) eglQueryContext }, 340 { "eglQueryString", (_EGLProc) eglQueryString }, 341 { "eglQuerySurface", (_EGLProc) eglQuerySurface }, 342 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, 343 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, 344 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, 345 { "eglSwapInterval", (_EGLProc) eglSwapInterval }, 346 { "eglTerminate", (_EGLProc) eglTerminate }, 347 { "eglWaitGL", (_EGLProc) eglWaitGL }, 348 { "eglWaitNative", (_EGLProc) eglWaitNative }, 349 /* Extensions */ 350#ifdef EGL_MESA_screen_surface 351 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, 352 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, 353 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, 354 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, 355 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, 356 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, 357 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, 358 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, 359 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, 360 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, 361 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, 362 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, 363#endif /* EGL_MESA_screen_surface */ 364#ifdef EGL_VERSION_1_2 365 { "eglBindAPI", (_EGLProc) eglBindAPI }, 366 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, 367 { "eglQueryAPI", (_EGLProc) eglQueryAPI }, 368 { "eglReleaseThread", (_EGLProc) eglReleaseThread }, 369 { "eglWaitClient", (_EGLProc) eglWaitClient }, 370#endif /* EGL_VERSION_1_2 */ 371 { NULL, NULL } 372 }; 373 EGLint i; 374 for (i = 0; egl_functions[i].name; i++) { 375 if (strcmp(egl_functions[i].name, procname) == 0) { 376 return (genericFunc) egl_functions[i].function; 377 } 378 } 379#if 0 380 /* XXX enable this code someday */ 381 return (genericFunc) _glapi_get_proc_address(procname); 382#else 383 return NULL; 384#endif 385} 386 387 388/* 389 * EGL_MESA_screen extension 390 */ 391 392EGLBoolean APIENTRY 393eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, 394 const EGLint *attrib_list, EGLModeMESA *modes, 395 EGLint modes_size, EGLint *num_modes) 396{ 397 _EGLDriver *drv = _eglLookupDriver(dpy); 398 if (drv) 399 return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes); 400 else 401 return EGL_FALSE; 402} 403 404 405EGLBoolean APIENTRY 406eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode) 407{ 408 _EGLDriver *drv = _eglLookupDriver(dpy); 409 if (drv) 410 return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode); 411 else 412 return EGL_FALSE; 413} 414 415 416EGLBoolean APIENTRY 417eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value) 418{ 419 _EGLDriver *drv = _eglLookupDriver(dpy); 420 if (drv) 421 return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value); 422 else 423 return EGL_FALSE; 424} 425 426 427EGLBoolean APIENTRY 428eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask) 429{ 430 _EGLDriver *drv = _eglLookupDriver(dpy); 431 if (drv) 432 return drv->API.CopyContextMESA(drv, dpy, source, dest, mask); 433 else 434 return EGL_FALSE; 435} 436 437 438EGLBoolean 439eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens) 440{ 441 _EGLDriver *drv = _eglLookupDriver(dpy); 442 if (drv) 443 return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens); 444 else 445 return EGL_FALSE; 446} 447 448 449EGLSurface 450eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) 451{ 452 _EGLDriver *drv = _eglLookupDriver(dpy); 453 return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list); 454} 455 456 457EGLBoolean 458eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode) 459{ 460 _EGLDriver *drv = _eglLookupDriver(dpy); 461 return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode); 462} 463 464 465EGLBoolean 466eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) 467{ 468 _EGLDriver *drv = _eglLookupDriver(dpy); 469 return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y); 470} 471 472 473EGLBoolean 474eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value) 475{ 476 _EGLDriver *drv = _eglLookupDriver(dpy); 477 return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value); 478} 479 480 481EGLBoolean 482eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface) 483{ 484 _EGLDriver *drv = _eglLookupDriver(dpy); 485 return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface); 486} 487 488 489EGLBoolean 490eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) 491{ 492 _EGLDriver *drv = _eglLookupDriver(dpy); 493 return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode); 494} 495 496 497const char * 498eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) 499{ 500 _EGLDriver *drv = _eglLookupDriver(dpy); 501 return drv->API.QueryModeStringMESA(drv, dpy, mode); 502} 503 504 505/** 506 ** EGL 1.2 507 **/ 508 509#ifdef EGL_VERSION_1_2 510 511EGLBoolean 512eglBindAPI(EGLenum api) 513{ 514 _EGLThreadInfo *t = _eglGetCurrentThread(); 515 516 switch (api) { 517 case EGL_OPENGL_ES_API: 518 if (_eglGlobal.OpenGLESAPISupported) { 519 t->CurrentAPI = api; 520 return EGL_TRUE; 521 } 522 _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); 523 return EGL_FALSE; 524 case EGL_OPENVG_API: 525 if (_eglGlobal.OpenVGAPISupported) { 526 t->CurrentAPI = api; 527 return EGL_TRUE; 528 } 529 _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); 530 return EGL_FALSE; 531 default: 532 return EGL_FALSE; 533 } 534 return EGL_TRUE; 535} 536 537 538EGLSurface 539eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, 540 EGLClientBuffer buffer, EGLConfig config, 541 const EGLint *attrib_list) 542{ 543 _EGLDriver *drv = _eglLookupDriver(dpy); 544 return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer, 545 config, attrib_list); 546} 547 548 549EGLenum 550eglQueryAPI(void) 551{ 552 /* returns one of EGL_OPENGL_ES_API or EGL_OPENVG_API */ 553 _EGLThreadInfo *t = _eglGetCurrentThread(); 554 return t->CurrentAPI; 555} 556 557 558EGLBoolean 559eglReleaseThread(void) 560{ 561 _EGLThreadInfo *t = _eglGetCurrentThread(); 562 EGLDisplay dpy = eglGetCurrentDisplay(); 563 if (dpy) { 564 _EGLDriver *drv = _eglLookupDriver(dpy); 565 /* unbind context */ 566 (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE, 567 EGL_NO_SURFACE, EGL_NO_CONTEXT); 568 } 569 _eglDeleteThreadData(t); 570 return EGL_TRUE; 571} 572 573 574EGLBoolean 575eglWaitClient(void) 576{ 577 EGLDisplay dpy = eglGetCurrentDisplay(); 578 if (dpy != EGL_NO_DISPLAY) { 579 _EGLDriver *drv = _eglLookupDriver(dpy); 580 return drv->API.WaitClient(drv, dpy); 581 } 582 else 583 return EGL_FALSE; 584} 585 586#endif /* EGL_VERSION_1_2 */ 587