Evas GL common: Create OpenGL ES 3.x contexts by default

Automatically fallback to OpenGL ES 2.0 if OpenGL ES 3 is not supported.
This is a first step in trying to support GLES 3 for Evas GL.

This commit is also a wild test to see whether using GLES 3 contexts
by default will break anything. The theory says that GLES 3 is
backwards compatible with GLESv2.

So, if anything GL breaks for you... scream loudly!
But before reporting any bugs, please set the env variable:
- export EVAS_GL_DISABLE_GLES3=1

This does not add any requirement for GLESv3 support.
This commit is contained in:
Jean-Philippe Andre 2015-03-05 19:21:24 +09:00
parent 611741e65d
commit 03ab2e27c8
5 changed files with 92 additions and 12 deletions

View File

@ -515,6 +515,7 @@ struct _Evas_Engine_GL_Context
#endif
GLuint preserve_bit;
int gles_version;
};
struct _Evas_GL_Texture_Pool

View File

@ -337,13 +337,14 @@ matrix_ortho(GLfloat *m,
}
static int
_evas_gl_common_version_check()
_evas_gl_common_version_check(int *gles_ver)
{
char *version;
char *tmp;
char *tmp2;
int major = 0;
int minor = 0;
*gles_ver = 0;
/*
* glGetString returns a string describing the current GL connection.
@ -375,11 +376,21 @@ _evas_gl_common_version_check()
return 0;
}
/* OpenGL ES 3.* */
if (strstr(version, "OpenGL ES 3"))
{
/* Supported */
*gles_ver = 3;
return 1;
}
/* OpenGL ES 2.* ? */
if (strstr(version, "OpenGL ES "))
{
/* Supported */
*gles_ver = 2;
return 1;
}
@ -422,7 +433,14 @@ _evas_gl_common_version_check()
free(version);
if (((major == 1) && (minor >= 4)) || (major >= 2))
return 1;
{
/* Map GL to GLES version: Refer http://en.wikipedia.org/wiki/OpenGL_ES */
if ((major >=4 ) && (minor >= 3))
*gles_ver = 3;
else
*gles_ver = 2;
return 1;
}
return 0;
}
@ -579,7 +597,7 @@ evas_gl_common_context_new(void)
{
Evas_Engine_GL_Context *gc;
const char *s;
int i;
int i, gles_version;
#if 1
if (_evas_gl_common_context)
@ -588,12 +606,13 @@ evas_gl_common_context_new(void)
return _evas_gl_common_context;
}
#endif
if (!_evas_gl_common_version_check())
if (!_evas_gl_common_version_check(&gles_version))
return NULL;
gc = calloc(1, sizeof(Evas_Engine_GL_Context));
if (!gc) return NULL;
tbm_symbols();
gc->gles_version = gles_version;
gc->references = 1;

View File

@ -479,6 +479,9 @@ evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version ver
EGLContext context = EGL_NO_CONTEXT;
int context_attrs[3];
if (eng_get_ob(re)->gles3 && (version >= EVAS_GL_GLES_2_X))
version = 3;
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
context_attrs[1] = version;
context_attrs[2] = EGL_NONE;
@ -698,7 +701,10 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
}
config_attrs[i++] = EGL_RENDERABLE_TYPE;
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
if (eng_get_ob(re)->gles3)
config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
else
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
config_attrs[i++] = EGL_SURFACE_TYPE;
config_attrs[i++] = EGL_PBUFFER_BIT;
config_attrs[i++] = EGL_NONE;
@ -2239,7 +2245,10 @@ eng_image_native_set(void *data, void *image, void *native)
config_attrs[i++] = EGL_STENCIL_SIZE;
config_attrs[i++] = 0;
config_attrs[i++] = EGL_RENDERABLE_TYPE;
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
if (eng_get_ob(re)->gles3)
config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
else
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
config_attrs[i++] = EGL_SURFACE_TYPE;
config_attrs[i++] = EGL_PIXMAP_BIT;
config_attrs[i++] = EGL_NONE;

View File

@ -65,6 +65,7 @@ struct _Outbuf
EGLSurface egl_surface[2];
EGLConfig egl_config;
EGLDisplay egl_disp;
Eina_Bool gles3 : 1;
#else
GLXContext context;
GLXWindow glxwin;

