2 * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 /* EGL function pointers */
19 #define EGL_EGLEXT_PROTOTYPES
21 #include <EGL/eglext.h>
22 #include <GLES2/gl2.h>
23 #include <GLES2/gl2ext.h>
33 #include <hybris/internal/binding.h>
36 #include <android/system/window.h>
39 static void *_libegl
= NULL
;
40 static void *_libgles
= NULL
;
42 static EGLint (*_eglGetError
)(void) = NULL
;
44 static EGLDisplay (*_eglGetDisplay
)(EGLNativeDisplayType display_id
) = NULL
;
45 static EGLBoolean (*_eglInitialize
)(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
) = NULL
;
46 static EGLBoolean (*_eglTerminate
)(EGLDisplay dpy
) = NULL
;
48 static const char * (*_eglQueryString
)(EGLDisplay dpy
, EGLint name
) = NULL
;
50 static EGLBoolean (*_eglGetConfigs
)(EGLDisplay dpy
, EGLConfig
*configs
,
51 EGLint config_size
, EGLint
*num_config
) = NULL
;
52 static EGLBoolean (*_eglChooseConfig
)(EGLDisplay dpy
, const EGLint
*attrib_list
,
53 EGLConfig
*configs
, EGLint config_size
,
54 EGLint
*num_config
) = NULL
;
55 static EGLBoolean (*_eglGetConfigAttrib
)(EGLDisplay dpy
, EGLConfig config
,
56 EGLint attribute
, EGLint
*value
) = NULL
;
58 static EGLSurface (*_eglCreateWindowSurface
)(EGLDisplay dpy
, EGLConfig config
,
59 EGLNativeWindowType win
,
60 const EGLint
*attrib_list
) = NULL
;
61 static EGLSurface (*_eglCreatePbufferSurface
)(EGLDisplay dpy
, EGLConfig config
,
62 const EGLint
*attrib_list
) = NULL
;
63 static EGLSurface (*_eglCreatePixmapSurface
)(EGLDisplay dpy
, EGLConfig config
,
64 EGLNativePixmapType pixmap
,
65 const EGLint
*attrib_list
) = NULL
;
66 static EGLBoolean (*_eglDestroySurface
)(EGLDisplay dpy
, EGLSurface surface
) = NULL
;
67 static EGLBoolean (*_eglQuerySurface
)(EGLDisplay dpy
, EGLSurface surface
,
68 EGLint attribute
, EGLint
*value
) = NULL
;
70 static EGLBoolean (*_eglBindAPI
)(EGLenum api
) = NULL
;
71 static EGLenum (*_eglQueryAPI
)(void) = NULL
;
73 static EGLBoolean (*_eglWaitClient
)(void) = NULL
;
75 static EGLBoolean (*_eglReleaseThread
)(void) = NULL
;
77 static EGLSurface (*_eglCreatePbufferFromClientBuffer
)(
78 EGLDisplay dpy
, EGLenum buftype
, EGLClientBuffer buffer
,
79 EGLConfig config
, const EGLint
*attrib_list
) = NULL
;
81 static EGLBoolean (*_eglSurfaceAttrib
)(EGLDisplay dpy
, EGLSurface surface
,
82 EGLint attribute
, EGLint value
) = NULL
;
83 static EGLBoolean (*_eglBindTexImage
)(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
) = NULL
;
84 static EGLBoolean (*_eglReleaseTexImage
)(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
) = NULL
;
87 static EGLBoolean (*_eglSwapInterval
)(EGLDisplay dpy
, EGLint interval
) = NULL
;
90 static EGLContext (*_eglCreateContext
)(EGLDisplay dpy
, EGLConfig config
,
91 EGLContext share_context
,
92 const EGLint
*attrib_list
) = NULL
;
93 static EGLBoolean (*_eglDestroyContext
)(EGLDisplay dpy
, EGLContext ctx
) = NULL
;
94 static EGLBoolean (*_eglMakeCurrent
)(EGLDisplay dpy
, EGLSurface draw
,
95 EGLSurface read
, EGLContext ctx
) = NULL
;
97 static EGLContext (*_eglGetCurrentContext
)(void) = NULL
;
98 static EGLSurface (*_eglGetCurrentSurface
)(EGLint readdraw
) = NULL
;
99 static EGLDisplay (*_eglGetCurrentDisplay
)(void) = NULL
;
100 static EGLBoolean (*_eglQueryContext
)(EGLDisplay dpy
, EGLContext ctx
,
101 EGLint attribute
, EGLint
*value
) = NULL
;
103 static EGLBoolean (*_eglWaitGL
)(void) = NULL
;
104 static EGLBoolean (*_eglWaitNative
)(EGLint engine
) = NULL
;
105 static EGLBoolean (*_eglSwapBuffers
)(EGLDisplay dpy
, EGLSurface surface
) = NULL
;
106 static EGLBoolean (*_eglCopyBuffers
)(EGLDisplay dpy
, EGLSurface surface
,
107 EGLNativePixmapType target
) = NULL
;
110 static EGLImageKHR (*_eglCreateImageKHR
)(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
, EGLClientBuffer buffer
, const EGLint
*attrib_list
) = NULL
;
111 static EGLBoolean (*_eglDestroyImageKHR
) (EGLDisplay dpy
, EGLImageKHR image
) = NULL
;
113 static void (*_glEGLImageTargetTexture2DOES
) (GLenum target
, GLeglImageOES image
) = NULL
;
115 static __eglMustCastToProperFunctionPointerType (*_eglGetProcAddress
)(const char *procname
) = NULL
;
117 static void _init_androidegl()
119 _libegl
= (void *) android_dlopen(getenv("LIBEGL") ? getenv("LIBEGL") : "libEGL.so", RTLD_LAZY
);
120 _libgles
= (void *) android_dlopen(getenv("LIBGLESV2") ? getenv("LIBGLESV2") : "libGLESv2.so", RTLD_LAZY
);
123 #define EGL_DLSYM(fptr, sym) do { if (_libegl == NULL) { _init_androidegl(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libegl, sym); } } while (0)
124 #define GLESv2_DLSYM(fptr, sym) do { if (_libgles == NULL) { _init_androidegl(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libgles, sym); } } while (0)
126 EGLint
eglGetError(void)
128 EGL_DLSYM(&_eglGetError
, "eglGetError");
129 return (*_eglGetError
)();
132 struct _eglDisplayMapping
{
133 EGLNativeDisplayType ndt
;
137 #define _EGL_MAX_DISPLAYS 100
139 struct _eglDisplayMapping
*_displayMappings
[_EGL_MAX_DISPLAYS
];
141 void _addMapping(EGLNativeDisplayType display_id
, EGLDisplay display
)
144 for (i
= 0; i
< _EGL_MAX_DISPLAYS
; i
++)
146 if (_displayMappings
[i
] == NULL
)
148 _displayMappings
[i
] = (struct _eglDisplayMapping
*) malloc(sizeof(struct _eglDisplayMapping
));
149 _displayMappings
[i
]->ndt
= display_id
;
150 _displayMappings
[i
]->display
= display
;
156 EGLNativeDisplayType
_egldisplay2NDT(EGLDisplay display
)
159 for (i
= 0; i
< _EGL_MAX_DISPLAYS
; i
++)
161 if (_displayMappings
[i
])
163 if (_displayMappings
[i
]->display
== display
)
165 return _displayMappings
[i
]->ndt
;
170 return EGL_NO_DISPLAY
;
173 EGLDisplay
eglGetDisplay(EGLNativeDisplayType display_id
)
175 EGL_DLSYM(&_eglGetDisplay
, "eglGetDisplay");
176 EGLNativeDisplayType real_display
;
178 if (!ws_IsValidDisplay(display_id
))
180 return EGL_NO_DISPLAY
;
183 real_display
= (*_eglGetDisplay
)(EGL_DEFAULT_DISPLAY
);
184 if (real_display
== EGL_NO_DISPLAY
)
186 return EGL_NO_DISPLAY
;
188 _addMapping(display_id
, real_display
);
192 EGLBoolean
eglInitialize(EGLDisplay dpy
, EGLint
*major
, EGLint
*minor
)
194 EGL_DLSYM(&_eglInitialize
, "eglInitialize");
195 return (*_eglInitialize
)(dpy
, major
, minor
);
198 EGLBoolean
eglTerminate(EGLDisplay dpy
)
200 EGL_DLSYM(&_eglTerminate
, "eglTerminate");
201 return (*_eglTerminate
)(dpy
);
204 const char * eglQueryString(EGLDisplay dpy
, EGLint name
)
206 EGL_DLSYM(&_eglQueryString
, "eglQueryString");
207 return ws_eglQueryString(dpy
, name
, _eglQueryString
);
210 EGLBoolean
eglGetConfigs(EGLDisplay dpy
, EGLConfig
*configs
,
211 EGLint config_size
, EGLint
*num_config
)
213 EGL_DLSYM(&_eglGetConfigs
, "eglGetConfigs");
214 return (*_eglGetConfigs
)(dpy
, configs
, config_size
, num_config
);
217 EGLBoolean
eglChooseConfig(EGLDisplay dpy
, const EGLint
*attrib_list
,
218 EGLConfig
*configs
, EGLint config_size
,
221 EGL_DLSYM(&_eglChooseConfig
, "eglChooseConfig");
222 return (*_eglChooseConfig
)(dpy
, attrib_list
,
223 configs
, config_size
,
227 EGLBoolean
eglGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
228 EGLint attribute
, EGLint
*value
)
230 EGL_DLSYM(&_eglGetConfigAttrib
, "eglGetConfigAttrib");
231 return (*_eglGetConfigAttrib
)(dpy
, config
,
235 EGLSurface
eglCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
236 EGLNativeWindowType win
,
237 const EGLint
*attrib_list
)
239 EGL_DLSYM(&_eglCreateWindowSurface
, "eglCreateWindowSurface");
241 win
= ws_CreateWindow(win
, _egldisplay2NDT(dpy
));
243 assert(((struct ANativeWindowBuffer
*) win
)->common
.magic
== ANDROID_NATIVE_WINDOW_MAGIC
);
245 EGLSurface result
= (*_eglCreateWindowSurface
)(dpy
, config
, win
, attrib_list
);
246 egl_helper_push_mapping(result
, win
);
250 EGLSurface
eglCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
251 const EGLint
*attrib_list
)
253 EGL_DLSYM(&_eglCreatePbufferSurface
, "eglCreatePbufferSurface");
254 return (*_eglCreatePbufferSurface
)(dpy
, config
, attrib_list
);
257 EGLSurface
eglCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
258 EGLNativePixmapType pixmap
,
259 const EGLint
*attrib_list
)
261 EGL_DLSYM(&_eglCreatePixmapSurface
, "eglCreatePixmapSurface");
262 return (*_eglCreatePixmapSurface
)(dpy
, config
, pixmap
, attrib_list
);
265 EGLBoolean
eglDestroySurface(EGLDisplay dpy
, EGLSurface surface
)
267 EGL_DLSYM(&_eglDestroySurface
, "eglDestroySurface");
268 EGLBoolean result
= (*_eglDestroySurface
)(dpy
, surface
);
271 * If the surface was created via eglCreateWindowSurface, we must
272 * notify the ws about surface destruction for clean-up.
274 if (egl_helper_has_mapping(surface
)) {
275 ws_DestroyWindow(egl_helper_pop_mapping(surface
));
281 EGLBoolean
eglQuerySurface(EGLDisplay dpy
, EGLSurface surface
,
282 EGLint attribute
, EGLint
*value
)
284 EGL_DLSYM(&_eglQuerySurface
, "eglQuerySurface");
285 return (*_eglQuerySurface
)(dpy
, surface
, attribute
, value
);
289 EGLBoolean
eglBindAPI(EGLenum api
)
291 EGL_DLSYM(&_eglBindAPI
, "eglBindAPI");
292 return (*_eglBindAPI
)(api
);
295 EGLenum
eglQueryAPI(void)
297 EGL_DLSYM(&_eglQueryAPI
, "eglQueryAPI");
298 return (*_eglQueryAPI
)();
301 EGLBoolean
eglWaitClient(void)
303 EGL_DLSYM(&_eglWaitClient
, "eglWaitClient");
304 return (*_eglWaitClient
)();
307 EGLBoolean
eglReleaseThread(void)
309 EGL_DLSYM(&_eglReleaseThread
, "eglReleaseThread");
310 return (*_eglReleaseThread
)();
313 EGLSurface
eglCreatePbufferFromClientBuffer(
314 EGLDisplay dpy
, EGLenum buftype
, EGLClientBuffer buffer
,
315 EGLConfig config
, const EGLint
*attrib_list
)
317 EGL_DLSYM(&_eglCreatePbufferFromClientBuffer
, "eglCreatePbufferFromClientBuffer");
318 return (*_eglCreatePbufferFromClientBuffer
)(dpy
, buftype
, buffer
, config
, attrib_list
);
321 EGLBoolean
eglSurfaceAttrib(EGLDisplay dpy
, EGLSurface surface
,
322 EGLint attribute
, EGLint value
)
324 EGL_DLSYM(&_eglSurfaceAttrib
, "eglSurfaceAttrib");
325 return (*_eglSurfaceAttrib
)(dpy
, surface
, attribute
, value
);
328 EGLBoolean
eglBindTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
330 EGL_DLSYM(&_eglBindTexImage
, "eglBindTexImage");
331 return (*_eglBindTexImage
)(dpy
, surface
, buffer
);
334 EGLBoolean
eglReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
336 EGL_DLSYM(&_eglReleaseTexImage
, "eglReleaseTexImage");
337 return (*_eglReleaseTexImage
)(dpy
, surface
, buffer
);
340 EGLBoolean
eglSwapInterval(EGLDisplay dpy
, EGLint interval
)
342 EGL_DLSYM(&_eglSwapInterval
, "eglSwapInterval");
343 return (*_eglSwapInterval
)(dpy
, interval
);
346 EGLContext
eglCreateContext(EGLDisplay dpy
, EGLConfig config
,
347 EGLContext share_context
,
348 const EGLint
*attrib_list
)
350 EGL_DLSYM(&_eglCreateContext
, "eglCreateContext");
351 return (*_eglCreateContext
)(dpy
, config
, share_context
, attrib_list
);
354 EGLBoolean
eglDestroyContext(EGLDisplay dpy
, EGLContext ctx
)
356 EGL_DLSYM(&_eglDestroyContext
, "eglDestroyContext");
357 return (*_eglDestroyContext
)(dpy
, ctx
);
360 EGLBoolean
eglMakeCurrent(EGLDisplay dpy
, EGLSurface draw
,
361 EGLSurface read
, EGLContext ctx
)
363 EGL_DLSYM(&_eglMakeCurrent
, "eglMakeCurrent");
364 return (*_eglMakeCurrent
)(dpy
, draw
, read
, ctx
);
367 EGLContext
eglGetCurrentContext(void)
369 EGL_DLSYM(&_eglGetCurrentContext
, "eglGetCurrentContext");
370 return (*_eglGetCurrentContext
)();
373 EGLSurface
eglGetCurrentSurface(EGLint readdraw
)
375 EGL_DLSYM(&_eglGetCurrentSurface
, "eglGetCurrentSurface");
376 return (*_eglGetCurrentSurface
)(readdraw
);
379 EGLDisplay
eglGetCurrentDisplay(void)
381 EGL_DLSYM(&_eglGetCurrentDisplay
, "eglGetCurrentDisplay");
382 return (*_eglGetCurrentDisplay
)();
385 EGLBoolean
eglQueryContext(EGLDisplay dpy
, EGLContext ctx
,
386 EGLint attribute
, EGLint
*value
)
388 EGL_DLSYM(&_eglQueryContext
, "eglQueryContext");
389 return (*_eglQueryContext
)(dpy
, ctx
, attribute
, value
);
392 EGLBoolean
eglWaitGL(void)
394 EGL_DLSYM(&_eglWaitGL
, "eglWaitGL");
395 return (*_eglWaitGL
)();
398 EGLBoolean
eglWaitNative(EGLint engine
)
400 EGL_DLSYM(&_eglWaitNative
, "eglWaitNative");
401 return (*_eglWaitNative
)(engine
);
404 EGLBoolean
eglSwapBuffers(EGLDisplay dpy
, EGLSurface surface
)
407 HYBRIS_TRACE_BEGIN("hybris-egl", "eglSwapBuffers", "");
408 EGL_DLSYM(&_eglSwapBuffers
, "eglSwapBuffers");
409 ret
= (*_eglSwapBuffers
)(dpy
, surface
);
410 HYBRIS_TRACE_END("hybris-egl", "eglSwapBuffers", "");
414 EGLBoolean
eglCopyBuffers(EGLDisplay dpy
, EGLSurface surface
,
415 EGLNativePixmapType target
)
417 EGL_DLSYM(&_eglCopyBuffers
, "eglCopyBuffers");
418 return (*_eglCopyBuffers
)(dpy
, surface
, target
);
421 static EGLImageKHR
_my_eglCreateImageKHR(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
, EGLClientBuffer buffer
, const EGLint
*attrib_list
)
423 EGL_DLSYM(&_eglCreateImageKHR
, "eglCreateImageKHR");
424 EGLContext newctx
= ctx
;
425 EGLenum newtarget
= target
;
426 EGLClientBuffer newbuffer
= buffer
;
427 const EGLint
*newattrib_list
= attrib_list
;
429 ws_passthroughImageKHR(&newctx
, &newtarget
, &newbuffer
, &newattrib_list
);
430 return (*_eglCreateImageKHR
)(dpy
, newctx
, newtarget
, newbuffer
, newattrib_list
);
433 static void _my_glEGLImageTargetTexture2DOES(GLenum target
, GLeglImageOES image
)
435 GLESv2_DLSYM(&_glEGLImageTargetTexture2DOES
, "glEGLImageTargetTexture2DOES");
436 (*_glEGLImageTargetTexture2DOES
)(target
, image
);
440 __eglMustCastToProperFunctionPointerType
eglGetProcAddress(const char *procname
)
442 EGL_DLSYM(&_eglGetProcAddress
, "eglGetProcAddress");
443 if (strcmp(procname
, "eglCreateImageKHR") == 0)
445 return _my_eglCreateImageKHR
;
447 else if (strcmp(procname
, "glEGLImageTargetTexture2DOES") == 0)
449 return _my_glEGLImageTargetTexture2DOES
;
451 __eglMustCastToProperFunctionPointerType ret
= ws_eglGetProcAddress(procname
);
453 return (*_eglGetProcAddress
)(procname
);
457 EGLBoolean
eglDestroyImageKHR(EGLDisplay dpy
, EGLImageKHR image
)
459 EGL_DLSYM(&_eglDestroyImageKHR
, "eglDestroyImageKHR");
460 return (*_eglDestroyImageKHR
)(dpy
, image
);
464 // vim:ts=4:sw=4:noexpandtab