VIGS: Fixed for OpenGL 3.1+ core 62/16662/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Thu, 20 Feb 2014 16:51:02 +0000 (20:51 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Thu, 20 Feb 2014 16:51:02 +0000 (20:51 +0400)
We've reimplemented everything using shaders
and VBOs, since this is the only way to go
in OpenGL 3.1+ core

Change-Id: I7a6787c74910e52fe06242499535d1be9137b3ef

hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_gl_backend.h
hw/vigs/vigs_gl_backend_agl.c
hw/vigs/vigs_gl_backend_glx.c
hw/vigs/vigs_gl_backend_wgl.c

index 01b2136..a9443e2 100644 (file)
@@ -110,6 +110,11 @@ struct vigs_gl_surface
      * Allocated on first access.
      */
     GLuint tmp_tex;
+
+    /*
+     * Ortho matrix for this surface.
+     */
+    GLfloat ortho[16];
 };
 
 static __inline struct vigs_winsys_gl_surface
@@ -123,28 +128,214 @@ static __inline struct vigs_winsys_gl_surface
  * @{
  */
 
+static const char *g_vs_tex_source =
+    "attribute vec4 vertCoord;\n"
+    "uniform mat4 proj;\n"
+    "attribute vec2 texCoord;\n"
+    "varying vec2 v_texCoord;\n"
+    "void main()\n"
+    "{\n"
+    "    v_texCoord = texCoord;\n"
+    "    gl_Position = proj * vertCoord;\n"
+    "}\n";
+
+static const char *g_fs_tex_source =
+    "uniform sampler2D tex;\n"
+    "varying vec2 v_texCoord;\n"
+    "void main()\n"
+    "{\n"
+    "    gl_FragColor = texture2D(tex, v_texCoord);\n"
+    "}\n";
+
+static const char *g_vs_color_source =
+    "attribute vec4 vertCoord;\n"
+    "uniform mat4 proj;\n"
+    "void main()\n"
+    "{\n"
+    "    gl_Position = proj * vertCoord;\n"
+    "}\n";
+
+static const char *g_fs_color_source =
+    "uniform vec4 color;\n"
+    "void main()\n"
+    "{\n"
+    "    gl_FragColor = color;\n"
+    "}\n";
+
+static GLuint vigs_gl_create_shader(struct vigs_gl_backend *backend,
+                                    const char *source,
+                                    GLenum type)
+{
+    GLuint shader = backend->CreateShader(type);
+    GLint tmp = 0;
+
+    if (!shader) {
+        VIGS_LOG_CRITICAL("Unable to create shader type %d", type);
+        return 0;
+    }
+
+    backend->ShaderSource(shader, 1, &source, NULL);
+    backend->CompileShader(shader);
+    backend->GetShaderiv(shader, GL_COMPILE_STATUS, &tmp);
+
+    if (!tmp) {
+        char *buff;
+
+        tmp = 0;
+
+        backend->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &tmp);
+
+        buff = g_malloc0(tmp);
+
+        backend->GetShaderInfoLog(shader, tmp, NULL, buff);
+
+        VIGS_LOG_CRITICAL("Unable to compile shader (type = %d) - %s",
+                          type, buff);
+
+        backend->DeleteShader(shader);
+
+        g_free(buff);
+
+        return 0;
+    }
+
+    return shader;
+}
+
+static GLuint vigs_gl_create_program(struct vigs_gl_backend *backend,
+                                     GLuint vs_id,
+                                     GLuint fs_id)
+{
+    GLuint program = backend->CreateProgram();
+    GLint tmp = 0;
+
+    if (!program) {
+        VIGS_LOG_CRITICAL("Unable to create program");
+        return 0;
+    }
+
+    backend->AttachShader(program, vs_id);
+    backend->AttachShader(program, fs_id);
+    backend->LinkProgram(program);
+    backend->GetProgramiv(program, GL_LINK_STATUS, &tmp);
+
+    if (!tmp) {
+        char *buff;
+
+        tmp = 0;
+
+        backend->GetProgramiv(program, GL_INFO_LOG_LENGTH, &tmp);
+
+        buff = g_malloc0(tmp);
+
+        backend->GetProgramInfoLog(program, tmp, NULL, buff);
+
+        VIGS_LOG_CRITICAL("Unable to link program - %s", buff);
+
+        backend->DeleteProgram(program);
+
+        g_free(buff);
+
+        return 0;
+    }
+
+    return program;
+}
+
+static void vigs_gl_draw_tex_prog(struct vigs_gl_backend *backend,
+                                  uint32_t count)
+{
+    uint32_t size = count * 16;
+
+    if (size > backend->vbo_size) {
+        backend->vbo_size = size;
+        backend->BufferData(GL_ARRAY_BUFFER,
+                            size,
+                            0,
+                            GL_STREAM_DRAW);
+    }
+
+    backend->BufferSubData(GL_ARRAY_BUFFER, 0,
+                           (size / 2), vigs_vector_data(&backend->v1));
+    backend->BufferSubData(GL_ARRAY_BUFFER, (size / 2),
+                           (size / 2), vigs_vector_data(&backend->v2));
+
+    backend->EnableVertexAttribArray(backend->tex_prog_vertCoord_loc);
+    backend->EnableVertexAttribArray(backend->tex_prog_texCoord_loc);
+
+    backend->VertexAttribPointer(backend->tex_prog_vertCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL);
+    backend->VertexAttribPointer(backend->tex_prog_texCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL + (size / 2));
+
+    backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+    backend->DisableVertexAttribArray(backend->tex_prog_texCoord_loc);
+    backend->DisableVertexAttribArray(backend->tex_prog_vertCoord_loc);
+}
+
+static void vigs_gl_draw_color_prog(struct vigs_gl_backend *backend,
+                                    const GLfloat color[4],
+                                    uint32_t count)
+{
+    uint32_t size = count * 8;
+
+    if (size > backend->vbo_size) {
+        backend->vbo_size = size;
+        backend->BufferData(GL_ARRAY_BUFFER,
+                            size,
+                            0,
+                            GL_STREAM_DRAW);
+    }
+
+    backend->BufferSubData(GL_ARRAY_BUFFER, 0, size,
+                           vigs_vector_data(&backend->v1));
+
+    backend->Uniform4fv(backend->color_prog_color_loc, 1, color);
+
+    backend->EnableVertexAttribArray(backend->color_prog_vertCoord_loc);
+
+    backend->VertexAttribPointer(backend->color_prog_vertCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL);
+
+    backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+    backend->DisableVertexAttribArray(backend->color_prog_vertCoord_loc);
+}
+
+static void vigs_gl_create_ortho(GLfloat left, GLfloat right,
+                                 GLfloat bottom, GLfloat top,
+                                 GLfloat near, GLfloat far,
+                                 GLfloat ortho[16])
+{
+    ortho[0] = 2.0f / (right - left);
+    ortho[5] = 2.0f / (top - bottom);
+    ortho[10] = -2.0f / (far - near);
+    ortho[12] = -(right + left) / (right - left);
+    ortho[13] = -(top + bottom) / (top - bottom);
+    ortho[14] = -(far + near) / (far - near);
+    ortho[15] = 1.0f;
+}
+
 static void vigs_gl_translate_color(vigsp_color color,
                                     vigsp_surface_format format,
-                                    GLubyte *red,
-                                    GLubyte *green,
-                                    GLubyte *blue,
-                                    GLubyte *alpha)
+                                    GLfloat res[4])
 {
-    *alpha = 0xFF;
+    res[3] = 1.0f;
     switch (format) {
     case vigsp_surface_bgra8888:
-        *alpha = (GLubyte)((color >> 24) & 0xFF);
+        res[3] = (GLfloat)((color >> 24) & 0xFF) / 255.0f;
         /* Fall through. */
     case vigsp_surface_bgrx8888:
-        *red = (GLubyte)((color >> 16) & 0xFF);
-        *green = (GLubyte)((color >> 8) & 0xFF);
-        *blue = (GLubyte)(color & 0xFF);
+        res[0] = (GLfloat)((color >> 16) & 0xFF) / 255.0f;
+        res[1] = (GLfloat)((color >> 8) & 0xFF) / 255.0f;
+        res[2] = (GLfloat)(color & 0xFF) / 255.0f;
         break;
     default:
         assert(false);
-        *red = 0;
-        *green = 0;
-        *blue = 0;
+        res[0] = 0.0f;
+        res[1] = 0.0f;
+        res[2] = 0.0f;
     }
 }
 
