console: use new drawing pipeline
authorDavid Herrmann <dh.herrmann@googlemail.com>
Fri, 20 Jan 2012 14:45:58 +0000 (15:45 +0100)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Fri, 20 Jan 2012 14:45:58 +0000 (15:45 +0100)
Instead of drawing with fixed-function GL pipeline we now use our own
shader for texture drawing. This also fixes test_console to no longer
depend on GL.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Makefile.am
src/console.c
src/output.h
src/output_context.c
tests/test_console.c

index ef94165..cdbb914 100644 (file)
@@ -85,12 +85,7 @@ kmscon_SOURCES = src/main.c
 kmscon_LDADD = libkmscon-core.la
 
 test_console_SOURCES = tests/test_console.c
-test_console_LDADD = \
-       libkmscon-core.la \
-       $(OPENGL_LIBS)
-test_console_CPPFLAGS = \
-       $(AM_CPPFLAGS) \
-       $(OPENGL_CFLAGS)
+test_console_LDADD = libkmscon-core.la
 
 test_output_SOURCES = tests/test_output.c
 test_output_LDADD = libkmscon-core.la
index cc63d57..9fdad47 100644 (file)
  * to a framebuffer as used by terminals and consoles.
  */
 
-/*
- * TODO: Avoid using this hack and instead retrieve GL extension
- * pointers dynamically on initialization.
- */
-#define GL_GLEXT_PROTOTYPES
-
 #include <errno.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <cairo.h>
-#include <GL/gl.h>
-#include <GL/glext.h>
 
 #include "console.h"
 #include "font.h"
