From 03ab2e27c87213ee0a19240787e2ff3e847b87ae Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Thu, 5 Mar 2015 19:21:24 +0900 Subject: [PATCH] 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. --- .../evas/engines/gl_common/evas_gl_common.h | 1 + .../evas/engines/gl_common/evas_gl_context.c | 27 ++++++++-- src/modules/evas/engines/gl_x11/evas_engine.c | 13 ++++- src/modules/evas/engines/gl_x11/evas_engine.h | 1 + src/modules/evas/engines/gl_x11/evas_x_main.c | 62 +++++++++++++++++++--- 5 files changed, 92 insertions(+), 12 deletions(-) diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 24e926f..c0f3c97 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -515,6 +515,7 @@ struct _Evas_Engine_GL_Context #endif GLuint preserve_bit; + int gles_version; }; struct _Evas_GL_Texture_Pool diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index b925d36..3f47cb6 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -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; diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 6bda8ea..0f5ae53 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -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; diff --git a/src/modules/evas/engines/gl_x11/evas_engine.h b/src/modules/evas/engines/gl_x11/evas_engine.h index 347c41f..114ea6e 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.h +++ b/src/modules/evas/engines/gl_x11/evas_engine.h @@ -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; diff --git a/src/modules/evas/engines/gl_x11/evas_x_main.c b/src/modules/evas/engines/gl_x11/evas_x_main.c index 7cad2e6..767f580 100644 --- a/src/modules/evas/engines/gl_x11/evas_x_main.c +++ b/src/modules/evas/engines/gl_x11/evas_x_main.c @@ -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); -- 2.7.4