@@ -186,41 +377,34 @@ fail:
     return false;
 }
 
-static bool vigs_gl_surface_create_framebuffer(struct vigs_gl_surface *gl_sfc)
+static bool vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc,
+                                              GLuint prog_id,
+                                              GLint proj_loc)
 {
     struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend;
 
-    if (gl_sfc->fb) {
-        return true;
-    }
+    if (!gl_sfc->fb) {
+        gl_backend->GenFramebuffers(1, &gl_sfc->fb);
 
-    gl_backend->GenFramebuffers(1, &gl_sfc->fb);
+        if (!gl_sfc->fb) {
+            return false;
+        }
+    }
 
-    if (!gl_sfc->fb) {
-        goto fail;
+    if (gl_backend->cur_prog_id != prog_id) {
+        gl_backend->UseProgram(prog_id);
+        gl_backend->cur_prog_id = prog_id;
     }
 
-    return true;
+    gl_backend->Viewport(0, 0,
+                         gl_sfc->base.ws_sfc->width,
+                         gl_sfc->base.ws_sfc->height);
 
-fail:
-    return false;
-}
+    gl_backend->UniformMatrix4fv(proj_loc, 1, GL_FALSE, gl_sfc->ortho);
 
-static void vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc)
-{
-    struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend;
+    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
 
-    gl_backend->Viewport(0, 0,
-                         gl_sfc->base.ws_sfc->width, gl_sfc->base.ws_sfc->height);
-    gl_backend->MatrixMode(GL_PROJECTION);
-    gl_backend->LoadIdentity();
-    gl_backend->Ortho(0.0, gl_sfc->base.ws_sfc->width,
-                      0.0, gl_sfc->base.ws_sfc->height,
-                      -1.0, 1.0);
-    gl_backend->MatrixMode(GL_MODELVIEW);
-    gl_backend->LoadIdentity();
-    gl_backend->Disable(GL_DEPTH_TEST);
-    gl_backend->Disable(GL_BLEND);
+    return true;
 }
 
 /*
@@ -406,7 +590,9 @@ static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc,
         goto out;
     }
 
-    if (!vigs_gl_surface_create_framebuffer(gl_sfc)) {
+    if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+                                           gl_backend->tex_prog_id,
+                                           gl_backend->tex_prog_proj_loc)) {
         goto out;
     }
 
@@ -416,52 +602,35 @@ static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc,
     sfc_w = ws_sfc->base.base.width;
     sfc_h = ws_sfc->base.base.height;
 
-    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
-
-    vigs_gl_surface_setup_framebuffer(gl_sfc);
-
-    gl_backend->Enable(GL_TEXTURE_2D);
-
     gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                      GL_TEXTURE_2D, gl_sfc->tmp_tex, 0);
 
     vert_coords = vigs_vector_append(&gl_backend->v1,
-                                     (8 * sizeof(GLfloat)));
+                                     (12 * sizeof(GLfloat)));
     tex_coords = vigs_vector_append(&gl_backend->v2,
-                                    (8 * sizeof(GLfloat)));
+                                    (12 * sizeof(GLfloat)));
 
-    vert_coords[0] = 0;
-    vert_coords[1] = sfc_h;
+    vert_coords[6] = vert_coords[0] = 0;
+    vert_coords[7] = vert_coords[1] = sfc_h;
     vert_coords[2] = sfc_w;
     vert_coords[3] = sfc_h;
-    vert_coords[4] = sfc_w;
-    vert_coords[5] = 0;
-    vert_coords[6] = 0;
-    vert_coords[7] = 0;
+    vert_coords[8] = vert_coords[4] = sfc_w;
+    vert_coords[9] = vert_coords[5] = 0;
+    vert_coords[10] = 0;
+    vert_coords[11] = 0;
 
-    tex_coords[0] = 0;
-    tex_coords[1] = 0;
+    tex_coords[6] = tex_coords[0] = 0;
+    tex_coords[7] = tex_coords[1] = 0;
     tex_coords[2] = 1;
     tex_coords[3] = 0;
-    tex_coords[4] = 1;
-    tex_coords[5] = 1;
-    tex_coords[6] = 0;
-    tex_coords[7] = 1;
-
-    gl_backend->EnableClientState(GL_VERTEX_ARRAY);
-    gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
+    tex_coords[8] = tex_coords[4] = 1;
+    tex_coords[9] = tex_coords[5] = 1;
+    tex_coords[10] = 0;
+    tex_coords[11] = 1;
 
     gl_backend->BindTexture(GL_TEXTURE_2D, ws_sfc->tex);
 
-    gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
-    gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
-    gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
-    gl_backend->DrawArrays(GL_QUADS, 0, 4);
-
-    gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
-    gl_backend->DisableClientState(GL_VERTEX_ARRAY);
+    vigs_gl_draw_tex_prog(gl_backend, 6);
 
     gl_backend->PixelStorei(GL_PACK_ALIGNMENT, 1);
     gl_backend->ReadPixels(0, 0, sfc_w, sfc_h,
@@ -493,7 +662,9 @@ static void vigs_gl_surface_draw_pixels(struct vigs_surface *sfc,
         goto out;
     }
 
-    if (!vigs_gl_surface_create_framebuffer(gl_sfc)) {
+    if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+                                           gl_backend->tex_prog_id,
+                                           gl_backend->tex_prog_proj_loc)) {
         goto out;
     }
 
@@ -525,54 +696,35 @@ static void vigs_gl_surface_draw_pixels(struct vigs_surface *sfc,
     vigs_vector_resize(&gl_backend->v1, 0);
     vigs_vector_resize(&gl_backend->v2, 0);
 
-    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
-
-    vigs_gl_surface_setup_framebuffer(gl_sfc);
-
-    gl_backend->Enable(GL_TEXTURE_2D);
-
     gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                      GL_TEXTURE_2D, ws_sfc->tex, 0);
 
     for (i = 0; i < num_entries; ++i) {
         vert_coords = vigs_vector_append(&gl_backend->v1,
-                                         (8 * sizeof(GLfloat)));
+                                         (12 * sizeof(GLfloat)));
         tex_coords = vigs_vector_append(&gl_backend->v2,
-                                        (8 * sizeof(GLfloat)));
+                                        (12 * sizeof(GLfloat)));
 
-        vert_coords[0] = entries[i].pos.x;
-        vert_coords[1] = sfc_h - entries[i].pos.y;
+        vert_coords[6] = vert_coords[0] = entries[i].pos.x;
+        vert_coords[7] = vert_coords[1] = sfc_h - entries[i].pos.y;
         vert_coords[2] = entries[i].pos.x + entries[i].size.w;
         vert_coords[3] = sfc_h - entries[i].pos.y;
-        vert_coords[4] = entries[i].pos.x + entries[i].size.w;
-        vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
-        vert_coords[6] = entries[i].pos.x;
-        vert_coords[7] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+        vert_coords[8] = vert_coords[4] = entries[i].pos.x + entries[i].size.w;
+        vert_coords[9] = vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+        vert_coords[10] = entries[i].pos.x;
+        vert_coords[11] = sfc_h - (entries[i].pos.y + entries[i].size.h);
 
-        tex_coords[0] = (GLfloat)entries[i].pos.x / sfc_w;
-        tex_coords[1] = (GLfloat)entries[i].pos.y / sfc_h;
+        tex_coords[6] = tex_coords[0] = (GLfloat)entries[i].pos.x / sfc_w;
+        tex_coords[7] = tex_coords[1] = (GLfloat)entries[i].pos.y / sfc_h;
         tex_coords[2] = (GLfloat)(entries[i].pos.x + entries[i].size.w) / sfc_w;
         tex_coords[3] = (GLfloat)entries[i].pos.y / sfc_h;
-        tex_coords[4] = (GLfloat)(entries[i].pos.x + entries[i].size.w) / sfc_w;
-        tex_coords[5] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
-        tex_coords[6] = (GLfloat)entries[i].pos.x / sfc_w;
-        tex_coords[7] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
+        tex_coords[8] = tex_coords[4] = (GLfloat)(entries[i].pos.x + entries[i].size.w) / sfc_w;
+        tex_coords[9] = tex_coords[5] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
+        tex_coords[10] = (GLfloat)entries[i].pos.x / sfc_w;
+        tex_coords[11] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
     }
 
-    gl_backend->EnableClientState(GL_VERTEX_ARRAY);
-    gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-    gl_backend->BindTexture(GL_TEXTURE_2D, gl_sfc->tmp_tex);
-
-    gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
-    gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
-    gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
-    gl_backend->DrawArrays(GL_QUADS, 0, num_entries * 4);
-
-    gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
-    gl_backend->DisableClientState(GL_VERTEX_ARRAY);
+    vigs_gl_draw_tex_prog(gl_backend, num_entries * 6);
 
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -606,7 +758,9 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst,
         goto out;
     }
 
-    if (!vigs_gl_surface_create_framebuffer(gl_dst)) {
+    if (!vigs_gl_surface_setup_framebuffer(gl_dst,
+                                           gl_backend->tex_prog_id,
+                                           gl_backend->tex_prog_proj_loc)) {
         goto out;
     }
 
@@ -617,12 +771,6 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst,
     src_h = ws_src->base.base.height;
     dst_h = ws_dst->base.base.height;
 
-    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_dst->fb);
-
-    vigs_gl_surface_setup_framebuffer(gl_dst);
-
-    gl_backend->Enable(GL_TEXTURE_2D);
-
     if (src == dst) {
         /*
          * Feedback loop is possible, use 'tmp_tex' instead.
@@ -638,27 +786,27 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst,
         ++total_entries;
 
         vert_coords = vigs_vector_append(&gl_backend->v1,
-                                         (8 * sizeof(GLfloat)));
+                                         (12 * sizeof(GLfloat)));
         tex_coords = vigs_vector_append(&gl_backend->v2,
-                                        (8 * sizeof(GLfloat)));
+                                        (12 * sizeof(GLfloat)));
 
-        vert_coords[0] = 0;
-        vert_coords[1] = src_h;
+        vert_coords[6] = vert_coords[0] = 0;
+        vert_coords[7] = vert_coords[1] = src_h;
         vert_coords[2] = src_w;
         vert_coords[3] = src_h;
-        vert_coords[4] = src_w;
-        vert_coords[5] = 0;
-        vert_coords[6] = 0;
-        vert_coords[7] = 0;
+        vert_coords[8] = vert_coords[4] = src_w;
+        vert_coords[9] = vert_coords[5] = 0;
+        vert_coords[10] = 0;
+        vert_coords[11] = 0;
 
-        tex_coords[0] = 0;
-        tex_coords[1] = 1;
+        tex_coords[6] = tex_coords[0] = 0;
+        tex_coords[7] = tex_coords[1] = 1;
         tex_coords[2] = 1;
         tex_coords[3] = 1;
-        tex_coords[4] = 1;
-        tex_coords[5] = 0;
-        tex_coords[6] = 0;
-        tex_coords[7] = 0;
+        tex_coords[8] = tex_coords[4] = 1;
+        tex_coords[9] = tex_coords[5] = 0;
+        tex_coords[10] = 0;
+        tex_coords[11] = 0;
     } else {
         /*
          * No feedback loop possible, render to 'front_tex'.
@@ -666,89 +814,72 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst,
 
         gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                          GL_TEXTURE_2D, ws_dst->tex, 0);
-
     }
 
     for (i = 0; i < num_entries; ++i) {
         vert_coords = vigs_vector_append(&gl_backend->v1,
-                                         (8 * sizeof(GLfloat)));
+                                         (12 * sizeof(GLfloat)));
         tex_coords = vigs_vector_append(&gl_backend->v2,
-                                        (8 * sizeof(GLfloat)));
+                                        (12 * sizeof(GLfloat)));
 
-        vert_coords[0] = entries[i].to.x;
-        vert_coords[1] = dst_h - entries[i].to.y;
+        vert_coords[6] = vert_coords[0] = entries[i].to.x;
+        vert_coords[7] = vert_coords[1] = dst_h - entries[i].to.y;
         vert_coords[2] = entries[i].to.x + entries[i].size.w;
         vert_coords[3] = dst_h - entries[i].to.y;
-        vert_coords[4] = entries[i].to.x + entries[i].size.w;
-        vert_coords[5] = dst_h - (entries[i].to.y + entries[i].size.h);
-        vert_coords[6] = entries[i].to.x;
-        vert_coords[7] = dst_h - (entries[i].to.y + entries[i].size.h);
+        vert_coords[8] = vert_coords[4] = entries[i].to.x + entries[i].size.w;
+        vert_coords[9] = vert_coords[5] = dst_h - (entries[i].to.y + entries[i].size.h);
+        vert_coords[10] = entries[i].to.x;
+        vert_coords[11] = dst_h - (entries[i].to.y + entries[i].size.h);
 
-        tex_coords[0] = (GLfloat)entries[i].from.x / src_w;
-        tex_coords[1] = (GLfloat)(src_h - entries[i].from.y) / src_h;
+        tex_coords[6] = tex_coords[0] = (GLfloat)entries[i].from.x / src_w;
+        tex_coords[7] = tex_coords[1] = (GLfloat)(src_h - entries[i].from.y) / src_h;
         tex_coords[2] = (GLfloat)(entries[i].from.x + entries[i].size.w) / src_w;
         tex_coords[3] = (GLfloat)(src_h - entries[i].from.y) / src_h;
-        tex_coords[4] = (GLfloat)(entries[i].from.x + entries[i].size.w) / src_w;
-        tex_coords[5] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
-        tex_coords[6] = (GLfloat)entries[i].from.x / src_w;
-        tex_coords[7] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
+        tex_coords[8] = tex_coords[4] = (GLfloat)(entries[i].from.x + entries[i].size.w) / src_w;
+        tex_coords[9] = tex_coords[5] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
+        tex_coords[10] = (GLfloat)entries[i].from.x / src_w;
+        tex_coords[11] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
     }
 
-    gl_backend->EnableClientState(GL_VERTEX_ARRAY);
-    gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
     gl_backend->BindTexture(GL_TEXTURE_2D, ws_src->tex);
 
-    gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
-    gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
-    gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
-    gl_backend->DrawArrays(GL_QUADS, 0, total_entries * 4);
+    vigs_gl_draw_tex_prog(gl_backend, total_entries * 6);
 
     if (src == dst) {
         vigs_vector_resize(&gl_backend->v1, 0);
         vigs_vector_resize(&gl_backend->v2, 0);
 
         vert_coords = vigs_vector_append(&gl_backend->v1,
-                                         (8 * sizeof(GLfloat)));
+                                         (12 * sizeof(GLfloat)));
         tex_coords = vigs_vector_append(&gl_backend->v2,
-                                        (8 * sizeof(GLfloat)));
+                                        (12 * sizeof(GLfloat)));
 
-        vert_coords[0] = 0;
-        vert_coords[1] = src_h;
+        vert_coords[6] = vert_coords[0] = 0;
+        vert_coords[7] = vert_coords[1] = src_h;
         vert_coords[2] = src_w;
         vert_coords[3] = src_h;
-        vert_coords[4] = src_w;
-        vert_coords[5] = 0;
-        vert_coords[6] = 0;
-        vert_coords[7] = 0;
+        vert_coords[8] = vert_coords[4] = src_w;
+        vert_coords[9] = vert_coords[5] = 0;
+        vert_coords[10] = 0;
+        vert_coords[11] = 0;
 
-        tex_coords[0] = 0;
-        tex_coords[1] = 1;
+        tex_coords[6] = tex_coords[0] = 0;
+        tex_coords[7] = tex_coords[1] = 1;
         tex_coords[2] = 1;
         tex_coords[3] = 1;
-        tex_coords[4] = 1;
-        tex_coords[5] = 0;
-        tex_coords[6] = 0;
-        tex_coords[7] = 0;
+        tex_coords[8] = tex_coords[4] = 1;
+        tex_coords[9] = tex_coords[5] = 0;
+        tex_coords[10] = 0;
+        tex_coords[11] = 0;
 
         gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                          GL_TEXTURE_2D, ws_dst->tex, 0);
 
         gl_backend->BindTexture(GL_TEXTURE_2D, gl_dst->tmp_tex);
 
-        gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
-        gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
-        gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
-        gl_backend->DrawArrays(GL_QUADS, 0, 4);
+        vigs_gl_draw_tex_prog(gl_backend, 6);
     }
 
-    gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
-    gl_backend->DisableClientState(GL_VERTEX_ARRAY);
-
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
 }
@@ -762,25 +893,21 @@ static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc,
     struct vigs_gl_surface *gl_sfc = (struct vigs_gl_surface*)sfc;
     struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc);
     uint32_t i;
-    GLubyte red, green, blue, alpha;
+    GLfloat colorf[4];
     GLfloat sfc_h;
 
     if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->tex)) {
         goto out;
     }
 
-    if (!vigs_gl_surface_create_framebuffer(gl_sfc)) {
+    if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+                                           gl_backend->color_prog_id,
+                                           gl_backend->color_prog_proj_loc)) {
         goto out;
     }
 
     sfc_h = ws_sfc->base.base.height;
 
-    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
-
-    vigs_gl_surface_setup_framebuffer(gl_sfc);
-
-    gl_backend->Disable(GL_TEXTURE_2D);
-
     gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                      GL_TEXTURE_2D, ws_sfc->tex, 0);
 
@@ -788,34 +915,21 @@ static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc,
 
     for (i = 0; i < num_entries; ++i) {
         GLfloat *vert_coords = vigs_vector_append(&gl_backend->v1,
-                                                  (8 * sizeof(GLfloat)));
+                                                  (12 * sizeof(GLfloat)));
 
-        vert_coords[0] = entries[i].pos.x;
-        vert_coords[1] = sfc_h - entries[i].pos.y;
+        vert_coords[6] = vert_coords[0] = entries[i].pos.x;
+        vert_coords[7] = vert_coords[1] = sfc_h - entries[i].pos.y;
         vert_coords[2] = entries[i].pos.x + entries[i].size.w;
         vert_coords[3] = sfc_h - entries[i].pos.y;
-        vert_coords[4] = entries[i].pos.x + entries[i].size.w;
-        vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
-        vert_coords[6] = entries[i].pos.x;
-        vert_coords[7] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+        vert_coords[8] = vert_coords[4] = entries[i].pos.x + entries[i].size.w;
+        vert_coords[9] = vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+        vert_coords[10] = entries[i].pos.x;
+        vert_coords[11] = sfc_h - (entries[i].pos.y + entries[i].size.h);
     }
 
-    gl_backend->EnableClientState(GL_VERTEX_ARRAY);
-
-    vigs_gl_translate_color(color,
-                            sfc->format,
-                            &red,
-                            &green,
-                            &blue,
-                            &alpha);
-
-    gl_backend->Color4ub(red, green, blue, alpha);
+    vigs_gl_translate_color(color, sfc->format, colorf);
 
-    gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
-
-    gl_backend->DrawArrays(GL_QUADS, 0, num_entries * 4);
-
-    gl_backend->DisableClientState(GL_VERTEX_ARRAY);
+    vigs_gl_draw_color_prog(gl_backend, colorf, num_entries * 6);
 
 out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -895,6 +1009,9 @@ static struct vigs_surface *vigs_gl_backend_create_surface(struct vigs_backend *
                       format,
                       id);
 
+    vigs_gl_create_ortho(0.0f, width, 0.0f, height,
+                         -1.0f, 1.0f, gl_sfc->ortho);
+
     ws_sfc->base.base.release(&ws_sfc->base.base);
 
     gl_sfc->base.read_pixels = &vigs_gl_surface_read_pixels;
@@ -1010,7 +1127,9 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
         }
     }
 
-    if (!vigs_gl_surface_create_framebuffer(gl_root_sfc)) {
+    if (!vigs_gl_surface_setup_framebuffer(gl_root_sfc,
+                                           gl_backend->tex_prog_id,
+                                           gl_backend->tex_prog_proj_loc)) {
         goto out;
     }
 
@@ -1018,9 +1137,9 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
     vigs_vector_resize(&gl_backend->v2, 0);
 
     vert_coords = vigs_vector_append(&gl_backend->v1,
-                                     (8 * sizeof(GLfloat)));
+                                     (12 * sizeof(GLfloat)));
     tex_coords = vigs_vector_append(&gl_backend->v2,
-                                    (8 * sizeof(GLfloat)));
+                                    (12 * sizeof(GLfloat)));
 
     if (surface->ptr) {
         /*
@@ -1043,50 +1162,36 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
                                   surface->ptr);
     }
 
-    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_root_sfc->fb);
-
-    vigs_gl_surface_setup_framebuffer(gl_root_sfc);
-
-    gl_backend->Enable(GL_TEXTURE_2D);
-
     gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                      GL_TEXTURE_2D, gl_root_sfc->tmp_tex, 0);
 
-    gl_backend->EnableClientState(GL_VERTEX_ARRAY);
-    gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-    gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
     if (!surface->ptr) {
         /*
          * If root surface is not scanout then we must render
          * it.
          */
 
