VIGS/YaGL: Using same OpenGL env variable 87/16687/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 21 Feb 2014 12:19:31 +0000 (16:19 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 21 Feb 2014 12:19:31 +0000 (16:19 +0400)
VIGS and YaGL should use the same env variable,
so that they could create compatible contexts

Change-Id: Ibe63f5d8abdb281a71f62118af0d0413ea8c8a7d

hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_gl_backend.h
hw/vigs/vigs_gl_backend_glx.c
hw/yagl/yagl_drivers/egl_glx/yagl_egl_glx.c

index a9443e2..de3d99c 100644 (file)
@@ -1316,6 +1316,17 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
         return false;
     }
 
+    if (!gl_backend->is_gl_2) {
+        gl_backend->GenVertexArrays(1, &gl_backend->vao);
+
+        if (!gl_backend->vao) {
+            VIGS_LOG_CRITICAL("cannot create VAO");
+            goto fail;
+        }
+
+        gl_backend->BindVertexArray(gl_backend->vao);
+    }
+
     gl_backend->tex_prog_vs_id = vigs_gl_create_shader(gl_backend,
                                                        g_vs_tex_source,
                                                        GL_VERTEX_SHADER);
@@ -1436,6 +1447,10 @@ void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
         gl_backend->DeleteShader(gl_backend->tex_prog_fs_id);
         gl_backend->DeleteProgram(gl_backend->tex_prog_id);
 
+        if (!gl_backend->is_gl_2) {
+            gl_backend->DeleteVertexArrays(1, &gl_backend->vao);
+        }
+
         gl_backend->make_current(gl_backend, false);
     }
 
index 8a5163b..8a4109a 100644 (file)
@@ -45,6 +45,8 @@ struct vigs_gl_backend
 
     struct winsys_gl_info ws_info;
 
+    bool is_gl_2;
+
     bool (*has_current)(struct vigs_gl_backend */*gl_backend*/);
 
     bool (*make_current)(struct vigs_gl_backend */*gl_backend*/,
@@ -122,6 +124,19 @@ struct vigs_gl_backend
      */
 
     /*
+     * OpenGL 3.1+ core functions and extensions.
+     * @{
+     */
+
+    void (GLAPIENTRY* GenVertexArrays)(GLsizei n, GLuint* arrays);
+    void (GLAPIENTRY* BindVertexArray)(GLuint array);
+    void (GLAPIENTRY* DeleteVertexArrays)(GLsizei n, const GLuint* arrays);
+
+    /*
+     * @}
+     */
+
+    /*
      * General purpose vectors.
      * @{
      */
@@ -137,6 +152,8 @@ struct vigs_gl_backend
      * Other.
      */
 
+    GLuint vao;
+
     GLuint tex_prog_vs_id;
     GLuint tex_prog_fs_id;
     GLuint tex_prog_id;
index 4e1e62d..6d6c242 100644 (file)
@@ -84,6 +84,7 @@ struct vigs_gl_backend_glx
     PFNGLXDESTROYCONTEXTPROC glXDestroyContext;
     PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrent;
     PFNGLXGETCURRENTCONTEXTPROC glXGetCurrentContext;
+    PFNGLXCREATENEWCONTEXTPROC glXCreateNewContext;
 
     /* GLX_ARB_create_context */
     PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
@@ -95,6 +96,100 @@ struct vigs_gl_backend_glx
     GLXContext read_pixels_ctx;
 };
 