View File

@ -7,6 +7,7 @@ static Eina_TLS _context_key = 0;
typedef EGLContext GLContext;
static EGLConfig fbconf = 0;
static EGLConfig rgba_fbconf = 0;
static Eina_Bool gles3_supported = EINA_FALSE;
#else
// FIXME: this will only work for 1 display connection (glx land can have > 1)
typedef GLXContext GLContext;
@ -158,10 +159,7 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
// EGL / GLES
#ifdef GL_GLES
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
context_attrs[1] = 2;
context_attrs[2] = EGL_NONE;
gw->gles3 = gles3_supported;
gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->disp));
if (!gw->egl_disp)
{
@ -197,13 +195,25 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
eng_window_free(gw);
return NULL;
}
try_gles2:
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
context_attrs[1] = gw->gles3 ? 3 : 2;
context_attrs[2] = EGL_NONE;
context = _tls_context_get();
gw->egl_context[0] = eglCreateContext
(gw->egl_disp, gw->egl_config, context, context_attrs);
if (gw->egl_context[0] == EGL_NO_CONTEXT)
{
ERR("eglCreateContext() fail. code=%#x", eglGetError());
if (gw->gles3)
{
/* Note: this shouldn't happen */
ERR("Trying again with an Open GL ES 2 context (fallback).");
gw->gles3 = EINA_FALSE;
goto try_gles2;
}
eng_window_free(gw);
return NULL;
}
@ -687,11 +697,46 @@ eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
EGLDisplay *egl_disp;
EGLConfig configs[200];
int major_version, minor_version;
const char *eglexts, *s;
egl_disp = eglGetDisplay((EGLNativeDisplayType)(einfo->info.display));
if (!egl_disp) return NULL;
if (!eglInitialize(egl_disp, &major_version, &minor_version)) return NULL;
eglexts = eglQueryString(egl_disp, EGL_EXTENSIONS);
if (eglexts && strstr(eglexts, "EGL_KHR_create_context"))
{
int k, numconfigs = 0, value;
EGLConfig *eglconfigs;
if (eglGetConfigs(egl_disp, NULL, 0, &numconfigs) &&
(numconfigs > 0))
{
eglconfigs = alloca(numconfigs * sizeof(EGLConfig));
eglGetConfigs(egl_disp, eglconfigs, numconfigs, &numconfigs);
for (k = 0; k < numconfigs; k++)
{
value = 0;
if (eglGetConfigAttrib(egl_disp, eglconfigs[k], EGL_RENDERABLE_TYPE, &value) &&
((value & EGL_OPENGL_ES3_BIT_KHR) != 0) &&
eglGetConfigAttrib(egl_disp, eglconfigs[k], EGL_SURFACE_TYPE, &value) &&
((value & EGL_WINDOW_BIT) != 0))
{
INF("OpenGL ES 3.x is supported!");
gles3_supported = EINA_TRUE;
break;
}
}
}
}
if (gles3_supported &&
(!(s = getenv("EVAS_GL_DISABLE_GLES3")) || (atoi(s) != 1)))
{
INF("Disabling OpenGL ES 3.x support.");
gles3_supported = EINA_FALSE;
}
for (alpha = 0; alpha < 2; alpha++)
{
Eina_Bool found;
@ -703,7 +748,10 @@ eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
config_attrs[n++] = EGL_SURFACE_TYPE;
config_attrs[n++] = EGL_WINDOW_BIT;
config_attrs[n++] = EGL_RENDERABLE_TYPE;
config_attrs[n++] = EGL_OPENGL_ES2_BIT;
if (gles3_supported)
config_attrs[n++] = EGL_OPENGL_ES3_BIT_KHR;
else
config_attrs[n++] = EGL_OPENGL_ES2_BIT;
# if 0
// FIXME: n900 - omap3 sgx libs break here
config_attrs[n++] = EGL_RED_SIZE;
@ -1007,6 +1055,8 @@ eng_gl_context_new(Outbuf *win)
if (!ctx) return NULL;
#if GL_GLES
if (win->gles3)
context_attrs[1] = 3;
ctx->context = eglCreateContext(win->egl_disp, win->egl_config,
win->egl_context[0], context_attrs);