-        vert_coords[0] = 0;
-        vert_coords[1] = ws_root_sfc->base.base.height;
+        vert_coords[6] = vert_coords[0] = 0;
+        vert_coords[7] = vert_coords[1] = ws_root_sfc->base.base.height;
         vert_coords[2] = ws_root_sfc->base.base.width;
         vert_coords[3] = ws_root_sfc->base.base.height;
-        vert_coords[4] = ws_root_sfc->base.base.width;
-        vert_coords[5] = 0;
-        vert_coords[6] = 0;
-        vert_coords[7] = 0;
+        vert_coords[8] = vert_coords[4] = ws_root_sfc->base.base.width;
+        vert_coords[9] = vert_coords[5] = 0;
+        vert_coords[10] = 0;
+        vert_coords[11] = 0;
 
-        tex_coords[0] = 0;
-        tex_coords[1] = 0;
+        tex_coords[6] = tex_coords[0] = 0;
+        tex_coords[7] =tex_coords[1] = 0;
         tex_coords[2] = 1;
         tex_coords[3] = 0;
-        tex_coords[4] = 1;
-        tex_coords[5] = 1;
-        tex_coords[6] = 0;
-        tex_coords[7] = 1;
+        tex_coords[8] = tex_coords[4] = 1;
+        tex_coords[9] = tex_coords[5] = 1;
+        tex_coords[10] = 0;
+        tex_coords[11] = 1;
 
         gl_backend->BindTexture(GL_TEXTURE_2D, ws_root_sfc->tex);
 