+static bool vigs_gl_backend_glx_check_gl_version(struct vigs_gl_backend_glx *gl_backend_glx,
+                                                 bool *is_gl_2)
+{
+    int config_attribs[] =
+    {
+        GLX_DOUBLEBUFFER, True,
+        GLX_RED_SIZE, 8,
+        GLX_GREEN_SIZE, 8,
+        GLX_BLUE_SIZE, 8,
+        GLX_ALPHA_SIZE, 8,
+        GLX_BUFFER_SIZE, 32,
+        GLX_DEPTH_SIZE, 24,
+        GLX_STENCIL_SIZE, 8,
+        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+        None
+    };
+    int ctx_attribs[] =
+    {
+        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+        GLX_CONTEXT_MINOR_VERSION_ARB, 1,
+        GLX_RENDER_TYPE, GLX_RGBA_TYPE,
+        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+        None
+    };
+    bool res = false;
+    const char *tmp;
+    int n = 0;
+    GLXFBConfig *configs = NULL;
+    GLXContext ctx = NULL;
+
+    tmp = getenv("GL_VERSION");
+
+    if (tmp) {
+        if (strcmp(tmp, "2") == 0) {
+            VIGS_LOG_INFO("GL_VERSION forces OpenGL version to 2.1");
+            *is_gl_2 = true;
+            res = true;
+        } else if (strcmp(tmp, "3_1") == 0) {
+            VIGS_LOG_INFO("GL_VERSION forces OpenGL version to 3.1");
+            *is_gl_2 = false;
+            res = true;
+        } else if (strcmp(tmp, "3_1_es3") == 0) {
+            VIGS_LOG_INFO("GL_VERSION forces OpenGL version to 3.1 ES3");
+            *is_gl_2 = false;
+            res = true;
+        } else if (strcmp(tmp, "3_2") == 0) {
+            VIGS_LOG_INFO("GL_VERSION forces OpenGL version to 3.2");
+            *is_gl_2 = false;
+            res = true;
+        } else {
+            VIGS_LOG_CRITICAL("Bad GL_VERSION value = %s", tmp);
+        }
+
+        goto out;
+    }
+
+    configs = gl_backend_glx->glXChooseFBConfig(gl_backend_glx->dpy,
+                                                DefaultScreen(gl_backend_glx->dpy),
+                                                config_attribs,
+                                                &n);
+
+    if (n <= 0) {
+        VIGS_LOG_ERROR("glXChooseFBConfig failed");
+        goto out;
+    }
+
+    ctx = gl_backend_glx->glXCreateContextAttribsARB(gl_backend_glx->dpy,
+                                                     configs[0],
+                                                     NULL,
+                                                     True,
+                                                     ctx_attribs);
+
+    *is_gl_2 = (ctx == NULL);
+    res = true;
+
+    if (ctx) {
+        VIGS_LOG_INFO("Using OpenGL 3.1+ core");
+    } else {
+        VIGS_LOG_INFO("glXCreateContextAttribsARB failed, using OpenGL 2.1");
+    }
+
+out:
+    if (ctx) {
+        gl_backend_glx->glXMakeContextCurrent(gl_backend_glx->dpy, 0, 0, NULL);
+        gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy, ctx);
+    }
+    if (configs) {
+        XFree(configs);
+    }
+
+    return res;
+}
+
 static GLXFBConfig vigs_gl_backend_glx_get_config(struct vigs_gl_backend_glx *gl_backend_glx)
 {
     int config_attribs[] =
@@ -180,19 +275,28 @@ static bool vigs_gl_backend_glx_create_context(struct vigs_gl_backend_glx *gl_ba
     int attribs[] =
     {
         GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
-        GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+        GLX_CONTEXT_MINOR_VERSION_ARB, 1,
         GLX_RENDER_TYPE, GLX_RGBA_TYPE,
+        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
         None
     };
 
-    *ctx = gl_backend_glx->glXCreateContextAttribsARB(gl_backend_glx->dpy,
-                                                      config,
-                                                      share_ctx,
-                                                      True,
-                                                      attribs);
+    if (gl_backend_glx->base.is_gl_2) {
+        *ctx = gl_backend_glx->glXCreateNewContext(gl_backend_glx->dpy,
+                                                   config,
+                                                   GLX_RGBA_TYPE,
+                                                   share_ctx,
+                                                   True);
+    } else {
+        *ctx = gl_backend_glx->glXCreateContextAttribsARB(gl_backend_glx->dpy,
+                                                          config,
+                                                          share_ctx,
+                                                          True,
+                                                          attribs);
+    }
 
     if (!*ctx) {
-        VIGS_LOG_CRITICAL("glXCreateContextAttribsARB failed");
+        VIGS_LOG_CRITICAL("glXCreateContextAttribsARB/glXCreateNewContext failed");
         return false;
     }
 
@@ -312,6 +416,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GLX_GET_PROC(PFNGLXDESTROYCONTEXTPROC, glXDestroyContext);
     VIGS_GLX_GET_PROC(PFNGLXMAKECONTEXTCURRENTPROC, glXMakeContextCurrent);
     VIGS_GLX_GET_PROC(PFNGLXGETCURRENTCONTEXTPROC, glXGetCurrentContext);
+    VIGS_GLX_GET_PROC(PFNGLXCREATENEWCONTEXTPROC, glXCreateNewContext);
     VIGS_GLX_GET_PROC(PFNGLXCREATECONTEXTATTRIBSARBPROC, glXCreateContextAttribsARB);
 
     VIGS_GL_GET_PROC(GenTextures, glGenTextures);
@@ -375,6 +480,17 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
 
     gl_backend_glx->dpy = x_display;
 
+    if (!vigs_gl_backend_glx_check_gl_version(gl_backend_glx,
+                                              &gl_backend_glx->base.is_gl_2)) {
+        goto fail2;
+    }
+
+    if (!gl_backend_glx->base.is_gl_2) {
+        VIGS_GL_GET_PROC(GenVertexArrays, glGenVertexArrays);
+        VIGS_GL_GET_PROC(BindVertexArray, glBindVertexArray);
+        VIGS_GL_GET_PROC(DeleteVertexArrays, glDeleteVertexArrays);
+    }
+
     config = vigs_gl_backend_glx_get_config(gl_backend_glx);
 
     if (!config) {
index bca0887..8f687a8 100644 (file)
@@ -168,27 +168,27 @@ static bool yagl_egl_glx_get_gl_version(struct yagl_egl_glx *egl_glx,
 
     YAGL_EGL_GLX_ENTER(yagl_egl_glx_get_gl_version, NULL);
 
-    tmp = getenv("YAGL_GL_VERSION");
+    tmp = getenv("GL_VERSION");
 
     if (tmp) {
-        if (strcmp(tmp, "gl_2") == 0) {
-            YAGL_LOG_INFO("YAGL_GL_VERSION forces OpenGL version to 2.1");
+        if (strcmp(tmp, "2") == 0) {
+            YAGL_LOG_INFO("GL_VERSION forces OpenGL version to 2.1");
             *version = yagl_gl_2;
             res = true;
-        } else if (strcmp(tmp, "gl_3_1") == 0) {
-            YAGL_LOG_INFO("YAGL_GL_VERSION forces OpenGL version to 3.1");
+        } else if (strcmp(tmp, "3_1") == 0) {
+            YAGL_LOG_INFO("GL_VERSION forces OpenGL version to 3.1");
             *version = yagl_gl_3_1;
             res = true;
-        } else if (strcmp(tmp, "gl_3_1_es3") == 0) {
-            YAGL_LOG_INFO("YAGL_GL_VERSION forces OpenGL version to 3.1 ES3");
+        } else if (strcmp(tmp, "3_1_es3") == 0) {
+            YAGL_LOG_INFO("GL_VERSION forces OpenGL version to 3.1 ES3");
             *version = yagl_gl_3_1_es3;
             res = true;
-        } else if (strcmp(tmp, "gl_3_2") == 0) {
-            YAGL_LOG_INFO("YAGL_GL_VERSION forces OpenGL version to 3.2");
+        } else if (strcmp(tmp, "3_2") == 0) {
+            YAGL_LOG_INFO("GL_VERSION forces OpenGL version to 3.2");
             *version = yagl_gl_3_2;
             res = true;
         } else {
-            YAGL_LOG_CRITICAL("Bad YAGL_GL_VERSION value = %s", tmp);
+            YAGL_LOG_CRITICAL("Bad GL_VERSION value = %s", tmp);
         }
 
         goto out;