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