-        gl_backend->VertexPointer(2, GL_FLOAT, 0, vert_coords);
-        gl_backend->TexCoordPointer(2, GL_FLOAT, 0, tex_coords);
-
-        gl_backend->DrawArrays(GL_QUADS, 0, 4);
+        vigs_gl_draw_tex_prog(gl_backend, 6);
     }
 
     /*
@@ -1123,35 +1228,29 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
         src_w = ws_sfc->base.base.width;
         src_h = ws_sfc->base.base.height;
 
-        vert_coords[0] = plane->dst_x;
-        vert_coords[1] = plane->dst_y;
+        vert_coords[6] = vert_coords[0] = plane->dst_x;
+        vert_coords[7] = vert_coords[1] = plane->dst_y;
         vert_coords[2] = plane->dst_x + (int)plane->dst_size.w;
         vert_coords[3] = plane->dst_y;
-        vert_coords[4] = plane->dst_x + (int)plane->dst_size.w;
-        vert_coords[5] = plane->dst_y + (int)plane->dst_size.h;
-        vert_coords[6] = plane->dst_x;
-        vert_coords[7] = plane->dst_y + (int)plane->dst_size.h;
+        vert_coords[8] = vert_coords[4] = plane->dst_x + (int)plane->dst_size.w;
+        vert_coords[9] = vert_coords[5] = plane->dst_y + (int)plane->dst_size.h;
+        vert_coords[10] = plane->dst_x;
+        vert_coords[11] = plane->dst_y + (int)plane->dst_size.h;
 
-        tex_coords[0] = (GLfloat)plane->src_rect.pos.x / src_w;
-        tex_coords[1] = (GLfloat)(src_h - plane->src_rect.pos.y) / src_h;
+        tex_coords[6] = tex_coords[0] = (GLfloat)plane->src_rect.pos.x / src_w;
+        tex_coords[7] = tex_coords[1] = (GLfloat)(src_h - plane->src_rect.pos.y) / src_h;
         tex_coords[2] = (GLfloat)(plane->src_rect.pos.x + plane->src_rect.size.w) / src_w;
         tex_coords[3] = (GLfloat)(src_h - plane->src_rect.pos.y) / src_h;
-        tex_coords[4] = (GLfloat)(plane->src_rect.pos.x + plane->src_rect.size.w) / src_w;
-        tex_coords[5] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
-        tex_coords[6] = (GLfloat)plane->src_rect.pos.x / src_w;
-        tex_coords[7] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
+        tex_coords[8] = tex_coords[4] = (GLfloat)(plane->src_rect.pos.x + plane->src_rect.size.w) / src_w;
+        tex_coords[9] = tex_coords[5] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
+        tex_coords[10] = (GLfloat)plane->src_rect.pos.x / src_w;
+        tex_coords[11] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
 
         gl_backend->BindTexture(GL_TEXTURE_2D, ws_sfc->tex);
 
-        gl_backend->VertexPointer(2, GL_FLOAT, 0, vert_coords);
-        gl_backend->TexCoordPointer(2, GL_FLOAT, 0, tex_coords);
-
-        gl_backend->DrawArrays(GL_QUADS, 0, 4);
+        vigs_gl_draw_tex_prog(gl_backend, 6);
     }
 
-    gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
-    gl_backend->DisableClientState(GL_VERTEX_ARRAY);
-
     /*
      * Now schedule asynchronous glReadPixels.
      */
