draw: corrections to allow for different cliptest cases
[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 if (config)
406 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
407 else
408 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
409
410 if (!share && share_list != EGL_NO_CONTEXT)
411 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
412
413 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
414 ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT;
415
416 RETURN_EGL_EVAL(disp, ret);
417 }
418
419
420 EGLBoolean EGLAPIENTRY
421 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
422 {
423 _EGLDisplay *disp = _eglLockDisplay(dpy);
424 _EGLContext *context = _eglLookupContext(ctx, disp);
425 _EGLDriver *drv;
426 EGLBoolean ret;
427
428 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
429 _eglUnlinkContext(context);
430 ret = drv->API.DestroyContext(drv, disp, context);
431
432 RETURN_EGL_EVAL(disp, ret);
433 }
434
435
436 EGLBoolean EGLAPIENTRY
437 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
438 EGLContext ctx)
439 {
440 _EGLDisplay *disp = _eglLockDisplay(dpy);
441 _EGLContext *context = _eglLookupContext(ctx, disp);
442 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
443 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
444 _EGLDriver *drv;
445 EGLBoolean ret;
446
447 if (!disp)
448 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
449 drv = disp->Driver;
450
451 /* display is allowed to be uninitialized under certain condition */
452 if (!disp->Initialized) {
453 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
454 ctx != EGL_NO_CONTEXT)
455 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
456 }
457 if (!drv)
458 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
459
460 if (!context && ctx != EGL_NO_CONTEXT)
461 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
462 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
463 (!read_surf && read != EGL_NO_SURFACE))
464 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
465
466 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
467
468 RETURN_EGL_EVAL(disp, ret);
469 }
470
471
472 EGLBoolean EGLAPIENTRY
473 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
474 EGLint attribute, EGLint *value)
475 {
476 _EGLDisplay *disp = _eglLockDisplay(dpy);
477 _EGLContext *context = _eglLookupContext(ctx, disp);
478 _EGLDriver *drv;
479 EGLBoolean ret;
480
481 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
482 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
483
484 RETURN_EGL_EVAL(disp, ret);
485 }
486
487
488 EGLSurface EGLAPIENTRY
489 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
490 EGLNativeWindowType window, const EGLint *attrib_list)
491 {
492 _EGLDisplay *disp = _eglLockDisplay(dpy);
493 _EGLConfig *conf = _eglLookupConfig(config, disp);
494 _EGLDriver *drv;
495 _EGLSurface *surf;
496 EGLSurface ret;
497
498 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
499 if (disp->Platform != _eglGetNativePlatform())
500 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
501
502 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
503 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
504
505 RETURN_EGL_EVAL(disp, ret);
506 }
507
508
509 EGLSurface EGLAPIENTRY
510 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
511 EGLNativePixmapType pixmap, const EGLint *attrib_list)
512 {
513 _EGLDisplay *disp = _eglLockDisplay(dpy);
514 _EGLConfig *conf = _eglLookupConfig(config, disp);
515 _EGLDriver *drv;
516 _EGLSurface *surf;
517 EGLSurface ret;
518
519 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
520 if (disp->Platform != _eglGetNativePlatform())
521 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
522
523 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
524 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
525
526 RETURN_EGL_EVAL(disp, ret);
527 }
528
529
530 EGLSurface EGLAPIENTRY
531 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
532 const EGLint *attrib_list)
533 {
534 _EGLDisplay *disp = _eglLockDisplay(dpy);
535 _EGLConfig *conf = _eglLookupConfig(config, disp);
536 _EGLDriver *drv;
537 _EGLSurface *surf;
538 EGLSurface ret;
539
540 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
541
542 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
543 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
544
545 RETURN_EGL_EVAL(disp, ret);
546 }
547
548
549 EGLBoolean EGLAPIENTRY
550 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
551 {
552 _EGLDisplay *disp = _eglLockDisplay(dpy);
553 _EGLSurface *surf = _eglLookupSurface(surface, disp);
554 _EGLDriver *drv;
555 EGLBoolean ret;
556
557 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
558 _eglUnlinkSurface(surf);
559 ret = drv->API.DestroySurface(drv, disp, surf);
560
561 RETURN_EGL_EVAL(disp, ret);
562 }
563
564 EGLBoolean EGLAPIENTRY
565 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
566 EGLint attribute, EGLint *value)
567 {
568 _EGLDisplay *disp = _eglLockDisplay(dpy);
569 _EGLSurface *surf = _eglLookupSurface(surface, disp);
570 _EGLDriver *drv;
571 EGLBoolean ret;
572
573 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
574 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
575
576 RETURN_EGL_EVAL(disp, ret);
577 }
578
579 EGLBoolean EGLAPIENTRY
580 eglSurfaceAttrib(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.SurfaceAttrib(drv, disp, surf, attribute, value);
590
591 RETURN_EGL_EVAL(disp, ret);
592 }
593
594
595 EGLBoolean EGLAPIENTRY
596 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
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.BindTexImage(drv, disp, surf, buffer);
605
606 RETURN_EGL_EVAL(disp, ret);
607 }
608
609
610 EGLBoolean EGLAPIENTRY
611 eglReleaseTexImage(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.ReleaseTexImage(drv, disp, surf, buffer);
620
621 RETURN_EGL_EVAL(disp, ret);
622 }
623
624
625 EGLBoolean EGLAPIENTRY
626 eglSwapInterval(EGLDisplay dpy, EGLint interval)
627 {
628 _EGLDisplay *disp = _eglLockDisplay(dpy);
629 _EGLContext *ctx = _eglGetCurrentContext();
630 _EGLSurface *surf;
631 _EGLDriver *drv;
632 EGLBoolean ret;
633
634 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
635
636 if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
637 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
638
639 surf = ctx->DrawSurface;
640 if (!_eglIsSurfaceLinked(surf))
641 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
642
643 ret = drv->API.SwapInterval(drv, disp, surf, interval);
644
645 RETURN_EGL_EVAL(disp, ret);
646 }
647
648
649 EGLBoolean EGLAPIENTRY
650 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
651 {
652 _EGLContext *ctx = _eglGetCurrentContext();
653 _EGLDisplay *disp = _eglLockDisplay(dpy);
654 _EGLSurface *surf = _eglLookupSurface(surface, disp);
655 _EGLDriver *drv;
656 EGLBoolean ret;
657
658 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
659
660 /* surface must be bound to current context in EGL 1.4 */
661 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
662 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
663
664 ret = drv->API.SwapBuffers(drv, disp, surf);
665
666 RETURN_EGL_EVAL(disp, ret);
667 }
668
669
670 EGLBoolean EGLAPIENTRY
671 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
672 {
673 _EGLDisplay *disp = _eglLockDisplay(dpy);
674 _EGLSurface *surf = _eglLookupSurface(surface, disp);
675 _EGLDriver *drv;
676 EGLBoolean ret;
677
678 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
679 if (disp->Platform != _eglGetNativePlatform())
680 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
681 ret = drv->API.CopyBuffers(drv, disp, surf, target);
682
683 RETURN_EGL_EVAL(disp, ret);
684 }
685
686
687 EGLBoolean EGLAPIENTRY
688 eglWaitClient(void)
689 {
690 _EGLContext *ctx = _eglGetCurrentContext();
691 _EGLDisplay *disp;
692 _EGLDriver *drv;
693 EGLBoolean ret;
694
695 if (!ctx)
696 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
697
698 disp = ctx->Resource.Display;
699 _eglLockMutex(&disp->Mutex);
700
701 /* let bad current context imply bad current surface */
702 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
703 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
704
705 /* a valid current context implies an initialized current display */
706 assert(disp->Initialized);
707 drv = disp->Driver;
708 ret = drv->API.WaitClient(drv, disp, ctx);
709
710 RETURN_EGL_EVAL(disp, ret);
711 }
712
713
714 EGLBoolean EGLAPIENTRY
715 eglWaitGL(void)
716 {
717 #ifdef EGL_VERSION_1_2
718 _EGLThreadInfo *t = _eglGetCurrentThread();
719 EGLint api_index = t->CurrentAPIIndex;
720 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
721 EGLBoolean ret;
722
723 if (api_index != es_index && _eglIsCurrentThreadDummy())
724 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
725
726 t->CurrentAPIIndex = es_index;
727 ret = eglWaitClient();
728 t->CurrentAPIIndex = api_index;
729 return ret;
730 #else
731 return eglWaitClient();
732 #endif
733 }
734
735
736 EGLBoolean EGLAPIENTRY
737 eglWaitNative(EGLint engine)
738 {
739 _EGLContext *ctx = _eglGetCurrentContext();
740 _EGLDisplay *disp;
741 _EGLDriver *drv;
742 EGLBoolean ret;
743
744 if (!ctx)
745 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
746
747 disp = ctx->Resource.Display;
748 _eglLockMutex(&disp->Mutex);
749
750 /* let bad current context imply bad current surface */
751 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
752 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
753
754 /* a valid current context implies an initialized current display */
755 assert(disp->Initialized);
756 drv = disp->Driver;
757 ret = drv->API.WaitNative(drv, disp, engine);
758
759 RETURN_EGL_EVAL(disp, ret);
760 }
761
762
763 EGLDisplay EGLAPIENTRY
764 eglGetCurrentDisplay(void)
765 {
766 _EGLContext *ctx = _eglGetCurrentContext();
767 EGLDisplay ret;
768
769 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
770
771 RETURN_EGL_SUCCESS(NULL, ret);
772 }
773
774
775 EGLContext EGLAPIENTRY
776 eglGetCurrentContext(void)
777 {
778 _EGLContext *ctx = _eglGetCurrentContext();
779 EGLContext ret;
780
781 ret = _eglGetContextHandle(ctx);
782
783 RETURN_EGL_SUCCESS(NULL, ret);
784 }
785
786
787 EGLSurface EGLAPIENTRY
788 eglGetCurrentSurface(EGLint readdraw)
789 {
790 _EGLContext *ctx = _eglGetCurrentContext();
791 EGLint err = EGL_SUCCESS;
792 _EGLSurface *surf;
793 EGLSurface ret;
794
795 if (!ctx)
796 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
797
798 switch (readdraw) {
799 case EGL_DRAW:
800 surf = ctx->DrawSurface;
801 break;
802 case EGL_READ:
803 surf = ctx->ReadSurface;
804 break;
805 default:
806 surf = NULL;
807 err = EGL_BAD_PARAMETER;
808 break;
809 }
810
811 ret = _eglGetSurfaceHandle(surf);
812
813 RETURN_EGL_ERROR(NULL, err, ret);
814 }
815
816
817 EGLint EGLAPIENTRY
818 eglGetError(void)
819 {
820 _EGLThreadInfo *t = _eglGetCurrentThread();
821 EGLint e = t->LastError;
822 if (!_eglIsCurrentThreadDummy())
823 t->LastError = EGL_SUCCESS;
824 return e;
825 }
826
827
828 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
829 eglGetProcAddress(const char *procname)
830 {
831 static const struct {
832 const char *name;
833 _EGLProc function;
834 } egl_functions[] = {
835 /* core functions should not be queryable, but, well... */
836 #ifdef _EGL_GET_CORE_ADDRESSES
837 /* alphabetical order */
838 { "eglBindAPI", (_EGLProc) eglBindAPI },
839 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
840 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
841 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
842 { "eglCreateContext", (_EGLProc) eglCreateContext },
843 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
844 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
845 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
846 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
847 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
848 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
849 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
850 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
851 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
852 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
853 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
854 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
855 { "eglGetError", (_EGLProc) eglGetError },
856 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
857 { "eglInitialize", (_EGLProc) eglInitialize },
858 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
859 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
860 { "eglQueryContext", (_EGLProc) eglQueryContext },
861 { "eglQueryString", (_EGLProc) eglQueryString },
862 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
863 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
864 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
865 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
866 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
867 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
868 { "eglTerminate", (_EGLProc) eglTerminate },
869 { "eglWaitClient", (_EGLProc) eglWaitClient },
870 { "eglWaitGL", (_EGLProc) eglWaitGL },
871 { "eglWaitNative", (_EGLProc) eglWaitNative },
872 #endif /* _EGL_GET_CORE_ADDRESSES */
873 #ifdef EGL_MESA_screen_surface
874 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
875 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
876 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
877 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
878 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
879 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
880 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
881 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
882 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
883 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
884 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
885 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
886 #endif /* EGL_MESA_screen_surface */
887 #ifdef EGL_MESA_drm_display
888 { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
889 #endif
890 #ifdef EGL_KHR_image_base
891 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
892 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
893 #endif /* EGL_KHR_image_base */
894 #ifdef EGL_NOK_swap_region
895 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
896 #endif
897 #ifdef EGL_MESA_drm_image
898 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
899 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
900 #endif
901 { NULL, NULL }
902 };
903 EGLint i;
904 _EGLProc ret;
905
906 if (!procname)
907 RETURN_EGL_SUCCESS(NULL, NULL);
908
909 ret = NULL;
910 if (strncmp(procname, "egl", 3) == 0) {
911 for (i = 0; egl_functions[i].name; i++) {
912 if (strcmp(egl_functions[i].name, procname) == 0) {
913 ret = egl_functions[i].function;
914 break;
915 }
916 }
917 }
918 if (!ret)
919 ret = _eglGetDriverProc(procname);
920
921 RETURN_EGL_SUCCESS(NULL, ret);
922 }
923
924
925 #ifdef EGL_MESA_screen_surface
926
927
928 /*
929 * EGL_MESA_screen extension
930 */
931
932 EGLBoolean EGLAPIENTRY
933 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
934 const EGLint *attrib_list, EGLModeMESA *modes,
935 EGLint modes_size, EGLint *num_modes)
936 {
937 _EGLDisplay *disp = _eglLockDisplay(dpy);
938 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
939 _EGLDriver *drv;
940 EGLBoolean ret;
941
942 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
943 ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
944 modes, modes_size, num_modes);
945
946 RETURN_EGL_EVAL(disp, ret);
947 }
948
949
950 EGLBoolean EGLAPIENTRY
951 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
952 EGLint mode_size, EGLint *num_mode)
953 {
954 _EGLDisplay *disp = _eglLockDisplay(dpy);
955 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
956 _EGLDriver *drv;
957 EGLBoolean ret;
958
959 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
960 ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
961
962 RETURN_EGL_EVAL(disp, ret);
963 }
964
965
966 EGLBoolean EGLAPIENTRY
967 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
968 EGLint attribute, EGLint *value)
969 {
970 _EGLDisplay *disp = _eglLockDisplay(dpy);
971 _EGLMode *m = _eglLookupMode(mode, disp);
972 _EGLDriver *drv;
973 EGLBoolean ret;
974
975 _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
976 ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
977
978 RETURN_EGL_EVAL(disp, ret);
979 }
980
981
982 EGLBoolean EGLAPIENTRY
983 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
984 EGLint mask)
985 {
986 _EGLDisplay *disp = _eglLockDisplay(dpy);
987 _EGLContext *source_context = _eglLookupContext(source, disp);
988 _EGLContext *dest_context = _eglLookupContext(dest, disp);
989 _EGLDriver *drv;
990 EGLBoolean ret;
991
992 _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
993 if (!dest_context)
994 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
995
996 ret = drv->API.CopyContextMESA(drv, disp,
997 source_context, dest_context, mask);
998
999 RETURN_EGL_EVAL(disp, ret);
1000 }
1001
1002
1003 EGLBoolean EGLAPIENTRY
1004 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
1005 EGLint max_screens, EGLint *num_screens)
1006 {
1007 _EGLDisplay *disp = _eglLockDisplay(dpy);
1008 _EGLDriver *drv;
1009 EGLBoolean ret;
1010
1011 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1012 ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
1013
1014 RETURN_EGL_EVAL(disp, ret);
1015 }
1016
1017
1018 EGLSurface EGLAPIENTRY
1019 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
1020 const EGLint *attrib_list)
1021 {
1022 _EGLDisplay *disp = _eglLockDisplay(dpy);
1023 _EGLConfig *conf = _eglLookupConfig(config, disp);
1024 _EGLDriver *drv;
1025 _EGLSurface *surf;
1026 EGLSurface ret;
1027
1028 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1029
1030 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
1031 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
1032
1033 RETURN_EGL_EVAL(disp, ret);
1034 }
1035
1036
1037 EGLBoolean EGLAPIENTRY
1038 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
1039 EGLSurface surface, EGLModeMESA mode)
1040 {
1041 _EGLDisplay *disp = _eglLockDisplay(dpy);
1042 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1043 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1044 _EGLMode *m = _eglLookupMode(mode, disp);
1045 _EGLDriver *drv;
1046 EGLBoolean ret;
1047
1048 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1049 if (!surf && surface != EGL_NO_SURFACE)
1050 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1051 if (!m && mode != EGL_NO_MODE_MESA)
1052 RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
1053
1054 ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
1055
1056 RETURN_EGL_EVAL(disp, ret);
1057 }
1058
1059
1060 EGLBoolean EGLAPIENTRY
1061 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
1062 {
1063 _EGLDisplay *disp = _eglLockDisplay(dpy);
1064 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1065 _EGLDriver *drv;
1066 EGLBoolean ret;
1067
1068 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1069 ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1070
1071 RETURN_EGL_EVAL(disp, ret);
1072 }
1073
1074
1075 EGLBoolean EGLAPIENTRY
1076 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1077 EGLint attribute, EGLint *value)
1078 {
1079 _EGLDisplay *disp = _eglLockDisplay(dpy);
1080 _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1081 _EGLDriver *drv;
1082 EGLBoolean ret;
1083
1084 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1085 ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1086
1087 RETURN_EGL_EVAL(disp, ret);
1088 }
1089
1090
1091 EGLBoolean EGLAPIENTRY
1092 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1093 EGLSurface *surface)
1094 {
1095 _EGLDisplay *disp = _eglLockDisplay(dpy);
1096 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1097 _EGLDriver *drv;
1098 _EGLSurface *surf;
1099 EGLBoolean ret;
1100
1101 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1102 ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1103 if (ret && surface)
1104 *surface = _eglGetSurfaceHandle(surf);
1105
1106 RETURN_EGL_EVAL(disp, ret);
1107 }
1108
1109
1110 EGLBoolean EGLAPIENTRY
1111 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1112 {
1113 _EGLDisplay *disp = _eglLockDisplay(dpy);
1114 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1115 _EGLDriver *drv;
1116 _EGLMode *m;
1117 EGLBoolean ret;
1118
1119 _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1120 ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1121 if (ret && mode)
1122 *mode = m->Handle;
1123
1124 RETURN_EGL_EVAL(disp, ret);
1125 }
1126
1127
1128 const char * EGLAPIENTRY
1129 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1130 {
1131 _EGLDisplay *disp = _eglLockDisplay(dpy);
1132 _EGLMode *m = _eglLookupMode(mode, disp);
1133 _EGLDriver *drv;
1134 const char *ret;
1135
1136 _EGL_CHECK_MODE(disp, m, NULL, drv);
1137 ret = drv->API.QueryModeStringMESA(drv, disp, m);
1138
1139 RETURN_EGL_EVAL(disp, ret);
1140 }
1141
1142
1143 #endif /* EGL_MESA_screen_surface */
1144
1145
1146 #ifdef EGL_MESA_drm_display
1147
1148 EGLDisplay EGLAPIENTRY
1149 eglGetDRMDisplayMESA(int fd)
1150 {
1151 _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) fd);
1152 return _eglGetDisplayHandle(dpy);
1153 }
1154
1155 #endif /* EGL_MESA_drm_display */
1156
1157 /**
1158 ** EGL 1.2
1159 **/
1160
1161 #ifdef EGL_VERSION_1_2
1162
1163
1164 /**
1165 * Specify the client API to use for subsequent calls including:
1166 * eglCreateContext()
1167 * eglGetCurrentContext()
1168 * eglGetCurrentDisplay()
1169 * eglGetCurrentSurface()
1170 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1171 * eglWaitClient()
1172 * eglWaitNative()
1173 * See section 3.7 "Rendering Context" in the EGL specification for details.
1174 */
1175 EGLBoolean EGLAPIENTRY
1176 eglBindAPI(EGLenum api)
1177 {
1178 _EGLThreadInfo *t = _eglGetCurrentThread();
1179
1180 if (_eglIsCurrentThreadDummy())
1181 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1182
1183 if (!_eglIsApiValid(api))
1184 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1185
1186 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1187
1188 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1189 }
1190
1191
1192 /**
1193 * Return the last value set with eglBindAPI().
1194 */
1195 EGLenum EGLAPIENTRY
1196 eglQueryAPI(void)
1197 {
1198 _EGLThreadInfo *t = _eglGetCurrentThread();
1199 EGLenum ret;
1200
1201 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1202 ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1203
1204 RETURN_EGL_SUCCESS(NULL, ret);
1205 }
1206
1207
1208 EGLSurface EGLAPIENTRY
1209 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1210 EGLClientBuffer buffer, EGLConfig config,
1211 const EGLint *attrib_list)
1212 {
1213 _EGLDisplay *disp = _eglLockDisplay(dpy);
1214 _EGLConfig *conf = _eglLookupConfig(config, disp);
1215 _EGLDriver *drv;
1216 _EGLSurface *surf;
1217 EGLSurface ret;
1218
1219 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1220
1221 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1222 conf, attrib_list);
1223 ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
1224
1225 RETURN_EGL_EVAL(disp, ret);
1226 }
1227
1228
1229 EGLBoolean EGLAPIENTRY
1230 eglReleaseThread(void)
1231 {
1232 /* unbind current contexts */
1233 if (!_eglIsCurrentThreadDummy()) {
1234 _EGLThreadInfo *t = _eglGetCurrentThread();
1235 EGLint api_index = t->CurrentAPIIndex;
1236 EGLint i;
1237
1238 for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1239 _EGLContext *ctx = t->CurrentContexts[i];
1240 if (ctx) {
1241 _EGLDisplay *disp = ctx->Resource.Display;
1242 _EGLDriver *drv;
1243
1244 t->CurrentAPIIndex = i;
1245
1246 _eglLockMutex(&disp->Mutex);
1247 drv = disp->Driver;
1248 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1249 _eglUnlockMutex(&disp->Mutex);
1250 }
1251 }
1252
1253 t->CurrentAPIIndex = api_index;
1254 }
1255
1256 _eglDestroyCurrentThread();
1257
1258 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1259 }
1260
1261
1262 #endif /* EGL_VERSION_1_2 */
1263
1264
1265 #ifdef EGL_KHR_image_base
1266
1267
1268 EGLImageKHR EGLAPIENTRY
1269 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1270 EGLClientBuffer buffer, const EGLint *attr_list)
1271 {
1272 _EGLDisplay *disp = _eglLockDisplay(dpy);
1273 _EGLContext *context = _eglLookupContext(ctx, disp);
1274 _EGLDriver *drv;
1275 _EGLImage *img;
1276 EGLImageKHR ret;
1277
1278 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1279 if (!context && ctx != EGL_NO_CONTEXT)
1280 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1281
1282 img = drv->API.CreateImageKHR(drv,
1283 disp, context, target, buffer, attr_list);
1284 ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
1285
1286 RETURN_EGL_EVAL(disp, ret);
1287 }
1288
1289
1290 EGLBoolean EGLAPIENTRY
1291 eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1292 {
1293 _EGLDisplay *disp = _eglLockDisplay(dpy);
1294 _EGLImage *img = _eglLookupImage(image, disp);
1295 _EGLDriver *drv;
1296 EGLBoolean ret;
1297
1298 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1299 if (!img)
1300 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1301
1302 _eglUnlinkImage(img);
1303 ret = drv->API.DestroyImageKHR(drv, disp, img);
1304
1305 RETURN_EGL_EVAL(disp, ret);
1306 }
1307
1308
1309 #endif /* EGL_KHR_image_base */
1310
1311
1312 #ifdef EGL_KHR_reusable_sync
1313
1314
1315 EGLSyncKHR EGLAPIENTRY
1316 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1317 {
1318 _EGLDisplay *disp = _eglLockDisplay(dpy);
1319 _EGLDriver *drv;
1320 _EGLSync *sync;
1321 EGLSyncKHR ret;
1322
1323 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1324
1325 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
1326 ret = (sync) ? _eglLinkSync(sync, disp) : EGL_NO_SYNC_KHR;
1327
1328 RETURN_EGL_EVAL(disp, ret);
1329 }
1330
1331
1332 EGLBoolean EGLAPIENTRY
1333 eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1334 {
1335 _EGLDisplay *disp = _eglLockDisplay(dpy);
1336 _EGLSync *s = _eglLookupSync(sync, disp);
1337 _EGLDriver *drv;
1338 EGLBoolean ret;
1339
1340 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1341 _eglUnlinkSync(s);
1342 ret = drv->API.DestroySyncKHR(drv, disp, s);
1343
1344 RETURN_EGL_EVAL(disp, ret);
1345 }
1346
1347
1348 EGLint EGLAPIENTRY
1349 eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1350 {
1351 _EGLDisplay *disp = _eglLockDisplay(dpy);
1352 _EGLSync *s = _eglLookupSync(sync, disp);
1353 _EGLDriver *drv;
1354 EGLint ret;
1355
1356 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1357 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1358
1359 RETURN_EGL_EVAL(disp, ret);
1360 }
1361
1362
1363 EGLBoolean EGLAPIENTRY
1364 eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1365 {
1366 _EGLDisplay *disp = _eglLockDisplay(dpy);
1367 _EGLSync *s = _eglLookupSync(sync, disp);
1368 _EGLDriver *drv;
1369 EGLBoolean ret;
1370
1371 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1372 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1373
1374 RETURN_EGL_EVAL(disp, ret);
1375 }
1376
1377
1378 EGLBoolean EGLAPIENTRY
1379 eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1380 {
1381 _EGLDisplay *disp = _eglLockDisplay(dpy);
1382 _EGLSync *s = _eglLookupSync(sync, disp);
1383 _EGLDriver *drv;
1384 EGLBoolean ret;
1385
1386 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1387 ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1388
1389 RETURN_EGL_EVAL(disp, ret);
1390 }
1391
1392
1393 #endif /* EGL_KHR_reusable_sync */
1394
1395
1396 #ifdef EGL_NOK_swap_region
1397
1398 EGLBoolean EGLAPIENTRY
1399 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1400 EGLint numRects, const EGLint *rects)
1401 {
1402 _EGLContext *ctx = _eglGetCurrentContext();
1403 _EGLDisplay *disp = _eglLockDisplay(dpy);
1404 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1405 _EGLDriver *drv;
1406 EGLBoolean ret;
1407
1408 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1409
1410 /* surface must be bound to current context in EGL 1.4 */
1411 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
1412 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1413
1414 if (drv->API.SwapBuffersRegionNOK)
1415 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1416 else
1417 ret = drv->API.SwapBuffers(drv, disp, surf);
1418
1419 RETURN_EGL_EVAL(disp, ret);
1420 }
1421
1422 #endif /* EGL_NOK_swap_region */
1423
1424
1425 #ifdef EGL_MESA_drm_image
1426
1427 EGLImageKHR EGLAPIENTRY
1428 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1429 {
1430 _EGLDisplay *disp = _eglLockDisplay(dpy);
1431 _EGLDriver *drv;
1432 _EGLImage *img;
1433 EGLImageKHR ret;
1434
1435 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1436
1437 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1438 ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
1439
1440 RETURN_EGL_EVAL(disp, ret);
1441 }
1442
1443 EGLBoolean EGLAPIENTRY
1444 eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
1445 EGLint *name, EGLint *handle, EGLint *stride)
1446 {
1447 _EGLDisplay *disp = _eglLockDisplay(dpy);
1448 _EGLImage *img = _eglLookupImage(image, disp);
1449 _EGLDriver *drv;
1450 EGLBoolean ret;
1451
1452 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1453 if (!img)
1454 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1455
1456 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1457
1458 RETURN_EGL_EVAL(disp, ret);
1459 }
1460
1461 #endif