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 <dh.herrmann@googlemail.com>
This commit is contained in:
parent
84f29458e5
commit
83cec439c6
@ -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
|
||||
|
@ -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 <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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user