Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

eglapi.c 51KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774
  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. * Public EGL API entrypoints
  31. *
  32. * Generally, we use the EGLDisplay parameter as a key to lookup the
  33. * appropriate device driver handle, then jump though the driver's
  34. * dispatch table to handle the function.
  35. *
  36. * That allows us the option of supporting multiple, simultaneous,
  37. * heterogeneous hardware devices in the future.
  38. *
  39. * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
  40. * opaque handles. Internal objects are linked to a display to
  41. * create the handles.
  42. *
  43. * For each public API entry point, the opaque handles are looked up
  44. * before being dispatched to the drivers. When it fails to look up
  45. * a handle, one of
  46. *
  47. * EGL_BAD_DISPLAY
  48. * EGL_BAD_CONFIG
  49. * EGL_BAD_CONTEXT
  50. * EGL_BAD_SURFACE
  51. * EGL_BAD_SCREEN_MESA
  52. * EGL_BAD_MODE_MESA
  53. *
  54. * is generated and the driver function is not called. An
  55. * uninitialized EGLDisplay has no driver associated with it. When
  56. * such display is detected,
  57. *
  58. * EGL_NOT_INITIALIZED
  59. *
  60. * is generated.
  61. *
  62. * Some of the entry points use current display, context, or surface
  63. * implicitly. For such entry points, the implicit objects are also
  64. * checked before calling the driver function. Other than the
  65. * errors listed above,
  66. *
  67. * EGL_BAD_CURRENT_SURFACE
  68. *
  69. * may also be generated.
  70. *
  71. * Notes on naming conventions:
  72. *
  73. * eglFooBar - public EGL function
  74. * EGL_FOO_BAR - public EGL token
  75. * EGLDatatype - public EGL datatype
  76. *
  77. * _eglFooBar - private EGL function
  78. * _EGLDatatype - private EGL datatype, typedef'd struct
  79. * _egl_struct - private EGL struct, non-typedef'd
  80. *
  81. */
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include <string.h>
  85. #include "c99_compat.h"
  86. #include "c11/threads.h"
  87. #include "eglcompiler.h"
  88. #include "eglglobals.h"
  89. #include "eglcontext.h"
  90. #include "egldisplay.h"
  91. #include "egltypedefs.h"
  92. #include "eglcurrent.h"
  93. #include "egldriver.h"
  94. #include "eglsurface.h"
  95. #include "eglconfig.h"
  96. #include "eglimage.h"
  97. #include "eglsync.h"
  98. #include "eglstring.h"
  99. /**
  100. * Macros to help return an API entrypoint.
  101. *
  102. * These macros will unlock the display and record the error code.
  103. */
  104. #define RETURN_EGL_ERROR(disp, err, ret) \
  105. do { \
  106. if (disp) \
  107. _eglUnlockDisplay(disp); \
  108. /* EGL error codes are non-zero */ \
  109. if (err) \
  110. _eglError(err, __func__); \
  111. return ret; \
  112. } while (0)
  113. #define RETURN_EGL_SUCCESS(disp, ret) \
  114. RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
  115. /* record EGL_SUCCESS only when ret evaluates to true */
  116. #define RETURN_EGL_EVAL(disp, ret) \
  117. RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
  118. /*
  119. * A bunch of macros and checks to simplify error checking.
  120. */
  121. #define _EGL_CHECK_DISPLAY(disp, ret, drv) \
  122. do { \
  123. drv = _eglCheckDisplay(disp, __func__); \
  124. if (!drv) \
  125. RETURN_EGL_ERROR(disp, 0, ret); \
  126. } while (0)
  127. #define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
  128. do { \
  129. drv = _eglCheck ## type(disp, obj, __func__); \
  130. if (!drv) \
  131. RETURN_EGL_ERROR(disp, 0, ret); \
  132. } while (0)
  133. #define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
  134. _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
  135. #define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
  136. _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
  137. #define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
  138. _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
  139. #define _EGL_CHECK_SYNC(disp, s, ret, drv) \
  140. _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
  141. static inline _EGLDriver *
  142. _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
  143. {
  144. if (!disp) {
  145. _eglError(EGL_BAD_DISPLAY, msg);
  146. return NULL;
  147. }
  148. if (!disp->Initialized) {
  149. _eglError(EGL_NOT_INITIALIZED, msg);
  150. return NULL;
  151. }
  152. return disp->Driver;
  153. }
  154. static inline _EGLDriver *
  155. _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
  156. {
  157. _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  158. if (!drv)
  159. return NULL;
  160. if (!surf) {
  161. _eglError(EGL_BAD_SURFACE, msg);
  162. return NULL;
  163. }
  164. return drv;
  165. }
  166. static inline _EGLDriver *
  167. _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
  168. {
  169. _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  170. if (!drv)
  171. return NULL;
  172. if (!context) {
  173. _eglError(EGL_BAD_CONTEXT, msg);
  174. return NULL;
  175. }
  176. return drv;
  177. }
  178. static inline _EGLDriver *
  179. _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
  180. {
  181. _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  182. if (!drv)
  183. return NULL;
  184. if (!conf) {
  185. _eglError(EGL_BAD_CONFIG, msg);
  186. return NULL;
  187. }
  188. return drv;
  189. }
  190. static inline _EGLDriver *
  191. _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
  192. {
  193. _EGLDriver *drv = _eglCheckDisplay(disp, msg);
  194. if (!drv)
  195. return NULL;
  196. if (!s) {
  197. _eglError(EGL_BAD_PARAMETER, msg);
  198. return NULL;
  199. }
  200. return drv;
  201. }
  202. /**
  203. * Lookup and lock a display.
  204. */
  205. static inline _EGLDisplay *
  206. _eglLockDisplay(EGLDisplay display)
  207. {
  208. _EGLDisplay *dpy = _eglLookupDisplay(display);
  209. if (dpy)
  210. mtx_lock(&dpy->Mutex);
  211. return dpy;
  212. }
  213. /**
  214. * Unlock a display.
  215. */
  216. static inline void
  217. _eglUnlockDisplay(_EGLDisplay *dpy)
  218. {
  219. mtx_unlock(&dpy->Mutex);
  220. }
  221. /**
  222. * This is typically the first EGL function that an application calls.
  223. * It associates a private _EGLDisplay object to the native display.
  224. */
  225. EGLDisplay EGLAPIENTRY
  226. eglGetDisplay(EGLNativeDisplayType nativeDisplay)
  227. {
  228. _EGLPlatformType plat;
  229. _EGLDisplay *dpy;
  230. void *native_display_ptr;
  231. STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
  232. native_display_ptr = (void*) nativeDisplay;
  233. plat = _eglGetNativePlatform(native_display_ptr);
  234. dpy = _eglFindDisplay(plat, native_display_ptr);
  235. return _eglGetDisplayHandle(dpy);
  236. }
  237. static EGLDisplay EGLAPIENTRY
  238. eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
  239. const EGLint *attrib_list)
  240. {
  241. _EGLDisplay *dpy;
  242. switch (platform) {
  243. #ifdef HAVE_X11_PLATFORM
  244. case EGL_PLATFORM_X11_EXT:
  245. dpy = _eglGetX11Display((Display*) native_display, attrib_list);
  246. break;
  247. #endif
  248. #ifdef HAVE_DRM_PLATFORM
  249. case EGL_PLATFORM_GBM_MESA:
  250. dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
  251. attrib_list);
  252. break;
  253. #endif
  254. #ifdef HAVE_WAYLAND_PLATFORM
  255. case EGL_PLATFORM_WAYLAND_EXT:
  256. dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
  257. attrib_list);
  258. break;
  259. #endif
  260. default:
  261. RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
  262. }
  263. return _eglGetDisplayHandle(dpy);
  264. }
  265. /**
  266. * Copy the extension into the string and update the string pointer.
  267. */
  268. static EGLint
  269. _eglAppendExtension(char **str, const char *ext)
  270. {
  271. char *s = *str;
  272. size_t len = strlen(ext);
  273. if (s) {
  274. memcpy(s, ext, len);
  275. s[len++] = ' ';
  276. s[len] = '\0';
  277. *str += len;
  278. }
  279. else {
  280. len++;
  281. }
  282. return (EGLint) len;
  283. }
  284. /**
  285. * Examine the individual extension enable/disable flags and recompute
  286. * the driver's Extensions string.
  287. */
  288. static void
  289. _eglCreateExtensionsString(_EGLDisplay *dpy)
  290. {
  291. #define _EGL_CHECK_EXTENSION(ext) \
  292. do { \
  293. if (dpy->Extensions.ext) { \
  294. _eglAppendExtension(&exts, "EGL_" #ext); \
  295. assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
  296. } \
  297. } while (0)
  298. char *exts = dpy->ExtensionsString;
  299. _EGL_CHECK_EXTENSION(MESA_drm_display);
  300. _EGL_CHECK_EXTENSION(MESA_drm_image);
  301. _EGL_CHECK_EXTENSION(MESA_configless_context);
  302. _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
  303. _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
  304. _EGL_CHECK_EXTENSION(KHR_image_base);
  305. _EGL_CHECK_EXTENSION(KHR_image_pixmap);
  306. if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
  307. _eglAppendExtension(&exts, "EGL_KHR_image");
  308. _EGL_CHECK_EXTENSION(KHR_vg_parent_image);
  309. _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
  310. _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
  311. _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
  312. _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
  313. _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
  314. _EGL_CHECK_EXTENSION(KHR_reusable_sync);
  315. _EGL_CHECK_EXTENSION(KHR_fence_sync);
  316. _EGL_CHECK_EXTENSION(KHR_wait_sync);
  317. _EGL_CHECK_EXTENSION(KHR_cl_event2);
  318. _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
  319. _EGL_CHECK_EXTENSION(KHR_create_context);
  320. _EGL_CHECK_EXTENSION(NOK_swap_region);
  321. _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
  322. _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
  323. _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
  324. _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
  325. _EGL_CHECK_EXTENSION(EXT_buffer_age);
  326. _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
  327. _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
  328. _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
  329. _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
  330. #undef _EGL_CHECK_EXTENSION
  331. }
  332. static void
  333. _eglCreateAPIsString(_EGLDisplay *dpy)
  334. {
  335. if (dpy->ClientAPIs & EGL_OPENGL_BIT)
  336. strcat(dpy->ClientAPIsString, "OpenGL ");
  337. if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT)
  338. strcat(dpy->ClientAPIsString, "OpenGL_ES ");
  339. if (dpy->ClientAPIs & EGL_OPENGL_ES2_BIT)
  340. strcat(dpy->ClientAPIsString, "OpenGL_ES2 ");
  341. if (dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR)
  342. strcat(dpy->ClientAPIsString, "OpenGL_ES3 ");
  343. if (dpy->ClientAPIs & EGL_OPENVG_BIT)
  344. strcat(dpy->ClientAPIsString, "OpenVG ");
  345. assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
  346. }
  347. /**
  348. * This is typically the second EGL function that an application calls.
  349. * Here we load/initialize the actual hardware driver.
  350. */
  351. EGLBoolean EGLAPIENTRY
  352. eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
  353. {
  354. _EGLDisplay *disp = _eglLockDisplay(dpy);
  355. if (!disp)
  356. RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
  357. if (!disp->Initialized) {
  358. if (!_eglMatchDriver(disp, EGL_FALSE))
  359. RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
  360. /* limit to APIs supported by core */
  361. disp->ClientAPIs &= _EGL_API_ALL_BITS;
  362. /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
  363. * classifies it as an EGL display extension, though conceptually it's an
  364. * EGL client extension.
  365. *
  366. * From the EGL_KHR_get_all_proc_addresses spec:
  367. *
  368. * The EGL implementation must expose the name
  369. * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
  370. * EGL_KHR_get_all_proc_addresses and supports
  371. * EGL_EXT_client_extensions.
  372. *
  373. * Mesa unconditionally exposes both client extensions mentioned above,
  374. * so the spec requires that each EGLDisplay unconditionally expose
  375. * EGL_KHR_get_all_proc_addresses also.
  376. */
  377. disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
  378. _eglCreateExtensionsString(disp);
  379. _eglCreateAPIsString(disp);
  380. _eglsnprintf(disp->VersionString, sizeof(disp->VersionString),
  381. "%d.%d (%s)", disp->VersionMajor, disp->VersionMinor,
  382. disp->Driver->Name);
  383. }
  384. /* Update applications version of major and minor if not NULL */
  385. if ((major != NULL) && (minor != NULL)) {
  386. *major = disp->VersionMajor;
  387. *minor = disp->VersionMinor;
  388. }
  389. RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  390. }
  391. EGLBoolean EGLAPIENTRY
  392. eglTerminate(EGLDisplay dpy)
  393. {
  394. _EGLDisplay *disp = _eglLockDisplay(dpy);
  395. if (!disp)
  396. RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
  397. if (disp->Initialized) {
  398. _EGLDriver *drv = disp->Driver;
  399. drv->API.Terminate(drv, disp);
  400. /* do not reset disp->Driver */
  401. disp->ClientAPIsString[0] = 0;
  402. disp->Initialized = EGL_FALSE;
  403. }
  404. RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  405. }
  406. const char * EGLAPIENTRY
  407. eglQueryString(EGLDisplay dpy, EGLint name)
  408. {
  409. _EGLDisplay *disp;
  410. _EGLDriver *drv;
  411. if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
  412. RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
  413. }
  414. disp = _eglLockDisplay(dpy);
  415. _EGL_CHECK_DISPLAY(disp, NULL, drv);
  416. switch (name) {
  417. case EGL_VENDOR:
  418. RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
  419. case EGL_VERSION:
  420. RETURN_EGL_SUCCESS(disp, disp->VersionString);
  421. case EGL_EXTENSIONS:
  422. RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
  423. case EGL_CLIENT_APIS:
  424. RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
  425. default:
  426. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
  427. }
  428. }
  429. EGLBoolean EGLAPIENTRY
  430. eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
  431. EGLint config_size, EGLint *num_config)
  432. {
  433. _EGLDisplay *disp = _eglLockDisplay(dpy);
  434. _EGLDriver *drv;
  435. EGLBoolean ret;
  436. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  437. ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
  438. RETURN_EGL_EVAL(disp, ret);
  439. }
  440. EGLBoolean EGLAPIENTRY
  441. eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
  442. EGLint config_size, EGLint *num_config)
  443. {
  444. _EGLDisplay *disp = _eglLockDisplay(dpy);
  445. _EGLDriver *drv;
  446. EGLBoolean ret;
  447. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  448. ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
  449. config_size, num_config);
  450. RETURN_EGL_EVAL(disp, ret);
  451. }
  452. EGLBoolean EGLAPIENTRY
  453. eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
  454. EGLint attribute, EGLint *value)
  455. {
  456. _EGLDisplay *disp = _eglLockDisplay(dpy);
  457. _EGLConfig *conf = _eglLookupConfig(config, disp);
  458. _EGLDriver *drv;
  459. EGLBoolean ret;
  460. _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
  461. ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
  462. RETURN_EGL_EVAL(disp, ret);
  463. }
  464. EGLContext EGLAPIENTRY
  465. eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
  466. const EGLint *attrib_list)
  467. {
  468. _EGLDisplay *disp = _eglLockDisplay(dpy);
  469. _EGLConfig *conf = _eglLookupConfig(config, disp);
  470. _EGLContext *share = _eglLookupContext(share_list, disp);
  471. _EGLDriver *drv;
  472. _EGLContext *context;
  473. EGLContext ret;
  474. _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
  475. if (!config && !disp->Extensions.MESA_configless_context)
  476. RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
  477. if (!share && share_list != EGL_NO_CONTEXT)
  478. RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
  479. context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
  480. ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
  481. RETURN_EGL_EVAL(disp, ret);
  482. }
  483. EGLBoolean EGLAPIENTRY
  484. eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
  485. {
  486. _EGLDisplay *disp = _eglLockDisplay(dpy);
  487. _EGLContext *context = _eglLookupContext(ctx, disp);
  488. _EGLDriver *drv;
  489. EGLBoolean ret;
  490. _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
  491. _eglUnlinkContext(context);
  492. ret = drv->API.DestroyContext(drv, disp, context);
  493. RETURN_EGL_EVAL(disp, ret);
  494. }
  495. EGLBoolean EGLAPIENTRY
  496. eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
  497. EGLContext ctx)
  498. {
  499. _EGLDisplay *disp = _eglLockDisplay(dpy);
  500. _EGLContext *context = _eglLookupContext(ctx, disp);
  501. _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
  502. _EGLSurface *read_surf = _eglLookupSurface(read, disp);
  503. _EGLDriver *drv;
  504. EGLBoolean ret;
  505. if (!disp)
  506. RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
  507. drv = disp->Driver;
  508. /* display is allowed to be uninitialized under certain condition */
  509. if (!disp->Initialized) {
  510. if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
  511. ctx != EGL_NO_CONTEXT)
  512. RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
  513. }
  514. if (!drv)
  515. RETURN_EGL_SUCCESS(disp, EGL_TRUE);
  516. if (!context && ctx != EGL_NO_CONTEXT)
  517. RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  518. if (!draw_surf || !read_surf) {
  519. /* From the EGL 1.4 (20130211) spec:
  520. *
  521. * To release the current context without assigning a new one, set ctx
  522. * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
  523. */
  524. if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
  525. RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  526. if ((!draw_surf && draw != EGL_NO_SURFACE) ||
  527. (!read_surf && read != EGL_NO_SURFACE))
  528. RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  529. if (draw_surf || read_surf)
  530. RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
  531. }
  532. ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
  533. RETURN_EGL_EVAL(disp, ret);
  534. }
  535. EGLBoolean EGLAPIENTRY
  536. eglQueryContext(EGLDisplay dpy, EGLContext ctx,
  537. EGLint attribute, EGLint *value)
  538. {
  539. _EGLDisplay *disp = _eglLockDisplay(dpy);
  540. _EGLContext *context = _eglLookupContext(ctx, disp);
  541. _EGLDriver *drv;
  542. EGLBoolean ret;
  543. _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
  544. ret = drv->API.QueryContext(drv, disp, context, attribute, value);
  545. RETURN_EGL_EVAL(disp, ret);
  546. }
  547. static EGLSurface
  548. _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
  549. void *native_window, const EGLint *attrib_list)
  550. {
  551. _EGLConfig *conf = _eglLookupConfig(config, disp);
  552. _EGLDriver *drv;
  553. _EGLSurface *surf;
  554. EGLSurface ret;
  555. _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  556. if (native_window == NULL)
  557. RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
  558. surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
  559. attrib_list);
  560. ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  561. RETURN_EGL_EVAL(disp, ret);
  562. }
  563. EGLSurface EGLAPIENTRY
  564. eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
  565. EGLNativeWindowType window, const EGLint *attrib_list)
  566. {
  567. _EGLDisplay *disp = _eglLockDisplay(dpy);
  568. STATIC_ASSERT(sizeof(void*) == sizeof(window));
  569. return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
  570. attrib_list);
  571. }
  572. static EGLSurface EGLAPIENTRY
  573. eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
  574. void *native_window,
  575. const EGLint *attrib_list)
  576. {
  577. _EGLDisplay *disp = _eglLockDisplay(dpy);
  578. #ifdef HAVE_X11_PLATFORM
  579. if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
  580. /* The `native_window` parameter for the X11 platform differs between
  581. * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
  582. * eglCreateWindowSurface(), the type of `native_window` is an Xlib
  583. * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
  584. * `Window*`. Convert `Window*` to `Window` because that's what
  585. * dri2_x11_create_window_surface() expects.
  586. */
  587. native_window = (void*) (* (Window*) native_window);
  588. }
  589. #endif
  590. return _eglCreateWindowSurfaceCommon(disp, config, native_window,
  591. attrib_list);
  592. }
  593. static EGLSurface
  594. _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
  595. void *native_pixmap, const EGLint *attrib_list)
  596. {
  597. _EGLConfig *conf = _eglLookupConfig(config, disp);
  598. _EGLDriver *drv;
  599. _EGLSurface *surf;
  600. EGLSurface ret;
  601. _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  602. surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
  603. attrib_list);
  604. ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  605. RETURN_EGL_EVAL(disp, ret);
  606. }
  607. EGLSurface EGLAPIENTRY
  608. eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
  609. EGLNativePixmapType pixmap, const EGLint *attrib_list)
  610. {
  611. _EGLDisplay *disp = _eglLockDisplay(dpy);
  612. STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
  613. return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
  614. attrib_list);
  615. }
  616. static EGLSurface EGLAPIENTRY
  617. eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
  618. void *native_pixmap,
  619. const EGLint *attrib_list)
  620. {
  621. _EGLDisplay *disp = _eglLockDisplay(dpy);
  622. #ifdef HAVE_X11_PLATFORM
  623. /* The `native_pixmap` parameter for the X11 platform differs between
  624. * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
  625. * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
  626. * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
  627. * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
  628. * dri2_x11_create_pixmap_surface() expects.
  629. */
  630. if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
  631. native_pixmap = (void*) (* (Pixmap*) native_pixmap);
  632. }
  633. #endif
  634. return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
  635. attrib_list);
  636. }
  637. EGLSurface EGLAPIENTRY
  638. eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
  639. const EGLint *attrib_list)
  640. {
  641. _EGLDisplay *disp = _eglLockDisplay(dpy);
  642. _EGLConfig *conf = _eglLookupConfig(config, disp);
  643. _EGLDriver *drv;
  644. _EGLSurface *surf;
  645. EGLSurface ret;
  646. _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  647. surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
  648. ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  649. RETURN_EGL_EVAL(disp, ret);
  650. }
  651. EGLBoolean EGLAPIENTRY
  652. eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
  653. {
  654. _EGLDisplay *disp = _eglLockDisplay(dpy);
  655. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  656. _EGLDriver *drv;
  657. EGLBoolean ret;
  658. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  659. _eglUnlinkSurface(surf);
  660. ret = drv->API.DestroySurface(drv, disp, surf);
  661. RETURN_EGL_EVAL(disp, ret);
  662. }
  663. EGLBoolean EGLAPIENTRY
  664. eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
  665. EGLint attribute, EGLint *value)
  666. {
  667. _EGLDisplay *disp = _eglLockDisplay(dpy);
  668. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  669. _EGLDriver *drv;
  670. EGLBoolean ret;
  671. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  672. ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
  673. RETURN_EGL_EVAL(disp, ret);
  674. }
  675. EGLBoolean EGLAPIENTRY
  676. eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
  677. EGLint attribute, EGLint value)
  678. {
  679. _EGLDisplay *disp = _eglLockDisplay(dpy);
  680. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  681. _EGLDriver *drv;
  682. EGLBoolean ret;
  683. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  684. ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
  685. RETURN_EGL_EVAL(disp, ret);
  686. }
  687. EGLBoolean EGLAPIENTRY
  688. eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  689. {
  690. _EGLDisplay *disp = _eglLockDisplay(dpy);
  691. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  692. _EGLDriver *drv;
  693. EGLBoolean ret;
  694. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  695. ret = drv->API.BindTexImage(drv, disp, surf, buffer);
  696. RETURN_EGL_EVAL(disp, ret);
  697. }
  698. EGLBoolean EGLAPIENTRY
  699. eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  700. {
  701. _EGLDisplay *disp = _eglLockDisplay(dpy);
  702. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  703. _EGLDriver *drv;
  704. EGLBoolean ret;
  705. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  706. ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
  707. RETURN_EGL_EVAL(disp, ret);
  708. }
  709. EGLBoolean EGLAPIENTRY
  710. eglSwapInterval(EGLDisplay dpy, EGLint interval)
  711. {
  712. _EGLDisplay *disp = _eglLockDisplay(dpy);
  713. _EGLContext *ctx = _eglGetCurrentContext();
  714. _EGLSurface *surf;
  715. _EGLDriver *drv;
  716. EGLBoolean ret;
  717. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  718. if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  719. ctx->Resource.Display != disp)
  720. RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
  721. surf = ctx->DrawSurface;
  722. if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
  723. RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  724. ret = drv->API.SwapInterval(drv, disp, surf, interval);
  725. RETURN_EGL_EVAL(disp, ret);
  726. }
  727. EGLBoolean EGLAPIENTRY
  728. eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  729. {
  730. _EGLContext *ctx = _eglGetCurrentContext();
  731. _EGLDisplay *disp = _eglLockDisplay(dpy);
  732. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  733. _EGLDriver *drv;
  734. EGLBoolean ret;
  735. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  736. /* surface must be bound to current context in EGL 1.4 */
  737. #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
  738. if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  739. surf != ctx->DrawSurface)
  740. RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  741. #endif
  742. ret = drv->API.SwapBuffers(drv, disp, surf);
  743. RETURN_EGL_EVAL(disp, ret);
  744. }
  745. #ifdef EGL_EXT_swap_buffers_with_damage
  746. static EGLBoolean EGLAPIENTRY
  747. eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
  748. EGLint *rects, EGLint n_rects)
  749. {
  750. _EGLContext *ctx = _eglGetCurrentContext();
  751. _EGLDisplay *disp = _eglLockDisplay(dpy);
  752. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  753. _EGLDriver *drv;
  754. EGLBoolean ret;
  755. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  756. /* surface must be bound to current context in EGL 1.4 */
  757. if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  758. surf != ctx->DrawSurface)
  759. RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  760. if ((n_rects > 0 && rects == NULL) || n_rects < 0)
  761. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  762. ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
  763. RETURN_EGL_EVAL(disp, ret);
  764. }
  765. #endif /* EGL_EXT_swap_buffers_with_damage */
  766. EGLBoolean EGLAPIENTRY
  767. eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
  768. {
  769. _EGLDisplay *disp = _eglLockDisplay(dpy);
  770. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  771. _EGLDriver *drv;
  772. EGLBoolean ret;
  773. void *native_pixmap_ptr;
  774. STATIC_ASSERT(sizeof(void*) == sizeof(target));
  775. native_pixmap_ptr = (void*) target;
  776. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  777. if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
  778. RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
  779. ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
  780. RETURN_EGL_EVAL(disp, ret);
  781. }
  782. EGLBoolean EGLAPIENTRY
  783. eglWaitClient(void)
  784. {
  785. _EGLContext *ctx = _eglGetCurrentContext();
  786. _EGLDisplay *disp;
  787. _EGLDriver *drv;
  788. EGLBoolean ret;
  789. if (!ctx)
  790. RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  791. disp = ctx->Resource.Display;
  792. mtx_lock(&disp->Mutex);
  793. /* let bad current context imply bad current surface */
  794. if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  795. _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  796. RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  797. /* a valid current context implies an initialized current display */
  798. assert(disp->Initialized);
  799. drv = disp->Driver;
  800. ret = drv->API.WaitClient(drv, disp, ctx);
  801. RETURN_EGL_EVAL(disp, ret);
  802. }
  803. EGLBoolean EGLAPIENTRY
  804. eglWaitGL(void)
  805. {
  806. _EGLThreadInfo *t = _eglGetCurrentThread();
  807. EGLint api_index = t->CurrentAPIIndex;
  808. EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
  809. EGLBoolean ret;
  810. if (api_index != es_index && _eglIsCurrentThreadDummy())
  811. RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  812. t->CurrentAPIIndex = es_index;
  813. ret = eglWaitClient();
  814. t->CurrentAPIIndex = api_index;
  815. return ret;
  816. }
  817. EGLBoolean EGLAPIENTRY
  818. eglWaitNative(EGLint engine)
  819. {
  820. _EGLContext *ctx = _eglGetCurrentContext();
  821. _EGLDisplay *disp;
  822. _EGLDriver *drv;
  823. EGLBoolean ret;
  824. if (!ctx)
  825. RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  826. disp = ctx->Resource.Display;
  827. mtx_lock(&disp->Mutex);
  828. /* let bad current context imply bad current surface */
  829. if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  830. _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
  831. RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
  832. /* a valid current context implies an initialized current display */
  833. assert(disp->Initialized);
  834. drv = disp->Driver;
  835. ret = drv->API.WaitNative(drv, disp, engine);
  836. RETURN_EGL_EVAL(disp, ret);
  837. }
  838. EGLDisplay EGLAPIENTRY
  839. eglGetCurrentDisplay(void)
  840. {
  841. _EGLContext *ctx = _eglGetCurrentContext();
  842. EGLDisplay ret;
  843. ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
  844. RETURN_EGL_SUCCESS(NULL, ret);
  845. }
  846. EGLContext EGLAPIENTRY
  847. eglGetCurrentContext(void)
  848. {
  849. _EGLContext *ctx = _eglGetCurrentContext();
  850. EGLContext ret;
  851. ret = _eglGetContextHandle(ctx);
  852. RETURN_EGL_SUCCESS(NULL, ret);
  853. }
  854. EGLSurface EGLAPIENTRY
  855. eglGetCurrentSurface(EGLint readdraw)
  856. {
  857. _EGLContext *ctx = _eglGetCurrentContext();
  858. EGLint err = EGL_SUCCESS;
  859. _EGLSurface *surf;
  860. EGLSurface ret;
  861. if (!ctx)
  862. RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
  863. switch (readdraw) {
  864. case EGL_DRAW:
  865. surf = ctx->DrawSurface;
  866. break;
  867. case EGL_READ:
  868. surf = ctx->ReadSurface;
  869. break;
  870. default:
  871. surf = NULL;
  872. err = EGL_BAD_PARAMETER;
  873. break;
  874. }
  875. ret = _eglGetSurfaceHandle(surf);
  876. RETURN_EGL_ERROR(NULL, err, ret);
  877. }
  878. EGLint EGLAPIENTRY
  879. eglGetError(void)
  880. {
  881. _EGLThreadInfo *t = _eglGetCurrentThread();
  882. EGLint e = t->LastError;
  883. if (!_eglIsCurrentThreadDummy())
  884. t->LastError = EGL_SUCCESS;
  885. return e;
  886. }
  887. #ifdef EGL_MESA_drm_display
  888. static EGLDisplay EGLAPIENTRY
  889. eglGetDRMDisplayMESA(int fd)
  890. {
  891. _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
  892. return _eglGetDisplayHandle(dpy);
  893. }
  894. #endif /* EGL_MESA_drm_display */
  895. /**
  896. ** EGL 1.2
  897. **/
  898. /**
  899. * Specify the client API to use for subsequent calls including:
  900. * eglCreateContext()
  901. * eglGetCurrentContext()
  902. * eglGetCurrentDisplay()
  903. * eglGetCurrentSurface()
  904. * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
  905. * eglWaitClient()
  906. * eglWaitNative()
  907. * See section 3.7 "Rendering Context" in the EGL specification for details.
  908. */
  909. EGLBoolean EGLAPIENTRY
  910. eglBindAPI(EGLenum api)
  911. {
  912. _EGLThreadInfo *t = _eglGetCurrentThread();
  913. if (_eglIsCurrentThreadDummy())
  914. RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
  915. if (!_eglIsApiValid(api))
  916. RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
  917. t->CurrentAPIIndex = _eglConvertApiToIndex(api);
  918. RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  919. }
  920. /**
  921. * Return the last value set with eglBindAPI().
  922. */
  923. EGLenum EGLAPIENTRY
  924. eglQueryAPI(void)
  925. {
  926. _EGLThreadInfo *t = _eglGetCurrentThread();
  927. EGLenum ret;
  928. /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
  929. ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
  930. RETURN_EGL_SUCCESS(NULL, ret);
  931. }
  932. EGLSurface EGLAPIENTRY
  933. eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
  934. EGLClientBuffer buffer, EGLConfig config,
  935. const EGLint *attrib_list)
  936. {
  937. _EGLDisplay *disp = _eglLockDisplay(dpy);
  938. _EGLConfig *conf = _eglLookupConfig(config, disp);
  939. _EGLDriver *drv;
  940. _EGLSurface *surf;
  941. EGLSurface ret;
  942. _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
  943. surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
  944. conf, attrib_list);
  945. ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
  946. RETURN_EGL_EVAL(disp, ret);
  947. }
  948. EGLBoolean EGLAPIENTRY
  949. eglReleaseThread(void)
  950. {
  951. /* unbind current contexts */
  952. if (!_eglIsCurrentThreadDummy()) {
  953. _EGLThreadInfo *t = _eglGetCurrentThread();
  954. EGLint api_index = t->CurrentAPIIndex;
  955. EGLint i;
  956. for (i = 0; i < _EGL_API_NUM_APIS; i++) {
  957. _EGLContext *ctx = t->CurrentContexts[i];
  958. if (ctx) {
  959. _EGLDisplay *disp = ctx->Resource.Display;
  960. _EGLDriver *drv;
  961. t->CurrentAPIIndex = i;
  962. mtx_lock(&disp->Mutex);
  963. drv = disp->Driver;
  964. (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
  965. mtx_unlock(&disp->Mutex);
  966. }
  967. }
  968. t->CurrentAPIIndex = api_index;
  969. }
  970. _eglDestroyCurrentThread();
  971. RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
  972. }
  973. static EGLImageKHR EGLAPIENTRY
  974. eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  975. EGLClientBuffer buffer, const EGLint *attr_list)
  976. {
  977. _EGLDisplay *disp = _eglLockDisplay(dpy);
  978. _EGLContext *context = _eglLookupContext(ctx, disp);
  979. _EGLDriver *drv;
  980. _EGLImage *img;
  981. EGLImageKHR ret;
  982. _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  983. if (!disp->Extensions.KHR_image_base)
  984. RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  985. if (!context && ctx != EGL_NO_CONTEXT)
  986. RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
  987. /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
  988. * <ctx> must be EGL_NO_CONTEXT..."
  989. */
  990. if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
  991. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
  992. img = drv->API.CreateImageKHR(drv,
  993. disp, context, target, buffer, attr_list);
  994. ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  995. RETURN_EGL_EVAL(disp, ret);
  996. }
  997. static EGLBoolean EGLAPIENTRY
  998. eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
  999. {
  1000. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1001. _EGLImage *img = _eglLookupImage(image, disp);
  1002. _EGLDriver *drv;
  1003. EGLBoolean ret;
  1004. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1005. if (!disp->Extensions.KHR_image_base)
  1006. RETURN_EGL_EVAL(disp, EGL_FALSE);
  1007. if (!img)
  1008. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1009. _eglUnlinkImage(img);
  1010. ret = drv->API.DestroyImageKHR(drv, disp, img);
  1011. RETURN_EGL_EVAL(disp, ret);
  1012. }
  1013. static EGLSyncKHR
  1014. _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
  1015. const EGLAttribKHR *attrib_list64, EGLBoolean is64)
  1016. {
  1017. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1018. _EGLContext *ctx = _eglGetCurrentContext();
  1019. _EGLDriver *drv;
  1020. _EGLSync *sync;
  1021. EGLSyncKHR ret;
  1022. _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
  1023. if (!disp->Extensions.KHR_cl_event2 && is64)
  1024. RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
  1025. /* return an error if the client API doesn't support GL_OES_EGL_sync */
  1026. if (!ctx || ctx->Resource.Display != dpy ||
  1027. ctx->ClientAPI != EGL_OPENGL_ES_API)
  1028. RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
  1029. switch (type) {
  1030. case EGL_SYNC_FENCE_KHR:
  1031. if (!disp->Extensions.KHR_fence_sync)
  1032. RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1033. break;
  1034. case EGL_SYNC_REUSABLE_KHR:
  1035. if (!disp->Extensions.KHR_reusable_sync)
  1036. RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1037. break;
  1038. case EGL_SYNC_CL_EVENT_KHR:
  1039. if (!disp->Extensions.KHR_cl_event2)
  1040. RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1041. break;
  1042. default:
  1043. RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
  1044. }
  1045. sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
  1046. ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
  1047. RETURN_EGL_EVAL(disp, ret);
  1048. }
  1049. static EGLSyncKHR EGLAPIENTRY
  1050. eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
  1051. {
  1052. return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE);
  1053. }
  1054. static EGLSyncKHR EGLAPIENTRY
  1055. eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list)
  1056. {
  1057. return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE);
  1058. }
  1059. static EGLBoolean EGLAPIENTRY
  1060. eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
  1061. {
  1062. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1063. _EGLSync *s = _eglLookupSync(sync, disp);
  1064. _EGLDriver *drv;
  1065. EGLBoolean ret;
  1066. _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1067. assert(disp->Extensions.KHR_reusable_sync ||
  1068. disp->Extensions.KHR_fence_sync);
  1069. _eglUnlinkSync(s);
  1070. ret = drv->API.DestroySyncKHR(drv, disp, s);
  1071. RETURN_EGL_EVAL(disp, ret);
  1072. }
  1073. static EGLint EGLAPIENTRY
  1074. eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
  1075. {
  1076. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1077. _EGLSync *s = _eglLookupSync(sync, disp);
  1078. _EGLDriver *drv;
  1079. EGLint ret;
  1080. _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1081. assert(disp->Extensions.KHR_reusable_sync ||
  1082. disp->Extensions.KHR_fence_sync);
  1083. if (s->SyncStatus == EGL_SIGNALED_KHR)
  1084. RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
  1085. ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
  1086. RETURN_EGL_EVAL(disp, ret);
  1087. }
  1088. static EGLint EGLAPIENTRY
  1089. eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
  1090. {
  1091. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1092. _EGLSync *s = _eglLookupSync(sync, disp);
  1093. _EGLContext *ctx = _eglGetCurrentContext();
  1094. _EGLDriver *drv;
  1095. EGLint ret;
  1096. _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1097. assert(disp->Extensions.KHR_wait_sync);
  1098. /* return an error if the client API doesn't support GL_OES_EGL_sync */
  1099. if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
  1100. RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
  1101. /* the API doesn't allow any flags yet */
  1102. if (flags != 0)
  1103. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1104. ret = drv->API.WaitSyncKHR(drv, disp, s);
  1105. RETURN_EGL_EVAL(disp, ret);
  1106. }
  1107. static EGLBoolean EGLAPIENTRY
  1108. eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
  1109. {
  1110. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1111. _EGLSync *s = _eglLookupSync(sync, disp);
  1112. _EGLDriver *drv;
  1113. EGLBoolean ret;
  1114. _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1115. assert(disp->Extensions.KHR_reusable_sync);
  1116. ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
  1117. RETURN_EGL_EVAL(disp, ret);
  1118. }
  1119. static EGLBoolean EGLAPIENTRY
  1120. eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
  1121. {
  1122. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1123. _EGLSync *s = _eglLookupSync(sync, disp);
  1124. _EGLDriver *drv;
  1125. EGLBoolean ret;
  1126. _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
  1127. assert(disp->Extensions.KHR_reusable_sync ||
  1128. disp->Extensions.KHR_fence_sync);
  1129. ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
  1130. RETURN_EGL_EVAL(disp, ret);
  1131. }
  1132. #ifdef EGL_NOK_swap_region
  1133. static EGLBoolean EGLAPIENTRY
  1134. eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
  1135. EGLint numRects, const EGLint *rects)
  1136. {
  1137. _EGLContext *ctx = _eglGetCurrentContext();
  1138. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1139. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1140. _EGLDriver *drv;
  1141. EGLBoolean ret;
  1142. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1143. if (!disp->Extensions.NOK_swap_region)
  1144. RETURN_EGL_EVAL(disp, EGL_FALSE);
  1145. /* surface must be bound to current context in EGL 1.4 */
  1146. if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
  1147. surf != ctx->DrawSurface)
  1148. RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
  1149. ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
  1150. RETURN_EGL_EVAL(disp, ret);
  1151. }
  1152. #endif /* EGL_NOK_swap_region */
  1153. #ifdef EGL_MESA_drm_image
  1154. static EGLImageKHR EGLAPIENTRY
  1155. eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
  1156. {
  1157. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1158. _EGLDriver *drv;
  1159. _EGLImage *img;
  1160. EGLImageKHR ret;
  1161. _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
  1162. if (!disp->Extensions.MESA_drm_image)
  1163. RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
  1164. img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
  1165. ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  1166. RETURN_EGL_EVAL(disp, ret);
  1167. }
  1168. static EGLBoolean EGLAPIENTRY
  1169. eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
  1170. EGLint *name, EGLint *handle, EGLint *stride)
  1171. {
  1172. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1173. _EGLImage *img = _eglLookupImage(image, disp);
  1174. _EGLDriver *drv;
  1175. EGLBoolean ret;
  1176. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1177. assert(disp->Extensions.MESA_drm_image);
  1178. if (!img)
  1179. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1180. ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
  1181. RETURN_EGL_EVAL(disp, ret);
  1182. }
  1183. #endif
  1184. #ifdef EGL_WL_bind_wayland_display
  1185. struct wl_display;
  1186. static EGLBoolean EGLAPIENTRY
  1187. eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1188. {
  1189. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1190. _EGLDriver *drv;
  1191. EGLBoolean ret;
  1192. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1193. assert(disp->Extensions.WL_bind_wayland_display);
  1194. if (!display)
  1195. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1196. ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
  1197. RETURN_EGL_EVAL(disp, ret);
  1198. }
  1199. static EGLBoolean EGLAPIENTRY
  1200. eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
  1201. {
  1202. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1203. _EGLDriver *drv;
  1204. EGLBoolean ret;
  1205. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1206. assert(disp->Extensions.WL_bind_wayland_display);
  1207. if (!display)
  1208. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1209. ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
  1210. RETURN_EGL_EVAL(disp, ret);
  1211. }
  1212. static EGLBoolean EGLAPIENTRY
  1213. eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
  1214. EGLint attribute, EGLint *value)
  1215. {
  1216. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1217. _EGLDriver *drv;
  1218. EGLBoolean ret;
  1219. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1220. assert(disp->Extensions.WL_bind_wayland_display);
  1221. if (!buffer)
  1222. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1223. ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
  1224. RETURN_EGL_EVAL(disp, ret);
  1225. }
  1226. #endif
  1227. #ifdef EGL_WL_create_wayland_buffer_from_image
  1228. static struct wl_buffer * EGLAPIENTRY
  1229. eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
  1230. {
  1231. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1232. _EGLImage *img;
  1233. _EGLDriver *drv;
  1234. struct wl_buffer *ret;
  1235. _EGL_CHECK_DISPLAY(disp, NULL, drv);
  1236. assert(disp->Extensions.WL_create_wayland_buffer_from_image);
  1237. img = _eglLookupImage(image, disp);
  1238. if (!img)
  1239. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
  1240. ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
  1241. RETURN_EGL_EVAL(disp, ret);
  1242. }
  1243. #endif
  1244. static EGLBoolean EGLAPIENTRY
  1245. eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
  1246. EGLint x, EGLint y, EGLint width, EGLint height)
  1247. {
  1248. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1249. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1250. _EGLDriver *drv;
  1251. EGLBoolean ret;
  1252. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1253. if (!disp->Extensions.NV_post_sub_buffer)
  1254. RETURN_EGL_EVAL(disp, EGL_FALSE);
  1255. ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
  1256. RETURN_EGL_EVAL(disp, ret);
  1257. }
  1258. static EGLBoolean EGLAPIENTRY
  1259. eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
  1260. EGLuint64KHR *ust, EGLuint64KHR *msc,
  1261. EGLuint64KHR *sbc)
  1262. {
  1263. _EGLDisplay *disp = _eglLockDisplay(display);
  1264. _EGLSurface *surf = _eglLookupSurface(surface, disp);
  1265. _EGLDriver *drv;
  1266. EGLBoolean ret;
  1267. _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
  1268. if (!disp->Extensions.CHROMIUM_sync_control)
  1269. RETURN_EGL_EVAL(disp, EGL_FALSE);
  1270. if (!ust || !msc || !sbc)
  1271. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1272. ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
  1273. RETURN_EGL_EVAL(disp, ret);
  1274. }
  1275. #ifdef EGL_MESA_image_dma_buf_export
  1276. static EGLBoolean EGLAPIENTRY
  1277. eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
  1278. EGLint *fourcc, EGLint *nplanes,
  1279. EGLuint64KHR *modifiers)
  1280. {
  1281. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1282. _EGLImage *img = _eglLookupImage(image, disp);
  1283. _EGLDriver *drv;
  1284. EGLBoolean ret;
  1285. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1286. assert(disp->Extensions.MESA_image_dma_buf_export);
  1287. if (!img)
  1288. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1289. ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
  1290. modifiers);
  1291. RETURN_EGL_EVAL(disp, ret);
  1292. }
  1293. static EGLBoolean EGLAPIENTRY
  1294. eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImageKHR image,
  1295. int *fds, EGLint *strides, EGLint *offsets)
  1296. {
  1297. _EGLDisplay *disp = _eglLockDisplay(dpy);
  1298. _EGLImage *img = _eglLookupImage(image, disp);
  1299. _EGLDriver *drv;
  1300. EGLBoolean ret;
  1301. _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
  1302. assert(disp->Extensions.MESA_image_dma_buf_export);
  1303. if (!img)
  1304. RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
  1305. ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
  1306. RETURN_EGL_EVAL(disp, ret);
  1307. }
  1308. #endif
  1309. __eglMustCastToProperFunctionPointerType EGLAPIENTRY
  1310. eglGetProcAddress(const char *procname)
  1311. {
  1312. static const struct {
  1313. const char *name;
  1314. _EGLProc function;
  1315. } egl_functions[] = {
  1316. /* core functions queryable in the presence of
  1317. * EGL_KHR_get_all_proc_addresses or EGL 1.5
  1318. */
  1319. /* alphabetical order */
  1320. { "eglBindAPI", (_EGLProc) eglBindAPI },
  1321. { "eglBindTexImage", (_EGLProc) eglBindTexImage },
  1322. { "eglChooseConfig", (_EGLProc) eglChooseConfig },
  1323. { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
  1324. { "eglCreateContext", (_EGLProc) eglCreateContext },
  1325. { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
  1326. { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
  1327. { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
  1328. { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
  1329. { "eglDestroyContext", (_EGLProc) eglDestroyContext },
  1330. { "eglDestroySurface", (_EGLProc) eglDestroySurface },
  1331. { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
  1332. { "eglGetConfigs", (_EGLProc) eglGetConfigs },
  1333. { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
  1334. { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
  1335. { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
  1336. { "eglGetDisplay", (_EGLProc) eglGetDisplay },
  1337. { "eglGetError", (_EGLProc) eglGetError },
  1338. { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
  1339. { "eglInitialize", (_EGLProc) eglInitialize },
  1340. { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
  1341. { "eglQueryAPI", (_EGLProc) eglQueryAPI },
  1342. { "eglQueryContext", (_EGLProc) eglQueryContext },
  1343. { "eglQueryString", (_EGLProc) eglQueryString },
  1344. { "eglQuerySurface", (_EGLProc) eglQuerySurface },
  1345. { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
  1346. { "eglReleaseThread", (_EGLProc) eglReleaseThread },
  1347. { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
  1348. { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
  1349. { "eglSwapInterval", (_EGLProc) eglSwapInterval },
  1350. { "eglTerminate", (_EGLProc) eglTerminate },
  1351. { "eglWaitClient", (_EGLProc) eglWaitClient },
  1352. { "eglWaitGL", (_EGLProc) eglWaitGL },
  1353. { "eglWaitNative", (_EGLProc) eglWaitNative },
  1354. #ifdef EGL_MESA_drm_display
  1355. { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
  1356. #endif
  1357. { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
  1358. { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
  1359. { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
  1360. { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
  1361. { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
  1362. { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
  1363. { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
  1364. { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
  1365. { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
  1366. #ifdef EGL_NOK_swap_region
  1367. { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
  1368. #endif
  1369. #ifdef EGL_MESA_drm_image
  1370. { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
  1371. { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
  1372. #endif
  1373. #ifdef EGL_WL_bind_wayland_display
  1374. { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
  1375. { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
  1376. { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
  1377. #endif
  1378. #ifdef EGL_WL_create_wayland_buffer_from_image
  1379. { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
  1380. #endif
  1381. { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
  1382. #ifdef EGL_EXT_swap_buffers_with_damage
  1383. { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
  1384. #endif
  1385. { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
  1386. { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
  1387. { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
  1388. { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
  1389. #ifdef EGL_MESA_image_dma_buf_export
  1390. { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
  1391. { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
  1392. #endif
  1393. { NULL, NULL }
  1394. };
  1395. EGLint i;
  1396. _EGLProc ret;
  1397. if (!procname)
  1398. RETURN_EGL_SUCCESS(NULL, NULL);
  1399. ret = NULL;
  1400. if (strncmp(procname, "egl", 3) == 0) {
  1401. for (i = 0; egl_functions[i].name; i++) {
  1402. if (strcmp(egl_functions[i].name, procname) == 0) {
  1403. ret = egl_functions[i].function;
  1404. break;
  1405. }
  1406. }
  1407. }
  1408. if (!ret)
  1409. ret = _eglGetDriverProc(procname);
  1410. RETURN_EGL_SUCCESS(NULL, ret);
  1411. }