@@ -1213,29 +1312,78 @@ static void vigs_gl_backend_batch_end(struct vigs_backend *backend)
 
 bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
 {
-    const char *extensions;
-
     if (!gl_backend->make_current(gl_backend, true)) {
         return false;
     }
 
-    extensions = (const char*)gl_backend->GetString(GL_EXTENSIONS);
+    gl_backend->tex_prog_vs_id = vigs_gl_create_shader(gl_backend,
+                                                       g_vs_tex_source,
+                                                       GL_VERTEX_SHADER);
 
-    if (!extensions) {
-        VIGS_LOG_CRITICAL("Unable to get extension string");
+    if (!gl_backend->tex_prog_vs_id) {
         goto fail;
     }
 
-    /*
-     * NPOT is needed in order to
-     * store custom sized surfaces as textures.
-     */
-    if ((strstr(extensions, "GL_OES_texture_npot ") == NULL) &&
-        (strstr(extensions, "GL_ARB_texture_non_power_of_two ") == NULL)) {
-        VIGS_LOG_CRITICAL("non power of 2 textures not supported");
+    gl_backend->tex_prog_fs_id = vigs_gl_create_shader(gl_backend,
+                                                       g_fs_tex_source,
+                                                       GL_FRAGMENT_SHADER);
+
+    if (!gl_backend->tex_prog_fs_id) {
+        goto fail;
+    }
+
+    gl_backend->tex_prog_id = vigs_gl_create_program(gl_backend,
+                                                     gl_backend->tex_prog_vs_id,
+                                                     gl_backend->tex_prog_fs_id);
+
+    if (!gl_backend->tex_prog_id) {
+        goto fail;
+    }
+
+    gl_backend->tex_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->tex_prog_id, "proj");
+    gl_backend->tex_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->tex_prog_id, "vertCoord");
+    gl_backend->tex_prog_texCoord_loc = gl_backend->GetAttribLocation(gl_backend->tex_prog_id, "texCoord");
+
+    gl_backend->color_prog_vs_id = vigs_gl_create_shader(gl_backend,
+                                                         g_vs_color_source,
+                                                         GL_VERTEX_SHADER);
+
+    if (!gl_backend->color_prog_vs_id) {
+        goto fail;
+    }
+
+    gl_backend->color_prog_fs_id = vigs_gl_create_shader(gl_backend,
+                                                         g_fs_color_source,
+                                                         GL_FRAGMENT_SHADER);
+
+    if (!gl_backend->color_prog_fs_id) {
         goto fail;
     }
 
+    gl_backend->color_prog_id = vigs_gl_create_program(gl_backend,
+                                                       gl_backend->color_prog_vs_id,
+                                                       gl_backend->color_prog_fs_id);
+
+    if (!gl_backend->color_prog_id) {
+        goto fail;
+    }
+
+    gl_backend->color_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->color_prog_id, "proj");
+    gl_backend->color_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->color_prog_id, "vertCoord");
+    gl_backend->color_prog_color_loc = gl_backend->GetUniformLocation(gl_backend->color_prog_id, "color");
+
+    gl_backend->GenBuffers(1, &gl_backend->vbo);
+
+    if (!gl_backend->vbo) {
+        VIGS_LOG_CRITICAL("cannot create VBO");
+        goto fail;
+    }
+
+    gl_backend->BindBuffer(GL_ARRAY_BUFFER, gl_backend->vbo);
+
+    gl_backend->UseProgram(gl_backend->tex_prog_id);
+    gl_backend->cur_prog_id = gl_backend->tex_prog_id;
+
     gl_backend->GenBuffers(1, &gl_backend->pbo);
 
     if (!gl_backend->pbo) {
@@ -1243,6 +1391,9 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
         goto fail;
     }
 
+    gl_backend->Disable(GL_DEPTH_TEST);
+    gl_backend->Disable(GL_BLEND);
+
     gl_backend->base.batch_start = &vigs_gl_backend_batch_start;
     gl_backend->base.create_surface = &vigs_gl_backend_create_surface;
     gl_backend->base.composite = &vigs_gl_backend_composite;
