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