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