egl: Change the way drivers are loaded.
[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 implemented with 32-bit unsigned integers.
13 * It's up to the driver function or fallback function to look up the
14 * handle and get an object.
15 * By using opaque handles, we leave open the possibility of having
16 * indirect rendering in the future, like GLX.
17 *
18 *
19 * Notes on naming conventions:
20 *
21 * eglFooBar - public EGL function
22 * EGL_FOO_BAR - public EGL token
23 * EGLDatatype - public EGL datatype
24 *
25 * _eglFooBar - private EGL function
26 * _EGLDatatype - private EGL datatype, typedef'd struct
27 * _egl_struct - private EGL struct, non-typedef'd
28 *
29 */
30
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include "eglcontext.h"
36 #include "egldisplay.h"
37 #include "egltypedefs.h"
38 #include "eglglobals.h"
39 #include "egldriver.h"
40 #include "eglsurface.h"
41 #include "eglconfig.h"
42 #include "eglscreen.h"
43 #include "eglmode.h"
44
45
46 /**
47 * This is typically the first EGL function that an application calls.
48 * We initialize our global vars and create a private _EGLDisplay object.
49 */
50 EGLDisplay EGLAPIENTRY
51 eglGetDisplay(NativeDisplayType nativeDisplay)
52 {
53 _EGLDisplay *dpy;
54 dpy = _eglFindDisplay(nativeDisplay);
55 if (!dpy) {
56 dpy = _eglNewDisplay(nativeDisplay);
57 if (dpy)
58 _eglLinkDisplay(dpy);
59 }
60 return _eglGetDisplayHandle(dpy);
61 }
62
63
64 /**
65 * This is typically the second EGL function that an application calls.
66 * Here we load/initialize the actual hardware driver.
67 */
68 EGLBoolean EGLAPIENTRY
69 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
70 {
71 _EGLDisplay *disp = _eglLookupDisplay(dpy);
72 _EGLDriver *drv;
73 EGLint major_int, minor_int;
74
75 if (!disp)
76 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
77
78 drv = disp->Driver;
79 if (!drv) {
80 drv = _eglOpenDriver(disp);
81 if (!drv)
82 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
83
84 /* Initialize the particular display now */
85 if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) {
86 _eglCloseDriver(drv, disp);
87 return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
88 }
89
90 drv->APImajor = major_int;
91 drv->APIminor = minor_int;
92 snprintf(drv->Version, sizeof(drv->Version),
93 "%d.%d (%s)", major_int, minor_int, drv->Name);
94
95 disp->Driver = drv;
96 } else {
97 major_int = drv->APImajor;
98 minor_int = drv->APIminor;
99 }
100
101 /* Update applications version of major and minor if not NULL */
102 if ((major != NULL) && (minor != NULL)) {
103 *major = major_int;
104 *minor = minor_int;
105 }
106
107 return EGL_TRUE;
108 }
109
110
111 EGLBoolean EGLAPIENTRY
112 eglTerminate(EGLDisplay dpy)
113 {
114 _EGLDisplay *disp = _eglLookupDisplay(dpy);
115 _EGLDriver *drv;
116
117 if (!disp)
118 return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
119
120 drv = disp->Driver;
121 if (drv) {
122 /* TODO drv->API.Terminate should be called here */
123 _eglCloseDriver(drv, disp);
124 disp->Driver = NULL;
125 }
126
127 return EGL_TRUE;
128 }
129
130
131 /**
132 * A bunch of check functions and declare macros to simply error checking.
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->Driver) {
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 #define _EGL_DECLARE_DD(dpy) \
192 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
193 _EGLDriver *drv; \
194 do { \
195 drv = _eglCheckDisplay(disp, __FUNCTION__); \
196 if (!drv) \
197 return EGL_FALSE; \
198 } while (0)
199
200
201 #define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \
202 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
203 _EGLSurface *surf = _eglLookupSurface((surface), disp); \
204 _EGLDriver *drv; \
205 do { \
206 drv = _eglCheckSurface(disp, surf, __FUNCTION__); \
207 if (!drv) \
208 return EGL_FALSE; \
209 } while (0)
210
211
212 #define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \
213 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
214 _EGLContext *context = _eglLookupContext((ctx), disp); \
215 _EGLDriver *drv; \
216 do { \
217 drv = _eglCheckContext(disp, context, __FUNCTION__); \
218 if (!drv) \
219 return EGL_FALSE; \
220 } while (0)
221
222
223 #ifdef EGL_MESA_screen_surface
224
225
226 static INLINE _EGLDriver *
227 _eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
228 {
229 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
230 if (!drv)
231 return NULL;
232 if (!scrn) {
233 _eglError(EGL_BAD_SCREEN_MESA, msg);
234 return NULL;
235 }
236 return drv;
237 }
238
239
240 static INLINE _EGLDriver *
241 _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
242 {
243 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
244 if (!drv)
245 return NULL;
246 if (!m) {
247 _eglError(EGL_BAD_MODE_MESA, msg);
248 return NULL;
249 }
250 return drv;
251 }
252
253
254 #define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \
255 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
256 _EGLScreen *scrn = _eglLookupScreen((screen), disp); \
257 _EGLDriver *drv; \
258 do { \
259 drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \
260 if (!drv) \
261 return EGL_FALSE; \
262 } while (0)
263
264
265 #define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \
266 _EGLDisplay *disp = _eglLookupDisplay(dpy); \
267 _EGLMode *m = _eglLookupMode((mode), disp); \
268 _EGLDriver *drv; \
269 do { \
270 drv = _eglCheckMode(disp, m, __FUNCTION__); \
271 if (!drv) \
272 return EGL_FALSE; \
273 } while (0)
274
275
276 #endif /* EGL_MESA_screen_surface */
277
278
279 const char * EGLAPIENTRY
280 eglQueryString(EGLDisplay dpy, EGLint name)
281 {
282 _EGL_DECLARE_DD(dpy);
283 return drv->API.QueryString(drv, disp, name);
284 }
285
286
287 EGLBoolean EGLAPIENTRY
288 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
289 EGLint config_size, EGLint *num_config)
290 {
291 _EGL_DECLARE_DD(dpy);
292 return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
293 }
294
295
296 EGLBoolean EGLAPIENTRY
297 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
298 EGLint config_size, EGLint *num_config)
299 {
300 _EGL_DECLARE_DD(dpy);
301 return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
302 config_size, num_config);
303 }
304
305
306 EGLBoolean EGLAPIENTRY
307 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
308 EGLint attribute, EGLint *value)
309 {
310 _EGLDisplay *disp = _eglLookupDisplay(dpy);
311 _EGLConfig *conf = _eglLookupConfig(config, disp);
312 _EGLDriver *drv;
313
314 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
315 if (!drv)
316 return EGL_FALSE;
317
318 return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
319 }
320
321
322 EGLContext EGLAPIENTRY
323 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
324 const EGLint *attrib_list)
325 {
326 _EGLDisplay *disp = _eglLookupDisplay(dpy);
327 _EGLConfig *conf = _eglLookupConfig(config, disp);
328 _EGLContext *share = _eglLookupContext(share_list, disp);
329 _EGLDriver *drv;
330 _EGLContext *context;
331
332 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
333 if (!drv)
334 return EGL_NO_CONTEXT;
335 if (!share && share_list != EGL_NO_CONTEXT) {
336 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
337 return EGL_NO_CONTEXT;
338 }
339
340 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
341 if (context)
342 return _eglLinkContext(context, disp);
343 else
344 return EGL_NO_CONTEXT;
345 }
346
347
348 EGLBoolean EGLAPIENTRY
349 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
350 {
351 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
352 _eglUnlinkContext(context);
353 return drv->API.DestroyContext(drv, disp, context);
354 }
355
356
357 EGLBoolean EGLAPIENTRY
358 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
359 EGLContext ctx)
360 {
361 _EGLDisplay *disp = _eglLookupDisplay(dpy);
362 _EGLContext *context = _eglLookupContext(ctx, disp);
363 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
364 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
365 _EGLDriver *drv;
366
367 drv = _eglCheckDisplay(disp, __FUNCTION__);
368 if (!drv)
369 return EGL_FALSE;
370 if (!context && ctx != EGL_NO_CONTEXT)
371 return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
372 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
373 (!read_surf && read != EGL_NO_SURFACE))
374 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
375
376 return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
377 }
378
379
380 EGLBoolean EGLAPIENTRY
381 eglQueryContext(EGLDisplay dpy, EGLContext ctx,
382 EGLint attribute, EGLint *value)
383 {
384 _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
385 return drv->API.QueryContext(drv, disp, context, attribute, value);
386 }
387
388
389 EGLSurface EGLAPIENTRY
390 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
391 NativeWindowType window, const EGLint *attrib_list)
392 {
393 _EGLDisplay *disp = _eglLookupDisplay(dpy);
394 _EGLConfig *conf = _eglLookupConfig(config, disp);
395 _EGLDriver *drv;
396 _EGLSurface *surf;
397
398 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
399 if (!drv)
400 return EGL_NO_SURFACE;
401
402 surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
403 if (surf)
404 return _eglLinkSurface(surf, disp);
405 else
406 return EGL_NO_SURFACE;
407 }
408
409
410 EGLSurface EGLAPIENTRY
411 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
412 NativePixmapType pixmap, const EGLint *attrib_list)
413 {
414 _EGLDisplay *disp = _eglLookupDisplay(dpy);
415 _EGLConfig *conf = _eglLookupConfig(config, disp);
416 _EGLDriver *drv;
417 _EGLSurface *surf;
418
419 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
420 if (!drv)
421 return EGL_NO_SURFACE;
422
423 surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
424 if (surf)
425 return _eglLinkSurface(surf, disp);
426 else
427 return EGL_NO_SURFACE;
428 }
429
430
431 EGLSurface EGLAPIENTRY
432 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
433 const EGLint *attrib_list)
434 {
435 _EGLDisplay *disp = _eglLookupDisplay(dpy);
436 _EGLConfig *conf = _eglLookupConfig(config, disp);
437 _EGLDriver *drv;
438 _EGLSurface *surf;
439
440 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
441 if (!drv)
442 return EGL_NO_SURFACE;
443
444 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
445 if (surf)
446 return _eglLinkSurface(surf, disp);
447 else
448 return EGL_NO_SURFACE;
449 }
450
451
452 EGLBoolean EGLAPIENTRY
453 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
454 {
455 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
456 _eglUnlinkSurface(surf);
457 return drv->API.DestroySurface(drv, disp, surf);
458 }
459
460 EGLBoolean EGLAPIENTRY
461 eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
462 EGLint attribute, EGLint *value)
463 {
464 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
465 return drv->API.QuerySurface(drv, disp, surf, attribute, value);
466 }
467
468 EGLBoolean EGLAPIENTRY
469 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
470 EGLint attribute, EGLint value)
471 {
472 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
473 return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
474 }
475
476
477 EGLBoolean EGLAPIENTRY
478 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
479 {
480 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
481 return drv->API.BindTexImage(drv, disp, surf, buffer);
482 }
483
484
485 EGLBoolean EGLAPIENTRY
486 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
487 {
488 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
489 return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
490 }
491
492
493 EGLBoolean EGLAPIENTRY
494 eglSwapInterval(EGLDisplay dpy, EGLint interval)
495 {
496 _EGL_DECLARE_DD(dpy);
497 return drv->API.SwapInterval(drv, disp, interval);
498 }
499
500
501 EGLBoolean EGLAPIENTRY
502 eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
503 {
504 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
505 return drv->API.SwapBuffers(drv, disp, surf);
506 }
507
508
509 EGLBoolean EGLAPIENTRY
510 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
511 {
512 _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
513 return drv->API.CopyBuffers(drv, disp, surf, target);
514 }
515
516
517 EGLBoolean EGLAPIENTRY
518 eglWaitGL(void)
519 {
520 _EGLDisplay *disp = _eglGetCurrentDisplay();
521 _EGLDriver *drv;
522
523 if (!disp)
524 return EGL_TRUE;
525
526 /* a current display is always initialized */
527 drv = disp->Driver;
528
529 return drv->API.WaitGL(drv, disp);
530 }
531
532
533 EGLBoolean EGLAPIENTRY
534 eglWaitNative(EGLint engine)
535 {
536 _EGLDisplay *disp = _eglGetCurrentDisplay();
537 _EGLDriver *drv;
538
539 if (!disp)
540 return EGL_TRUE;
541
542 /* a current display is always initialized */
543 drv = disp->Driver;
544
545 return drv->API.WaitNative(drv, disp, engine);
546 }
547
548
549 EGLDisplay EGLAPIENTRY
550 eglGetCurrentDisplay(void)
551 {
552 _EGLDisplay *dpy = _eglGetCurrentDisplay();
553 return _eglGetDisplayHandle(dpy);
554 }
555
556
557 EGLContext EGLAPIENTRY
558 eglGetCurrentContext(void)
559 {
560 _EGLContext *ctx = _eglGetCurrentContext();
561 return _eglGetContextHandle(ctx);
562 }
563
564
565 EGLSurface EGLAPIENTRY
566 eglGetCurrentSurface(EGLint readdraw)
567 {
568 _EGLSurface *s = _eglGetCurrentSurface(readdraw);
569 return _eglGetSurfaceHandle(s);
570 }
571
572
573 EGLint EGLAPIENTRY
574 eglGetError(void)
575 {
576 _EGLThreadInfo *t = _eglGetCurrentThread();
577 EGLint e = t->LastError;
578 if (!_eglIsCurrentThreadDummy())
579 t->LastError = EGL_SUCCESS;
580 return e;
581 }
582
583
584 void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
585 {
586 typedef void (*genericFunc)();
587 struct name_function {
588 const char *name;
589 _EGLProc function;
590 };
591 static struct name_function egl_functions[] = {
592 /* alphabetical order */
593 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
594 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
595 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
596 { "eglCreateContext", (_EGLProc) eglCreateContext },
597 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
598 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
599 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
600 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
601 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
602 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
603 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
604 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
605 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
606 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
607 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
608 { "eglGetError", (_EGLProc) eglGetError },
609 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
610 { "eglInitialize", (_EGLProc) eglInitialize },
611 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
612 { "eglQueryContext", (_EGLProc) eglQueryContext },
613 { "eglQueryString", (_EGLProc) eglQueryString },
614 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
615 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
616 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
617 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
618 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
619 { "eglTerminate", (_EGLProc) eglTerminate },
620 { "eglWaitGL", (_EGLProc) eglWaitGL },
621 { "eglWaitNative", (_EGLProc) eglWaitNative },
622 /* Extensions */
623 #ifdef EGL_MESA_screen_surface
624 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
625 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
626 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
627 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
628 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
629 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
630 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
631 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
632 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
633 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
634 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
635 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
636 #endif /* EGL_MESA_screen_surface */
637 #ifdef EGL_VERSION_1_2
638 { "eglBindAPI", (_EGLProc) eglBindAPI },
639 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
640 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
641 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
642 { "eglWaitClient", (_EGLProc) eglWaitClient },
643 #endif /* EGL_VERSION_1_2 */
644 { NULL, NULL }
645 };
646 EGLint i;
647 for (i = 0; egl_functions[i].name; i++) {
648 if (strcmp(egl_functions[i].name, procname) == 0) {
649 return (genericFunc) egl_functions[i].function;
650 }
651 }
652
653 /* now loop over drivers to query their procs */
654 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
655 _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname);
656 if (p)
657 return p;
658 }
659
660 return NULL;
661 }
662
663
664 /*
665 * EGL_MESA_screen extension
666 */
667
668 EGLBoolean EGLAPIENTRY
669 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
670 const EGLint *attrib_list, EGLModeMESA *modes,
671 EGLint modes_size, EGLint *num_modes)
672 {
673 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
674 return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
675 modes, modes_size, num_modes);
676 }
677
678
679 EGLBoolean EGLAPIENTRY
680 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
681 EGLint mode_size, EGLint *num_mode)
682 {
683 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
684 return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
685 }
686
687
688 EGLBoolean EGLAPIENTRY
689 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
690 EGLint attribute, EGLint *value)
691 {
692 _EGL_DECLARE_DD_AND_MODE(dpy, mode);
693 return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
694 }
695
696
697 EGLBoolean EGLAPIENTRY
698 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
699 EGLint mask)
700 {
701 _EGLDisplay *disp = _eglLookupDisplay(dpy);
702 _EGLContext *source_context = _eglLookupContext(source, disp);
703 _EGLContext *dest_context = _eglLookupContext(dest, disp);
704 _EGLDriver *drv;
705
706 drv = _eglCheckContext(disp, source_context, __FUNCTION__);
707 if (!drv || !dest_context) {
708 if (drv)
709 _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
710 return EGL_FALSE;
711 }
712
713 return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
714 mask);
715 }
716
717
718 EGLBoolean
719 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
720 EGLint max_screens, EGLint *num_screens)
721 {
722 _EGL_DECLARE_DD(dpy);
723 return drv->API.GetScreensMESA(drv, disp, screens,
724 max_screens, num_screens);
725 }
726
727
728 EGLSurface
729 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
730 const EGLint *attrib_list)
731 {
732 _EGLDisplay *disp = _eglLookupDisplay(dpy);
733 _EGLConfig *conf = _eglLookupConfig(config, disp);
734 _EGLDriver *drv;
735 _EGLSurface *surf;
736
737 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
738 if (!drv)
739 return EGL_NO_SURFACE;
740
741 surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
742 if (surf)
743 return _eglLinkSurface(surf, disp);
744 else
745 return EGL_NO_SURFACE;
746 }
747
748
749 EGLBoolean
750 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
751 EGLSurface surface, EGLModeMESA mode)
752 {
753 _EGLDisplay *disp = _eglLookupDisplay(dpy);
754 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
755 _EGLSurface *surf = _eglLookupSurface(surface, disp);
756 _EGLMode *m = _eglLookupMode(mode, disp);
757 _EGLDriver *drv;
758
759 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
760 if (!drv)
761 return EGL_FALSE;
762 if (!surf && surface != EGL_NO_SURFACE)
763 return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
764 if (!m && mode != EGL_NO_MODE_MESA)
765 return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
766
767 return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
768 }
769
770
771 EGLBoolean
772 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
773 {
774 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
775 return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
776 }
777
778
779 EGLBoolean
780 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
781 EGLint attribute, EGLint *value)
782 {
783 _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
784 return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
785 }
786
787
788 EGLBoolean
789 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
790 EGLSurface *surface)
791 {
792 _EGLDisplay *disp = _eglLookupDisplay(dpy);
793 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
794 _EGLDriver *drv;
795 _EGLSurface *surf;
796
797 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
798 if (!drv)
799 return EGL_FALSE;
800
801 if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
802 surf = NULL;
803 if (surface)
804 *surface = _eglGetSurfaceHandle(surf);
805 return (surf != NULL);
806 }
807
808
809 EGLBoolean
810 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
811 {
812 _EGLDisplay *disp = _eglLookupDisplay(dpy);
813 _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
814 _EGLDriver *drv;
815 _EGLMode *m;
816
817 drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
818 if (!drv)
819 return EGL_FALSE;
820
821 if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
822 m = NULL;
823 if (mode)
824 *mode = m->Handle;
825
826 return (m != NULL);
827 }
828
829
830 const char *
831 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
832 {
833 _EGL_DECLARE_DD_AND_MODE(dpy, mode);
834 return drv->API.QueryModeStringMESA(drv, disp, m);
835 }
836
837
838 /**
839 ** EGL 1.2
840 **/
841
842 #ifdef EGL_VERSION_1_2
843
844
845 /**
846 * Specify the client API to use for subsequent calls including:
847 * eglCreateContext()
848 * eglGetCurrentContext()
849 * eglGetCurrentDisplay()
850 * eglGetCurrentSurface()
851 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
852 * eglWaitClient()
853 * eglWaitNative()
854 * See section 3.7 "Rendering Context" in the EGL specification for details.
855 */
856 EGLBoolean
857 eglBindAPI(EGLenum api)
858 {
859 _EGLThreadInfo *t = _eglGetCurrentThread();
860
861 if (_eglIsCurrentThreadDummy())
862 return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
863
864 if (!_eglIsApiValid(api))
865 return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
866
867 switch (api) {
868 #ifdef EGL_VERSION_1_4
869 case EGL_OPENGL_API:
870 if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
871 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
872 return EGL_TRUE;
873 }
874 _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
875 return EGL_FALSE;
876 #endif
877 case EGL_OPENGL_ES_API:
878 if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
879 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
880 return EGL_TRUE;
881 }
882 _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
883 return EGL_FALSE;
884 case EGL_OPENVG_API:
885 if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
886 t->CurrentAPIIndex = _eglConvertApiToIndex(api);
887 return EGL_TRUE;
888 }
889 _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
890 return EGL_FALSE;
891 default:
892 return EGL_FALSE;
893 }
894 return EGL_TRUE;
895 }
896
897
898 /**
899 * Return the last value set with eglBindAPI().
900 */
901 EGLenum
902 eglQueryAPI(void)
903 {
904 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
905 _EGLThreadInfo *t = _eglGetCurrentThread();
906 return _eglConvertApiFromIndex(t->CurrentAPIIndex);
907 }
908
909
910 EGLSurface
911 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
912 EGLClientBuffer buffer, EGLConfig config,
913 const EGLint *attrib_list)
914 {
915 _EGLDisplay *disp = _eglLookupDisplay(dpy);
916 _EGLConfig *conf = _eglLookupConfig(config, disp);
917 _EGLDriver *drv;
918 _EGLSurface *surf;
919
920 drv = _eglCheckConfig(disp, conf, __FUNCTION__);
921 if (!drv)
922 return EGL_NO_SURFACE;
923
924 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
925 conf, attrib_list);
926 if (surf)
927 return _eglLinkSurface(surf, disp);
928 else
929 return EGL_NO_SURFACE;
930 }
931
932
933 EGLBoolean
934 eglReleaseThread(void)
935 {
936 /* unbind current context */
937 if (!_eglIsCurrentThreadDummy()) {
938 _EGLDisplay *disp = _eglGetCurrentDisplay();
939 _EGLDriver *drv;
940 if (disp) {
941 drv = disp->Driver;
942 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
943 }
944 }
945
946 _eglDestroyCurrentThread();
947 return EGL_TRUE;
948 }
949
950
951 EGLBoolean
952 eglWaitClient(void)
953 {
954 _EGLDisplay *disp = _eglGetCurrentDisplay();
955 _EGLDriver *drv;
956
957 if (!disp)
958 return EGL_TRUE;
959
960 /* a current display is always initialized */
961 drv = disp->Driver;
962
963 return drv->API.WaitClient(drv, disp);
964 }
965
966
967 #endif /* EGL_VERSION_1_2 */