@@ -56,9 +48,10 @@ struct kmscon_console {
        size_t ref;
        struct kmscon_font_factory *ff;
        struct kmscon_compositor *comp;
+       struct kmscon_context *ctx;
 
        /* GL texture and font */
-       GLuint tex;
+       unsigned int tex;
        unsigned int res_x;
        unsigned int res_y;
        struct kmscon_font *font;
@@ -81,7 +74,7 @@ struct kmscon_console {
 static void kmscon_console_free_res(struct kmscon_console *con)
 {
        if (con && con->cr) {
-               glDeleteTextures(1, &con->tex);
+               kmscon_context_free_tex(con->ctx, con->tex);
                cairo_destroy(con->cr);
                cairo_surface_destroy(con->surf);
                free(con->surf_buf);
@@ -128,11 +121,7 @@ static int kmscon_console_new_res(struct kmscon_console *con)
        con->surf = surface;
        con->cr = cr;
 
-       glGenTextures(1, &con->tex);
-       glBindTexture(GL_TEXTURE_RECTANGLE, con->tex);
-       glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, con->res_x, con->res_y,
-                               0, GL_BGRA, GL_UNSIGNED_BYTE, con->surf_buf);
-       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+       con->tex = kmscon_context_new_tex(con->ctx);
 
        log_debug("console: new resolution %ux%u\n", con->res_x, con->res_y);
        return 0;
@@ -162,6 +151,7 @@ int kmscon_console_new(struct kmscon_console **out,
        con->ref = 1;
        con->ff = ff;
        con->comp = comp;
+       con->ctx = kmscon_compositor_get_context(comp);
        log_debug("console: new console\n");
 
        ret = kmscon_buffer_new(&con->cells, 0, 0);
@@ -328,9 +318,8 @@ void kmscon_console_draw(struct kmscon_console *con)
        cairo_restore(con->cr);
 
        /* refresh GL texture contents */
-       glBindTexture(GL_TEXTURE_RECTANGLE, con->tex);
-       glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, con->res_x, con->res_y,
-                               0, GL_BGRA, GL_UNSIGNED_BYTE, con->surf_buf);
+       kmscon_context_set_tex(con->ctx, con->tex, con->res_x, con->res_y,
+                                                       con->surf_buf);
 }
 
 /*
@@ -345,29 +334,13 @@ void kmscon_console_draw(struct kmscon_console *con)
  */
 void kmscon_console_map(struct kmscon_console *con)
 {
+       static const float vertices[] = { -1, -1, 1, -1, 1, 1, -1, 1 };
+       static const float texpos[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+
        if (!con || !con->cr)
                return;
 
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glEnable(GL_TEXTURE_RECTANGLE);
-       glBindTexture(GL_TEXTURE_RECTANGLE, con->tex);
-
-       glBegin(GL_QUADS);
-               glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
-
-               glTexCoord2f(0.0f, 0.0f);
-               glVertex2f(-1.0f, -1.0f);
-
-               glTexCoord2f(con->res_x, 0.0f);
-               glVertex2f(1.0f, -1.0f);
-
-               glTexCoord2f(con->res_x, con->res_y);
-               glVertex2f(1.0f, 1.0f);
-
-               glTexCoord2f(0.0f, con->res_y);
-               glVertex2f(-1.0f, 1.0f);
-       glEnd();
+       kmscon_context_draw_tex(con->ctx, vertices, texpos, 4, con->tex);
 }
 
 void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch)
index b6b016b..136a042 100644 (file)
@@ -121,6 +121,12 @@ void kmscon_context_viewport(struct kmscon_context *ctx,
 void kmscon_context_clear(struct kmscon_context *ctx);
 void kmscon_context_draw_def(struct kmscon_context *ctx, float *vertices,
                                                float *colors, size_t num);
+void kmscon_context_draw_tex(struct kmscon_context *ctx, const float *vertices,
+               const float *texcoords, size_t num, unsigned int tex);
+unsigned int kmscon_context_new_tex(struct kmscon_context *ctx);
+void kmscon_context_free_tex(struct kmscon_context *ctx, unsigned int tex);
+void kmscon_context_set_tex(struct kmscon_context *ctx, unsigned int tex,
+                       unsigned int width, unsigned int height, void *buf);
 
 /* compositors */
 
index d7df5af..82aaece 100644 (file)
@@ -86,6 +86,7 @@ typedef GLint (*PFNGLGETUNIFORMLOCATIONPROC)
                                        (GLuint program, const GLchar *name);
 typedef void (*PFNGLUNIFORMMATRIX4FVPROC) (GLint location,
                GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (*PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
 typedef void (*PFNGLVERTEXATTRIBPOINTERPROC)
                (GLuint index, GLint size, GLenum type, GLboolean normalized,
                                        GLsizei stride, const GLvoid *pointer);
@@ -139,6 +140,7 @@ struct kmscon_context {
        PFNGLGETPROGRAMINFOLOGPROC proc_get_program_info_log;
        PFNGLGETUNIFORMLOCATIONPROC proc_get_uniform_location;
        PFNGLUNIFORMMATRIX4FVPROC proc_uniform_matrix_4fv;
+       PFNGLUNIFORM1IPROC proc_uniform_1i;
        PFNGLVERTEXATTRIBPOINTERPROC proc_vertex_attrib_pointer;
        PFNGLENABLEVERTEXATTRIBARRAYPROC proc_enable_vertex_attrib_array;
        PFNGLDRAWARRAYSEXTPROC proc_draw_arrays;
@@ -423,6 +425,8 @@ int kmscon_context_new(struct kmscon_context **out, void *gbm)
                (void*) eglGetProcAddress("glGetUniformLocation");
        ctx->proc_uniform_matrix_4fv =
                (void*) eglGetProcAddress("glUniformMatrix4fv");
+       ctx->proc_uniform_1i =
+               (void*) eglGetProcAddress("glUniform1i");
        ctx->proc_vertex_attrib_pointer =
                (void*) eglGetProcAddress("glVertexAttribPointer");
        ctx->proc_enable_vertex_attrib_array =
@@ -462,6 +466,7 @@ int kmscon_context_new(struct kmscon_context **out, void *gbm)
                        !ctx->proc_get_program_info_log ||
                        !ctx->proc_get_uniform_location ||
                        !ctx->proc_uniform_matrix_4fv ||
+                       !ctx->proc_uniform_1i ||
                        !ctx->proc_vertex_attrib_pointer ||
                        !ctx->proc_enable_vertex_attrib_array ||
                        !ctx->proc_draw_arrays) {
@@ -612,6 +617,67 @@ void kmscon_context_draw_def(struct kmscon_context *ctx, float *vertices,
        ctx->proc_draw_arrays(GL_QUADS, 0, num);
 }
 
+void kmscon_context_draw_tex(struct kmscon_context *ctx, const float *vertices,
+                       const float *texcoords, size_t num, unsigned int tex)
+{
+       static const float m[16] = { 1, 0, 0, 0,
+                                       0, 1, 0, 0,
+                                       0, 0, 1, 0,
+                                       0, 0, 0, 1 };
+
+       if (!ctx)
+               return;
+
+       glActiveTexture(GL_TEXTURE0);
+       glBindTexture(GL_TEXTURE_2D, tex);
+
+       ctx->proc_use_program(ctx->tex_program);
+       ctx->proc_uniform_matrix_4fv(ctx->tex_uni_projection, 1, GL_FALSE, m);
+       ctx->proc_uniform_1i(ctx->tex_uni_texture, 0);
+
+       ctx->proc_vertex_attrib_pointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+       ctx->proc_vertex_attrib_pointer(1, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
+       ctx->proc_enable_vertex_attrib_array(0);
+       ctx->proc_enable_vertex_attrib_array(1);
+       ctx->proc_draw_arrays(GL_QUADS, 0, num);
+}
+
+unsigned int kmscon_context_new_tex(struct kmscon_context *ctx)
+{
+       GLuint tex = 0;
+
+       if (!ctx)
+               return tex;
+
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+       return tex;
+}
+
+void kmscon_context_free_tex(struct kmscon_context *ctx, unsigned int tex)
+{
+       if (!ctx)
+               return;
+
+       glDeleteTextures(1, &tex);
+}
+
+void kmscon_context_set_tex(struct kmscon_context *ctx, unsigned int tex,
+                       unsigned int width, unsigned int height, void *buf)
+{
+       if (!ctx || !buf || !width || !height)
+               return;
+
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA,
+                                               GL_UNSIGNED_BYTE, buf);
+}
+
 int renderbuffer_new(struct renderbuffer **out, struct kmscon_context *ctx,
                                                                void *bo)
 {
index 2221214..d243644 100644 (file)
@@ -40,7 +40,6 @@
  */
 
 #define _BSD_SOURCE
-#define GL_GLEXT_PROTOTYPES
 
 #include <errno.h>
 #include <inttypes.h>
@@ -51,8 +50,6 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <GL/gl.h>
-#include <GL/glext.h>
 #include "console.h"
 #include "eloop.h"
 #include "font.h"
@@ -116,11 +113,13 @@ static void map_outputs(struct console *con)
 {
        int ret;
        struct kmscon_output *iter;
+       struct kmscon_context *ctx;
 
        if (kmscon_compositor_is_asleep(con->comp))
                return;
 
        kmscon_console_draw(con->con);
+       ctx = kmscon_compositor_get_context(con->comp);
 
        iter = kmscon_compositor_get_outputs(con->comp);
        for ( ; iter; iter = kmscon_output_next(iter)) {
@@ -131,9 +130,7 @@ static void map_outputs(struct console *con)
                if (ret)
                        continue;
 
-               glClearColor(0.0, 0.0, 0.0, 1.0);
-               glClear(GL_COLOR_BUFFER_BIT);
-
+               kmscon_context_clear(ctx);
                kmscon_console_map(con->con);
 
                ret = kmscon_output_swap(iter);