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