695701933d97c8b1b3d17f1ac9e9deaee6a024b7
[platform/adaptation/renesas_rcar/libegl.git] / egl.c
1 /*
2  * Copyright (c) 2013 Renesas Solutions Corp.
3  * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * Authors:
18  *  Takanari Hayama <taki@igel.co.jp>
19  *
20  */
21
22 /* EGL function pointers */
23 #define EGL_EGLEXT_PROTOTYPES
24 #include <EGL/egl.h>
25 #include <EGL/eglext.h>
26
27 #define IMG_LIBEGL_PATH "libEGL-pvr.so"
28
29 #if defined(DEBUG)
30 #       define EGL_DEBUG(s, x...)       { printf(s, ## x); }
31 #else
32 #       define EGL_DEBUG(s, x...)       { }
33 #endif
34
35 #ifndef EGL_WAYLAND_BUFFER_WL
36 /* TI headers don't define this */
37 #define EGL_WAYLAND_BUFFER_WL    0x31D5 /* eglCreateImageKHR target */
38 #endif
39
40 #include <dlfcn.h>
41 #include <stddef.h>
42 #include <stdlib.h>
43 #include <malloc.h>
44 #include <string.h>
45 #include <assert.h>
46
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <fcntl.h>
50
51 #define WANT_WAYLAND
52
53 #ifdef WANT_WAYLAND
54 #include <wayland-kms.h>
55 #include <gbm/gbm.h>
56 #include <gbm/common.h>
57 #endif
58
59 static EGLint(*_eglGetError) (void);
60
61 static EGLDisplay(*_eglGetDisplay) (EGLNativeDisplayType display_id);
62 static EGLBoolean(*_eglInitialize) (EGLDisplay dpy, EGLint * major,
63                                    EGLint * minor);
64 static EGLBoolean(*_eglTerminate) (EGLDisplay dpy);
65
66 static const char *(*_eglQueryString) (EGLDisplay dpy, EGLint name);
67
68 static EGLBoolean(*_eglGetConfigs) (EGLDisplay dpy, EGLConfig * configs,
69                                    EGLint config_size, EGLint * num_config);
70 static EGLBoolean(*_eglChooseConfig) (EGLDisplay dpy,
71                                      const EGLint * attrib_list,
72                                      EGLConfig * configs,
73                                      EGLint config_size, EGLint * num_config);
74 static EGLBoolean(*_eglGetConfigAttrib) (EGLDisplay dpy,
75                                         EGLConfig config,
76                                         EGLint attribute, EGLint * value);
77
78 static EGLSurface(*_eglCreateWindowSurface) (EGLDisplay dpy,
79                                             EGLConfig config,
80                                             EGLNativeWindowType win,
81                                             const EGLint * attrib_list);
82 static EGLSurface(*_eglCreatePbufferSurface) (EGLDisplay dpy,
83                                              EGLConfig config,
84                                              const EGLint * attrib_list);
85 static EGLSurface(*_eglCreatePixmapSurface) (EGLDisplay dpy,
86                                             EGLConfig config,
87                                             EGLNativePixmapType pixmap,
88                                             const EGLint * attrib_list);
89 static EGLBoolean(*_eglDestroySurface) (EGLDisplay dpy, EGLSurface surface);
90 static EGLBoolean(*_eglQuerySurface) (EGLDisplay dpy, EGLSurface surface,
91                                      EGLint attribute, EGLint * value);
92
93 static EGLBoolean(*_eglBindAPI) (EGLenum api);
94 static EGLenum(*_eglQueryAPI) (void);
95
96 static EGLBoolean(*_eglWaitClient) (void);
97
98 static EGLBoolean(*_eglReleaseThread) (void);
99
100 static EGLSurface(*_eglCreatePbufferFromClientBuffer) (EGLDisplay dpy,
101                                                       EGLenum buftype,
102                                                       EGLClientBuffer
103                                                       buffer,
104                                                       EGLConfig config,
105                                                       const EGLint *
106                                                       attrib_list);
107
108 static EGLBoolean(*_eglSurfaceAttrib) (EGLDisplay dpy,
109                                       EGLSurface surface,
110                                       EGLint attribute, EGLint value);
111 static EGLBoolean(*_eglBindTexImage) (EGLDisplay dpy, EGLSurface surface,
112                                      EGLint buffer);
113 static EGLBoolean(*_eglReleaseTexImage) (EGLDisplay dpy,
114                                         EGLSurface surface, EGLint buffer);
115
116 static EGLBoolean(*_eglSwapInterval) (EGLDisplay dpy, EGLint interval);
117
118 static EGLContext(*_eglCreateContext) (EGLDisplay dpy, EGLConfig config,
119                                       EGLContext share_context,
120                                       const EGLint * attrib_list);
121 static EGLBoolean(*_eglDestroyContext) (EGLDisplay dpy, EGLContext ctx);
122 static EGLBoolean(*_eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw,
123                                     EGLSurface read, EGLContext ctx);
124
125 static EGLContext(*_eglGetCurrentContext) (void);
126 static EGLSurface(*_eglGetCurrentSurface) (EGLint readdraw);
127 static EGLDisplay(*_eglGetCurrentDisplay) (void);
128 static EGLBoolean(*_eglQueryContext) (EGLDisplay dpy, EGLContext ctx,
129                                      EGLint attribute, EGLint * value);
130
131 static EGLBoolean(*_eglWaitGL) (void);
132 static EGLBoolean(*_eglWaitNative) (EGLint engine);
133 static EGLBoolean(*_eglSwapBuffers) (EGLDisplay dpy, EGLSurface surface);
134 static EGLBoolean(*_eglCopyBuffers) (EGLDisplay dpy, EGLSurface surface,
135                                     EGLNativePixmapType target);
136
137 static EGLImageKHR(*_eglCreateImageKHR) (EGLDisplay dpy, EGLContext ctx,
138                                         EGLenum target,
139                                         EGLClientBuffer buffer,
140                                         const EGLint * attrib_list);
141 static EGLBoolean(*_eglDestroyImageKHR) (EGLDisplay dpy, EGLImageKHR image);
142
143 static __eglMustCastToProperFunctionPointerType(*_eglGetProcAddress) (const char *procname);
144
145 static void *_libegl = NULL;
146
147 static void _init_egl()
148 {
149         const char *filename = (getenv("LIBEGL")) ? getenv("LIBEGL") : IMG_LIBEGL_PATH;
150         _libegl = dlopen(filename, RTLD_LAZY);
151 }
152
153 #define EGL_DLSYM(f)                    \
154         if (!_libegl) _init_egl();      \
155         if (!_##f) _##f = dlsym(_libegl, #f);   \
156
157 EGLint eglGetError(void)
158 {
159         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
160         EGL_DLSYM(eglGetError);
161         return _eglGetError();
162 }
163
164 #ifdef WANT_WAYLAND
165 static struct gbm_device *__gbm;
166 static struct wl_display *__wl_display = NULL;
167 #endif
168
169 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
170 {
171         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
172         EGL_DLSYM(eglGetDisplay);
173
174 #ifdef WANT_WAYLAND
175         if (display_id) {
176                 void *head = *(void**)display_id;
177                 if (head == gbm_create_device)
178                         __gbm = (struct gbm_device*)display_id;
179                 if (head == &wl_display_interface)
180                         __wl_display = (struct wl_display*)display_id;
181         }
182 #endif
183
184 #if 0
185         {
186                 FILE *fp = fopen("/proc/self/maps", "r");
187                 char buf[BUFSIZ];
188                 int count;
189                 while(!feof(fp)) {
190                         count = fread(buf, 1, BUFSIZ, fp);
191                         fwrite(buf, count, 1, stdout);
192                 }
193                 fclose(fp);
194
195                 EGL_DEBUG("\n\n%s: %p\n", __func__, _eglGetDisplay);
196         }
197 #endif
198         return _eglGetDisplay(display_id);
199 }
200
201 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint * major, EGLint * minor)
202 {
203         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
204         EGL_DLSYM(eglInitialize);
205         return _eglInitialize(dpy, major, minor);
206 }
207
208 EGLBoolean eglTerminate(EGLDisplay dpy)
209 {
210         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
211         EGL_DLSYM(eglTerminate);
212         return _eglTerminate(dpy);
213 }
214
215 #define EGL_WL_EXT_STRING "EGL_WL_bind_wayland_display "
216
217 const char *eglQueryString(EGLDisplay dpy, EGLint name)
218 {
219         static char *_eglextstr = NULL;
220         const char *ret;
221
222         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
223         EGL_DLSYM(eglQueryString);
224         ret = _eglQueryString(dpy, name);
225
226 #ifdef WANT_WAYLAND
227         if (name == EGL_EXTENSIONS) {
228                 assert(ret != NULL);
229
230                 if (!_eglextstr) {
231                         _eglextstr = calloc(1, strlen(ret) + strlen(EGL_WL_EXT_STRING) + 1);
232                         if (_eglextstr) {
233                                 strcat(_eglextstr, ret);
234                                 strcat(_eglextstr, EGL_WL_EXT_STRING);
235                         } else {
236                                 _eglextstr = (char*)ret;
237                         }
238                 }
239
240                 ret = _eglextstr;
241         }
242 #endif
243         return ret;
244 }
245
246 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig * configs,
247                          EGLint config_size, EGLint * num_config)
248 {
249         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
250         EGL_DLSYM(eglGetConfigs);
251         return _eglGetConfigs(dpy, configs, config_size, num_config);
252 }
253
254 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint * attrib_list,
255                            EGLConfig * configs, EGLint config_size,
256                            EGLint * num_config)
257 {
258         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
259         EGL_DLSYM(eglChooseConfig);
260         return _eglChooseConfig(dpy, attrib_list,
261                                configs, config_size, num_config);
262 }
263
264 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
265                               EGLint attribute, EGLint * value)
266 {
267         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
268         EGL_DLSYM(eglGetConfigAttrib);
269         return _eglGetConfigAttrib(dpy, config, attribute, value);
270 }
271
272 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
273                                   EGLNativeWindowType win,
274                                   const EGLint * attrib_list)
275 {
276         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
277         EGL_DLSYM(eglCreateWindowSurface);
278         return _eglCreateWindowSurface(dpy, config, win, attrib_list);
279 }
280
281 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
282                                    const EGLint * attrib_list)
283 {
284         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
285         EGL_DLSYM(eglCreatePbufferSurface);
286         return _eglCreatePbufferSurface(dpy, config, attrib_list);
287 }
288
289 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
290                                   EGLNativePixmapType pixmap,
291                                   const EGLint * attrib_list)
292 {
293         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
294         EGL_DLSYM(eglCreatePixmapSurface);
295         return _eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
296 }
297
298 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
299 {
300         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
301         EGL_DLSYM(eglDestroySurface);
302         return _eglDestroySurface(dpy, surface);
303 }
304
305 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
306                            EGLint attribute, EGLint * value)
307 {
308         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
309         EGL_DLSYM(eglQuerySurface);
310         return _eglQuerySurface(dpy, surface, attribute, value);
311 }
312
313 EGLBoolean eglBindAPI(EGLenum api)
314 {
315         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
316         EGL_DLSYM(eglBindAPI);
317         return _eglBindAPI(api);
318 }
319
320 EGLenum eglQueryAPI(void)
321 {
322         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
323         EGL_DLSYM(eglQueryAPI);
324         return _eglQueryAPI();
325 }
326
327 EGLBoolean eglWaitClient(void)
328 {
329         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
330         EGL_DLSYM(eglWaitClient);
331         return _eglWaitClient();
332 }
333
334 EGLBoolean eglReleaseThread(void)
335 {
336         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
337         EGL_DLSYM(eglReleaseThread);
338         return _eglReleaseThread();
339 }
340
341 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
342                                             EGLClientBuffer buffer,
343                                             EGLConfig config,
344                                             const EGLint * attrib_list)
345 {
346         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
347         EGL_DLSYM(eglCreatePbufferFromClientBuffer);
348         return _eglCreatePbufferFromClientBuffer(dpy, buftype, buffer,
349                                                 config, attrib_list);
350 }
351
352 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
353                             EGLint attribute, EGLint value)
354 {
355         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
356         EGL_DLSYM(eglSurfaceAttrib);
357         return _eglSurfaceAttrib(dpy, surface, attribute, value);
358 }
359
360 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
361 {
362         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
363         EGL_DLSYM(eglBindTexImage);
364         return _eglBindTexImage(dpy, surface, buffer);
365 }
366
367 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
368 {
369         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
370         EGL_DLSYM(eglReleaseTexImage);
371         return _eglReleaseTexImage(dpy, surface, buffer);
372 }
373
374 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
375 {
376         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
377         EGL_DLSYM(eglSwapInterval);
378         return _eglSwapInterval(dpy, interval);
379 }
380
381 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
382                             EGLContext share_context,
383                             const EGLint * attrib_list)
384 {
385         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
386         EGL_DLSYM(eglCreateContext);
387         return _eglCreateContext(dpy, config, share_context, attrib_list);
388 }
389
390 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
391 {
392         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
393         EGL_DLSYM(eglDestroyContext);
394         return _eglDestroyContext(dpy, ctx);
395 }
396
397 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
398                           EGLSurface read, EGLContext ctx)
399 {
400         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
401         EGL_DLSYM(eglMakeCurrent);
402         return _eglMakeCurrent(dpy, draw, read, ctx);
403 }
404
405 EGLContext eglGetCurrentContext(void)
406 {
407         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
408         EGL_DLSYM(eglGetCurrentContext);
409         return _eglGetCurrentContext();
410 }
411
412 EGLSurface eglGetCurrentSurface(EGLint readdraw)
413 {
414         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
415         EGL_DLSYM(eglGetCurrentSurface);
416         return _eglGetCurrentSurface(readdraw);
417 }
418
419 EGLDisplay eglGetCurrentDisplay(void)
420 {
421         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
422         EGL_DLSYM(eglGetCurrentDisplay);
423         return _eglGetCurrentDisplay();
424 }
425
426 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx,
427                            EGLint attribute, EGLint * value)
428 {
429         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
430         EGL_DLSYM(eglQueryContext);
431         return _eglQueryContext(dpy, ctx, attribute, value);
432 }
433
434 EGLBoolean eglWaitGL(void)
435 {
436         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
437         EGL_DLSYM(eglWaitGL);
438         return _eglWaitGL();
439 }
440
441 EGLBoolean eglWaitNative(EGLint engine)
442 {
443         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
444         EGL_DLSYM(eglWaitNative);
445         return _eglWaitNative(engine);
446 }
447
448 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
449 {
450         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
451         EGL_DLSYM(eglSwapBuffers);
452         return _eglSwapBuffers(dpy, surface);
453 }
454
455 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
456                           EGLNativePixmapType target)
457 {
458         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
459         EGL_DLSYM(eglCopyBuffers);
460         return _eglCopyBuffers(dpy, surface, target);
461 }
462
463 static EGLImageKHR __eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx,
464                                          EGLenum target, EGLClientBuffer buffer,
465                                          const EGLint * attrib_list)
466 {
467         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
468         if (!_eglCreateImageKHR) {
469                 /* we can't EGL_DLSYM this, because it doesn't exist in libEGL.
470                  * IMG's libEGL. we also can't ask ourselves for the location of
471                  * eglGetProcAddress, otherwise we'll end up calling ourselves again, so
472                  * we must look up eglGetProcAddress first and ask SGX
473                  */
474                 EGL_DLSYM(eglGetProcAddress);
475                 _eglCreateImageKHR = (void*)_eglGetProcAddress("eglCreateImageKHR");
476         }
477
478         /*
479          * We consider EGL_WAYLAND_BUFFER_WL to be EGL_ANTIVE_PIXMAP_KHR.
480          * This way IMG EGL will pass the request to underlying WSEGL.
481          */
482         if (target == EGL_WAYLAND_BUFFER_WL) {
483                 EGL_DEBUG("%s: %s: mapping EGL_WAYLAND_BUFFER_WL to EGL_NATIVE_PIXMAP_KHR\n", __FILE__, __func__);
484                 target = EGL_NATIVE_PIXMAP_KHR;
485         }
486
487 #if 0
488         {
489                 int count = 0;
490                 EGLint *_attr, *_attr2, *head;
491                 
492                 _attr = attrib_list;
493                 while (*_attr != EGL_NONE) {
494                         count += 2;
495                         _attr++; _attr++;
496                 }
497                 count++;
498                 EGL_DEBUG("%s: %s: count=%d\n", __FILE__, __func__, count);
499                 head = _attr2 = alloca(sizeof(EGLint) * count);
500
501                 _attr = attrib_list;
502                 while (*_attr != EGL_NONE) {
503                         if (*_attr != EGL_WAYLAND_PLANE_WL) {
504                                 EGL_DEBUG("%s: %s: copying %x\n", __FILE__, __func__, *_attr);
505                                 *_attr2 = *_attr;
506                                 _attr2++; _attr++;
507
508                                 *_attr2 = *_attr;
509                                 _attr2++; _attr++;
510                         } else {
511                                 EGL_DEBUG("%s: %s: skipping %x\n", __FILE__, __func__, *_attr);
512                                 _attr++; _attr++;
513                         }
514                 }
515                 *_attr2 = - EGL_NONE;
516                 attrib_list = head;
517         }
518 #endif
519
520         EGL_DEBUG("%s: %s (target=%d, EGL_WAYLAND_BUFFER_WL=%d, EGL_NATIVE_PIXMAP_KHR=%d) : %p\n", __FILE__, __func__, target, EGL_WAYLAND_BUFFER_WL, EGL_NATIVE_PIXMAP_KHR, _eglCreateImageKHR);
521 //      return _eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
522         return _eglCreateImageKHR(dpy, ctx, target, buffer, NULL);
523 }
524
525 #ifdef WANT_WAYLAND
526 static struct wl_kms *__wl_kms = NULL;
527
528 static EGLBoolean __eglBindWaylandDisplayWL(EGLDisplay dpy,
529                                               struct wl_display *display)
530 {
531         char *device_name = "/dev/dri/card0";
532         int fd = -1;
533
534         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
535         // TODO: create server side for wl_kms.
536         if (__wl_kms)
537                 return EGL_FALSE;
538
539         if (__gbm) {
540                 fd = gbm_device_get_fd(__gbm);
541                 device_name = _gbm_fd_get_device_name(fd);
542         } else {
543                 fd = open(device_name, O_RDWR);
544                 if (fd < 0)
545                         return EGL_FALSE;
546                 __gbm = gbm_create_device(fd);
547         }
548         EGL_DEBUG("%s: decice_name=%s\n", __func__, device_name);
549
550         __wl_kms = wayland_kms_init(display, __wl_display, device_name, fd);
551         return EGL_TRUE;
552 }
553
554 static EGLBoolean __eglUnbindWaylandDisplayWL(EGLDisplay dpy,
555                                                 struct wl_display *display)
556 {
557         // TODO: destroy wl_kms?
558         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
559         if (__wl_kms)
560                 wayland_kms_uninit(__wl_kms);
561
562         return EGL_TRUE;
563 }
564
565 static EGLBoolean __eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
566                                               EGLint attribute, EGLint * value)
567 {
568         int ret, val;
569         enum wl_kms_attribute attr;
570         EGLBoolean result = EGL_FALSE;
571
572         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
573         switch (attribute) {
574         case EGL_TEXTURE_FORMAT:
575                 attr = WL_KMS_TEXTURE_FORMAT;
576                 break;
577         case EGL_WIDTH:
578                 attr = WL_KMS_WIDTH;
579                 break;
580         case EGL_HEIGHT:
581                 attr = WL_KMS_HEIGHT;
582                 break;
583         default:
584                 return EGL_FALSE;
585         }
586         
587         ret = wayland_kms_query_buffer(__wl_kms, buffer, attr, &val);
588         if (!ret) { 
589                 *value = (EGLint)val;
590                 result = EGL_TRUE;
591         }
592
593         return result;
594 }
595 #endif
596
597 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
598 {
599         EGL_DLSYM(eglGetProcAddress);
600
601         EGL_DEBUG("%s: %s(%s)\n", __FILE__, __func__, procname);
602         if (strcmp(procname, "eglCreateImageKHR") == 0) {
603                 return (__eglMustCastToProperFunctionPointerType)__eglCreateImageKHR;
604         }
605 #ifdef WANT_WAYLAND
606         else if (strcmp(procname, "eglBindWaylandDisplayWL") == 0) {
607                 return (__eglMustCastToProperFunctionPointerType)__eglBindWaylandDisplayWL;
608         } else if (strcmp(procname, "eglUnbindWaylandDisplayWL") == 0) {
609                 return (__eglMustCastToProperFunctionPointerType)__eglUnbindWaylandDisplayWL;
610         } else if (strcmp(procname, "eglQueryWaylandBufferWL") == 0) {
611                 return (__eglMustCastToProperFunctionPointerType)__eglQueryWaylandBufferWL;
612         }
613 #endif
614         return _eglGetProcAddress(procname);
615 }
616
617 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
618 {
619         EGL_DEBUG("%s: %s\n", __FILE__, __func__);
620         EGL_DLSYM(eglDestroyImageKHR);
621         return _eglDestroyImageKHR(dpy, image);
622 }