@@ -1269,6 +1420,21 @@ void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
 
     if (gl_backend->make_current(gl_backend, true)) {
         gl_backend->DeleteBuffers(1, &gl_backend->pbo);
+        gl_backend->DeleteBuffers(1, &gl_backend->vbo);
+        gl_backend->DetachShader(gl_backend->color_prog_id,
+                                 gl_backend->color_prog_vs_id);
+        gl_backend->DetachShader(gl_backend->color_prog_id,
+                                 gl_backend->color_prog_fs_id);
+        gl_backend->DeleteShader(gl_backend->color_prog_vs_id);
+        gl_backend->DeleteShader(gl_backend->color_prog_fs_id);
+        gl_backend->DeleteProgram(gl_backend->color_prog_id);
+        gl_backend->DetachShader(gl_backend->tex_prog_id,
+                                 gl_backend->tex_prog_vs_id);
+        gl_backend->DetachShader(gl_backend->tex_prog_id,
+                                 gl_backend->tex_prog_fs_id);
+        gl_backend->DeleteShader(gl_backend->tex_prog_vs_id);
+        gl_backend->DeleteShader(gl_backend->tex_prog_fs_id);
+        gl_backend->DeleteProgram(gl_backend->tex_prog_id);
 
         gl_backend->make_current(gl_backend, false);
     }
index 223aa02..8a5163b 100644 (file)
@@ -61,8 +61,6 @@ struct vigs_gl_backend
     void (GLAPIENTRY *GenTextures)(GLsizei n, GLuint *textures);
     void (GLAPIENTRY *DeleteTextures)(GLsizei n, const GLuint *textures);
     void (GLAPIENTRY *BindTexture)(GLenum target, GLuint texture);
-    void (GLAPIENTRY *Begin)(GLenum mode);
-    void (GLAPIENTRY *End)(void);
     void (GLAPIENTRY *CullFace)(GLenum mode);
     void (GLAPIENTRY *TexParameterf)(GLenum target, GLenum pname, GLfloat param);
     void (GLAPIENTRY *TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params);
