#include "egl.h" EGLint eglGetError(void) { return IMGeglGetError(); } EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) { return IMGeglGetDisplay(display_id); } EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { return IMGeglInitialize(dpy, major, minor); } EGLBoolean eglTerminate(EGLDisplay dpy) { return IMGeglTerminate(dpy); } const char * eglQueryString(EGLDisplay dpy, EGLint name) { return IMGeglQueryString(dpy, name); } void (* eglGetProcAddress(const char *procname))(void) { return IMGeglGetProcAddress(procname); } EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { return IMGeglGetConfigs(dpy, configs, config_size, num_config); } EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { /* We have two issues to work around here. * * The first is about EGL_RECORDABLE_ANDROID: * When the following conditions are met... * 1. EGL_PBUFFER_BIT is set in EGL_SURFACE_TYPE * 2. EGL_OPENGL_ES2_BIT is set in EGL_RENDERABLE_TYPE * ...EGL_RECORDABLE_ANDROID is forced to EGL_FALSE. * Why this happens is unknown, but the end result is no configs get returned. * Code meeting the above conditions seems to work fine without EGL_RECORDABLE_ANDROID, * so in this shim we'll drop it on their behalf so they actually get an EGLConfig. * * The second is about EGL_FRAMEBUFFER_TARGET_ANDROID: * There is not a single damn user of this anywhere except surfaceflinger. * What's happening is our drivers don't recognize it, and so don't return * a config. End result is it has to retry eglChooseConfig 3 times. It's * not actually a requirement though, the issue is simply the drivers failing * since they don't *recognize* the attribute. * So we will drop this for surfaceflinger to avoid 2 extra calls to eglChooseConfig. * Considering this is only used when surfaceflinger starts up, we'll use the compiler * hints to indicate it's rare, to optimize for basically every other call to us. */ bool renderabletype_es2 = false, surfacetype_pbuffer = false; int attrib_count = 0, recordable_val_pos = -1, fbtarget_pos = -1; /* attrib_list is terminated by EGL_NONE key */ while( attrib_list[attrib_count++] != EGL_NONE ) { if( attrib_list[attrib_count-1] == EGL_RENDERABLE_TYPE ) { /* if EGL_RENDERABLE_TYPE is specified, usually EGL_OPENGL_ES2_BIT is set. */ if( (attrib_list[attrib_count] & EGL_OPENGL_ES2_BIT) != 0 ) renderabletype_es2 = true; } else if( attrib_list[attrib_count-1] == EGL_SURFACE_TYPE ) { /* the pbuffer bit seems to be rarely specified though. */ if( (attrib_list[attrib_count] & EGL_PBUFFER_BIT) != 0 ) surfacetype_pbuffer = true; } else if( attrib_list[attrib_count-1] == EGL_RECORDABLE_ANDROID ) { /* It is generally useless to specify EGL_RECORDABLE_ANDROID * as something other than EGL_TRUE; expect that to be the case */ if( CC_LIKELY( attrib_list[attrib_count] == EGL_TRUE ) ) recordable_val_pos = attrib_count; } else if( CC_UNLIKELY( attrib_list[attrib_count-1] == EGL_FRAMEBUFFER_TARGET_ANDROID ) ) { fbtarget_pos = attrib_count - 1; } /* the array is k/v pairs; for every key we can skip an iteration */ ++attrib_count; } if( recordable_val_pos != -1 && (!surfacetype_pbuffer || !renderabletype_es2) ) recordable_val_pos = -1; /* It appears that surfaceflinger is snappier without a GL ES2 config. * For now, lets avoid fixing this for GL ES2. End result is surfaceflinger * will still avoid *one* extra call to eglChooseConfig which is nice. */ #ifndef FB_TARGET_FIX_EGL2_ALSO if( CC_UNLIKELY( fbtarget_pos != -1 ) && renderabletype_es2 ) fbtarget_pos = -1; #endif if( recordable_val_pos != -1 || CC_UNLIKELY( fbtarget_pos != -1 ) ) { EGLint override_attrib_list[attrib_count]; memcpy( override_attrib_list, attrib_list, attrib_count * sizeof(EGLint) ); if( CC_LIKELY( recordable_val_pos != -1 ) ) override_attrib_list[recordable_val_pos] = EGL_DONT_CARE; if( CC_UNLIKELY( fbtarget_pos != -1 ) ) { memmove( &override_attrib_list[fbtarget_pos], &override_attrib_list[fbtarget_pos+2], (attrib_count - fbtarget_pos - 2) * sizeof(EGLint) ); } return IMGeglChooseConfig(dpy, override_attrib_list, configs, config_size, num_config); } return IMGeglChooseConfig(dpy, attrib_list, configs, config_size, num_config); } EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { return IMGeglGetConfigAttrib(dpy, config, attribute, value); } EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { return IMGeglCreateWindowSurface(dpy, config, win, attrib_list); } EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { return IMGeglCreatePixmapSurface(dpy, config, pixmap, attrib_list); } EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { return IMGeglCreatePbufferSurface(dpy, config, attrib_list); } EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { return IMGeglDestroySurface(dpy, surface); } EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { return IMGeglQuerySurface(dpy, surface, attribute, value); } EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { return IMGeglCreateContext(dpy, config, share_context, attrib_list); } EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { return IMGeglDestroyContext(dpy, ctx); } EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { return IMGeglMakeCurrent(dpy, draw, read, ctx); } EGLContext eglGetCurrentContext(void) { return IMGeglGetCurrentContext(); } EGLSurface eglGetCurrentSurface(EGLint readdraw) { return IMGeglGetCurrentSurface(readdraw); } EGLDisplay eglGetCurrentDisplay(void) { return IMGeglGetCurrentDisplay(); } EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { return IMGeglQueryContext(dpy, ctx, attribute, value); } EGLBoolean eglWaitGL(void) { return IMGeglWaitGL(); } EGLBoolean eglWaitNative(EGLint engine) { return IMGeglWaitNative(engine); } EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { return IMGeglSwapBuffers(dpy, draw); } EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { return IMGeglCopyBuffers(dpy, surface, target); } EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { return IMGeglSwapInterval(dpy, interval); } EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { return IMGeglSurfaceAttrib(dpy, surface, attribute, value); } EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { return IMGeglBindTexImage(dpy, surface, buffer); } EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { return IMGeglReleaseTexImage(dpy, surface, buffer); } EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { return IMGeglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list); } EGLBoolean eglBindAPI(EGLenum api) { return IMGeglBindAPI(api); } EGLenum eglQueryAPI(void) { return IMGeglQueryAPI(); } EGLBoolean eglWaitClient(void) { return IMGeglWaitClient(); } EGLBoolean eglReleaseThread(void) { return IMGeglReleaseThread(); }