summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-03-08 11:52:59 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-03-08 15:44:39 +0900
commit265c851a8f2ac3cd1f93d523736d4cce0454fe2c (patch)
tree8e9d7818c1810d337f71e119ef9b4f4fd92badfd
parent9dcf2d3965b91e2c8f58066d46ecd518d72f933b (diff)
evas gl: Fix version detection for GLES 3.1
It was assumed that GLES 3 would only work with EGL but in fact OpenGL 4.3 & 4.5 are supersets of GLES 3.0 & 3.1 respectively. So GLX should also support GLES 3.0 or GLES 3.1 for evas gl, if the driver supports it, of course. Of course while doing this patch things didn't go like they were supposed to go. I'm currently using NVIDIA's proprietary driver, that conveniently provides EGL with GLES 3.2. But wait, there's a catch: GL_VERSION is "OpenGL ES 3.2 NVIDIA" except that none of the functions of GLES 3.1 or GLES 3.2 are actually supported. Those functions are only present in the GLX/OpenGL variant of the driver. Thanks so much for making my life easier... So yeah, this patch contains a hack for those invalid versions of GLES 3.x. What was supposed to be a small fix became a huge mess. Also add a comment about the possibly invalid auto-upgrade from GLES 2 to GLES 3. This adds a test case in elm_test, but only to verify that elm_glview_version_add(3) actually works. We need a proper GLES 3 test case, eventually (and 3.1, 3.2 of course).
-rw-r--r--src/bin/elementary/test.c2
-rw-r--r--src/bin/elementary/test_glview.c21
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_api.c71
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h2
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c53
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core.c36
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core_private.h3
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.c9
8 files changed, 138 insertions, 59 deletions
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index e3d9dc6413..a850816d18 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -253,6 +253,7 @@ void test_grid_static(void *data, Evas_Object *obj, void *event_info);
253void test_glview_simple(void *data, Evas_Object *obj, void *event_info); 253void test_glview_simple(void *data, Evas_Object *obj, void *event_info);
254void test_glview(void *data, Evas_Object *obj, void *event_info); 254void test_glview(void *data, Evas_Object *obj, void *event_info);
255void test_glview_manygears(void *data, Evas_Object *obj, void *event_info); 255void test_glview_manygears(void *data, Evas_Object *obj, void *event_info);
256void test_glview_gles3(void *data, Evas_Object *obj, void *event_info);
256void test_3d(void *data, Evas_Object *obj, void *event_info); 257void test_3d(void *data, Evas_Object *obj, void *event_info);
257void test_naviframe(void *data, Evas_Object *obj, void *event_info); 258void test_naviframe(void *data, Evas_Object *obj, void *event_info);
258void test_naviframe2(void *data, Evas_Object *obj, void *event_info); 259void test_naviframe2(void *data, Evas_Object *obj, void *event_info);
@@ -859,6 +860,7 @@ add_tests:
859 ADD_TEST(NULL, "3D", "GLViewSimple", test_glview_simple); 860 ADD_TEST(NULL, "3D", "GLViewSimple", test_glview_simple);
860 ADD_TEST(NULL, "3D", "GLView Gears", test_glview); 861 ADD_TEST(NULL, "3D", "GLView Gears", test_glview);
861 ADD_TEST(NULL, "3D", "GLView Many Gears", test_glview_manygears); 862 ADD_TEST(NULL, "3D", "GLView Many Gears", test_glview_manygears);
863 ADD_TEST(NULL, "3D", "GLView GL ES 3.x", test_glview_gles3);
862 864
863 //------------------------------// 865 //------------------------------//
864 ADD_TEST(NULL, "Web", "Web", test_web); 866 ADD_TEST(NULL, "Web", "Web", test_web);
diff --git a/src/bin/elementary/test_glview.c b/src/bin/elementary/test_glview.c
index 2b68a73ca7..beb291a693 100644
--- a/src/bin/elementary/test_glview.c
+++ b/src/bin/elementary/test_glview.c
@@ -427,6 +427,9 @@ _init_gl(Evas_Object *obj)
427{ 427{
428 GLData *gld = evas_object_data_get(obj, "gld"); 428 GLData *gld = evas_object_data_get(obj, "gld");
429 429
430 printf("GL_VERSION: %s\n", gld->glapi->glGetString(GL_VERSION));
431 fflush(stdout);
432
430 gears_init(gld); 433 gears_init(gld);
431} 434}
432 435
@@ -611,8 +614,8 @@ _mouse_up(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *e
611 gld->mouse_down = 0; 614 gld->mouse_down = 0;
612} 615}
613 616
614void 617static void
615test_glview(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 618_test_glview_do(Evas_GL_Context_Version version)
616{ 619{
617 Evas_Object *win, *bx, *bt, *gl, *lb; 620 Evas_Object *win, *bx, *bt, *gl, *lb;
618 Ecore_Animator *ani; 621 Ecore_Animator *ani;
@@ -649,7 +652,7 @@ test_glview(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
649 evas_object_show(bx); 652 evas_object_show(bx);
650 653
651 // Add a GLView 654 // Add a GLView
652 gl = elm_glview_add(win); 655 gl = elm_glview_version_add(win, version);
653 if (gl) 656 if (gl)
654 { 657 {
655 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL); 658 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -723,3 +726,15 @@ test_glview(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
723 evas_object_resize(win, 320, 480); 726 evas_object_resize(win, 320, 480);
724 evas_object_show(win); 727 evas_object_show(win);
725} 728}
729
730void
731test_glview(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
732{
733 _test_glview_do(EVAS_GL_GLES_2_X);
734}
735
736void
737test_glview_gles3(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
738{
739 _test_glview_do(EVAS_GL_GLES_3_X);
740}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_api.c b/src/modules/evas/engines/gl_common/evas_gl_api.c
index 3ccb5b95b6..14378143e0 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_api.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_api.c
@@ -1324,12 +1324,13 @@ _evgl_glGetString(GLenum name)
1324{ 1324{
1325 static char _version[128] = {0}; 1325 static char _version[128] = {0};
1326 static char _glsl[128] = {0}; 1326 static char _glsl[128] = {0};
1327 const char *ret, *version_extra;
1327 EVGL_Resource *rsc; 1328 EVGL_Resource *rsc;
1328 const char *ret; 1329 EVGL_Context *ctx;
1329 1330
1330 /* We wrap two values here: 1331 /* We wrap two values here:
1331 * 1332 *
1332 * VERSION: Since OpenGL ES 3 is not supported yet, we return OpenGL ES 2.0 1333 * VERSION: Since OpenGL ES 3 is not supported yet*, we return OpenGL ES 2.0
1333 * The string is not modified on desktop GL (eg. 4.4.0 NVIDIA 343.22) 1334 * The string is not modified on desktop GL (eg. 4.4.0 NVIDIA 343.22)
1334 * GLES 3 support is not exposed because apps can't use GLES 3 core 1335 * GLES 3 support is not exposed because apps can't use GLES 3 core
1335 * functions yet. 1336 * functions yet.
@@ -1337,6 +1338,8 @@ _evgl_glGetString(GLenum name)
1337 * EXTENSIONS: This should return only the list of GL extensions supported 1338 * EXTENSIONS: This should return only the list of GL extensions supported
1338 * by Evas GL. This means as many extensions as possible should be 1339 * by Evas GL. This means as many extensions as possible should be
1339 * added to the whitelist. 1340 * added to the whitelist.
1341 *
1342 * *: GLES 3.0/3.1 is not fully supported... we also have buggy drivers!
1340 */ 1343 */
1341 1344
1342 /* 1345 /*
@@ -1353,11 +1356,12 @@ _evgl_glGetString(GLenum name)
1353 if ((!(rsc = _evgl_tls_resource_get())) || !rsc->current_ctx) 1356 if ((!(rsc = _evgl_tls_resource_get())) || !rsc->current_ctx)
1354 { 1357 {
1355 ERR("Current context is NULL, not calling glGetString"); 1358 ERR("Current context is NULL, not calling glGetString");
1356 // This sets evas_gl_error_get instead of glGetError... 1359 // This sets evas_gl_error_get instead of eglGetError...
1357 evas_gl_common_error_set(NULL, EVAS_GL_BAD_CONTEXT); 1360 evas_gl_common_error_set(NULL, EVAS_GL_BAD_CONTEXT);
1358 return NULL; 1361 return NULL;
1359 } 1362 }
1360 1363
1364 ctx = rsc->current_ctx;
1361 switch (name) 1365 switch (name)
1362 { 1366 {
1363 case GL_VENDOR: 1367 case GL_VENDOR:
@@ -1369,6 +1373,7 @@ _evgl_glGetString(GLenum name)
1369 ret = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); 1373 ret = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
1370 if (!ret) return NULL; 1374 if (!ret) return NULL;
1371#ifdef GL_GLES 1375#ifdef GL_GLES
1376 // FIXME: We probably shouldn't wrap anything for EGL
1372 if (ret[18] != '1') 1377 if (ret[18] != '1')
1373 { 1378 {
1374 // We try not to remove the vendor fluff 1379 // We try not to remove the vendor fluff
@@ -1388,20 +1393,14 @@ _evgl_glGetString(GLenum name)
1388 ret = (const char *) glGetString(GL_VERSION); 1393 ret = (const char *) glGetString(GL_VERSION);
1389 if (!ret) return NULL; 1394 if (!ret) return NULL;
1390#ifdef GL_GLES 1395#ifdef GL_GLES
1391 if ((ret[10] != '2') && (ret[10] != '3')) 1396 version_extra = ret + 10;
1392 {
1393 // We try not to remove the vendor fluff
1394 snprintf(_version, sizeof(_version), "OpenGL ES 2.0 Evas GL (%s)", ret + 10);
1395 _version[sizeof(_version) - 1] = '\0';
1396 return (const GLubyte *) _version;
1397 }
1398 return (const GLubyte *) ret;
1399#else 1397#else
1400 // Desktop GL, we still keep the official name 1398 version_extra = ret;
1401 snprintf(_version, sizeof(_version), "OpenGL ES 2.0 Evas GL (%s)", (char *) ret); 1399#endif
1400 snprintf(_version, sizeof(_version), "OpenGL ES %d.%d Evas GL (%s)",
1401 (int) ctx->version, ctx->version_minor, version_extra);
1402 _version[sizeof(_version) - 1] = '\0'; 1402 _version[sizeof(_version) - 1] = '\0';
1403 return (const GLubyte *) _version; 1403 return (const GLubyte *) _version;
1404#endif
1405 1404
1406 case GL_EXTENSIONS: 1405 case GL_EXTENSIONS:
1407 // Passing the version - GLESv2/GLESv3. 1406 // Passing the version - GLESv2/GLESv3.
@@ -3242,17 +3241,19 @@ _debug_gles3_api_get(Evas_GL_API *funcs, int minor_version)
3242 3241
3243 3242
3244static Eina_Bool 3243static Eina_Bool
3245_evgl_load_gles3_apis(void *dl_handle, Evas_GL_API *funcs, int minor_version) 3244_evgl_load_gles3_apis(void *dl_handle, Evas_GL_API *funcs, int minor_version,
3245 void *(*get_proc_address)(const char *))
3246{ 3246{
3247 if (!dl_handle) return EINA_FALSE; 3247 if (!dl_handle) return EINA_FALSE;
3248 Eina_Bool ret_value = EINA_FALSE;
3248 3249
3249#define ORD(name) \ 3250#define ORD(name) do { \
3250 funcs->name = dlsym(dl_handle, #name); \ 3251 funcs->name = dlsym(dl_handle, #name); \
3251 if (!funcs->name) \ 3252 if (!funcs->name && get_proc_address) get_proc_address(#name); \
3252 { \ 3253 if (!funcs->name) { \
3253 WRN("%s symbol not found", #name); \ 3254 WRN("%s symbol not found", #name); \
3254 return EINA_FALSE; \ 3255 return ret_value; \
3255 } 3256 } } while (0)
3256 3257
3257 // Used to update extensions 3258 // Used to update extensions
3258 ORD(glGetString); 3259 ORD(glGetString);
@@ -3366,6 +3367,7 @@ _evgl_load_gles3_apis(void *dl_handle, Evas_GL_API *funcs, int minor_version)
3366 if (minor_version > 0) 3367 if (minor_version > 0)
3367 { 3368 {
3368 //GLES 3.1 3369 //GLES 3.1
3370 ret_value = EINA_TRUE;
3369 ORD(glDispatchCompute); 3371 ORD(glDispatchCompute);
3370 ORD(glDispatchComputeIndirect); 3372 ORD(glDispatchComputeIndirect);
3371 ORD(glDrawArraysIndirect); 3373 ORD(glDrawArraysIndirect);
@@ -3435,15 +3437,15 @@ _evgl_load_gles3_apis(void *dl_handle, Evas_GL_API *funcs, int minor_version)
3435 ORD(glVertexAttribBinding); 3437 ORD(glVertexAttribBinding);
3436 ORD(glVertexBindingDivisor); 3438 ORD(glVertexBindingDivisor);
3437 } 3439 }
3438
3439#undef ORD 3440#undef ORD
3441
3440 return EINA_TRUE; 3442 return EINA_TRUE;
3441} 3443}
3442 3444
3443 3445
3444 3446
3445static Eina_Bool 3447static Eina_Bool
3446_evgl_gles3_api_init(int minor_version) 3448_evgl_gles3_api_init(int minor_version, void *(*get_proc_address)(const char *))
3447{ 3449{
3448 static Eina_Bool _initialized = EINA_FALSE; 3450 static Eina_Bool _initialized = EINA_FALSE;
3449 if (_initialized) return EINA_TRUE; 3451 if (_initialized) return EINA_TRUE;
@@ -3475,7 +3477,7 @@ _evgl_gles3_api_init(int minor_version)
3475 return EINA_FALSE; 3477 return EINA_FALSE;
3476 } 3478 }
3477 3479
3478 if (!_evgl_load_gles3_apis(_gles3_handle, &_gles3_api, minor_version)) 3480 if (!_evgl_load_gles3_apis(_gles3_handle, &_gles3_api, minor_version, get_proc_address))
3479 { 3481 {
3480 return EINA_FALSE; 3482 return EINA_FALSE;
3481 } 3483 }
@@ -3484,26 +3486,23 @@ _evgl_gles3_api_init(int minor_version)
3484 return EINA_TRUE; 3486 return EINA_TRUE;
3485} 3487}
3486 3488
3487
3488void 3489void
3489_evgl_api_gles3_get(Evas_GL_API *funcs, Eina_Bool debug) 3490_evgl_api_gles3_get(Evas_GL_API *funcs, void *(*get_proc_address)(const char *),
3491 Eina_Bool debug, int minor_version)
3490{ 3492{
3491 const char *ret = (const char *) glGetString(GL_VERSION); 3493 int effective_minor = minor_version;
3492 int minor_version = ret[12] - '0';
3493 3494
3494 if (minor_version > 9 || minor_version < 0) 3495 if (!_evgl_gles3_api_init(minor_version, get_proc_address))
3495 {
3496 ERR("OpenGL ES version is invalid.");
3497 return;
3498 }
3499
3500 if (!_evgl_gles3_api_init(minor_version))
3501 return; 3496 return;
3502 3497
3498 // Hack for NVIDIA. See also evas_gl_core.c:_context_ext_check()
3499 if (!_gles3_api.glVertexBindingDivisor)
3500 effective_minor = 0;
3501
3503 if (debug) 3502 if (debug)
3504 _debug_gles3_api_get(funcs, minor_version); 3503 _debug_gles3_api_get(funcs, effective_minor);
3505 else 3504 else
3506 _normal_gles3_api_get(funcs, minor_version); 3505 _normal_gles3_api_get(funcs, effective_minor);
3507 3506
3508 if (evgl_engine->direct_scissor_off) 3507 if (evgl_engine->direct_scissor_off)
3509 _direct_scissor_off_api_get(funcs); 3508 _direct_scissor_off_api_get(funcs);
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 59549efe84..d78c21a5b1 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -543,7 +543,7 @@ typedef void (*Evas_Gl_Symbols)(void *(*GetProcAddress)(const char *sym));
543 543
544EAPI void __evas_gl_err(int err, const char *file, const char *func, int line, const char *op); 544EAPI void __evas_gl_err(int err, const char *file, const char *func, int line, const char *op);
545 545
546int evas_gl_common_version_check(void); 546int evas_gl_common_version_check(int *minor_version);
547void evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc, 547void evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc,
548 int rot, int gw, int gh, 548 int rot, int gw, int gh,
549 int cx, int cy, int cw, int ch, 549 int cx, int cy, int cw, int ch,
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 ec8fd826b6..45ea67776b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -493,7 +493,7 @@ matrix_ortho(GLfloat *m,
493} 493}
494 494
495int 495int
496evas_gl_common_version_check(void) 496evas_gl_common_version_check(int *minor_version)
497{ 497{
498 char *version; 498 char *version;
499 char *tmp; 499 char *tmp;
@@ -506,6 +506,8 @@ evas_gl_common_version_check(void)
506 * GL_VERSION is used to get the version of the connection 506 * GL_VERSION is used to get the version of the connection
507 */ 507 */
508 508
509 if (minor_version) *minor_version = 0;
510
509 version = (char *)glGetString(GL_VERSION); 511 version = (char *)glGetString(GL_VERSION);
510 if (!version) 512 if (!version)
511 { 513 {
@@ -541,6 +543,12 @@ evas_gl_common_version_check(void)
541 if (strstr(version, "OpenGL ES 3")) 543 if (strstr(version, "OpenGL ES 3"))
542 { 544 {
543 /* Supported */ 545 /* Supported */
546 if (minor_version)
547 {
548 if ((version[11] == '.') && isdigit(version[12]))
549 *minor_version = atoi(&version[12]);
550 else *minor_version = 0;
551 }
544 return 3; 552 return 3;
545 } 553 }
546 554
@@ -549,6 +557,13 @@ evas_gl_common_version_check(void)
549 if (strstr(version, "OpenGL ES ")) 557 if (strstr(version, "OpenGL ES "))
550 { 558 {
551 /* Supported */ 559 /* Supported */
560 if (minor_version)
561 {
562 if ((version[10] == '2') &&
563 (version[11] == '.') && isdigit(version[12]))
564 *minor_version = atoi(&version[12]);
565 else *minor_version = 0;
566 }
552 return 2; 567 return 2;
553 } 568 }
554 569
@@ -590,22 +605,32 @@ evas_gl_common_version_check(void)
590 fail: 605 fail:
591 free(version); 606 free(version);
592 607
593 if (((major == 1) && (minor >= 4)) || (major >= 2)) 608 // OpenGL 4.5 is supposed to be a superset of GLES 3.1
609 if ((major == 4) && (minor >= 5))
594 { 610 {
595 /* Map GL to GLES version: Refer http://en.wikipedia.org/wiki/OpenGL_ES */ 611 if (minor_version) *minor_version = 1;
596 if ((major >= 4) && (minor >= 3)) 612 return 3;
597 return 3; 613 }
598 else if ((major > 3) || ((major == 3) && (minor >= 3))) /* >= 3.3 */
599 {
600 const char *exts = NULL;
601 int num = 0;
602 614
603 if (_has_ext("GL_ARB_ES3_compatibility", &exts, &num)) 615 // OpenGL 4.3 is supposed to be a superset of GLES 3.0
604 return 3; 616 if ((major == 4) && (minor >= 3))
605 } 617 return 3;
606 return 2; /* emulated support */ 618
619 // Extension GL_ARB_ES3_compatibility means OpenGL is a superset of GLES 3.0
620 if ((major > 3) || ((major == 3) && (minor >= 3)))
621 {
622 const char *exts = NULL;
623 int num = 0;
624
625 if (_has_ext("GL_ARB_ES3_compatibility", &exts, &num))
626 return 3;
607 } 627 }
608 628
629 // OpenGL >= 1.4 is a superset of the features of GLES 2 (albeit not an
630 // exact function match)
631 if (((major == 1) && (minor >= 4)) || (major >= 2))
632 return 2; /* emulated support */
633
609 return 0; 634 return 0;
610} 635}
611 636
@@ -787,7 +812,7 @@ evas_gl_common_context_new(void)
787 if (!glsym_glGetStringi) 812 if (!glsym_glGetStringi)
788 glsym_glGetStringi = dlsym(RTLD_DEFAULT, "glGetStringi"); 813 glsym_glGetStringi = dlsym(RTLD_DEFAULT, "glGetStringi");
789 814
790 gles_version = evas_gl_common_version_check(); 815 gles_version = evas_gl_common_version_check(NULL);
791 if (!gles_version) return NULL; 816 if (!gles_version) return NULL;
792 817
793 gc = calloc(1, sizeof(Evas_Engine_GL_Context)); 818 gc = calloc(1, sizeof(Evas_Engine_GL_Context));
diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c
index b50adfcfac..2c91183baf 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_core.c
@@ -494,7 +494,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
494 int depth_stencil = 0; 494 int depth_stencil = 0;
495 int fb_status = 0; 495 int fb_status = 0;
496 int w = 2, h = 2; // Test it with a simple (2,2) surface. Should I test it with NPOT? 496 int w = 2, h = 2; // Test it with a simple (2,2) surface. Should I test it with NPOT?
497 Evas_GL_Context_Version ver = evas_gl_common_version_check(); 497 Evas_GL_Context_Version ver = evas_gl_common_version_check(NULL);
498 498
499 // Gen FBO 499 // Gen FBO
500 glGenFramebuffers(1, &fbo); 500 glGenFramebuffers(1, &fbo);
@@ -912,7 +912,7 @@ _surface_cap_init(void *eng_data)
912 evgl_engine->caps.max_h = max_size; 912 evgl_engine->caps.max_h = max_size;
913 DBG("Max Surface Width: %d Height: %d", evgl_engine->caps.max_w, evgl_engine->caps.max_h); 913 DBG("Max Surface Width: %d Height: %d", evgl_engine->caps.max_w, evgl_engine->caps.max_h);
914 914
915 gles_version = evas_gl_common_version_check(); 915 gles_version = evas_gl_common_version_check(NULL);
916 916
917 // Check for MSAA support 917 // Check for MSAA support
918 if (gles_version == 3) 918 if (gles_version == 3)
@@ -1019,6 +1019,20 @@ _context_ext_check(EVGL_Context *ctx)
1019 } 1019 }
1020#endif 1020#endif
1021 1021
1022 if (ctx->version == EVAS_GL_GLES_3_X)
1023 {
1024 /* HACK, as of 2017/03/08:
1025 * Some NVIDIA drivers pretend to support GLES 3.1 with EGL but in
1026 * fact none of the new functions are available, neither through
1027 * dlsym() nor eglGetProcAddress(). GLX/OpenGL should work though.
1028 * This is a fixup for glGetString(GL_VERSION).
1029 */
1030 if (!gles3_funcs->glVertexBindingDivisor)
1031 ctx->version_minor = 0;
1032 else
1033 ctx->version_minor = 1;
1034 }
1035
1022 ctx->extension_checked = 1; 1036 ctx->extension_checked = 1;
1023 1037
1024 return 1; 1038 return 1;
@@ -2315,6 +2329,7 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
2315 2329
2316 // Set default values 2330 // Set default values
2317 ctx->version = version; 2331 ctx->version = version;
2332 ctx->version_minor = 0;
2318 ctx->scissor_coord[0] = 0; 2333 ctx->scissor_coord[0] = 0;
2319 ctx->scissor_coord[1] = 0; 2334 ctx->scissor_coord[1] = 0;
2320 ctx->scissor_coord[2] = evgl_engine->caps.max_w; 2335 ctx->scissor_coord[2] = evgl_engine->caps.max_w;
@@ -3116,6 +3131,7 @@ Evas_GL_API *
3116evgl_api_get(void *eng_data, Evas_GL_Context_Version version, Eina_Bool alloc_only) 3131evgl_api_get(void *eng_data, Evas_GL_Context_Version version, Eina_Bool alloc_only)
3117{ 3132{
3118 Evas_GL_API *api = NULL; 3133 Evas_GL_API *api = NULL;
3134 int minor_version = 0;
3119 3135
3120 if (version == EVAS_GL_GLES_2_X) 3136 if (version == EVAS_GL_GLES_2_X)
3121 { 3137 {
@@ -3129,10 +3145,15 @@ evgl_api_get(void *eng_data, Evas_GL_Context_Version version, Eina_Bool alloc_on
3129 } 3145 }
3130 else if (version == EVAS_GL_GLES_3_X) 3146 else if (version == EVAS_GL_GLES_3_X)
3131 { 3147 {
3148 if (evas_gl_common_version_check(&minor_version) < 3)
3149 {
3150 ERR("OpenGL ES 3.x is not supported.");
3151 return NULL;
3152 }
3132 if (!gles3_funcs) gles3_funcs = calloc(1, EVAS_GL_API_STRUCT_SIZE); 3153 if (!gles3_funcs) gles3_funcs = calloc(1, EVAS_GL_API_STRUCT_SIZE);
3133 api = gles3_funcs; 3154 api = gles3_funcs;
3134 } 3155 }
3135 else return NULL; 3156 if (!api) return NULL;
3136 if (alloc_only && (api->version == EVAS_GL_API_VERSION)) 3157 if (alloc_only && (api->version == EVAS_GL_API_VERSION))
3137 return api; 3158 return api;
3138 3159
@@ -3154,7 +3175,14 @@ evgl_api_get(void *eng_data, Evas_GL_Context_Version version, Eina_Bool alloc_on
3154 } 3175 }
3155 else if (version == EVAS_GL_GLES_3_X) 3176 else if (version == EVAS_GL_GLES_3_X)
3156 { 3177 {
3157 _evgl_api_gles3_get(api, evgl_engine->api_debug_mode); 3178 void *(*get_proc_address)(const char *) = NULL;
3179 const char *egl_exts;
3180
3181 egl_exts = evgl_engine->funcs->ext_string_get(eng_data);
3182 if (egl_exts && strstr(egl_exts, "EGL_KHR_get_all_proc_addresses"))
3183 get_proc_address = evgl_engine->funcs->proc_address_get;
3184
3185 _evgl_api_gles3_get(api, get_proc_address, evgl_engine->api_debug_mode, minor_version);
3158 evgl_api_gles3_ext_get(api, evgl_engine->funcs->proc_address_get, evgl_engine->funcs->ext_string_get(eng_data)); 3186 evgl_api_gles3_ext_get(api, evgl_engine->funcs->proc_address_get, evgl_engine->funcs->ext_string_get(eng_data));
3159 } 3187 }
3160 3188
diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h b/src/modules/evas/engines/gl_common/evas_gl_core_private.h
index 71deebe4c4..e6afff639c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h
@@ -163,6 +163,7 @@ struct _EVGL_Context
163 EVGLNative_Context context; 163 EVGLNative_Context context;
164 164
165 Evas_GL_Context_Version version; 165 Evas_GL_Context_Version version;
166 int version_minor;
166 167
167 // Context FBO 168 // Context FBO
168 GLuint surface_fbo; 169 GLuint surface_fbo;
@@ -352,7 +353,7 @@ extern EVGL_Engine *evgl_engine;
352// Internally used functions 353// Internally used functions
353extern void _evgl_api_gles2_get(Evas_GL_API *api, Eina_Bool debug); 354extern void _evgl_api_gles2_get(Evas_GL_API *api, Eina_Bool debug);
354extern void _evgl_api_gles1_get(Evas_GL_API *api, Eina_Bool debug); 355extern void _evgl_api_gles1_get(Evas_GL_API *api, Eina_Bool debug);
355extern void _evgl_api_gles3_get(Evas_GL_API *api, Eina_Bool debug); 356extern void _evgl_api_gles3_get(Evas_GL_API *funcs, void *(*get_proc_address)(const char *), Eina_Bool debug, int minor_version);
356extern EVGL_Resource *_evgl_tls_resource_get(void); 357extern EVGL_Resource *_evgl_tls_resource_get(void);
357extern EVGL_Resource *_evgl_tls_resource_create(void *data); 358extern EVGL_Resource *_evgl_tls_resource_create(void *data);
358extern void _evgl_tls_resource_destroy(void *data); 359extern void _evgl_tls_resource_destroy(void *data);
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c
index 94bfdedbb9..13929aaf19 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -494,6 +494,15 @@ evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version ver
494 EGLContext context = EGL_NO_CONTEXT; 494 EGLContext context = EGL_NO_CONTEXT;
495 int context_attrs[3]; 495 int context_attrs[3];
496 496
497 /* Upgrade GLES 2 to GLES 3.
498 *
499 * FIXME: Maybe we don't want to do this, unless we have no choice.
500 * An alternative would be to use eglCreateImage() to share the indirect
501 * rendering FBO between two contexts of incompatible version. For now,
502 * we always upgrade the real context version to GLES 3 when it's available.
503 * But this leads to some issues, namely that the list of extensions is
504 * different, and MSAA surfaces also work differently.
505 */
497 if (eng_get_ob(re)->gles3 && (version >= EVAS_GL_GLES_2_X)) 506 if (eng_get_ob(re)->gles3 && (version >= EVAS_GL_GLES_2_X))
498 version = 3; 507 version = 3;
499 508