2 * Copyright (c) 2013 Renesas Solutions Corp.
3 * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Takanari Hayama <taki@igel.co.jp>
22 /* EGL function pointers */
23 #define EGL_EGLEXT_PROTOTYPES
25 #include <EGL/eglext.h>
27 #define IMG_LIBEGL_PATH "libEGL-pvr.so"
30 # define EGL_DEBUG(s, x...) { printf(s, ## x); }
32 # define EGL_DEBUG(s, x...) { }
35 #ifndef EGL_WAYLAND_BUFFER_WL
36 /* TI headers don't define this */
37 #define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
47 #include <sys/types.h>
54 #include <wayland-kms.h>
58 static EGLint(*_eglGetError) (void);
60 static EGLDisplay(*_eglGetDisplay) (EGLNativeDisplayType display_id);
61 static EGLBoolean(*_eglInitialize) (EGLDisplay dpy, EGLint * major,
63 static EGLBoolean(*_eglTerminate) (EGLDisplay dpy);
65 static const char *(*_eglQueryString) (EGLDisplay dpy, EGLint name);
67 static EGLBoolean(*_eglGetConfigs) (EGLDisplay dpy, EGLConfig * configs,
68 EGLint config_size, EGLint * num_config);
69 static EGLBoolean(*_eglChooseConfig) (EGLDisplay dpy,
70 const EGLint * attrib_list,
72 EGLint config_size, EGLint * num_config);
73 static EGLBoolean(*_eglGetConfigAttrib) (EGLDisplay dpy,
75 EGLint attribute, EGLint * value);
77 static EGLSurface(*_eglCreateWindowSurface) (EGLDisplay dpy,
79 EGLNativeWindowType win,
80 const EGLint * attrib_list);
81 static EGLSurface(*_eglCreatePbufferSurface) (EGLDisplay dpy,
83 const EGLint * attrib_list);
84 static EGLSurface(*_eglCreatePixmapSurface) (EGLDisplay dpy,
86 EGLNativePixmapType pixmap,
87 const EGLint * attrib_list);
88 static EGLBoolean(*_eglDestroySurface) (EGLDisplay dpy, EGLSurface surface);
89 static EGLBoolean(*_eglQuerySurface) (EGLDisplay dpy, EGLSurface surface,
90 EGLint attribute, EGLint * value);
92 static EGLBoolean(*_eglBindAPI) (EGLenum api);
93 static EGLenum(*_eglQueryAPI) (void);
95 static EGLBoolean(*_eglWaitClient) (void);
97 static EGLBoolean(*_eglReleaseThread) (void);
99 static EGLSurface(*_eglCreatePbufferFromClientBuffer) (EGLDisplay dpy,
107 static EGLBoolean(*_eglSurfaceAttrib) (EGLDisplay dpy,
109 EGLint attribute, EGLint value);
110 static EGLBoolean(*_eglBindTexImage) (EGLDisplay dpy, EGLSurface surface,
112 static EGLBoolean(*_eglReleaseTexImage) (EGLDisplay dpy,
113 EGLSurface surface, EGLint buffer);
115 static EGLBoolean(*_eglSwapInterval) (EGLDisplay dpy, EGLint interval);
117 static EGLContext(*_eglCreateContext) (EGLDisplay dpy, EGLConfig config,
118 EGLContext share_context,
119 const EGLint * attrib_list);
120 static EGLBoolean(*_eglDestroyContext) (EGLDisplay dpy, EGLContext ctx);
121 static EGLBoolean(*_eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw,
122 EGLSurface read, EGLContext ctx);
124 static EGLContext(*_eglGetCurrentContext) (void);
125 static EGLSurface(*_eglGetCurrentSurface) (EGLint readdraw);
126 static EGLDisplay(*_eglGetCurrentDisplay) (void);
127 static EGLBoolean(*_eglQueryContext) (EGLDisplay dpy, EGLContext ctx,
128 EGLint attribute, EGLint * value);
130 static EGLBoolean(*_eglWaitGL) (void);
131 static EGLBoolean(*_eglWaitNative) (EGLint engine);
132 static EGLBoolean(*_eglSwapBuffers) (EGLDisplay dpy, EGLSurface surface);
133 static EGLBoolean(*_eglCopyBuffers) (EGLDisplay dpy, EGLSurface surface,
134 EGLNativePixmapType target);
136 static EGLImageKHR(*_eglCreateImageKHR) (EGLDisplay dpy, EGLContext ctx,
138 EGLClientBuffer buffer,
139 const EGLint * attrib_list);
140 static EGLBoolean(*_eglDestroyImageKHR) (EGLDisplay dpy, EGLImageKHR image);
142 static __eglMustCastToProperFunctionPointerType(*_eglGetProcAddress) (const char *procname);
144 static void *_libegl = NULL;
146 static void _init_egl()
148 const char *filename = (getenv("LIBEGL")) ? getenv("LIBEGL") : IMG_LIBEGL_PATH;
149 _libegl = dlopen(filename, RTLD_LAZY);
152 #define EGL_DLSYM(f) \
153 if (!_libegl) _init_egl(); \
154 if (!_##f) _##f = dlsym(_libegl, #f); \
156 EGLint eglGetError(void)
158 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
159 EGL_DLSYM(eglGetError);
160 return _eglGetError();
164 static struct gbm_device *__gbm;
165 static struct wl_display *__wl_display = NULL;
168 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
170 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
171 EGL_DLSYM(eglGetDisplay);
175 void *head = *(void**)display_id;
176 if (head == gbm_create_device)
177 __gbm = (struct gbm_device*)display_id;
178 if (head == &wl_display_interface)
179 __wl_display = (struct wl_display*)display_id;
185 FILE *fp = fopen("/proc/self/maps", "r");
189 count = fread(buf, 1, BUFSIZ, fp);
190 fwrite(buf, count, 1, stdout);
194 EGL_DEBUG("\n\n%s: %p\n", __func__, _eglGetDisplay);
197 return _eglGetDisplay(display_id);
200 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint * major, EGLint * minor)
202 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
203 EGL_DLSYM(eglInitialize);
204 return _eglInitialize(dpy, major, minor);
207 EGLBoolean eglTerminate(EGLDisplay dpy)
209 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
210 EGL_DLSYM(eglTerminate);
211 return _eglTerminate(dpy);
214 #define EGL_WL_EXT_STRING "EGL_WL_bind_wayland_display "
216 const char *eglQueryString(EGLDisplay dpy, EGLint name)
218 static char *_eglextstr = NULL;
221 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
222 EGL_DLSYM(eglQueryString);
223 ret = _eglQueryString(dpy, name);
226 if (name == EGL_EXTENSIONS) {
230 _eglextstr = calloc(1, strlen(ret) + strlen(EGL_WL_EXT_STRING) + 1);
232 strcat(_eglextstr, ret);
233 strcat(_eglextstr, EGL_WL_EXT_STRING);
235 _eglextstr = (char*)ret;
245 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig * configs,
246 EGLint config_size, EGLint * num_config)
248 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
249 EGL_DLSYM(eglGetConfigs);
250 return _eglGetConfigs(dpy, configs, config_size, num_config);
253 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint * attrib_list,
254 EGLConfig * configs, EGLint config_size,
257 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
258 EGL_DLSYM(eglChooseConfig);
259 return _eglChooseConfig(dpy, attrib_list,
260 configs, config_size, num_config);
263 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
264 EGLint attribute, EGLint * value)
266 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
267 EGL_DLSYM(eglGetConfigAttrib);
268 return _eglGetConfigAttrib(dpy, config, attribute, value);
271 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
272 EGLNativeWindowType win,
273 const EGLint * attrib_list)
275 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
276 EGL_DLSYM(eglCreateWindowSurface);
277 return _eglCreateWindowSurface(dpy, config, win, attrib_list);
280 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
281 const EGLint * attrib_list)
283 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
284 EGL_DLSYM(eglCreatePbufferSurface);
285 return _eglCreatePbufferSurface(dpy, config, attrib_list);
288 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
289 EGLNativePixmapType pixmap,
290 const EGLint * attrib_list)
292 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
293 EGL_DLSYM(eglCreatePixmapSurface);
294 return _eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
297 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
299 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
300 EGL_DLSYM(eglDestroySurface);
301 return _eglDestroySurface(dpy, surface);
304 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
305 EGLint attribute, EGLint * value)
307 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
308 EGL_DLSYM(eglQuerySurface);
309 return _eglQuerySurface(dpy, surface, attribute, value);
312 EGLBoolean eglBindAPI(EGLenum api)
314 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
315 EGL_DLSYM(eglBindAPI);
316 return _eglBindAPI(api);
319 EGLenum eglQueryAPI(void)
321 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
322 EGL_DLSYM(eglQueryAPI);
323 return _eglQueryAPI();
326 EGLBoolean eglWaitClient(void)
328 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
329 EGL_DLSYM(eglWaitClient);
330 return _eglWaitClient();
333 EGLBoolean eglReleaseThread(void)
335 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
336 EGL_DLSYM(eglReleaseThread);
337 return _eglReleaseThread();
340 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
341 EGLClientBuffer buffer,
343 const EGLint * attrib_list)
345 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
346 EGL_DLSYM(eglCreatePbufferFromClientBuffer);
347 return _eglCreatePbufferFromClientBuffer(dpy, buftype, buffer,
348 config, attrib_list);
351 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
352 EGLint attribute, EGLint value)
354 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
355 EGL_DLSYM(eglSurfaceAttrib);
356 return _eglSurfaceAttrib(dpy, surface, attribute, value);
359 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
361 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
362 EGL_DLSYM(eglBindTexImage);
363 return _eglBindTexImage(dpy, surface, buffer);
366 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
368 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
369 EGL_DLSYM(eglReleaseTexImage);
370 return _eglReleaseTexImage(dpy, surface, buffer);
373 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
375 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
376 EGL_DLSYM(eglSwapInterval);
377 return _eglSwapInterval(dpy, interval);
380 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
381 EGLContext share_context,
382 const EGLint * attrib_list)
384 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
385 EGL_DLSYM(eglCreateContext);
386 return _eglCreateContext(dpy, config, share_context, attrib_list);
389 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
391 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
392 EGL_DLSYM(eglDestroyContext);
393 return _eglDestroyContext(dpy, ctx);
396 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
397 EGLSurface read, EGLContext ctx)
399 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
400 EGL_DLSYM(eglMakeCurrent);
401 return _eglMakeCurrent(dpy, draw, read, ctx);
404 EGLContext eglGetCurrentContext(void)
406 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
407 EGL_DLSYM(eglGetCurrentContext);
408 return _eglGetCurrentContext();
411 EGLSurface eglGetCurrentSurface(EGLint readdraw)
413 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
414 EGL_DLSYM(eglGetCurrentSurface);
415 return _eglGetCurrentSurface(readdraw);
418 EGLDisplay eglGetCurrentDisplay(void)
420 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
421 EGL_DLSYM(eglGetCurrentDisplay);
422 return _eglGetCurrentDisplay();
425 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx,
426 EGLint attribute, EGLint * value)
428 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
429 EGL_DLSYM(eglQueryContext);
430 return _eglQueryContext(dpy, ctx, attribute, value);
433 EGLBoolean eglWaitGL(void)
435 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
436 EGL_DLSYM(eglWaitGL);
440 EGLBoolean eglWaitNative(EGLint engine)
442 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
443 EGL_DLSYM(eglWaitNative);
444 return _eglWaitNative(engine);
447 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
449 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
450 EGL_DLSYM(eglSwapBuffers);
451 return _eglSwapBuffers(dpy, surface);
454 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
455 EGLNativePixmapType target)
457 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
458 EGL_DLSYM(eglCopyBuffers);
459 return _eglCopyBuffers(dpy, surface, target);
462 static EGLImageKHR __eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx,
463 EGLenum target, EGLClientBuffer buffer,
464 const EGLint * attrib_list)
466 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
467 if (!_eglCreateImageKHR) {
468 /* we can't EGL_DLSYM this, because it doesn't exist in libEGL.
469 * IMG's libEGL. we also can't ask ourselves for the location of
470 * eglGetProcAddress, otherwise we'll end up calling ourselves again, so
471 * we must look up eglGetProcAddress first and ask SGX
473 EGL_DLSYM(eglGetProcAddress);
474 _eglCreateImageKHR = (void*)_eglGetProcAddress("eglCreateImageKHR");
478 * We consider EGL_WAYLAND_BUFFER_WL to be EGL_ANTIVE_PIXMAP_KHR.
479 * This way IMG EGL will pass the request to underlying WSEGL.
481 if (target == EGL_WAYLAND_BUFFER_WL) {
482 EGL_DEBUG("%s: %s: mapping EGL_WAYLAND_BUFFER_WL to EGL_NATIVE_PIXMAP_KHR\n", __FILE__, __func__);
483 target = EGL_NATIVE_PIXMAP_KHR;
489 EGLint *_attr, *_attr2, *head;
492 while (*_attr != EGL_NONE) {
497 EGL_DEBUG("%s: %s: count=%d\n", __FILE__, __func__, count);
498 head = _attr2 = alloca(sizeof(EGLint) * count);
501 while (*_attr != EGL_NONE) {
502 if (*_attr != EGL_WAYLAND_PLANE_WL) {
503 EGL_DEBUG("%s: %s: copying %x\n", __FILE__, __func__, *_attr);
510 EGL_DEBUG("%s: %s: skipping %x\n", __FILE__, __func__, *_attr);
514 *_attr2 = - EGL_NONE;
519 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);
520 // return _eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
521 return _eglCreateImageKHR(dpy, ctx, target, buffer, NULL);
525 static struct wl_kms *__wl_kms = NULL;
527 static EGLBoolean __eglBindWaylandDisplayWL(EGLDisplay dpy,
528 struct wl_display *display)
530 char *device_name = "/dev/dri/card0";
533 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
534 // TODO: create server side for wl_kms.
539 fd = gbm_device_get_fd(__gbm);
541 fd = open(device_name, O_RDWR);
544 __gbm = gbm_create_device(fd);
546 EGL_DEBUG("%s: decice_name=%s\n", __func__, device_name);
548 __wl_kms = wayland_kms_init(display, __wl_display, device_name, fd);
552 static EGLBoolean __eglUnbindWaylandDisplayWL(EGLDisplay dpy,
553 struct wl_display *display)
555 // TODO: destroy wl_kms?
556 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
558 wayland_kms_uninit(__wl_kms);
563 static EGLBoolean __eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
564 EGLint attribute, EGLint * value)
567 enum wl_kms_attribute attr;
568 EGLBoolean result = EGL_FALSE;
570 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
572 case EGL_TEXTURE_FORMAT:
573 attr = WL_KMS_TEXTURE_FORMAT;
579 attr = WL_KMS_HEIGHT;
585 ret = wayland_kms_query_buffer(__wl_kms, buffer, attr, &val);
587 *value = (EGLint)val;
595 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
597 EGL_DLSYM(eglGetProcAddress);
599 EGL_DEBUG("%s: %s(%s)\n", __FILE__, __func__, procname);
600 if (strcmp(procname, "eglCreateImageKHR") == 0) {
601 return (__eglMustCastToProperFunctionPointerType)__eglCreateImageKHR;
604 else if (strcmp(procname, "eglBindWaylandDisplayWL") == 0) {
605 return (__eglMustCastToProperFunctionPointerType)__eglBindWaylandDisplayWL;
606 } else if (strcmp(procname, "eglUnbindWaylandDisplayWL") == 0) {
607 return (__eglMustCastToProperFunctionPointerType)__eglUnbindWaylandDisplayWL;
608 } else if (strcmp(procname, "eglQueryWaylandBufferWL") == 0) {
609 return (__eglMustCastToProperFunctionPointerType)__eglQueryWaylandBufferWL;
612 return _eglGetProcAddress(procname);
615 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
617 EGL_DEBUG("%s: %s\n", __FILE__, __func__);
618 EGL_DLSYM(eglDestroyImageKHR);
619 return _eglDestroyImageKHR(dpy, image);