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