OSDN Git Service

332b98adf2c5a982e7af8c15f2b5dd82f22d2b61
[android-x86/external-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  * This is typically the first EGL function that an application calls.
47  * We initialize our global vars and create a private _EGLDisplay object.
48  */
49 EGLDisplay EGLAPIENTRY
50 eglGetDisplay(NativeDisplayType nativeDisplay)
51 {
52    _EGLDisplay *dpy;
53    _eglInitGlobals();
54    dpy = _eglNewDisplay(nativeDisplay);
55    return _eglGetDisplayHandle(dpy);
56 }
57
58
59 /**
60  * This is typically the second EGL function that an application calls.
61  * Here we load/initialize the actual hardware driver.
62  */
63 EGLBoolean EGLAPIENTRY
64 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
65 {
66    EGLint major_int, minor_int;
67
68    if (dpy) {
69       EGLBoolean retVal;
70       _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy);
71       if (!dpyPriv) {
72          return EGL_FALSE;
73       }
74       dpyPriv->Driver = _eglOpenDriver(dpyPriv,
75                                        dpyPriv->DriverName,
76                                        dpyPriv->DriverArgs);
77       if (!dpyPriv->Driver) {
78          return EGL_FALSE;
79       }
80       /* Initialize the particular driver now */
81       retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy,
82                                                &major_int, &minor_int);
83
84       dpyPriv->Driver->APImajor = major_int;
85       dpyPriv->Driver->APIminor = minor_int;
86       snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version),
87                "%d.%d (%s)", major_int, minor_int, dpyPriv->Driver->Name);
88
89       /* Update applications version of major and minor if not NULL */
90       if((major != NULL) && (minor != NULL))
91       {
92          *major = major_int;
93          *minor = minor_int;
94       }
95
96       return retVal;
97    }
98    return EGL_FALSE;
99 }
100
101
102 EGLBoolean EGLAPIENTRY
103 eglTerminate(EGLDisplay dpy)
104 {
105    _EGLDriver *drv = _eglLookupDriver(dpy);
106    if (drv)
107       return _eglCloseDriver(drv, dpy);
108    else
109       return EGL_FALSE;
110 }
111
112
113 const char * EGLAPIENTRY
114 eglQueryString(EGLDisplay dpy, EGLint name)
115 {
116    _EGLDriver *drv = _eglLookupDriver(dpy);
117    if (drv)
118       return drv->API.QueryString(drv, dpy, name);
119    else
120       return NULL;
121 }
122
123
124 EGLBoolean EGLAPIENTRY
125 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
126 {
127    _EGLDriver *drv = _eglLookupDriver(dpy);
128    /* XXX check drv for null in remaining functions */
129    return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
130 }
131
132
133 EGLBoolean EGLAPIENTRY
134 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
135 {
136    _EGLDriver *drv = _eglLookupDriver(dpy);
137    return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
138 }
139
140
141 EGLBoolean EGLAPIENTRY
142 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
143 {
144    _EGLDriver *drv = _eglLookupDriver(dpy);
145    return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
146 }
147
148
149 EGLContext EGLAPIENTRY
150 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
151 {
152    _EGLDriver *drv = _eglLookupDriver(dpy);
153    return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
154 }
155
156
157 EGLBoolean EGLAPIENTRY
158 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
159 {
160    _EGLDriver *drv = _eglLookupDriver(dpy);
161    return drv->API.DestroyContext(drv, dpy, ctx);
162 }
163
164
165 EGLBoolean EGLAPIENTRY
166 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
167 {
168    _EGLDriver *drv = _eglLookupDriver(dpy);
169    return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
170 }
171
172
173 EGLBoolean EGLAPIENTRY
174 eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
175 {
176    _EGLDriver *drv = _eglLookupDriver(dpy);
177    return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
178 }
179
180
181 EGLSurface EGLAPIENTRY
182 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
183 {
184    _EGLDriver *drv = _eglLookupDriver(dpy);
185    return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
186 }
187
188
189 EGLSurface EGLAPIENTRY
190 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
191 {
192    _EGLDriver *drv = _eglLookupDriver(dpy);
193    return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
194 }
195
196
197 EGLSurface EGLAPIENTRY
198 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
199 {
200    _EGLDriver *drv = _eglLookupDriver(dpy);
201    return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
202 }
203
204
205 EGLBoolean EGLAPIENTRY
206 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
207 {
208    _EGLDriver *drv = _eglLookupDriver(dpy);
209    return drv->API.DestroySurface(drv, dpy, surface);
210 }
211
212
213 EGLBoolean EGLAPIENTRY
214 eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
215 {
216    _EGLDriver *drv = _eglLookupDriver(dpy);
217    return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
218 }
219
220
221 EGLBoolean EGLAPIENTRY
222 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
223 {
224    _EGLDriver *drv = _eglLookupDriver(dpy);
225    return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
226 }
227
228
229 EGLBoolean EGLAPIENTRY
230 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
231 {
232    _EGLDriver *drv = _eglLookupDriver(dpy);
233    return drv->API.BindTexImage(drv, dpy, surface, buffer);
234 }
235
236
237 EGLBoolean EGLAPIENTRY
238 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
239 {
240    _EGLDriver *drv = _eglLookupDriver(dpy);
241    return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
242 }
243
244
245 EGLBoolean EGLAPIENTRY
246 eglSwapInterval(EGLDisplay dpy, EGLint interval)
247 {
248    _EGLDriver *drv = _eglLookupDriver(dpy);
249    return drv->API.SwapInterval(drv, dpy, interval);
250 }
251
252
253 EGLBoolean EGLAPIENTRY
254 eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
255 {
256    _EGLDriver *drv = _eglLookupDriver(dpy);
257    return drv->API.SwapBuffers(drv, dpy, draw);
258 }
259
260
261 EGLBoolean EGLAPIENTRY
262 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
263 {
264    _EGLDriver *drv = _eglLookupDriver(dpy);
265    return drv->API.CopyBuffers(drv, dpy, surface, target);
266 }
267
268
269 EGLBoolean EGLAPIENTRY
270 eglWaitGL(void)
271 {
272    EGLDisplay dpy = eglGetCurrentDisplay();
273    if (dpy != EGL_NO_DISPLAY) {
274       _EGLDriver *drv = _eglLookupDriver(dpy);
275       return drv->API.WaitGL(drv, dpy);
276    }
277    else
278       return EGL_FALSE;
279 }
280
281
282 EGLBoolean EGLAPIENTRY
283 eglWaitNative(EGLint engine)
284 {
285    EGLDisplay dpy = eglGetCurrentDisplay();
286    if (dpy != EGL_NO_DISPLAY) {
287       _EGLDriver *drv = _eglLookupDriver(dpy);
288       return drv->API.WaitNative(drv, dpy, engine);
289    }
290    else
291       return EGL_FALSE;
292 }
293
294
295 EGLDisplay EGLAPIENTRY
296 eglGetCurrentDisplay(void)
297 {
298    _EGLDisplay *dpy = _eglGetCurrentDisplay();
299    return _eglGetDisplayHandle(dpy);
300 }
301
302
303 EGLContext EGLAPIENTRY
304 eglGetCurrentContext(void)
305 {
306    _EGLContext *ctx = _eglGetCurrentContext();
307    return _eglGetContextHandle(ctx);
308 }
309
310
311 EGLSurface EGLAPIENTRY
312 eglGetCurrentSurface(EGLint readdraw)
313 {
314    _EGLSurface *s = _eglGetCurrentSurface(readdraw);
315    return _eglGetSurfaceHandle(s);
316 }
317
318
319 EGLint EGLAPIENTRY
320 eglGetError(void)
321 {
322    _EGLThreadInfo *t = _eglGetCurrentThread();
323    EGLint e = t->LastError;
324    if (!_eglIsCurrentThreadDummy())
325       t->LastError = EGL_SUCCESS;
326    return e;
327 }
328
329
330 void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
331 {
332    typedef void (*genericFunc)();
333    struct name_function {
334       const char *name;
335       _EGLProc function;
336    };
337    static struct name_function egl_functions[] = {
338       /* alphabetical order */
339       { "eglBindTexImage", (_EGLProc) eglBindTexImage },
340       { "eglChooseConfig", (_EGLProc) eglChooseConfig },
341       { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
342       { "eglCreateContext", (_EGLProc) eglCreateContext },
343       { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
344       { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
345       { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
346       { "eglDestroyContext", (_EGLProc) eglDestroyContext },
347       { "eglDestroySurface", (_EGLProc) eglDestroySurface },
348       { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
349       { "eglGetConfigs", (_EGLProc) eglGetConfigs },
350       { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
351       { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
352       { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
353       { "eglGetDisplay", (_EGLProc) eglGetDisplay },
354       { "eglGetError", (_EGLProc) eglGetError },
355       { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
356       { "eglInitialize", (_EGLProc) eglInitialize },
357       { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
358       { "eglQueryContext", (_EGLProc) eglQueryContext },
359       { "eglQueryString", (_EGLProc) eglQueryString },
360       { "eglQuerySurface", (_EGLProc) eglQuerySurface },
361       { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
362       { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
363       { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
364       { "eglSwapInterval", (_EGLProc) eglSwapInterval },
365       { "eglTerminate", (_EGLProc) eglTerminate },
366       { "eglWaitGL", (_EGLProc) eglWaitGL },
367       { "eglWaitNative", (_EGLProc) eglWaitNative },
368       /* Extensions */
369 #ifdef EGL_MESA_screen_surface
370       { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
371       { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
372       { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
373       { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
374       { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
375       { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
376       { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
377       { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
378       { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
379       { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
380       { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
381       { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
382 #endif /* EGL_MESA_screen_surface */
383 #ifdef EGL_VERSION_1_2
384       { "eglBindAPI", (_EGLProc) eglBindAPI },
385       { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
386       { "eglQueryAPI", (_EGLProc) eglQueryAPI },
387       { "eglReleaseThread", (_EGLProc) eglReleaseThread },
388       { "eglWaitClient", (_EGLProc) eglWaitClient },
389 #endif /* EGL_VERSION_1_2 */
390       { NULL, NULL }
391    };
392    EGLint i;
393    for (i = 0; egl_functions[i].name; i++) {
394       if (strcmp(egl_functions[i].name, procname) == 0) {
395          return (genericFunc) egl_functions[i].function;
396       }
397    }
398
399    /* now loop over drivers to query their procs */
400    for (i = 0; i < _eglGlobal.NumDrivers; i++) {
401       _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname);
402       if (p)
403          return p;
404    }
405
406    return NULL;
407 }
408
409
410 /*
411  * EGL_MESA_screen extension
412  */
413
414 EGLBoolean EGLAPIENTRY
415 eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
416                   const EGLint *attrib_list, EGLModeMESA *modes,
417                   EGLint modes_size, EGLint *num_modes)
418 {
419    _EGLDriver *drv = _eglLookupDriver(dpy);
420    if (drv)
421       return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
422    else
423       return EGL_FALSE;
424 }
425
426
427 EGLBoolean EGLAPIENTRY
428 eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
429 {
430    _EGLDriver *drv = _eglLookupDriver(dpy);
431    if (drv)
432       return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
433    else
434       return EGL_FALSE;
435 }
436
437
438 EGLBoolean EGLAPIENTRY
439 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
440 {
441    _EGLDriver *drv = _eglLookupDriver(dpy);
442    if (drv)
443       return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
444    else
445       return EGL_FALSE;
446 }
447
448
449 EGLBoolean EGLAPIENTRY
450 eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
451 {
452    _EGLDriver *drv = _eglLookupDriver(dpy);
453    if (drv)
454       return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
455    else
456       return EGL_FALSE;
457 }
458
459
460 EGLBoolean
461 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
462 {
463    _EGLDriver *drv = _eglLookupDriver(dpy);
464    if (drv)
465       return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
466    else
467       return EGL_FALSE;
468 }
469
470
471 EGLSurface
472 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
473 {
474    _EGLDriver *drv = _eglLookupDriver(dpy);
475    return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
476 }
477
478
479 EGLBoolean
480 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
481 {
482    _EGLDriver *drv = _eglLookupDriver(dpy);
483    return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
484 }
485
486
487 EGLBoolean
488 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
489 {
490    _EGLDriver *drv = _eglLookupDriver(dpy);
491    return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
492 }
493
494
495 EGLBoolean
496 eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
497 {
498    _EGLDriver *drv = _eglLookupDriver(dpy);
499    return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
500 }
501
502
503 EGLBoolean
504 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
505 {
506    _EGLDriver *drv = _eglLookupDriver(dpy);
507    return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
508 }
509
510
511 EGLBoolean
512 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
513 {
514    _EGLDriver *drv = _eglLookupDriver(dpy);
515    return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
516 }
517
518
519 const char *
520 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
521 {
522    _EGLDriver *drv = _eglLookupDriver(dpy);
523    return drv->API.QueryModeStringMESA(drv, dpy, mode);
524 }
525
526
527 /**
528  ** EGL 1.2
529  **/
530
531 #ifdef EGL_VERSION_1_2
532
533
534 /**
535  * Specify the client API to use for subsequent calls including:
536  *  eglCreateContext()
537  *  eglGetCurrentContext()
538  *  eglGetCurrentDisplay()
539  *  eglGetCurrentSurface()
540  *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
541  *  eglWaitClient()
542  *  eglWaitNative()
543  * See section 3.7 "Rendering Context" in the EGL specification for details.
544  */
545 EGLBoolean
546 eglBindAPI(EGLenum api)
547 {
548    _EGLThreadInfo *t = _eglGetCurrentThread();
549
550    if (_eglIsCurrentThreadDummy())
551       return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
552
553    if (!_eglIsApiValid(api))
554       return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
555
556    switch (api) {
557 #ifdef EGL_VERSION_1_4
558    case EGL_OPENGL_API:
559       if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
560          t->CurrentAPIIndex = _eglConvertApiToIndex(api);
561          return EGL_TRUE;
562       }
563       _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
564       return EGL_FALSE;
565 #endif
566    case EGL_OPENGL_ES_API:
567       if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
568          t->CurrentAPIIndex = _eglConvertApiToIndex(api);
569          return EGL_TRUE;
570       }
571       _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
572       return EGL_FALSE;
573    case EGL_OPENVG_API:
574       if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
575          t->CurrentAPIIndex = _eglConvertApiToIndex(api);
576          return EGL_TRUE;
577       }
578       _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
579       return EGL_FALSE;
580    default:
581       return EGL_FALSE;
582    }
583    return EGL_TRUE;
584 }
585
586
587 /**
588  * Return the last value set with eglBindAPI().
589  */
590 EGLenum
591 eglQueryAPI(void)
592 {
593    /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
594    _EGLThreadInfo *t = _eglGetCurrentThread();
595    return _eglConvertApiFromIndex(t->CurrentAPIIndex);
596 }
597
598
599 EGLSurface
600 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
601                                  EGLClientBuffer buffer, EGLConfig config,
602                                  const EGLint *attrib_list)
603 {
604    _EGLDriver *drv = _eglLookupDriver(dpy);
605    return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
606                                                  config, attrib_list);
607 }
608
609
610 EGLBoolean
611 eglReleaseThread(void)
612 {
613    EGLDisplay dpy;
614
615    if (_eglIsCurrentThreadDummy())
616       return EGL_TRUE;
617
618    dpy = eglGetCurrentDisplay();
619    if (dpy) {
620       _EGLDriver *drv = _eglLookupDriver(dpy);
621       /* unbind context */
622       (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
623                                   EGL_NO_SURFACE, EGL_NO_CONTEXT);
624    }
625    _eglDestroyCurrentThread();
626    return EGL_TRUE;
627 }
628
629
630 EGLBoolean
631 eglWaitClient(void)
632 {
633    EGLDisplay dpy = eglGetCurrentDisplay();
634    if (dpy != EGL_NO_DISPLAY) {
635       _EGLDriver *drv = _eglLookupDriver(dpy);
636       return drv->API.WaitClient(drv, dpy);
637    }
638    else
639       return EGL_FALSE;
640 }
641
642 #endif /* EGL_VERSION_1_2 */