some initial EGL 1.2 work
[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
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "eglcontext.h"
37 #include "egldisplay.h"
38 #include "egltypedefs.h"
39 #include "eglglobals.h"
40 #include "egldriver.h"
41 #include "eglsurface.h"
42
43
44
45 /**
46 * NOTE: displayName is treated as a string in _eglChooseDriver()!!!
47 * This will probably change!
48 * See _eglChooseDriver() for details!
49 */
50 EGLDisplay APIENTRY
51 eglGetDisplay(NativeDisplayType displayName)
52 {
53 _EGLDisplay *dpy;
54 _eglInitGlobals();
55 dpy = _eglNewDisplay(displayName);
56 if (dpy)
57 return dpy->Handle;
58 else
59 return EGL_NO_DISPLAY;
60 }
61
62
63 EGLBoolean APIENTRY
64 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
65 {
66 if (dpy) {
67 _EGLDriver *drv = _eglChooseDriver(dpy);
68 if (drv)
69 return drv->API.Initialize(drv, dpy, major, minor);
70 }
71 return EGL_FALSE;
72 }
73
74
75 EGLBoolean APIENTRY
76 eglTerminate(EGLDisplay dpy)
77 {
78 _EGLDriver *drv = _eglLookupDriver(dpy);
79 if (drv)
80 return _eglCloseDriver(drv, dpy);
81 else
82 return EGL_FALSE;
83 }
84
85
86 const char * APIENTRY
87 eglQueryString(EGLDisplay dpy, EGLint name)
88 {
89 _EGLDriver *drv = _eglLookupDriver(dpy);
90 if (drv)
91 return drv->API.QueryString(drv, dpy, name);
92 else
93 return NULL;
94 }
95
96
97 EGLBoolean APIENTRY
98 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
99 {
100 _EGLDriver *drv = _eglLookupDriver(dpy);
101 /* XXX check drv for null in remaining functions */
102 return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
103 }
104
105
106 EGLBoolean APIENTRY
107 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
108 {
109 _EGLDriver *drv = _eglLookupDriver(dpy);
110 return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
111 }
112
113
114 EGLBoolean APIENTRY
115 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
116 {
117 _EGLDriver *drv = _eglLookupDriver(dpy);
118 return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
119 }
120
121
122 EGLContext APIENTRY
123 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
124 {
125 _EGLDriver *drv = _eglLookupDriver(dpy);
126 return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
127 }
128
129
130 EGLBoolean APIENTRY
131 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
132 {
133 _EGLDriver *drv = _eglLookupDriver(dpy);
134 return drv->API.DestroyContext(drv, dpy, ctx);
135 }
136
137
138 EGLBoolean APIENTRY
139 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
140 {
141 _EGLDriver *drv = _eglLookupDriver(dpy);
142 return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
143 }
144
145
146 EGLBoolean APIENTRY
147 eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
148 {
149 _EGLDriver *drv = _eglLookupDriver(dpy);
150 return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
151 }
152
153
154 EGLSurface APIENTRY
155 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
156 {
157 _EGLDriver *drv = _eglLookupDriver(dpy);
158 return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
159 }
160
161
162 EGLSurface APIENTRY
163 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
164 {
165 _EGLDriver *drv = _eglLookupDriver(dpy);
166 return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
167 }
168
169
170 EGLSurface APIENTRY
171 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
172 {
173 _EGLDriver *drv = _eglLookupDriver(dpy);
174 return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
175 }
176
177
178 EGLBoolean APIENTRY
179 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
180 {
181 _EGLDriver *drv = _eglLookupDriver(dpy);
182 return drv->API.DestroySurface(drv, dpy, surface);
183 }
184
185
186 EGLBoolean APIENTRY
187 eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
188 {
189 _EGLDriver *drv = _eglLookupDriver(dpy);
190 return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
191 }
192
193
194 EGLBoolean APIENTRY
195 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
196 {
197 _EGLDriver *drv = _eglLookupDriver(dpy);
198 return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
199 }
200
201
202 EGLBoolean APIENTRY
203 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
204 {
205 _EGLDriver *drv = _eglLookupDriver(dpy);
206 return drv->API.BindTexImage(drv, dpy, surface, buffer);
207 }
208
209
210 EGLBoolean APIENTRY
211 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
212 {
213 _EGLDriver *drv = _eglLookupDriver(dpy);
214 return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
215 }
216
217
218 EGLBoolean APIENTRY
219 eglSwapInterval(EGLDisplay dpy, EGLint interval)
220 {
221 _EGLDriver *drv = _eglLookupDriver(dpy);
222 return drv->API.SwapInterval(drv, dpy, interval);
223 }
224
225
226 EGLBoolean APIENTRY
227 eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
228 {
229 _EGLDriver *drv = _eglLookupDriver(dpy);
230 return drv->API.SwapBuffers(drv, dpy, draw);
231 }
232
233
234 EGLBoolean APIENTRY
235 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
236 {
237 _EGLDriver *drv = _eglLookupDriver(dpy);
238 return drv->API.CopyBuffers(drv, dpy, surface, target);
239 }
240
241
242 EGLBoolean APIENTRY
243 eglWaitGL(void)
244 {
245 EGLDisplay dpy = eglGetCurrentDisplay();
246 if (dpy != EGL_NO_DISPLAY) {
247 _EGLDriver *drv = _eglLookupDriver(dpy);
248 return drv->API.WaitGL(drv, dpy);
249 }
250 else
251 return EGL_FALSE;
252 }
253
254
255 EGLBoolean APIENTRY
256 eglWaitNative(EGLint engine)
257 {
258 EGLDisplay dpy = eglGetCurrentDisplay();
259 if (dpy != EGL_NO_DISPLAY) {
260 _EGLDriver *drv = _eglLookupDriver(dpy);
261 return drv->API.WaitNative(drv, dpy, engine);
262 }
263 else
264 return EGL_FALSE;
265 }
266
267
268 EGLDisplay APIENTRY
269 eglGetCurrentDisplay(void)
270 {
271 _EGLDisplay *dpy = _eglGetCurrentDisplay();
272 if (dpy)
273 return dpy->Handle;
274 else
275 return EGL_NO_DISPLAY;
276 }
277
278
279 EGLContext APIENTRY
280 eglGetCurrentContext(void)
281 {
282 _EGLContext *ctx = _eglGetCurrentContext();
283 if (ctx)
284 return ctx->Handle;
285 else
286 return EGL_NO_CONTEXT;
287 }
288
289
290 EGLSurface APIENTRY
291 eglGetCurrentSurface(EGLint readdraw)
292 {
293 _EGLSurface *s = _eglGetCurrentSurface(readdraw);
294 if (s)
295 return s->Handle;
296 else
297 return EGL_NO_SURFACE;
298 }
299
300
301 EGLint APIENTRY
302 eglGetError(void)
303 {
304 _EGLThreadInfo *t = _eglGetCurrentThread();
305 EGLint e = t->LastError;
306 t->LastError = EGL_SUCCESS;
307 return e;
308 }
309
310
311 void (* APIENTRY eglGetProcAddress(const char *procname))()
312 {
313 typedef void (*genericFunc)();
314 struct name_function {
315 const char *name;
316 _EGLProc function;
317 };
318 static struct name_function egl_functions[] = {
319 /* alphabetical order */
320 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
321 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
322 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
323 { "eglCreateContext", (_EGLProc) eglCreateContext },
324 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
325 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
326 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
327 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
328 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
329 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
330 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
331 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
332 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
333 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
334 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
335 { "eglGetError", (_EGLProc) eglGetError },
336 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
337 { "eglInitialize", (_EGLProc) eglInitialize },
338 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
339 { "eglQueryContext", (_EGLProc) eglQueryContext },
340 { "eglQueryString", (_EGLProc) eglQueryString },
341 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
342 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
343 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
344 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
345 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
346 { "eglTerminate", (_EGLProc) eglTerminate },
347 { "eglWaitGL", (_EGLProc) eglWaitGL },
348 { "eglWaitNative", (_EGLProc) eglWaitNative },
349 /* Extensions */
350 #ifdef EGL_MESA_screen_surface
351 { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
352 { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
353 { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
354 { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
355 { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
356 { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
357 { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
358 { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
359 { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
360 { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
361 { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
362 { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
363 #endif /* EGL_MESA_screen_surface */
364 #ifdef EGL_VERSION_1_2
365 { "eglBindAPI", (_EGLProc) eglBindAPI },
366 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
367 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
368 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
369 { "eglWaitClient", (_EGLProc) eglWaitClient },
370 #endif /* EGL_VERSION_1_2 */
371 { NULL, NULL }
372 };
373 EGLint i;
374 for (i = 0; egl_functions[i].name; i++) {
375 if (strcmp(egl_functions[i].name, procname) == 0) {
376 return (genericFunc) egl_functions[i].function;
377 }
378 }
379 #if 0
380 /* XXX enable this code someday */
381 return (genericFunc) _glapi_get_proc_address(procname);
382 #else
383 return NULL;
384 #endif
385 }
386
387
388 /*
389 * EGL_MESA_screen extension
390 */
391
392 EGLBoolean APIENTRY
393 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
394 const EGLint *attrib_list, EGLModeMESA *modes,
395 EGLint modes_size, EGLint *num_modes)
396 {
397 _EGLDriver *drv = _eglLookupDriver(dpy);
398 if (drv)
399 return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
400 else
401 return EGL_FALSE;
402 }
403
404
405 EGLBoolean APIENTRY
406 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
407 {
408 _EGLDriver *drv = _eglLookupDriver(dpy);
409 if (drv)
410 return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
411 else
412 return EGL_FALSE;
413 }
414
415
416 EGLBoolean APIENTRY
417 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
418 {
419 _EGLDriver *drv = _eglLookupDriver(dpy);
420 if (drv)
421 return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
422 else
423 return EGL_FALSE;
424 }
425
426
427 EGLBoolean APIENTRY
428 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
429 {
430 _EGLDriver *drv = _eglLookupDriver(dpy);
431 if (drv)
432 return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
433 else
434 return EGL_FALSE;
435 }
436
437
438 EGLBoolean
439 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
440 {
441 _EGLDriver *drv = _eglLookupDriver(dpy);
442 if (drv)
443 return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
444 else
445 return EGL_FALSE;
446 }
447
448
449 EGLSurface
450 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
451 {
452 _EGLDriver *drv = _eglLookupDriver(dpy);
453 return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
454 }
455
456
457 EGLBoolean
458 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
459 {
460 _EGLDriver *drv = _eglLookupDriver(dpy);
461 return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
462 }
463
464
465 EGLBoolean
466 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
467 {
468 _EGLDriver *drv = _eglLookupDriver(dpy);
469 return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
470 }
471
472
473 EGLBoolean
474 eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
475 {
476 _EGLDriver *drv = _eglLookupDriver(dpy);
477 return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
478 }
479
480
481 EGLBoolean
482 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
483 {
484 _EGLDriver *drv = _eglLookupDriver(dpy);
485 return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
486 }
487
488
489 EGLBoolean
490 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
491 {
492 _EGLDriver *drv = _eglLookupDriver(dpy);
493 return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
494 }
495
496
497 const char *
498 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
499 {
500 _EGLDriver *drv = _eglLookupDriver(dpy);
501 return drv->API.QueryModeStringMESA(drv, dpy, mode);
502 }
503
504
505 /**
506 ** EGL 1.2
507 **/
508
509 #ifdef EGL_VERSION_1_2
510
511 EGLBoolean
512 eglBindAPI(EGLenum api)
513 {
514 _EGLThreadInfo *t = _eglGetCurrentThread();
515
516 switch (api) {
517 case EGL_OPENGL_ES_API:
518 if (_eglGlobal.OpenGLESAPISupported) {
519 t->CurrentAPI = api;
520 return EGL_TRUE;
521 }
522 _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
523 return EGL_FALSE;
524 case EGL_OPENVG_API:
525 if (_eglGlobal.OpenVGAPISupported) {
526 t->CurrentAPI = api;
527 return EGL_TRUE;
528 }
529 _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
530 return EGL_FALSE;
531 default:
532 return EGL_FALSE;
533 }
534 return EGL_TRUE;
535 }
536
537
538 EGLSurface
539 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
540 EGLClientBuffer buffer, EGLConfig config,
541 const EGLint *attrib_list)
542 {
543 _EGLDriver *drv = _eglLookupDriver(dpy);
544 return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
545 config, attrib_list);
546 }
547
548
549 EGLenum
550 eglQueryAPI(void)
551 {
552 /* returns one of EGL_OPENGL_ES_API or EGL_OPENVG_API */
553 _EGLThreadInfo *t = _eglGetCurrentThread();
554 return t->CurrentAPI;
555 }
556
557
558 EGLBoolean
559 eglReleaseThread(void)
560 {
561 _EGLThreadInfo *t = _eglGetCurrentThread();
562 EGLDisplay dpy = eglGetCurrentDisplay();
563 if (dpy) {
564 _EGLDriver *drv = _eglLookupDriver(dpy);
565 /* unbind context */
566 (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
567 EGL_NO_SURFACE, EGL_NO_CONTEXT);
568 }
569 _eglDeleteThreadData(t);
570 return EGL_TRUE;
571 }
572
573
574 EGLBoolean
575 eglWaitClient(void)
576 {
577 EGLDisplay dpy = eglGetCurrentDisplay();
578 if (dpy != EGL_NO_DISPLAY) {
579 _EGLDriver *drv = _eglLookupDriver(dpy);
580 return drv->API.WaitClient(drv, dpy);
581 }
582 else
583 return EGL_FALSE;
584 }
585
586 #endif /* EGL_VERSION_1_2 */