From 83cec439c6541c908512f42755cd6dc218181bd8 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 20 Jan 2012 15:45:58 +0100 Subject: [PATCH] console: use new drawing pipeline 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 --- Makefile.am | 7 +----- src/console.c | 49 +++++++++----------------------------- src/output.h | 6 +++++ src/output_context.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_console.c | 9 +++---- 5 files changed, 87 insertions(+), 50 deletions(-) diff --git a/Makefile.am b/Makefile.am index ef94165..cdbb914 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/src/console.c b/src/console.c index cc63d57..9fdad47 100644 --- a/src/console.c +++ b/src/console.c @@ -31,20 +31,12 @@ * 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 #include #include #include #include -#include -#include #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) diff --git a/src/output.h b/src/output.h index b6b016b..136a042 100644 --- a/src/output.h +++ b/src/output.h @@ -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 */ diff --git a/src/output_context.c b/src/output_context.c index d7df5af..82aaece 100644 --- a/src/output_context.c +++ b/src/output_context.c @@ -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) { diff --git a/tests/test_console.c b/tests/test_console.c index 2221214..d243644 100644 --- a/tests/test_console.c +++ b/tests/test_console.c @@ -40,7 +40,6 @@ */ #define _BSD_SOURCE -#define GL_GLEXT_PROTOTYPES #include #include @@ -51,8 +50,6 @@ #include #include -#include -#include #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); -- 2.7.4