255 lines
7.6 KiB
C
255 lines
7.6 KiB
C
#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();
|
|
}
|