@@ -70,10 +68,6 @@ struct vigs_gl_backend
     void (GLAPIENTRY *TexParameteriv)(GLenum target, GLenum pname, const GLint *params);
     void (GLAPIENTRY *TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
     void (GLAPIENTRY *TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
-    void (GLAPIENTRY *TexEnvf)(GLenum target, GLenum pname, GLfloat param);
-    void (GLAPIENTRY *TexEnvfv)(GLenum target, GLenum pname, const GLfloat *params);
-    void (GLAPIENTRY *TexEnvi)(GLenum target, GLenum pname, GLint param);
-    void (GLAPIENTRY *TexEnviv)(GLenum target, GLenum pname, const GLint *params);
     void (GLAPIENTRY *Clear)(GLbitfield mask);
     void (GLAPIENTRY *ClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
     void (GLAPIENTRY *Disable)(GLenum cap);
@@ -93,29 +87,35 @@ struct vigs_gl_backend
     void (GLAPIENTRY *FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
     void (GLAPIENTRY *FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
     void (GLAPIENTRY *GetIntegerv)(GLenum pname, GLint *params);
-    const GLubyte *(GLAPIENTRY *GetString)(GLenum name);
-    void (GLAPIENTRY *LoadIdentity)(void);
-    void (GLAPIENTRY *MatrixMode)(GLenum mode);
-    void (GLAPIENTRY *Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
-    void (GLAPIENTRY *EnableClientState)(GLenum array);
-    void (GLAPIENTRY *DisableClientState)(GLenum array);
-    void (GLAPIENTRY *Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-    void (GLAPIENTRY *TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
-    void (GLAPIENTRY *VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
     void (GLAPIENTRY *DrawArrays)(GLenum mode, GLint first, GLsizei count);
-    void (GLAPIENTRY *Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
-    void (GLAPIENTRY *WindowPos2f)(GLfloat x, GLfloat y);
-    void (GLAPIENTRY *PixelZoom)(GLfloat xfactor, GLfloat yfactor);
-    void (GLAPIENTRY *DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data);
-    void (GLAPIENTRY *BlendFunc)(GLenum sfactor, GLenum dfactor);
-    void (GLAPIENTRY *CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
-    void (GLAPIENTRY *BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
     void (GLAPIENTRY *GenBuffers)(GLsizei n, GLuint *buffers);
     void (GLAPIENTRY *DeleteBuffers)(GLsizei n, const GLuint *buffers);
     void (GLAPIENTRY *BindBuffer)(GLenum target, GLuint buffer);
     void (GLAPIENTRY *BufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+    void (GLAPIENTRY *BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
     GLvoid *(GLAPIENTRY *MapBuffer)(GLenum target, GLenum access);
     GLboolean (GLAPIENTRY *UnmapBuffer)(GLenum target);
+    GLuint (GLAPIENTRY* CreateProgram)(void);
+    GLuint (GLAPIENTRY* CreateShader)(GLenum type);
+    void (GLAPIENTRY* CompileShader)(GLuint shader);
+    void (GLAPIENTRY* AttachShader)(GLuint program, GLuint shader);
+    void (GLAPIENTRY* LinkProgram)(GLuint program);
+    void (GLAPIENTRY* GetProgramiv)(GLuint program, GLenum pname, GLint* params);
+    void (GLAPIENTRY* GetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+    void (GLAPIENTRY* GetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+    void (GLAPIENTRY* GetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+    void (GLAPIENTRY* DetachShader)(GLuint program, GLuint shader);
+    void (GLAPIENTRY* DeleteProgram)(GLuint program);
+    void (GLAPIENTRY* DeleteShader)(GLuint shader);
+    void (GLAPIENTRY* DisableVertexAttribArray)(GLuint index);
+    void (GLAPIENTRY* EnableVertexAttribArray)(GLuint index);
+    void (GLAPIENTRY* ShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
+    void (GLAPIENTRY* UseProgram)(GLuint program);
+    GLint (GLAPIENTRY* GetAttribLocation)(GLuint program, const GLchar* name);
+    GLint (GLAPIENTRY* GetUniformLocation)(GLuint program, const GLchar* name);
+    void (GLAPIENTRY* VertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
+    void (GLAPIENTRY* Uniform4fv)(GLint location, GLsizei count, const GLfloat* value);
+    void (GLAPIENTRY* UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
 
     /*
      * @}
@@ -134,9 +134,28 @@ struct vigs_gl_backend
      */
 
     /*
-     *
+     * Other.
      */
 
+    GLuint tex_prog_vs_id;
+    GLuint tex_prog_fs_id;
+    GLuint tex_prog_id;
+    GLint tex_prog_proj_loc;
+    GLint tex_prog_vertCoord_loc;
+    GLint tex_prog_texCoord_loc;
+
+    GLuint color_prog_vs_id;
+    GLuint color_prog_fs_id;
+    GLuint color_prog_id;
+    GLint color_prog_proj_loc;
+    GLint color_prog_vertCoord_loc;
+    GLint color_prog_color_loc;
+
+    GLuint vbo;
+    uint32_t vbo_size;
+
+    GLuint cur_prog_id;
+
     struct work_queue *read_pixels_queue;
 
     GLuint pbo;
index ba5c04a..9ee6c05 100644 (file)
@@ -238,8 +238,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(GenTextures, glGenTextures);
     VIGS_GL_GET_PROC(DeleteTextures, glDeleteTextures);
     VIGS_GL_GET_PROC(BindTexture, glBindTexture);
-    VIGS_GL_GET_PROC(Begin, glBegin);
-    VIGS_GL_GET_PROC(End, glEnd);
     VIGS_GL_GET_PROC(CullFace, glCullFace);
     VIGS_GL_GET_PROC(TexParameterf, glTexParameterf);
     VIGS_GL_GET_PROC(TexParameterfv, glTexParameterfv);
@@ -247,10 +245,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(TexParameteriv, glTexParameteriv);
     VIGS_GL_GET_PROC(TexImage2D, glTexImage2D);
     VIGS_GL_GET_PROC(TexSubImage2D, glTexSubImage2D);
-    VIGS_GL_GET_PROC(TexEnvf, glTexEnvf);
-    VIGS_GL_GET_PROC(TexEnvfv, glTexEnvfv);
-    VIGS_GL_GET_PROC(TexEnvi, glTexEnvi);
-    VIGS_GL_GET_PROC(TexEnviv, glTexEnviv);
     VIGS_GL_GET_PROC(Clear, glClear);
     VIGS_GL_GET_PROC(ClearColor, glClearColor);
     VIGS_GL_GET_PROC(Disable, glDisable);
@@ -270,29 +264,35 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(FramebufferRenderbuffer, glFramebufferRenderbufferEXT);
     VIGS_GL_GET_PROC(FramebufferTexture2D, glFramebufferTexture2DEXT);
     VIGS_GL_GET_PROC(GetIntegerv, glGetIntegerv);
-    VIGS_GL_GET_PROC(GetString, glGetString);
-    VIGS_GL_GET_PROC(LoadIdentity, glLoadIdentity);
-    VIGS_GL_GET_PROC(MatrixMode, glMatrixMode);
-    VIGS_GL_GET_PROC(Ortho, glOrtho);
-    VIGS_GL_GET_PROC(EnableClientState, glEnableClientState);
-    VIGS_GL_GET_PROC(DisableClientState, glDisableClientState);
-    VIGS_GL_GET_PROC(Color4f, glColor4f);
-    VIGS_GL_GET_PROC(TexCoordPointer, glTexCoordPointer);
-    VIGS_GL_GET_PROC(VertexPointer, glVertexPointer);
     VIGS_GL_GET_PROC(DrawArrays, glDrawArrays);
-    VIGS_GL_GET_PROC(Color4ub, glColor4ub);
-    VIGS_GL_GET_PROC(WindowPos2f, glWindowPos2f);
-    VIGS_GL_GET_PROC(PixelZoom, glPixelZoom);
-    VIGS_GL_GET_PROC(DrawPixels, glDrawPixels);
-    VIGS_GL_GET_PROC(BlendFunc, glBlendFunc);
-    VIGS_GL_GET_PROC(CopyTexImage2D, glCopyTexImage2D);
-    VIGS_GL_GET_PROC(BlitFramebuffer, glBlitFramebufferEXT);
     VIGS_GL_GET_PROC(GenBuffers, glGenBuffers);
     VIGS_GL_GET_PROC(DeleteBuffers, glDeleteBuffers);
     VIGS_GL_GET_PROC(BindBuffer, glBindBuffer);
     VIGS_GL_GET_PROC(BufferData, glBufferData);
+    VIGS_GL_GET_PROC(BufferSubData, glBufferSubData);
     VIGS_GL_GET_PROC(MapBuffer, glMapBuffer);
     VIGS_GL_GET_PROC(UnmapBuffer, glUnmapBuffer);
+    VIGS_GL_GET_PROC(CreateProgram, glCreateProgram);
+    VIGS_GL_GET_PROC(CreateShader, glCreateShader);
+    VIGS_GL_GET_PROC(CompileShader, glCompileShader);
+    VIGS_GL_GET_PROC(AttachShader, glAttachShader);
+    VIGS_GL_GET_PROC(LinkProgram, glLinkProgram);
+    VIGS_GL_GET_PROC(GetProgramiv, glGetProgramiv);
+    VIGS_GL_GET_PROC(GetProgramInfoLog, glGetProgramInfoLog);
+    VIGS_GL_GET_PROC(GetShaderiv, glGetShaderiv);
+    VIGS_GL_GET_PROC(GetShaderInfoLog, glGetShaderInfoLog);
+    VIGS_GL_GET_PROC(DetachShader, glDetachShader);
+    VIGS_GL_GET_PROC(DeleteProgram, glDeleteProgram);
+    VIGS_GL_GET_PROC(DeleteShader, glDeleteShader);
+    VIGS_GL_GET_PROC(DisableVertexAttribArray, glDisableVertexAttribArray);
+    VIGS_GL_GET_PROC(EnableVertexAttribArray, glEnableVertexAttribArray);
+    VIGS_GL_GET_PROC(ShaderSource, glShaderSource);
+    VIGS_GL_GET_PROC(UseProgram, glUseProgram);
+    VIGS_GL_GET_PROC(GetAttribLocation, glGetAttribLocation);
+    VIGS_GL_GET_PROC(GetUniformLocation, glGetUniformLocation);
+    VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
+    VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
+    VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
 
     config_id = vigs_gl_backend_agl_choose_config(gl_backend_agl);
 
index f3482b7..4e1e62d 100644 (file)
@@ -317,8 +317,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(GenTextures, glGenTextures);
     VIGS_GL_GET_PROC(DeleteTextures, glDeleteTextures);
     VIGS_GL_GET_PROC(BindTexture, glBindTexture);
-    VIGS_GL_GET_PROC(Begin, glBegin);
-    VIGS_GL_GET_PROC(End, glEnd);
     VIGS_GL_GET_PROC(CullFace, glCullFace);
     VIGS_GL_GET_PROC(TexParameterf, glTexParameterf);
     VIGS_GL_GET_PROC(TexParameterfv, glTexParameterfv);
@@ -326,10 +324,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(TexParameteriv, glTexParameteriv);
     VIGS_GL_GET_PROC(TexImage2D, glTexImage2D);
     VIGS_GL_GET_PROC(TexSubImage2D, glTexSubImage2D);
-    VIGS_GL_GET_PROC(TexEnvf, glTexEnvf);
-    VIGS_GL_GET_PROC(TexEnvfv, glTexEnvfv);
-    VIGS_GL_GET_PROC(TexEnvi, glTexEnvi);
-    VIGS_GL_GET_PROC(TexEnviv, glTexEnviv);
     VIGS_GL_GET_PROC(Clear, glClear);
     VIGS_GL_GET_PROC(ClearColor, glClearColor);
     VIGS_GL_GET_PROC(Disable, glDisable);
@@ -349,29 +343,35 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(FramebufferRenderbuffer, glFramebufferRenderbufferEXT);
     VIGS_GL_GET_PROC(FramebufferTexture2D, glFramebufferTexture2DEXT);
     VIGS_GL_GET_PROC(GetIntegerv, glGetIntegerv);
-    VIGS_GL_GET_PROC(GetString, glGetString);
-    VIGS_GL_GET_PROC(LoadIdentity, glLoadIdentity);
-    VIGS_GL_GET_PROC(MatrixMode, glMatrixMode);
-    VIGS_GL_GET_PROC(Ortho, glOrtho);
-    VIGS_GL_GET_PROC(EnableClientState, glEnableClientState);
-    VIGS_GL_GET_PROC(DisableClientState, glDisableClientState);
-    VIGS_GL_GET_PROC(Color4f, glColor4f);
-    VIGS_GL_GET_PROC(TexCoordPointer, glTexCoordPointer);
-    VIGS_GL_GET_PROC(VertexPointer, glVertexPointer);
     VIGS_GL_GET_PROC(DrawArrays, glDrawArrays);
-    VIGS_GL_GET_PROC(Color4ub, glColor4ub);
-    VIGS_GL_GET_PROC(WindowPos2f, glWindowPos2f);
-    VIGS_GL_GET_PROC(PixelZoom, glPixelZoom);
-    VIGS_GL_GET_PROC(DrawPixels, glDrawPixels);
-    VIGS_GL_GET_PROC(BlendFunc, glBlendFunc);
-    VIGS_GL_GET_PROC(CopyTexImage2D, glCopyTexImage2D);
-    VIGS_GL_GET_PROC(BlitFramebuffer, glBlitFramebufferEXT);
     VIGS_GL_GET_PROC(GenBuffers, glGenBuffers);
     VIGS_GL_GET_PROC(DeleteBuffers, glDeleteBuffers);
     VIGS_GL_GET_PROC(BindBuffer, glBindBuffer);
     VIGS_GL_GET_PROC(BufferData, glBufferData);
+    VIGS_GL_GET_PROC(BufferSubData, glBufferSubData);
     VIGS_GL_GET_PROC(MapBuffer, glMapBuffer);
     VIGS_GL_GET_PROC(UnmapBuffer, glUnmapBuffer);
+    VIGS_GL_GET_PROC(CreateProgram, glCreateProgram);
+    VIGS_GL_GET_PROC(CreateShader, glCreateShader);
+    VIGS_GL_GET_PROC(CompileShader, glCompileShader);
+    VIGS_GL_GET_PROC(AttachShader, glAttachShader);
+    VIGS_GL_GET_PROC(LinkProgram, glLinkProgram);
+    VIGS_GL_GET_PROC(GetProgramiv, glGetProgramiv);
+    VIGS_GL_GET_PROC(GetProgramInfoLog, glGetProgramInfoLog);
+    VIGS_GL_GET_PROC(GetShaderiv, glGetShaderiv);
+    VIGS_GL_GET_PROC(GetShaderInfoLog, glGetShaderInfoLog);
+    VIGS_GL_GET_PROC(DetachShader, glDetachShader);
+    VIGS_GL_GET_PROC(DeleteProgram, glDeleteProgram);
+    VIGS_GL_GET_PROC(DeleteShader, glDeleteShader);
+    VIGS_GL_GET_PROC(DisableVertexAttribArray, glDisableVertexAttribArray);
+    VIGS_GL_GET_PROC(EnableVertexAttribArray, glEnableVertexAttribArray);
+    VIGS_GL_GET_PROC(ShaderSource, glShaderSource);
+    VIGS_GL_GET_PROC(UseProgram, glUseProgram);
+    VIGS_GL_GET_PROC(GetAttribLocation, glGetAttribLocation);
+    VIGS_GL_GET_PROC(GetUniformLocation, glGetUniformLocation);
+    VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
+    VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
+    VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
 
     gl_backend_glx->dpy = x_display;
 
index 101c376..3762696 100644 (file)
@@ -421,8 +421,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(GenTextures, glGenTextures);
     VIGS_GL_GET_PROC(DeleteTextures, glDeleteTextures);
     VIGS_GL_GET_PROC(BindTexture, glBindTexture);
-    VIGS_GL_GET_PROC(Begin, glBegin);
-    VIGS_GL_GET_PROC(End, glEnd);
     VIGS_GL_GET_PROC(CullFace, glCullFace);
     VIGS_GL_GET_PROC(TexParameterf, glTexParameterf);
     VIGS_GL_GET_PROC(TexParameterfv, glTexParameterfv);
@@ -430,10 +428,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(TexParameteriv, glTexParameteriv);
     VIGS_GL_GET_PROC(TexImage2D, glTexImage2D);
     VIGS_GL_GET_PROC(TexSubImage2D, glTexSubImage2D);
-    VIGS_GL_GET_PROC(TexEnvf, glTexEnvf);
-    VIGS_GL_GET_PROC(TexEnvfv, glTexEnvfv);
-    VIGS_GL_GET_PROC(TexEnvi, glTexEnvi);
-    VIGS_GL_GET_PROC(TexEnviv, glTexEnviv);
     VIGS_GL_GET_PROC(Clear, glClear);
     VIGS_GL_GET_PROC(ClearColor, glClearColor);
     VIGS_GL_GET_PROC(Disable, glDisable);
@@ -453,29 +447,35 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(FramebufferRenderbuffer, glFramebufferRenderbufferEXT);
     VIGS_GL_GET_PROC(FramebufferTexture2D, glFramebufferTexture2DEXT);
     VIGS_GL_GET_PROC(GetIntegerv, glGetIntegerv);
-    VIGS_GL_GET_PROC(GetString, glGetString);
-    VIGS_GL_GET_PROC(LoadIdentity, glLoadIdentity);
-    VIGS_GL_GET_PROC(MatrixMode, glMatrixMode);
-    VIGS_GL_GET_PROC(Ortho, glOrtho);
-    VIGS_GL_GET_PROC(EnableClientState, glEnableClientState);
-    VIGS_GL_GET_PROC(DisableClientState, glDisableClientState);
-    VIGS_GL_GET_PROC(Color4f, glColor4f);
-    VIGS_GL_GET_PROC(TexCoordPointer, glTexCoordPointer);
-    VIGS_GL_GET_PROC(VertexPointer, glVertexPointer);
     VIGS_GL_GET_PROC(DrawArrays, glDrawArrays);
-    VIGS_GL_GET_PROC(Color4ub, glColor4ub);
-    VIGS_GL_GET_PROC(WindowPos2f, glWindowPos2f);
-    VIGS_GL_GET_PROC(PixelZoom, glPixelZoom);
-    VIGS_GL_GET_PROC(DrawPixels, glDrawPixels);
-    VIGS_GL_GET_PROC(BlendFunc, glBlendFunc);
-    VIGS_GL_GET_PROC(CopyTexImage2D, glCopyTexImage2D);
-    VIGS_GL_GET_PROC(BlitFramebuffer, glBlitFramebufferEXT);
     VIGS_GL_GET_PROC(GenBuffers, glGenBuffers);
     VIGS_GL_GET_PROC(DeleteBuffers, glDeleteBuffers);
     VIGS_GL_GET_PROC(BindBuffer, glBindBuffer);
     VIGS_GL_GET_PROC(BufferData, glBufferData);
+    VIGS_GL_GET_PROC(BufferSubData, glBufferSubData);
     VIGS_GL_GET_PROC(MapBuffer, glMapBuffer);
     VIGS_GL_GET_PROC(UnmapBuffer, glUnmapBuffer);
+    VIGS_GL_GET_PROC(CreateProgram, glCreateProgram);
+    VIGS_GL_GET_PROC(CreateShader, glCreateShader);
+    VIGS_GL_GET_PROC(CompileShader, glCompileShader);
+    VIGS_GL_GET_PROC(AttachShader, glAttachShader);
+    VIGS_GL_GET_PROC(LinkProgram, glLinkProgram);
+    VIGS_GL_GET_PROC(GetProgramiv, glGetProgramiv);
+    VIGS_GL_GET_PROC(GetProgramInfoLog, glGetProgramInfoLog);
+    VIGS_GL_GET_PROC(GetShaderiv, glGetShaderiv);
+    VIGS_GL_GET_PROC(GetShaderInfoLog, glGetShaderInfoLog);
+    VIGS_GL_GET_PROC(DetachShader, glDetachShader);
+    VIGS_GL_GET_PROC(DeleteProgram, glDeleteProgram);
+    VIGS_GL_GET_PROC(DeleteShader, glDeleteShader);
+    VIGS_GL_GET_PROC(DisableVertexAttribArray, glDisableVertexAttribArray);
+    VIGS_GL_GET_PROC(EnableVertexAttribArray, glEnableVertexAttribArray);
+    VIGS_GL_GET_PROC(ShaderSource, glShaderSource);
+    VIGS_GL_GET_PROC(UseProgram, glUseProgram);
+    VIGS_GL_GET_PROC(GetAttribLocation, glGetAttribLocation);
+    VIGS_GL_GET_PROC(GetUniformLocation, glGetUniformLocation);
+    VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
+    VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
+    VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
 
     gl_backend_wgl->wglMakeCurrent(NULL, NULL);
     gl_backend_wgl->wglDeleteContext(tmp_ctx);