eglapi.c revision 848b8605
1/************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5 * Copyright 2010-2011 LunarG, Inc. 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sub license, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial portions 18 * of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 * 28 **************************************************************************/ 29 30 31/** 32 * Public EGL API entrypoints 33 * 34 * Generally, we use the EGLDisplay parameter as a key to lookup the 35 * appropriate device driver handle, then jump though the driver's 36 * dispatch table to handle the function. 37 * 38 * That allows us the option of supporting multiple, simultaneous, 39 * heterogeneous hardware devices in the future. 40 * 41 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are 42 * opaque handles. Internal objects are linked to a display to 43 * create the handles. 44 * 45 * For each public API entry point, the opaque handles are looked up 46 * before being dispatched to the drivers. When it fails to look up 47 * a handle, one of 48 * 49 * EGL_BAD_DISPLAY 50 * EGL_BAD_CONFIG 51 * EGL_BAD_CONTEXT 52 * EGL_BAD_SURFACE 53 * EGL_BAD_SCREEN_MESA 54 * EGL_BAD_MODE_MESA 55 * 56 * is generated and the driver function is not called. An 57 * uninitialized EGLDisplay has no driver associated with it. When 58 * such display is detected, 59 * 60 * EGL_NOT_INITIALIZED 61 * 62 * is generated. 63 * 64 * Some of the entry points use current display, context, or surface 65 * implicitly. For such entry points, the implicit objects are also 66 * checked before calling the driver function. Other than the 67 * errors listed above, 68 * 69 * EGL_BAD_CURRENT_SURFACE 70 * 71 * may also be generated. 72 * 73 * Notes on naming conventions: 74 * 75 * eglFooBar - public EGL function 76 * EGL_FOO_BAR - public EGL token 77 * EGLDatatype - public EGL datatype 78 * 79 * _eglFooBar - private EGL function 80 * _EGLDatatype - private EGL datatype, typedef'd struct 81 * _egl_struct - private EGL struct, non-typedef'd 82 * 83 */ 84 85 86#include <stdio.h> 87#include <stdlib.h> 88#include <string.h> 89 90#include "eglglobals.h" 91#include "eglcontext.h" 92#include "egldisplay.h" 93#include "egltypedefs.h" 94#include "eglcurrent.h" 95#include "egldriver.h" 96#include "eglsurface.h" 97#include "eglconfig.h" 98#include "eglscreen.h" 99#include "eglmode.h" 100#include "eglimage.h" 101#include "eglsync.h" 102 103 104/** 105 * Macros to help return an API entrypoint. 106 * 107 * These macros will unlock the display and record the error code. 108 */ 109#define RETURN_EGL_ERROR(disp, err, ret) \ 110 do { \ 111 if (disp) \ 112 _eglUnlockDisplay(disp); \ 113 /* EGL error codes are non-zero */ \ 114 if (err) \ 115 _eglError(err, __FUNCTION__); \ 116 return ret; \ 117 } while (0) 118 119#define RETURN_EGL_SUCCESS(disp, ret) \ 120 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret) 121 122/* record EGL_SUCCESS only when ret evaluates to true */ 123#define RETURN_EGL_EVAL(disp, ret) \ 124 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) 125 126 127/* 128 * A bunch of macros and checks to simplify error checking. 129 */ 130 131#define _EGL_CHECK_DISPLAY(disp, ret, drv) \ 132 do { \ 133 drv = _eglCheckDisplay(disp, __FUNCTION__); \ 134 if (!drv) \ 135 RETURN_EGL_ERROR(disp, 0, ret); \ 136 } while (0) 137 138#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \ 139 do { \ 140 drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ 141 if (!drv) \ 142 RETURN_EGL_ERROR(disp, 0, ret); \ 143 } while (0) 144 145#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \ 146 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv) 147 148#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \ 149 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv) 150 151#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \ 152 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv) 153 154#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \ 155 _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv) 156 157#define _EGL_CHECK_MODE(disp, m, ret, drv) \ 158 _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) 159 160#define _EGL_CHECK_SYNC(disp, s, ret, drv) \ 161 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) 162 163 164static INLINE _EGLDriver * 165_eglCheckDisplay(_EGLDisplay *disp, const char *msg) 166{ 167 if (!disp) { 168 _eglError(EGL_BAD_DISPLAY, msg); 169 return NULL; 170 } 171 if (!disp->Initialized) { 172 _eglError(EGL_NOT_INITIALIZED, msg); 173 return NULL; 174 } 175 return disp->Driver; 176} 177 178 179static INLINE _EGLDriver * 180_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) 181{ 182 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 183 if (!drv) 184 return NULL; 185 if (!surf) { 186 _eglError(EGL_BAD_SURFACE, msg); 187 return NULL; 188 } 189 return drv; 190} 191 192 193static INLINE _EGLDriver * 194_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) 195{ 196 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 197 if (!drv) 198 return NULL; 199 if (!context) { 200 _eglError(EGL_BAD_CONTEXT, msg); 201 return NULL; 202 } 203 return drv; 204} 205 206 207static INLINE _EGLDriver * 208_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) 209{ 210 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 211 if (!drv) 212 return NULL; 213 if (!conf) { 214 _eglError(EGL_BAD_CONFIG, msg); 215 return NULL; 216 } 217 return drv; 218} 219 220 221static INLINE _EGLDriver * 222_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) 223{ 224 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 225 if (!drv) 226 return NULL; 227 if (!s) { 228 _eglError(EGL_BAD_PARAMETER, msg); 229 return NULL; 230 } 231 return drv; 232} 233 234 235#ifdef EGL_MESA_screen_surface 236 237 238static INLINE _EGLDriver * 239_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) 240{ 241 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 242 if (!drv) 243 return NULL; 244 if (!scrn) { 245 _eglError(EGL_BAD_SCREEN_MESA, msg); 246 return NULL; 247 } 248 return drv; 249} 250 251 252static INLINE _EGLDriver * 253_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) 254{ 255 _EGLDriver *drv = _eglCheckDisplay(disp, msg); 256 if (!drv) 257 return NULL; 258 if (!m) { 259 _eglError(EGL_BAD_MODE_MESA, msg); 260 return NULL; 261 } 262 return drv; 263} 264 265 266#endif /* EGL_MESA_screen_surface */ 267 268 269/** 270 * Lookup and lock a display. 271 */ 272static INLINE _EGLDisplay * 273_eglLockDisplay(EGLDisplay display) 274{ 275 _EGLDisplay *dpy = _eglLookupDisplay(display); 276 if (dpy) 277 _eglLockMutex(&dpy->Mutex); 278 return dpy; 279} 280 281 282/** 283 * Unlock a display. 284 */ 285static INLINE void 286_eglUnlockDisplay(_EGLDisplay *dpy) 287{ 288 _eglUnlockMutex(&dpy->Mutex); 289} 290 291 292/** 293 * This is typically the first EGL function that an application calls. 294 * It associates a private _EGLDisplay object to the native display. 295 */ 296EGLDisplay EGLAPIENTRY 297eglGetDisplay(EGLNativeDisplayType nativeDisplay) 298{ 299 _EGLPlatformType plat; 300 _EGLDisplay *dpy; 301 void *native_display_ptr; 302 303 STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay)); 304 native_display_ptr = (void*) nativeDisplay; 305 306 plat = _eglGetNativePlatform(native_display_ptr); 307 dpy = _eglFindDisplay(plat, native_display_ptr); 308 return _eglGetDisplayHandle(dpy); 309} 310 311EGLDisplay EGLAPIENTRY 312eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, 313 const EGLint *attrib_list) 314{ 315 _EGLDisplay *dpy; 316 317 switch (platform) { 318#ifdef HAVE_X11_PLATFORM 319 case EGL_PLATFORM_X11_EXT: 320 dpy = _eglGetX11Display((Display*) native_display, attrib_list); 321 break; 322#endif 323#ifdef HAVE_DRM_PLATFORM 324 case EGL_PLATFORM_GBM_MESA: 325 dpy = _eglGetGbmDisplay((struct gbm_device*) native_display, 326 attrib_list); 327 break; 328#endif 329#ifdef HAVE_WAYLAND_PLATFORM 330 case EGL_PLATFORM_WAYLAND_EXT: 331 dpy = _eglGetWaylandDisplay((struct wl_display*) native_display, 332 attrib_list); 333 break; 334#endif 335 default: 336 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL); 337 } 338 339 return _eglGetDisplayHandle(dpy); 340} 341 342/** 343 * This is typically the second EGL function that an application calls. 344 * Here we load/initialize the actual hardware driver. 345 */ 346EGLBoolean EGLAPIENTRY 347eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 348{ 349 _EGLDisplay *disp = _eglLockDisplay(dpy); 350 351 if (!disp) 352 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 353 354 if (!disp->Initialized) { 355 if (!_eglMatchDriver(disp, EGL_FALSE)) 356 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); 357 358 /* limit to APIs supported by core */ 359 disp->ClientAPIs &= _EGL_API_ALL_BITS; 360 } 361 362 /* Update applications version of major and minor if not NULL */ 363 if ((major != NULL) && (minor != NULL)) { 364 *major = disp->VersionMajor; 365 *minor = disp->VersionMinor; 366 } 367 368 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 369} 370 371 372EGLBoolean EGLAPIENTRY 373eglTerminate(EGLDisplay dpy) 374{ 375 _EGLDisplay *disp = _eglLockDisplay(dpy); 376 377 if (!disp) 378 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 379 380 if (disp->Initialized) { 381 _EGLDriver *drv = disp->Driver; 382 383 drv->API.Terminate(drv, disp); 384 /* do not reset disp->Driver */ 385 disp->Initialized = EGL_FALSE; 386 } 387 388 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 389} 390 391 392const char * EGLAPIENTRY 393eglQueryString(EGLDisplay dpy, EGLint name) 394{ 395 _EGLDisplay *disp; 396 _EGLDriver *drv; 397 const char *ret; 398 399 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) { 400 RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString); 401 } 402 403 disp = _eglLockDisplay(dpy); 404 _EGL_CHECK_DISPLAY(disp, NULL, drv); 405 ret = drv->API.QueryString(drv, disp, name); 406 407 RETURN_EGL_EVAL(disp, ret); 408} 409 410 411EGLBoolean EGLAPIENTRY 412eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, 413 EGLint config_size, EGLint *num_config) 414{ 415 _EGLDisplay *disp = _eglLockDisplay(dpy); 416 _EGLDriver *drv; 417 EGLBoolean ret; 418 419 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 420 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config); 421 422 RETURN_EGL_EVAL(disp, ret); 423} 424 425 426EGLBoolean EGLAPIENTRY 427eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, 428 EGLint config_size, EGLint *num_config) 429{ 430 _EGLDisplay *disp = _eglLockDisplay(dpy); 431 _EGLDriver *drv; 432 EGLBoolean ret; 433 434 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 435 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, 436 config_size, num_config); 437 438 RETURN_EGL_EVAL(disp, ret); 439} 440 441 442EGLBoolean EGLAPIENTRY 443eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 444 EGLint attribute, EGLint *value) 445{ 446 _EGLDisplay *disp = _eglLockDisplay(dpy); 447 _EGLConfig *conf = _eglLookupConfig(config, disp); 448 _EGLDriver *drv; 449 EGLBoolean ret; 450 451 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv); 452 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); 453 454 RETURN_EGL_EVAL(disp, ret); 455} 456 457 458EGLContext EGLAPIENTRY 459eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, 460 const EGLint *attrib_list) 461{ 462 _EGLDisplay *disp = _eglLockDisplay(dpy); 463 _EGLConfig *conf = _eglLookupConfig(config, disp); 464 _EGLContext *share = _eglLookupContext(share_list, disp); 465 _EGLDriver *drv; 466 _EGLContext *context; 467 EGLContext ret; 468 469 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv); 470 471 if (!config && !disp->Extensions.MESA_configless_context) 472 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT); 473 474 if (!share && share_list != EGL_NO_CONTEXT) 475 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); 476 477 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); 478 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT; 479 480 RETURN_EGL_EVAL(disp, ret); 481} 482 483 484EGLBoolean EGLAPIENTRY 485eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 486{ 487 _EGLDisplay *disp = _eglLockDisplay(dpy); 488 _EGLContext *context = _eglLookupContext(ctx, disp); 489 _EGLDriver *drv; 490 EGLBoolean ret; 491 492 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); 493 _eglUnlinkContext(context); 494 ret = drv->API.DestroyContext(drv, disp, context); 495 496 RETURN_EGL_EVAL(disp, ret); 497} 498 499 500EGLBoolean EGLAPIENTRY 501eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, 502 EGLContext ctx) 503{ 504 _EGLDisplay *disp = _eglLockDisplay(dpy); 505 _EGLContext *context = _eglLookupContext(ctx, disp); 506 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); 507 _EGLSurface *read_surf = _eglLookupSurface(read, disp); 508 _EGLDriver *drv; 509 EGLBoolean ret; 510 511 if (!disp) 512 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 513 drv = disp->Driver; 514 515 /* display is allowed to be uninitialized under certain condition */ 516 if (!disp->Initialized) { 517 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || 518 ctx != EGL_NO_CONTEXT) 519 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 520 } 521 if (!drv) 522 RETURN_EGL_SUCCESS(disp, EGL_TRUE); 523 524 if (!context && ctx != EGL_NO_CONTEXT) 525 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 526 if (!draw_surf || !read_surf) { 527 /* From the EGL 1.4 (20130211) spec: 528 * 529 * To release the current context without assigning a new one, set ctx 530 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE. 531 */ 532 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT) 533 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 534 535 if ((!draw_surf && draw != EGL_NO_SURFACE) || 536 (!read_surf && read != EGL_NO_SURFACE)) 537 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 538 if (draw_surf || read_surf) 539 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); 540 } 541 542 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); 543 544 RETURN_EGL_EVAL(disp, ret); 545} 546 547 548EGLBoolean EGLAPIENTRY 549eglQueryContext(EGLDisplay dpy, EGLContext ctx, 550 EGLint attribute, EGLint *value) 551{ 552 _EGLDisplay *disp = _eglLockDisplay(dpy); 553 _EGLContext *context = _eglLookupContext(ctx, disp); 554 _EGLDriver *drv; 555 EGLBoolean ret; 556 557 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); 558 ret = drv->API.QueryContext(drv, disp, context, attribute, value); 559 560 RETURN_EGL_EVAL(disp, ret); 561} 562 563 564static EGLSurface 565_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config, 566 void *native_window, const EGLint *attrib_list) 567{ 568 _EGLConfig *conf = _eglLookupConfig(config, disp); 569 _EGLDriver *drv; 570 _EGLSurface *surf; 571 EGLSurface ret; 572 573 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 574 575 if (native_window == NULL) 576 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 577 578 surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window, 579 attrib_list); 580 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 581 582 RETURN_EGL_EVAL(disp, ret); 583} 584 585 586EGLSurface EGLAPIENTRY 587eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, 588 EGLNativeWindowType window, const EGLint *attrib_list) 589{ 590 _EGLDisplay *disp = _eglLockDisplay(dpy); 591 STATIC_ASSERT(sizeof(void*) == sizeof(window)); 592 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window, 593 attrib_list); 594} 595 596 597EGLSurface EGLAPIENTRY 598eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, 599 void *native_window, 600 const EGLint *attrib_list) 601{ 602 _EGLDisplay *disp = _eglLockDisplay(dpy); 603 604#ifdef HAVE_X11_PLATFORM 605 if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) { 606 /* The `native_window` parameter for the X11 platform differs between 607 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In 608 * eglCreateWindowSurface(), the type of `native_window` is an Xlib 609 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is 610 * `Window*`. Convert `Window*` to `Window` because that's what 611 * dri2_x11_create_window_surface() expects. 612 */ 613 native_window = (void*) (* (Window*) native_window); 614 } 615#endif 616 617 return _eglCreateWindowSurfaceCommon(disp, config, native_window, 618 attrib_list); 619} 620 621 622static EGLSurface 623_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, 624 void *native_pixmap, const EGLint *attrib_list) 625{ 626 _EGLConfig *conf = _eglLookupConfig(config, disp); 627 _EGLDriver *drv; 628 _EGLSurface *surf; 629 EGLSurface ret; 630 631 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 632 surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap, 633 attrib_list); 634 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 635 636 RETURN_EGL_EVAL(disp, ret); 637} 638 639 640EGLSurface EGLAPIENTRY 641eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, 642 EGLNativePixmapType pixmap, const EGLint *attrib_list) 643{ 644 _EGLDisplay *disp = _eglLockDisplay(dpy); 645 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap)); 646 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap, 647 attrib_list); 648} 649 650EGLSurface EGLAPIENTRY 651eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, 652 void *native_pixmap, 653 const EGLint *attrib_list) 654{ 655 _EGLDisplay *disp = _eglLockDisplay(dpy); 656 657#ifdef HAVE_X11_PLATFORM 658 /* The `native_pixmap` parameter for the X11 platform differs between 659 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In 660 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib 661 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is 662 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what 663 * dri2_x11_create_pixmap_surface() expects. 664 */ 665 if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) { 666 native_pixmap = (void*) (* (Pixmap*) native_pixmap); 667 } 668#endif 669 670 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap, 671 attrib_list); 672} 673 674 675EGLSurface EGLAPIENTRY 676eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, 677 const EGLint *attrib_list) 678{ 679 _EGLDisplay *disp = _eglLockDisplay(dpy); 680 _EGLConfig *conf = _eglLookupConfig(config, disp); 681 _EGLDriver *drv; 682 _EGLSurface *surf; 683 EGLSurface ret; 684 685 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 686 687 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); 688 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 689 690 RETURN_EGL_EVAL(disp, ret); 691} 692 693 694EGLBoolean EGLAPIENTRY 695eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 696{ 697 _EGLDisplay *disp = _eglLockDisplay(dpy); 698 _EGLSurface *surf = _eglLookupSurface(surface, disp); 699 _EGLDriver *drv; 700 EGLBoolean ret; 701 702 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 703 _eglUnlinkSurface(surf); 704 ret = drv->API.DestroySurface(drv, disp, surf); 705 706 RETURN_EGL_EVAL(disp, ret); 707} 708 709EGLBoolean EGLAPIENTRY 710eglQuerySurface(EGLDisplay dpy, EGLSurface surface, 711 EGLint attribute, EGLint *value) 712{ 713 _EGLDisplay *disp = _eglLockDisplay(dpy); 714 _EGLSurface *surf = _eglLookupSurface(surface, disp); 715 _EGLDriver *drv; 716 EGLBoolean ret; 717 718 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 719 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value); 720 721 RETURN_EGL_EVAL(disp, ret); 722} 723 724EGLBoolean EGLAPIENTRY 725eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, 726 EGLint attribute, EGLint value) 727{ 728 _EGLDisplay *disp = _eglLockDisplay(dpy); 729 _EGLSurface *surf = _eglLookupSurface(surface, disp); 730 _EGLDriver *drv; 731 EGLBoolean ret; 732 733 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 734 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); 735 736 RETURN_EGL_EVAL(disp, ret); 737} 738 739 740EGLBoolean EGLAPIENTRY 741eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 742{ 743 _EGLDisplay *disp = _eglLockDisplay(dpy); 744 _EGLSurface *surf = _eglLookupSurface(surface, disp); 745 _EGLDriver *drv; 746 EGLBoolean ret; 747 748 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 749 ret = drv->API.BindTexImage(drv, disp, surf, buffer); 750 751 RETURN_EGL_EVAL(disp, ret); 752} 753 754 755EGLBoolean EGLAPIENTRY 756eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 757{ 758 _EGLDisplay *disp = _eglLockDisplay(dpy); 759 _EGLSurface *surf = _eglLookupSurface(surface, disp); 760 _EGLDriver *drv; 761 EGLBoolean ret; 762 763 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 764 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer); 765 766 RETURN_EGL_EVAL(disp, ret); 767} 768 769 770EGLBoolean EGLAPIENTRY 771eglSwapInterval(EGLDisplay dpy, EGLint interval) 772{ 773 _EGLDisplay *disp = _eglLockDisplay(dpy); 774 _EGLContext *ctx = _eglGetCurrentContext(); 775 _EGLSurface *surf; 776 _EGLDriver *drv; 777 EGLBoolean ret; 778 779 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 780 781 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 782 ctx->Resource.Display != disp) 783 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 784 785 surf = ctx->DrawSurface; 786 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE) 787 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 788 789 ret = drv->API.SwapInterval(drv, disp, surf, interval); 790 791 RETURN_EGL_EVAL(disp, ret); 792} 793 794 795EGLBoolean EGLAPIENTRY 796eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 797{ 798 _EGLContext *ctx = _eglGetCurrentContext(); 799 _EGLDisplay *disp = _eglLockDisplay(dpy); 800 _EGLSurface *surf = _eglLookupSurface(surface, disp); 801 _EGLDriver *drv; 802 EGLBoolean ret; 803 804 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 805 806 /* surface must be bound to current context in EGL 1.4 */ 807 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 808 surf != ctx->DrawSurface) 809 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 810 811 ret = drv->API.SwapBuffers(drv, disp, surf); 812 813 RETURN_EGL_EVAL(disp, ret); 814} 815 816 817#ifdef EGL_EXT_swap_buffers_with_damage 818 819EGLBoolean EGLAPIENTRY 820eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, 821 EGLint *rects, EGLint n_rects) 822{ 823 _EGLContext *ctx = _eglGetCurrentContext(); 824 _EGLDisplay *disp = _eglLockDisplay(dpy); 825 _EGLSurface *surf = _eglLookupSurface(surface, disp); 826 _EGLDriver *drv; 827 EGLBoolean ret; 828 829 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 830 831 /* surface must be bound to current context in EGL 1.4 */ 832 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 833 surf != ctx->DrawSurface) 834 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 835 836 if ((n_rects > 0 && rects == NULL) || n_rects < 0) 837 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 838 839 ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects); 840 841 RETURN_EGL_EVAL(disp, ret); 842} 843 844#endif /* EGL_EXT_swap_buffers_with_damage */ 845 846EGLBoolean EGLAPIENTRY 847eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 848{ 849 _EGLDisplay *disp = _eglLockDisplay(dpy); 850 _EGLSurface *surf = _eglLookupSurface(surface, disp); 851 _EGLDriver *drv; 852 EGLBoolean ret; 853 void *native_pixmap_ptr; 854 855 STATIC_ASSERT(sizeof(void*) == sizeof(target)); 856 native_pixmap_ptr = (void*) target; 857 858 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 859 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay)) 860 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE); 861 ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr); 862 863 RETURN_EGL_EVAL(disp, ret); 864} 865 866 867EGLBoolean EGLAPIENTRY 868eglWaitClient(void) 869{ 870 _EGLContext *ctx = _eglGetCurrentContext(); 871 _EGLDisplay *disp; 872 _EGLDriver *drv; 873 EGLBoolean ret; 874 875 if (!ctx) 876 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 877 878 disp = ctx->Resource.Display; 879 _eglLockMutex(&disp->Mutex); 880 881 /* let bad current context imply bad current surface */ 882 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 883 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) 884 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 885 886 /* a valid current context implies an initialized current display */ 887 assert(disp->Initialized); 888 drv = disp->Driver; 889 ret = drv->API.WaitClient(drv, disp, ctx); 890 891 RETURN_EGL_EVAL(disp, ret); 892} 893 894 895EGLBoolean EGLAPIENTRY 896eglWaitGL(void) 897{ 898 _EGLThreadInfo *t = _eglGetCurrentThread(); 899 EGLint api_index = t->CurrentAPIIndex; 900 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); 901 EGLBoolean ret; 902 903 if (api_index != es_index && _eglIsCurrentThreadDummy()) 904 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); 905 906 t->CurrentAPIIndex = es_index; 907 ret = eglWaitClient(); 908 t->CurrentAPIIndex = api_index; 909 return ret; 910} 911 912 913EGLBoolean EGLAPIENTRY 914eglWaitNative(EGLint engine) 915{ 916 _EGLContext *ctx = _eglGetCurrentContext(); 917 _EGLDisplay *disp; 918 _EGLDriver *drv; 919 EGLBoolean ret; 920 921 if (!ctx) 922 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 923 924 disp = ctx->Resource.Display; 925 _eglLockMutex(&disp->Mutex); 926 927 /* let bad current context imply bad current surface */ 928 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 929 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) 930 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 931 932 /* a valid current context implies an initialized current display */ 933 assert(disp->Initialized); 934 drv = disp->Driver; 935 ret = drv->API.WaitNative(drv, disp, engine); 936 937 RETURN_EGL_EVAL(disp, ret); 938} 939 940 941EGLDisplay EGLAPIENTRY 942eglGetCurrentDisplay(void) 943{ 944 _EGLContext *ctx = _eglGetCurrentContext(); 945 EGLDisplay ret; 946 947 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; 948 949 RETURN_EGL_SUCCESS(NULL, ret); 950} 951 952 953EGLContext EGLAPIENTRY 954eglGetCurrentContext(void) 955{ 956 _EGLContext *ctx = _eglGetCurrentContext(); 957 EGLContext ret; 958 959 ret = _eglGetContextHandle(ctx); 960 961 RETURN_EGL_SUCCESS(NULL, ret); 962} 963 964 965EGLSurface EGLAPIENTRY 966eglGetCurrentSurface(EGLint readdraw) 967{ 968 _EGLContext *ctx = _eglGetCurrentContext(); 969 EGLint err = EGL_SUCCESS; 970 _EGLSurface *surf; 971 EGLSurface ret; 972 973 if (!ctx) 974 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE); 975 976 switch (readdraw) { 977 case EGL_DRAW: 978 surf = ctx->DrawSurface; 979 break; 980 case EGL_READ: 981 surf = ctx->ReadSurface; 982 break; 983 default: 984 surf = NULL; 985 err = EGL_BAD_PARAMETER; 986 break; 987 } 988 989 ret = _eglGetSurfaceHandle(surf); 990 991 RETURN_EGL_ERROR(NULL, err, ret); 992} 993 994 995EGLint EGLAPIENTRY 996eglGetError(void) 997{ 998 _EGLThreadInfo *t = _eglGetCurrentThread(); 999 EGLint e = t->LastError; 1000 if (!_eglIsCurrentThreadDummy()) 1001 t->LastError = EGL_SUCCESS; 1002 return e; 1003} 1004 1005 1006__eglMustCastToProperFunctionPointerType EGLAPIENTRY 1007eglGetProcAddress(const char *procname) 1008{ 1009 static const struct { 1010 const char *name; 1011 _EGLProc function; 1012 } egl_functions[] = { 1013 /* core functions should not be queryable, but, well... */ 1014#ifdef _EGL_GET_CORE_ADDRESSES 1015 /* alphabetical order */ 1016 { "eglBindAPI", (_EGLProc) eglBindAPI }, 1017 { "eglBindTexImage", (_EGLProc) eglBindTexImage }, 1018 { "eglChooseConfig", (_EGLProc) eglChooseConfig }, 1019 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, 1020 { "eglCreateContext", (_EGLProc) eglCreateContext }, 1021 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, 1022 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, 1023 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, 1024 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, 1025 { "eglDestroyContext", (_EGLProc) eglDestroyContext }, 1026 { "eglDestroySurface", (_EGLProc) eglDestroySurface }, 1027 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, 1028 { "eglGetConfigs", (_EGLProc) eglGetConfigs }, 1029 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, 1030 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, 1031 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, 1032 { "eglGetDisplay", (_EGLProc) eglGetDisplay }, 1033 { "eglGetError", (_EGLProc) eglGetError }, 1034 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, 1035 { "eglInitialize", (_EGLProc) eglInitialize }, 1036 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, 1037 { "eglQueryAPI", (_EGLProc) eglQueryAPI }, 1038 { "eglQueryContext", (_EGLProc) eglQueryContext }, 1039 { "eglQueryString", (_EGLProc) eglQueryString }, 1040 { "eglQuerySurface", (_EGLProc) eglQuerySurface }, 1041 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, 1042 { "eglReleaseThread", (_EGLProc) eglReleaseThread }, 1043 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, 1044 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, 1045 { "eglSwapInterval", (_EGLProc) eglSwapInterval }, 1046 { "eglTerminate", (_EGLProc) eglTerminate }, 1047 { "eglWaitClient", (_EGLProc) eglWaitClient }, 1048 { "eglWaitGL", (_EGLProc) eglWaitGL }, 1049 { "eglWaitNative", (_EGLProc) eglWaitNative }, 1050#endif /* _EGL_GET_CORE_ADDRESSES */ 1051#ifdef EGL_MESA_screen_surface 1052 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, 1053 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, 1054 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, 1055 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, 1056 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, 1057 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, 1058 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, 1059 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, 1060 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, 1061 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, 1062 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, 1063 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, 1064#endif /* EGL_MESA_screen_surface */ 1065#ifdef EGL_MESA_drm_display 1066 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, 1067#endif 1068 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, 1069 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, 1070 { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, 1071 { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR }, 1072 { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR }, 1073 { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR }, 1074 { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR }, 1075#ifdef EGL_NOK_swap_region 1076 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, 1077#endif 1078#ifdef EGL_MESA_drm_image 1079 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, 1080 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, 1081#endif 1082#ifdef EGL_WL_bind_wayland_display 1083 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, 1084 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, 1085 { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, 1086#endif 1087#ifdef EGL_WL_create_wayland_buffer_from_image 1088 { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL }, 1089#endif 1090 { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, 1091#ifdef EGL_EXT_swap_buffers_with_damage 1092 { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT }, 1093#endif 1094 { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT }, 1095 { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT }, 1096 { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT }, 1097 { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, 1098 { NULL, NULL } 1099 }; 1100 EGLint i; 1101 _EGLProc ret; 1102 1103 if (!procname) 1104 RETURN_EGL_SUCCESS(NULL, NULL); 1105 1106 ret = NULL; 1107 if (strncmp(procname, "egl", 3) == 0) { 1108 for (i = 0; egl_functions[i].name; i++) { 1109 if (strcmp(egl_functions[i].name, procname) == 0) { 1110 ret = egl_functions[i].function; 1111 break; 1112 } 1113 } 1114 } 1115 if (!ret) 1116 ret = _eglGetDriverProc(procname); 1117 1118 RETURN_EGL_SUCCESS(NULL, ret); 1119} 1120 1121 1122#ifdef EGL_MESA_screen_surface 1123 1124 1125/* 1126 * EGL_MESA_screen extension 1127 */ 1128 1129EGLBoolean EGLAPIENTRY 1130eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, 1131 const EGLint *attrib_list, EGLModeMESA *modes, 1132 EGLint modes_size, EGLint *num_modes) 1133{ 1134 _EGLDisplay *disp = _eglLockDisplay(dpy); 1135 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1136 _EGLDriver *drv; 1137 EGLBoolean ret; 1138 1139 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1140 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, 1141 modes, modes_size, num_modes); 1142 1143 RETURN_EGL_EVAL(disp, ret); 1144} 1145 1146 1147EGLBoolean EGLAPIENTRY 1148eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, 1149 EGLint mode_size, EGLint *num_mode) 1150{ 1151 _EGLDisplay *disp = _eglLockDisplay(dpy); 1152 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1153 _EGLDriver *drv; 1154 EGLBoolean ret; 1155 1156 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1157 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); 1158 1159 RETURN_EGL_EVAL(disp, ret); 1160} 1161 1162 1163EGLBoolean EGLAPIENTRY 1164eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, 1165 EGLint attribute, EGLint *value) 1166{ 1167 _EGLDisplay *disp = _eglLockDisplay(dpy); 1168 _EGLMode *m = _eglLookupMode(mode, disp); 1169 _EGLDriver *drv; 1170 EGLBoolean ret; 1171 1172 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv); 1173 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); 1174 1175 RETURN_EGL_EVAL(disp, ret); 1176} 1177 1178 1179EGLBoolean EGLAPIENTRY 1180eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, 1181 EGLint mask) 1182{ 1183 _EGLDisplay *disp = _eglLockDisplay(dpy); 1184 _EGLContext *source_context = _eglLookupContext(source, disp); 1185 _EGLContext *dest_context = _eglLookupContext(dest, disp); 1186 _EGLDriver *drv; 1187 EGLBoolean ret; 1188 1189 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv); 1190 if (!dest_context) 1191 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 1192 1193 ret = drv->API.CopyContextMESA(drv, disp, 1194 source_context, dest_context, mask); 1195 1196 RETURN_EGL_EVAL(disp, ret); 1197} 1198 1199 1200EGLBoolean EGLAPIENTRY 1201eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, 1202 EGLint max_screens, EGLint *num_screens) 1203{ 1204 _EGLDisplay *disp = _eglLockDisplay(dpy); 1205 _EGLDriver *drv; 1206 EGLBoolean ret; 1207 1208 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1209 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); 1210 1211 RETURN_EGL_EVAL(disp, ret); 1212} 1213 1214 1215EGLSurface EGLAPIENTRY 1216eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, 1217 const EGLint *attrib_list) 1218{ 1219 _EGLDisplay *disp = _eglLockDisplay(dpy); 1220 _EGLConfig *conf = _eglLookupConfig(config, disp); 1221 _EGLDriver *drv; 1222 _EGLSurface *surf; 1223 EGLSurface ret; 1224 1225 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 1226 1227 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); 1228 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1229 1230 RETURN_EGL_EVAL(disp, ret); 1231} 1232 1233 1234EGLBoolean EGLAPIENTRY 1235eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, 1236 EGLSurface surface, EGLModeMESA mode) 1237{ 1238 _EGLDisplay *disp = _eglLockDisplay(dpy); 1239 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1240 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1241 _EGLMode *m = _eglLookupMode(mode, disp); 1242 _EGLDriver *drv; 1243 EGLBoolean ret; 1244 1245 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1246 if (!surf && surface != EGL_NO_SURFACE) 1247 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1248 if (!m && mode != EGL_NO_MODE_MESA) 1249 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); 1250 1251 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); 1252 1253 RETURN_EGL_EVAL(disp, ret); 1254} 1255 1256 1257EGLBoolean EGLAPIENTRY 1258eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) 1259{ 1260 _EGLDisplay *disp = _eglLockDisplay(dpy); 1261 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1262 _EGLDriver *drv; 1263 EGLBoolean ret; 1264 1265 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1266 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); 1267 1268 RETURN_EGL_EVAL(disp, ret); 1269} 1270 1271 1272EGLBoolean EGLAPIENTRY 1273eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, 1274 EGLint attribute, EGLint *value) 1275{ 1276 _EGLDisplay *disp = _eglLockDisplay(dpy); 1277 _EGLScreen *scrn = _eglLookupScreen(screen, disp); 1278 _EGLDriver *drv; 1279 EGLBoolean ret; 1280 1281 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1282 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); 1283 1284 RETURN_EGL_EVAL(disp, ret); 1285} 1286 1287 1288EGLBoolean EGLAPIENTRY 1289eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, 1290 EGLSurface *surface) 1291{ 1292 _EGLDisplay *disp = _eglLockDisplay(dpy); 1293 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1294 _EGLDriver *drv; 1295 _EGLSurface *surf; 1296 EGLBoolean ret; 1297 1298 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1299 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); 1300 if (ret && surface) 1301 *surface = _eglGetSurfaceHandle(surf); 1302 1303 RETURN_EGL_EVAL(disp, ret); 1304} 1305 1306 1307EGLBoolean EGLAPIENTRY 1308eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) 1309{ 1310 _EGLDisplay *disp = _eglLockDisplay(dpy); 1311 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); 1312 _EGLDriver *drv; 1313 _EGLMode *m; 1314 EGLBoolean ret; 1315 1316 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); 1317 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); 1318 if (ret && mode) 1319 *mode = m->Handle; 1320 1321 RETURN_EGL_EVAL(disp, ret); 1322} 1323 1324 1325const char * EGLAPIENTRY 1326eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) 1327{ 1328 _EGLDisplay *disp = _eglLockDisplay(dpy); 1329 _EGLMode *m = _eglLookupMode(mode, disp); 1330 _EGLDriver *drv; 1331 const char *ret; 1332 1333 _EGL_CHECK_MODE(disp, m, NULL, drv); 1334 ret = drv->API.QueryModeStringMESA(drv, disp, m); 1335 1336 RETURN_EGL_EVAL(disp, ret); 1337} 1338 1339 1340#endif /* EGL_MESA_screen_surface */ 1341 1342 1343#ifdef EGL_MESA_drm_display 1344 1345EGLDisplay EGLAPIENTRY 1346eglGetDRMDisplayMESA(int fd) 1347{ 1348 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd); 1349 return _eglGetDisplayHandle(dpy); 1350} 1351 1352#endif /* EGL_MESA_drm_display */ 1353 1354/** 1355 ** EGL 1.2 1356 **/ 1357 1358/** 1359 * Specify the client API to use for subsequent calls including: 1360 * eglCreateContext() 1361 * eglGetCurrentContext() 1362 * eglGetCurrentDisplay() 1363 * eglGetCurrentSurface() 1364 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) 1365 * eglWaitClient() 1366 * eglWaitNative() 1367 * See section 3.7 "Rendering Context" in the EGL specification for details. 1368 */ 1369EGLBoolean EGLAPIENTRY 1370eglBindAPI(EGLenum api) 1371{ 1372 _EGLThreadInfo *t = _eglGetCurrentThread(); 1373 1374 if (_eglIsCurrentThreadDummy()) 1375 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); 1376 1377 if (!_eglIsApiValid(api)) 1378 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); 1379 1380 t->CurrentAPIIndex = _eglConvertApiToIndex(api); 1381 1382 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1383} 1384 1385 1386/** 1387 * Return the last value set with eglBindAPI(). 1388 */ 1389EGLenum EGLAPIENTRY 1390eglQueryAPI(void) 1391{ 1392 _EGLThreadInfo *t = _eglGetCurrentThread(); 1393 EGLenum ret; 1394 1395 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ 1396 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); 1397 1398 RETURN_EGL_SUCCESS(NULL, ret); 1399} 1400 1401 1402EGLSurface EGLAPIENTRY 1403eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, 1404 EGLClientBuffer buffer, EGLConfig config, 1405 const EGLint *attrib_list) 1406{ 1407 _EGLDisplay *disp = _eglLockDisplay(dpy); 1408 _EGLConfig *conf = _eglLookupConfig(config, disp); 1409 _EGLDriver *drv; 1410 _EGLSurface *surf; 1411 EGLSurface ret; 1412 1413 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); 1414 1415 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, 1416 conf, attrib_list); 1417 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1418 1419 RETURN_EGL_EVAL(disp, ret); 1420} 1421 1422 1423EGLBoolean EGLAPIENTRY 1424eglReleaseThread(void) 1425{ 1426 /* unbind current contexts */ 1427 if (!_eglIsCurrentThreadDummy()) { 1428 _EGLThreadInfo *t = _eglGetCurrentThread(); 1429 EGLint api_index = t->CurrentAPIIndex; 1430 EGLint i; 1431 1432 for (i = 0; i < _EGL_API_NUM_APIS; i++) { 1433 _EGLContext *ctx = t->CurrentContexts[i]; 1434 if (ctx) { 1435 _EGLDisplay *disp = ctx->Resource.Display; 1436 _EGLDriver *drv; 1437 1438 t->CurrentAPIIndex = i; 1439 1440 _eglLockMutex(&disp->Mutex); 1441 drv = disp->Driver; 1442 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); 1443 _eglUnlockMutex(&disp->Mutex); 1444 } 1445 } 1446 1447 t->CurrentAPIIndex = api_index; 1448 } 1449 1450 _eglDestroyCurrentThread(); 1451 1452 RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1453} 1454 1455 1456EGLImageKHR EGLAPIENTRY 1457eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1458 EGLClientBuffer buffer, const EGLint *attr_list) 1459{ 1460 _EGLDisplay *disp = _eglLockDisplay(dpy); 1461 _EGLContext *context = _eglLookupContext(ctx, disp); 1462 _EGLDriver *drv; 1463 _EGLImage *img; 1464 EGLImageKHR ret; 1465 1466 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); 1467 if (!disp->Extensions.KHR_image_base) 1468 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); 1469 if (!context && ctx != EGL_NO_CONTEXT) 1470 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); 1471 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display, 1472 * <ctx> must be EGL_NO_CONTEXT..." 1473 */ 1474 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT) 1475 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 1476 1477 img = drv->API.CreateImageKHR(drv, 1478 disp, context, target, buffer, attr_list); 1479 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; 1480 1481 RETURN_EGL_EVAL(disp, ret); 1482} 1483 1484 1485EGLBoolean EGLAPIENTRY 1486eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) 1487{ 1488 _EGLDisplay *disp = _eglLockDisplay(dpy); 1489 _EGLImage *img = _eglLookupImage(image, disp); 1490 _EGLDriver *drv; 1491 EGLBoolean ret; 1492 1493 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1494 if (!disp->Extensions.KHR_image_base) 1495 RETURN_EGL_EVAL(disp, EGL_FALSE); 1496 if (!img) 1497 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1498 1499 _eglUnlinkImage(img); 1500 ret = drv->API.DestroyImageKHR(drv, disp, img); 1501 1502 RETURN_EGL_EVAL(disp, ret); 1503} 1504 1505 1506EGLSyncKHR EGLAPIENTRY 1507eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) 1508{ 1509 _EGLDisplay *disp = _eglLockDisplay(dpy); 1510 _EGLDriver *drv; 1511 _EGLSync *sync; 1512 EGLSyncKHR ret; 1513 1514 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); 1515 if (!disp->Extensions.KHR_reusable_sync) 1516 RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR); 1517 1518 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list); 1519 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR; 1520 1521 RETURN_EGL_EVAL(disp, ret); 1522} 1523 1524 1525EGLBoolean EGLAPIENTRY 1526eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) 1527{ 1528 _EGLDisplay *disp = _eglLockDisplay(dpy); 1529 _EGLSync *s = _eglLookupSync(sync, disp); 1530 _EGLDriver *drv; 1531 EGLBoolean ret; 1532 1533 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1534 assert(disp->Extensions.KHR_reusable_sync); 1535 1536 _eglUnlinkSync(s); 1537 ret = drv->API.DestroySyncKHR(drv, disp, s); 1538 1539 RETURN_EGL_EVAL(disp, ret); 1540} 1541 1542 1543EGLint EGLAPIENTRY 1544eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) 1545{ 1546 _EGLDisplay *disp = _eglLockDisplay(dpy); 1547 _EGLSync *s = _eglLookupSync(sync, disp); 1548 _EGLDriver *drv; 1549 EGLint ret; 1550 1551 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1552 assert(disp->Extensions.KHR_reusable_sync); 1553 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout); 1554 1555 RETURN_EGL_EVAL(disp, ret); 1556} 1557 1558 1559EGLBoolean EGLAPIENTRY 1560eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) 1561{ 1562 _EGLDisplay *disp = _eglLockDisplay(dpy); 1563 _EGLSync *s = _eglLookupSync(sync, disp); 1564 _EGLDriver *drv; 1565 EGLBoolean ret; 1566 1567 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1568 assert(disp->Extensions.KHR_reusable_sync); 1569 ret = drv->API.SignalSyncKHR(drv, disp, s, mode); 1570 1571 RETURN_EGL_EVAL(disp, ret); 1572} 1573 1574 1575EGLBoolean EGLAPIENTRY 1576eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) 1577{ 1578 _EGLDisplay *disp = _eglLockDisplay(dpy); 1579 _EGLSync *s = _eglLookupSync(sync, disp); 1580 _EGLDriver *drv; 1581 EGLBoolean ret; 1582 1583 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); 1584 assert(disp->Extensions.KHR_reusable_sync); 1585 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); 1586 1587 RETURN_EGL_EVAL(disp, ret); 1588} 1589 1590 1591#ifdef EGL_NOK_swap_region 1592 1593EGLBoolean EGLAPIENTRY 1594eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, 1595 EGLint numRects, const EGLint *rects) 1596{ 1597 _EGLContext *ctx = _eglGetCurrentContext(); 1598 _EGLDisplay *disp = _eglLockDisplay(dpy); 1599 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1600 _EGLDriver *drv; 1601 EGLBoolean ret; 1602 1603 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 1604 1605 if (!disp->Extensions.NOK_swap_region) 1606 RETURN_EGL_EVAL(disp, EGL_FALSE); 1607 1608 /* surface must be bound to current context in EGL 1.4 */ 1609 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1610 surf != ctx->DrawSurface) 1611 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1612 1613 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects); 1614 1615 RETURN_EGL_EVAL(disp, ret); 1616} 1617 1618#endif /* EGL_NOK_swap_region */ 1619 1620 1621#ifdef EGL_MESA_drm_image 1622 1623EGLImageKHR EGLAPIENTRY 1624eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) 1625{ 1626 _EGLDisplay *disp = _eglLockDisplay(dpy); 1627 _EGLDriver *drv; 1628 _EGLImage *img; 1629 EGLImageKHR ret; 1630 1631 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); 1632 if (!disp->Extensions.MESA_drm_image) 1633 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); 1634 1635 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list); 1636 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; 1637 1638 RETURN_EGL_EVAL(disp, ret); 1639} 1640 1641EGLBoolean EGLAPIENTRY 1642eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, 1643 EGLint *name, EGLint *handle, EGLint *stride) 1644{ 1645 _EGLDisplay *disp = _eglLockDisplay(dpy); 1646 _EGLImage *img = _eglLookupImage(image, disp); 1647 _EGLDriver *drv; 1648 EGLBoolean ret; 1649 1650 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1651 assert(disp->Extensions.MESA_drm_image); 1652 1653 if (!img) 1654 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1655 1656 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride); 1657 1658 RETURN_EGL_EVAL(disp, ret); 1659} 1660 1661#endif 1662 1663#ifdef EGL_WL_bind_wayland_display 1664struct wl_display; 1665 1666EGLBoolean EGLAPIENTRY 1667eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 1668{ 1669 _EGLDisplay *disp = _eglLockDisplay(dpy); 1670 _EGLDriver *drv; 1671 EGLBoolean ret; 1672 1673 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1674 assert(disp->Extensions.WL_bind_wayland_display); 1675 1676 if (!display) 1677 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1678 1679 ret = drv->API.BindWaylandDisplayWL(drv, disp, display); 1680 1681 RETURN_EGL_EVAL(disp, ret); 1682} 1683 1684EGLBoolean EGLAPIENTRY 1685eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 1686{ 1687 _EGLDisplay *disp = _eglLockDisplay(dpy); 1688 _EGLDriver *drv; 1689 EGLBoolean ret; 1690 1691 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1692 assert(disp->Extensions.WL_bind_wayland_display); 1693 1694 if (!display) 1695 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1696 1697 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display); 1698 1699 RETURN_EGL_EVAL(disp, ret); 1700} 1701 1702EGLBoolean EGLAPIENTRY 1703eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, 1704 EGLint attribute, EGLint *value) 1705{ 1706 _EGLDisplay *disp = _eglLockDisplay(dpy); 1707 _EGLDriver *drv; 1708 EGLBoolean ret; 1709 1710 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); 1711 assert(disp->Extensions.WL_bind_wayland_display); 1712 1713 if (!buffer) 1714 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1715 1716 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value); 1717 1718 RETURN_EGL_EVAL(disp, ret); 1719} 1720#endif 1721 1722#ifdef EGL_WL_create_wayland_buffer_from_image 1723struct wl_buffer * EGLAPIENTRY 1724eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image) 1725{ 1726 _EGLDisplay *disp = _eglLockDisplay(dpy); 1727 _EGLImage *img; 1728 _EGLDriver *drv; 1729 struct wl_buffer *ret; 1730 1731 _EGL_CHECK_DISPLAY(disp, NULL, drv); 1732 assert(disp->Extensions.WL_create_wayland_buffer_from_image); 1733 1734 img = _eglLookupImage(image, disp); 1735 1736 if (!img) 1737 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL); 1738 1739 ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img); 1740 1741 RETURN_EGL_EVAL(disp, ret); 1742} 1743#endif 1744 1745EGLBoolean EGLAPIENTRY 1746eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, 1747 EGLint x, EGLint y, EGLint width, EGLint height) 1748{ 1749 _EGLDisplay *disp = _eglLockDisplay(dpy); 1750 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1751 _EGLDriver *drv; 1752 EGLBoolean ret; 1753 1754 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 1755 1756 if (!disp->Extensions.NV_post_sub_buffer) 1757 RETURN_EGL_EVAL(disp, EGL_FALSE); 1758 1759 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height); 1760 1761 RETURN_EGL_EVAL(disp, ret); 1762} 1763 1764EGLBoolean EGLAPIENTRY 1765eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface, 1766 EGLuint64KHR *ust, EGLuint64KHR *msc, 1767 EGLuint64KHR *sbc) 1768{ 1769 _EGLDisplay *disp = _eglLockDisplay(display); 1770 _EGLSurface *surf = _eglLookupSurface(surface, disp); 1771 _EGLDriver *drv; 1772 EGLBoolean ret; 1773 1774 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); 1775 if (!disp->Extensions.CHROMIUM_sync_control) 1776 RETURN_EGL_EVAL(disp, EGL_FALSE); 1777 1778 if (!ust || !msc || !sbc) 1779 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1780 1781 ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc); 1782 1783 RETURN_EGL_EVAL(disp, ret); 1784} 1785