egl: Clean up header inclusions.
[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 #include "eglcontext.h"
60 #include "egldisplay.h"
61 #include "egltypedefs.h"
62 #include "eglglobals.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
71
72 /**
73 * This is typically the first EGL function that an application calls.
74 * We initialize our global vars and create a private _EGLDisplay object.
75 */
76 EGLDisplay EGLAPIENTRY
77 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
78 {
79 _EGLDisplay *dpy;
80 dpy = _eglFindDisplay(nativeDisplay);
81 if (!dpy) {
82 dpy = _eglNewDisplay(nativeDisplay);
83 if (dpy)
84 _eglLinkDisplay(dpy);
85 }
86 return _eglGetDisplayHandle(dpy);
87 }
88
89
90 /**
91 * This is typically the second EGL function that an application calls.
92 * Here we load/initialize the actual hardware driver.
93 */
94 EGLBoolean EGLAPIENTRY
95 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
96 {
97 _EGLDisplay *disp = _eglLookupDisplay(dpy);
98 EGLint major_int, minor_int;
99
100 if (!disp)
101 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
102
103 if (!disp->Initialized) {
104 _EGLDriver *drv = disp->Driver;
105
106 if (!drv) {
107 _eglPreloadDrivers();
108 drv = _eglMatchDriver(disp);
109 if (!drv)
110 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
111 }
112
113 /* Initialize the particular display now */
114 if (!drv->API.Initialize(drv, disp, &major_int, &minor_int))
115 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
116
117 disp->APImajor = major_int;
118 disp->APIminor = minor_int;
119 snprintf(disp->Version, sizeof(disp->Version),
120 "%d.%d (%s)", major_int, minor_int, drv->Name);
121
122 /* limit to APIs supported by core */
123 disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
124
125 disp->Driver = drv;
126 disp->Initialized = EGL_TRUE;
127 } else {
128 major_int = disp->APImajor;
129 minor_int = disp->APIminor;
130 }
131
132 /* Update applications version of major and minor if not NULL */
133 if ((major != NULL) && (minor != NULL)) {
134 *major = major_int;
135 *minor = minor_int;
136 }
137
138 return EGL_TRUE;
139 }
140
141
142 EGLBoolean EGLAPIENTRY
143 eglTerminate(EGLDisplay dpy)
144 {
145 _EGLDisplay *disp = _eglLookupDisplay(dpy);
146
147 if (!disp)
148 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
149
150 if (disp->Initialized) {
151 _EGLDriver *drv = disp->Driver;
152
153 drv->API.Terminate(drv, disp);
154 /* do not reset disp->Driver */
155 disp->Initialized = EGL_FALSE;
156 }
157
158 return EGL_TRUE;
159 }
160
161
162 /**
163 * A bunch of check functions and declare macros to simply error checking.
164 */
165 static INLINE _EGLDriver *
166 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
167 {
168 if (!disp) {
169 _eglError(EGL_BAD_DISPLAY, msg);
170 return NULL;
171 }
172 if (!disp->Initialized) {
173 _eglError(EGL_NOT_INITIALIZED, msg);
174 return NULL;
175 }
176 return disp->Driver;
177 }
178
179
180 static INLINE _EGLDriver *
181 _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
182 {
183 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
184 if (!drv)
185 return NULL;
186 if (!surf) {
187 _eglError(EGL_BAD_SURFACE, msg);
188 return NULL;
189 }
190 return drv;
191 }
192
193
194 static INLINE _EGLDriver *
195 _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
196 {
197 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
198 if (!drv)
199 return NULL;
200 if (!context) {
201 _eglError(EGL_BAD_CONTEXT, msg);
202 return NULL;
203 }
204 return drv;
205 }
206
207
208 static INLINE _EGLDriver *
209 _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
210 {
211 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
212 if (!drv)
213 return NULL;
214 if (!conf) {
215 _eglError(EGL_BAD_CONFIG, msg);
216 return NULL;
217 }
218 return drv;
219 }
220
221
222 #define _EGL_DECLARE_DD(dpy) \
223 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
224 _EGLDriver *drv; \
225 do { \
226 drv = _eglCheckDisplay(disp, __FUNCTION__); \
227 if (!drv) \
228 return EGL_FALSE; \
229 } while (0)
230
231
232 #define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \
233 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
234 _EGLSurface *surf = _eglLookupSurface((surface), disp); \
235 _EGLDriver *drv; \
236 do { \
237 drv = _eglCheckSurface(disp, surf, __FUNCTION__); \
238 if (!drv) \
239 return EGL_FALSE; \
240 } while (0)
241
242
243 #define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \
244 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
245 _EGLContext *context = _eglLookupContext((ctx), disp); \
246 _EGLDriver *drv; \
247 do { \
248 drv = _eglCheckContext(disp, context, __FUNCTION__); \
249 if (!drv) \
250 return EGL_FALSE; \
251 } while (0)
252
253
254 #ifdef EGL_MESA_screen_surface
255
256
257 static INLINE _EGLDriver *
258 _eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
259 {
260 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
261 if (!drv)
262 return NULL;
263 if (!scrn) {
264 _eglError(EGL_BAD_SCREEN_MESA, msg);
265 return NULL;
266 }
267 return drv;
268 }
269
270
271 static INLINE _EGLDriver *
272 _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
273 {
274 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
275 if (!drv)
276 return NULL;
277 if (!m) {
278 _eglError(EGL_BAD_MODE_MESA, msg);
279 return NULL;
280 }
281 return drv;
282 }
283
284
285 #define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \
286 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
287 _EGLScreen *scrn = _eglLookupScreen((screen), disp); \
288 _EGLDriver *drv; \
289 do { \
290 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \
291 if (!drv) \
292 return EGL_FALSE; \
293 } while (0)
294
295
296 #define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \
297 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
298 _EGLMode *m = _eglLookupMode((mode), disp); \
299 _EGLDriver *drv; \
300 do { \
301 drv = _eglCheckMode(disp, m, __FUNCTION__); \
302 if (!drv) \
303 return EGL_FALSE; \
304 } while (0)
305
306
307 #endif /* EGL_MESA_screen_surface */
308
309
310 const char * EGLAPIENTRY
311 eglQueryString(EGLDisplay dpy, EGLint name)
312 {
313 _EGL_DECLARE_DD(dpy);
314 return drv->API.QueryString(drv, disp, name);
315 }
316
317
318 EGLBoolean EGLAPIENTRY
319 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
320 EGLint config_size, EGLint *num_config)
321 {
322 _EGL_DECLARE_DD(dpy);
323 return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
324 }
325
326
327 EGLBoolean EGLAPIENTRY
328 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
329 EGLint config_size, EGLint *num_config)
330 {
331 _EGL_DECLARE_DD(dpy);
332 return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
333 config_size, num_config);
334 }
335
336
337 EGLBoolean EGLAPIENTRY
338 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
339 EGLint attribute, EGLint *value)
340 {
341 _EGLDisplay *disp = _eglLookupDisplay(dpy);
342 _EGLConfig *conf = _eglLookupConfig(config, disp);
343 _EGLDriver *drv;
344
345 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
346 if (!drv)
347 return EGL_FALSE;
348
349 return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
350 }
351
352
353 EGLContext EGLAPIENTRY
354 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
355 const EGLint *attrib_list)
356 {
357 _EGLDisplay *disp = _eglLookupDisplay(dpy);
358 _EGLConfig *conf = _eglLookupConfig(config, disp);
359 _EGLContext *share = _eglLookupContext(share_list, disp);
360 _EGLDriver *drv;
361 _EGLContext *context;
362
363 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
364 if (!drv)
365 return EGL_NO_CONTEXT;
366 if (!share && share_list != EGL_NO_CONTEXT) {
367 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
368 return EGL_NO_CONTEXT;
369 }
370
371 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
372 if (context)
373 return _eglLinkContext(context, disp);
374 else
375 return EGL_NO_CONTEXT;
376 }
377
378
379 EGLBoolean EGLAPIENTRY
380 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
381 {
382 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
383 _eglUnlinkContext(context);
384 return drv->API.DestroyContext(drv, disp, context);
385 }
386
387
388 EGLBoolean EGLAPIENTRY
389 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
390 EGLContext ctx)
391 {
392 _EGLDisplay *disp = _eglLookupDisplay(dpy);
393 _EGLContext *context = _eglLookupContext(ctx, disp);
394 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
395 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
396 _EGLDriver *drv;
397
398 if (!disp)
399 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
400 drv = disp->Driver;
401
402 /* display is allowed to be uninitialized under certain condition */
403 if (!disp->Initialized) {
404 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
405 ctx != EGL_NO_CONTEXT)
406 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
407 }
408 if (!drv)
409 return EGL_TRUE;
410
411 if (!context && ctx != EGL_NO_CONTEXT)
412 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
413 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
414 (!read_surf && read != EGL_NO_SURFACE))
415 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
416
417 return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
418 }
419
420
421 EGLBoolean EGLAPIENTRY
422 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
423 EGLint attribute, EGLint *value)
424 {
425 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
426 return drv->API.QueryContext(drv, disp, context, attribute, value);
427 }
428
429
430 EGLSurface EGLAPIENTRY
431 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
432 EGLNativeWindowType window, const EGLint *attrib_list)
433 {
434 _EGLDisplay *disp = _eglLookupDisplay(dpy);
435 _EGLConfig *conf = _eglLookupConfig(config, disp);
436 _EGLDriver *drv;
437 _EGLSurface *surf;
438
439 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
440 if (!drv)
441 return EGL_NO_SURFACE;
442
443 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
444 if (surf)
445 return _eglLinkSurface(surf, disp);
446 else
447 return EGL_NO_SURFACE;
448 }
449
450
451 EGLSurface EGLAPIENTRY
452 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
453 EGLNativePixmapType pixmap, const EGLint *attrib_list)
454 {
455 _EGLDisplay *disp = _eglLookupDisplay(dpy);
456 _EGLConfig *conf = _eglLookupConfig(config, disp);
457 _EGLDriver *drv;
458 _EGLSurface *surf;
459
460 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
461 if (!drv)
462 return EGL_NO_SURFACE;
463
464 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
465 if (surf)
466 return _eglLinkSurface(surf, disp);
467 else
468 return EGL_NO_SURFACE;
469 }
470
471
472 EGLSurface EGLAPIENTRY
473 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
474 const EGLint *attrib_list)
475 {
476 _EGLDisplay *disp = _eglLookupDisplay(dpy);
477 _EGLConfig *conf = _eglLookupConfig(config, disp);
478 _EGLDriver *drv;
479 _EGLSurface *surf;
480
481 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
482 if (!drv)
483 return EGL_NO_SURFACE;
484
485 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
486 if (surf)
487 return _eglLinkSurface(surf, disp);
488 else
489 return EGL_NO_SURFACE;
490 }
491
492
493 EGLBoolean EGLAPIENTRY
494 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
495 {
496 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
497 _eglUnlinkSurface(surf);
498 return drv->API.DestroySurface(drv, disp, surf);
499 }
500
501 EGLBoolean EGLAPIENTRY
502 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
503 EGLint attribute, EGLint *value)
504 {
505 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
506 return drv->API.QuerySurface(drv, disp, surf, attribute, value);
507 }
508
509 EGLBoolean EGLAPIENTRY
510 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
511 EGLint attribute, EGLint value)
512 {
513 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
514 return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
515 }
516
517
518 EGLBoolean EGLAPIENTRY
519 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
520 {
521 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
522 return drv->API.BindTexImage(drv, disp, surf, buffer);
523 }
524
525
526 EGLBoolean EGLAPIENTRY
527 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
528 {
529 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
530 return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
531 }
532
533
534 EGLBoolean EGLAPIENTRY
535 eglSwapInterval(EGLDisplay dpy, EGLint interval)
536 {
537 _EGLContext *ctx = _eglGetCurrentContext();
538 _EGLSurface *surf;
539 _EGL_DECLARE_DD(dpy);
540
541 if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
542 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
543
544 surf = ctx->DrawSurface;
545 if (!_eglIsSurfaceLinked(surf))
546 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
547
548 return drv->API.SwapInterval(drv, disp, surf, interval);
549 }
550
551
552 EGLBoolean EGLAPIENTRY
553 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
554 {
555 _EGLContext *ctx = _eglGetCurrentContext();
556 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
557
558 /* surface must be bound to current context in EGL 1.4 */
559 if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
560 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
561
562 return drv->API.SwapBuffers(drv, disp, surf);
563 }
564
565
566 EGLBoolean EGLAPIENTRY
567 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
568 {
569 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
570 return drv->API.CopyBuffers(drv, disp, surf, target);
571 }
572
573
574 EGLBoolean EGLAPIENTRY
575 eglWaitClient(void)
576 {
577 _EGLContext *ctx = _eglGetCurrentContext();
578 _EGLDisplay *disp;
579 _EGLDriver *drv;
580
581 if (!ctx)
582 return EGL_TRUE;
583 /* let bad current context imply bad current surface */
584 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
585 return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
586
587 /* a valid current context implies an initialized current display */
588 disp = ctx->Resource.Display;
589 assert(disp->Initialized);
590 drv = disp->Driver;
591
592 return drv->API.WaitClient(drv, disp, ctx);
593 }
594
595
596 EGLBoolean EGLAPIENTRY
597 eglWaitGL(void)
598 {
599 #ifdef EGL_VERSION_1_2
600 _EGLThreadInfo *t = _eglGetCurrentThread();
601 EGLint api_index = t->CurrentAPIIndex;
602 EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
603 EGLBoolean ret;
604
605 if (api_index != es_index && _eglIsCurrentThreadDummy())
606 return _eglError(EGL_BAD_ALLOC, "eglWaitGL");
607
608 t->CurrentAPIIndex = es_index;
609 ret = eglWaitClient();
610 t->CurrentAPIIndex = api_index;
611 return ret;
612 #else
613 return eglWaitClient();
614 #endif
615 }
616
617
618 EGLBoolean EGLAPIENTRY
619 eglWaitNative(EGLint engine)
620 {
621 _EGLContext *ctx = _eglGetCurrentContext();
622 _EGLDisplay *disp;
623 _EGLDriver *drv;
624
625 if (!ctx)
626 return EGL_TRUE;
627 /* let bad current context imply bad current surface */
628 if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
629 return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__);
630
631 /* a valid current context implies an initialized current display */
632 disp = ctx->Resource.Display;
633 assert(disp->Initialized);
634 drv = disp->Driver;
635
636 return drv->API.WaitNative(drv, disp, engine);
637 }
638
639
640 EGLDisplay EGLAPIENTRY
641 eglGetCurrentDisplay(void)
642 {
643 _EGLContext *ctx = _eglGetCurrentContext();
644 return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
645 }
646
647
648 EGLContext EGLAPIENTRY
649 eglGetCurrentContext(void)
650 {
651 _EGLContext *ctx = _eglGetCurrentContext();
652 return _eglGetContextHandle(ctx);
653 }
654
655
656 EGLSurface EGLAPIENTRY
657 eglGetCurrentSurface(EGLint readdraw)
658 {
659 _EGLContext *ctx = _eglGetCurrentContext();
660 _EGLSurface *surf;
661
662 if (!ctx)
663 return EGL_NO_SURFACE;
664
665 switch (readdraw) {
666 case EGL_DRAW:
667 surf = ctx->DrawSurface;
668 break;
669 case EGL_READ:
670 surf = ctx->ReadSurface;
671 break;
672 default:
673 _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
674 surf = NULL;
675 break;
676 }
677
678 return _eglGetSurfaceHandle(surf);
679 }
680
681
682 EGLint EGLAPIENTRY
683 eglGetError(void)
684 {
685 _EGLThreadInfo *t = _eglGetCurrentThread();
686 EGLint e = t->LastError;
687 if (!_eglIsCurrentThreadDummy())
688 t->LastError = EGL_SUCCESS;
689 return e;
690 }
691
692
693 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
694 eglGetProcAddress(const char *procname)
695 {
696 static const struct {
697 const char *name;
698 _EGLProc function;
699 } egl_functions[] = {
700 /* extensions only */
701 #ifdef EGL_MESA_screen_surface
702 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
703 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
704 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
705 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
706 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
707 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
708 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
709 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
710 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
711 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
712 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
713 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
714 #endif /* EGL_MESA_screen_surface */
715 #ifdef EGL_KHR_image_base
716 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
717 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
718 #endif /* EGL_KHR_image_base */
719 { NULL, NULL }
720 };
721 EGLint i;
722
723 if (!procname)
724 return NULL;
725 if (strncmp(procname, "egl", 3) == 0) {
726 for (i = 0; egl_functions[i].name; i++) {
727 if (strcmp(egl_functions[i].name, procname) == 0)
728 return egl_functions[i].function;
729 }
730 }
731
732 _eglPreloadDrivers();
733
734 /* now loop over drivers to query their procs */
735 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
736 _EGLDriver *drv = _eglGlobal.Drivers[i];
737 _EGLProc p = drv->API.GetProcAddress(drv, procname);
738 if (p)
739 return p;
740 }
741
742 return NULL;
743 }
744
745
746 #ifdef EGL_MESA_screen_surface
747
748
749 /*
750 * EGL_MESA_screen extension
751 */
752
753 EGLBoolean EGLAPIENTRY
754 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
755 const EGLint *attrib_list, EGLModeMESA *modes,
756 EGLint modes_size, EGLint *num_modes)
757 {
758 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
759 return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
760 modes, modes_size, num_modes);
761 }
762
763
764 EGLBoolean EGLAPIENTRY
765 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
766 EGLint mode_size, EGLint *num_mode)
767 {
768 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
769 return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
770 }
771
772
773 EGLBoolean EGLAPIENTRY
774 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
775 EGLint attribute, EGLint *value)
776 {
777 _EGL_DECLARE_DD_AND_MODE(dpy, mode);
778 return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
779 }
780
781
782 EGLBoolean EGLAPIENTRY
783 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
784 EGLint mask)
785 {
786 _EGLDisplay *disp = _eglLookupDisplay(dpy);
787 _EGLContext *source_context = _eglLookupContext(source, disp);
788 _EGLContext *dest_context = _eglLookupContext(dest, disp);
789 _EGLDriver *drv;
790
791 drv = _eglCheckContext(disp, source_context, __FUNCTION__);
792 if (!drv || !dest_context) {
793 if (drv)
794 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
795 return EGL_FALSE;
796 }
797
798 return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
799 mask);
800 }
801
802
803 EGLBoolean
804 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
805 EGLint max_screens, EGLint *num_screens)
806 {
807 _EGL_DECLARE_DD(dpy);
808 return drv->API.GetScreensMESA(drv, disp, screens,
809 max_screens, num_screens);
810 }
811
812
813 EGLSurface
814 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
815 const EGLint *attrib_list)
816 {
817 _EGLDisplay *disp = _eglLookupDisplay(dpy);
818 _EGLConfig *conf = _eglLookupConfig(config, disp);
819 _EGLDriver *drv;
820 _EGLSurface *surf;
821
822 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
823 if (!drv)
824 return EGL_NO_SURFACE;
825
826 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
827 if (surf)
828 return _eglLinkSurface(surf, disp);
829 else
830 return EGL_NO_SURFACE;
831 }
832
833
834 EGLBoolean
835 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
836 EGLSurface surface, EGLModeMESA mode)
837 {
838 _EGLDisplay *disp = _eglLookupDisplay(dpy);
839 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
840 _EGLSurface *surf = _eglLookupSurface(surface, disp);
841 _EGLMode *m = _eglLookupMode(mode, disp);
842 _EGLDriver *drv;
843
844 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
845 if (!drv)
846 return EGL_FALSE;
847 if (!surf && surface != EGL_NO_SURFACE)
848 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
849 if (!m && mode != EGL_NO_MODE_MESA)
850 return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
851
852 return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
853 }
854
855
856 EGLBoolean
857 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
858 {
859 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
860 return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
861 }
862
863
864 EGLBoolean
865 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
866 EGLint attribute, EGLint *value)
867 {
868 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
869 return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
870 }
871
872
873 EGLBoolean
874 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
875 EGLSurface *surface)
876 {
877 _EGLDisplay *disp = _eglLookupDisplay(dpy);
878 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
879 _EGLDriver *drv;
880 _EGLSurface *surf;
881
882 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
883 if (!drv)
884 return EGL_FALSE;
885
886 if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
887 surf = NULL;
888 if (surface)
889 *surface = _eglGetSurfaceHandle(surf);
890 return (surf != NULL);
891 }
892
893
894 EGLBoolean
895 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
896 {
897 _EGLDisplay *disp = _eglLookupDisplay(dpy);
898 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
899 _EGLDriver *drv;
900 _EGLMode *m;
901
902 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
903 if (!drv)
904 return EGL_FALSE;
905
906 if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
907 m = NULL;
908 if (mode)
909 *mode = m->Handle;
910
911 return (m != NULL);
912 }
913
914
915 const char *
916 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
917 {
918 _EGL_DECLARE_DD_AND_MODE(dpy, mode);
919 return drv->API.QueryModeStringMESA(drv, disp, m);
920 }
921
922
923 #endif /* EGL_MESA_screen_surface */
924
925
926 /**
927 ** EGL 1.2
928 **/
929
930 #ifdef EGL_VERSION_1_2
931
932
933 /**
934 * Specify the client API to use for subsequent calls including:
935 * eglCreateContext()
936 * eglGetCurrentContext()
937 * eglGetCurrentDisplay()
938 * eglGetCurrentSurface()
939 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
940 * eglWaitClient()
941 * eglWaitNative()
942 * See section 3.7 "Rendering Context" in the EGL specification for details.
943 */
944 EGLBoolean
945 eglBindAPI(EGLenum api)
946 {
947 _EGLThreadInfo *t = _eglGetCurrentThread();
948
949 if (_eglIsCurrentThreadDummy())
950 return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
951
952 if (!_eglIsApiValid(api))
953 return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
954
955 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
956 return EGL_TRUE;
957 }
958
959
960 /**
961 * Return the last value set with eglBindAPI().
962 */
963 EGLenum
964 eglQueryAPI(void)
965 {
966 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
967 _EGLThreadInfo *t = _eglGetCurrentThread();
968 return _eglConvertApiFromIndex(t->CurrentAPIIndex);
969 }
970
971
972 EGLSurface
973 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
974 EGLClientBuffer buffer, EGLConfig config,
975 const EGLint *attrib_list)
976 {
977 _EGLDisplay *disp = _eglLookupDisplay(dpy);
978 _EGLConfig *conf = _eglLookupConfig(config, disp);
979 _EGLDriver *drv;
980 _EGLSurface *surf;
981
982 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
983 if (!drv)
984 return EGL_NO_SURFACE;
985
986 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
987 conf, attrib_list);
988 if (surf)
989 return _eglLinkSurface(surf, disp);
990 else
991 return EGL_NO_SURFACE;
992 }
993
994
995 EGLBoolean
996 eglReleaseThread(void)
997 {
998 /* unbind current contexts */
999 if (!_eglIsCurrentThreadDummy()) {
1000 _EGLThreadInfo *t = _eglGetCurrentThread();
1001 EGLint api_index = t->CurrentAPIIndex;
1002 EGLint i;
1003
1004 for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1005 _EGLContext *ctx = t->CurrentContexts[i];
1006 if (ctx) {
1007 _EGLDisplay *disp = ctx->Resource.Display;
1008 _EGLDriver *drv = disp->Driver;
1009 t->CurrentAPIIndex = i;
1010 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1011 }
1012 }
1013
1014 t->CurrentAPIIndex = api_index;
1015 }
1016
1017 _eglDestroyCurrentThread();
1018 return EGL_TRUE;
1019 }
1020
1021
1022 #endif /* EGL_VERSION_1_2 */
1023
1024
1025 #ifdef EGL_KHR_image_base
1026
1027
1028 EGLImageKHR
1029 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1030 EGLClientBuffer buffer, const EGLint *attr_list)
1031 {
1032 _EGLDisplay *disp = _eglLookupDisplay(dpy);
1033 _EGLContext *context = _eglLookupContext(ctx, disp);
1034 _EGLDriver *drv;
1035 _EGLImage *img;
1036
1037 drv = _eglCheckDisplay(disp, __FUNCTION__);
1038 if (!drv)
1039 return EGL_NO_IMAGE_KHR;
1040 if (!context && ctx != EGL_NO_CONTEXT) {
1041 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
1042 return EGL_NO_IMAGE_KHR;
1043 }
1044
1045 img = drv->API.CreateImageKHR(drv,
1046 disp, context, target, buffer, attr_list);
1047 if (img)
1048 return _eglLinkImage(img, disp);
1049 else
1050 return EGL_NO_IMAGE_KHR;
1051 }
1052
1053
1054 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1055 {
1056 _EGLDisplay *disp = _eglLookupDisplay(dpy);
1057 _EGLImage *img = _eglLookupImage(image, disp);
1058 _EGLDriver *drv;
1059
1060 drv = _eglCheckDisplay(disp, __FUNCTION__);
1061 if (!drv)
1062 return EGL_FALSE;
1063 if (!img)
1064 return _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
1065
1066 _eglUnlinkImage(img);
1067 return drv->API.DestroyImageKHR(drv, disp, img);
1068 }
1069
1070
1071 #endif /* EGL_KHR_image_base */