mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 18:32:44 +00:00
Make font rendering more robust.
Dynamically sized buffers, etc.
This commit is contained in:
parent
614b866f57
commit
d129ff3d13
2
Makefile
2
Makefile
@ -394,7 +394,7 @@ else
|
||||
ifneq ($(findstring icc,$(CC)),)
|
||||
CFLAGS += -std=c99 -D_GNU_SOURCE
|
||||
else
|
||||
CFLAGS += -std=gnu99
|
||||
CFLAGS += -std=gnu99 -D_GNU_SOURCE
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
|
@ -98,39 +98,28 @@ void gl_free_font(void *data)
|
||||
#define emit(c, vx, vy) do { \
|
||||
font_vertex[ 2 * (6 * i + c) + 0] = (x + (delta_x + off_x + vx * width) * scale) * inv_win_width; \
|
||||
font_vertex[ 2 * (6 * i + c) + 1] = (y + (delta_y - off_y - vy * height) * scale) * inv_win_height; \
|
||||
font_vertex_dark[2 * (6 * i + c) + 0] = (x + (delta_x + off_x - 2 + vx * width) * scale) * inv_win_width; \
|
||||
font_vertex_dark[2 * (6 * i + c) + 1] = (y + (delta_y - off_y - 2 - vy * height) * scale) * inv_win_height; \
|
||||
font_tex_coords[ 2 * (6 * i + c) + 0] = (tex_x + vx * width) * inv_tex_size_x; \
|
||||
font_tex_coords[ 2 * (6 * i + c) + 1] = (tex_y + vy * height) * inv_tex_size_y; \
|
||||
font_color_dark[ 4 * (6 * i + c) + 0] = 0.3f * color[0]; \
|
||||
font_color_dark[ 4 * (6 * i + c) + 1] = 0.3f * color[1]; \
|
||||
font_color_dark[ 4 * (6 * i + c) + 2] = 0.3f * color[2]; \
|
||||
font_color_dark[ 4 * (6 * i + c) + 3] = color[3]; \
|
||||
font_color[ 4 * (6 * i + c) + 0] = color[0]; \
|
||||
font_color[ 4 * (6 * i + c) + 1] = color[1]; \
|
||||
font_color[ 4 * (6 * i + c) + 2] = color[2]; \
|
||||
font_color[ 4 * (6 * i + c) + 3] = color[3]; \
|
||||
} while(0)
|
||||
|
||||
static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, const GLfloat color[4], GLfloat pos_x, GLfloat pos_y, bool full_screen)
|
||||
static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, const GLfloat color[4], GLfloat pos_x, GLfloat pos_y)
|
||||
{
|
||||
unsigned i;
|
||||
gl_t *gl = font->gl;
|
||||
|
||||
// Rebind shaders so attrib cache gets reset.
|
||||
if (gl->shader && gl->shader->use)
|
||||
gl->shader->use(gl, GL_SHADER_STOCK_BLEND);
|
||||
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, full_screen, false);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBindTexture(GL_TEXTURE_2D, font->tex);
|
||||
|
||||
#define MAX_MSG_LEN_CHUNK 32
|
||||
#define MAX_MSG_LEN_CHUNK 64
|
||||
GLfloat font_tex_coords[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_vertex[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_vertex_dark[2 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_color[4 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
GLfloat font_color_dark[4 * 6 * MAX_MSG_LEN_CHUNK];
|
||||
|
||||
unsigned msg_len_full = strlen(msg);
|
||||
unsigned msg_len = min(msg_len_full, MAX_MSG_LEN_CHUNK);
|
||||
@ -175,14 +164,6 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, co
|
||||
delta_y -= gly->advance_y;
|
||||
}
|
||||
|
||||
// TODO: Make drop shadows parameterized?
|
||||
gl->coords.tex_coord = font_tex_coords;
|
||||
gl->coords.vertex = font_vertex_dark;
|
||||
gl->coords.color = font_color_dark;
|
||||
gl->coords.vertices = 6 * msg_len;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp_no_rot);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6 * msg_len);
|
||||
|
||||
gl->coords.tex_coord = font_tex_coords;
|
||||
gl->coords.vertex = font_vertex;
|
||||
gl->coords.color = font_color;
|
||||
@ -201,21 +182,20 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, co
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
gl->coords.vertices = 4;
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);
|
||||
}
|
||||
|
||||
static void gl_render_msg(void *data, const char *msg, const struct font_params *params)
|
||||
{
|
||||
GLfloat x, y, scale;
|
||||
GLfloat color[4];
|
||||
GLfloat color[4], color_dark[4];
|
||||
bool full_screen;
|
||||
|
||||
gl_raster_t *font = (gl_raster_t*)data;
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
gl_t *gl = font->gl;
|
||||
|
||||
if (params)
|
||||
{
|
||||
x = params->x;
|
||||
@ -245,7 +225,23 @@ static void gl_render_msg(void *data, const char *msg, const struct font_params
|
||||
color[3] = 1.0f;
|
||||
}
|
||||
|
||||
render_message(font, msg, scale, color, x, y, full_screen);
|
||||
color_dark[0] = color[0] * 0.3f;
|
||||
color_dark[1] = color[1] * 0.3f;
|
||||
color_dark[2] = color[2] * 0.3f;
|
||||
color_dark[3] = color[3];
|
||||
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, full_screen, false);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
// TODO: Make drop shadows parameterized?
|
||||
render_message(font, msg, scale, color_dark,
|
||||
x - scale * 2.0f / gl->vp.width, y - scale * 2.0f / gl->vp.height);
|
||||
render_message(font, msg, scale, color, x, y);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);
|
||||
}
|
||||
|
||||
const gl_font_renderer_t gl_raster_font = {
|
||||
|
5
gfx/gl.c
5
gfx/gl.c
@ -1037,6 +1037,7 @@ static void gl_frame_fbo(void *data, const struct gl_tex_info *tex_info)
|
||||
gl->vp.width, gl->vp.height, g_extern.frame_count,
|
||||
tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt);
|
||||
|
||||
gl->coords.vertices = 4;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
@ -1086,6 +1087,7 @@ static void gl_frame_fbo(void *data, const struct gl_tex_info *tex_info)
|
||||
|
||||
gl->coords.vertex = gl->vertex_ptr;
|
||||
|
||||
gl->coords.vertices = 4;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
@ -1474,6 +1476,7 @@ static inline void gl_draw_texture(void *data)
|
||||
|
||||
if (gl->shader)
|
||||
gl->shader->use(gl, GL_SHADER_STOCK_BLEND);
|
||||
gl->coords.vertices = 4;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp_no_rot);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
@ -1612,6 +1615,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
g_extern.frame_count,
|
||||
&tex_info, gl->prev_info, NULL, 0);
|
||||
|
||||
gl->coords.vertices = 4;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
@ -2796,6 +2800,7 @@ static void gl_render_overlay(void *data)
|
||||
gl->coords.vertex = gl->overlay[i].vertex_coord;
|
||||
gl->coords.tex_coord = gl->overlay[i].tex_coord;
|
||||
gl->coords.color = white_color_mod;
|
||||
gl->coords.vertices = 4;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp_no_rot);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
@ -64,11 +64,11 @@ static char glsl_alias_define[1024];
|
||||
struct cache_vbo
|
||||
{
|
||||
GLuint vbo_primary;
|
||||
GLfloat buffer_primary[128];
|
||||
GLfloat *buffer_primary;
|
||||
size_t size_primary;
|
||||
|
||||
GLuint vbo_secondary;
|
||||
GLfloat buffer_secondary[128];
|
||||
GLfloat *buffer_secondary;
|
||||
size_t size_secondary;
|
||||
};
|
||||
static struct cache_vbo glsl_vbo[GFX_MAX_SHADERS];
|
||||
@ -467,18 +467,24 @@ static void gl_glsl_reset_attrib(void)
|
||||
gl_attrib_index = 0;
|
||||
}
|
||||
|
||||
static void gl_glsl_set_vbo(GLfloat *buffer, size_t *buffer_elems, const GLfloat *data, size_t elems)
|
||||
static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems, const GLfloat *data, size_t elems)
|
||||
{
|
||||
if (elems != *buffer_elems || memcmp(data, buffer, elems * sizeof(GLfloat)))
|
||||
if (elems != *buffer_elems || memcmp(data, *buffer, elems * sizeof(GLfloat)))
|
||||
{
|
||||
//RARCH_LOG("[GL]: VBO updated with %u elems.\n", (unsigned)elems);
|
||||
memcpy(buffer, data, elems * sizeof(GLfloat));
|
||||
if (elems > *buffer_elems)
|
||||
{
|
||||
GLfloat *new_buffer = (GLfloat*)realloc(*buffer, elems * sizeof(GLfloat));
|
||||
rarch_assert(new_buffer);
|
||||
*buffer = new_buffer;
|
||||
}
|
||||
|
||||
memcpy(*buffer, data, elems * sizeof(GLfloat));
|
||||
glBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat), data, GL_STATIC_DRAW);
|
||||
*buffer_elems = elems;
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_glsl_set_attribs(GLuint vbo, GLfloat *buffer, size_t *buffer_elems,
|
||||
static void gl_glsl_set_attribs(GLuint vbo, GLfloat **buffer, size_t *buffer_elems,
|
||||
const GLfloat *data, size_t elems, const struct glsl_attrib *attrs, size_t num_attrs)
|
||||
{
|
||||
size_t i;
|
||||
@ -639,6 +645,9 @@ static void gl_glsl_deinit(void)
|
||||
glDeleteBuffers(1, &glsl_vbo[i].vbo_primary);
|
||||
if (glsl_vbo[i].vbo_secondary)
|
||||
glDeleteBuffers(1, &glsl_vbo[i].vbo_secondary);
|
||||
|
||||
free(glsl_vbo[i].buffer_primary);
|
||||
free(glsl_vbo[i].buffer_secondary);
|
||||
}
|
||||
memset(&glsl_vbo, 0, sizeof(glsl_vbo));
|
||||
}
|
||||
@ -843,7 +852,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
if (!glsl_enable || (gl_program[active_index] == 0))
|
||||
return;
|
||||
|
||||
GLfloat buffer[128];
|
||||
GLfloat buffer[512];
|
||||
unsigned i;
|
||||
size_t size = 0;
|
||||
struct glsl_attrib attribs[32];
|
||||
@ -986,7 +995,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
if (size)
|
||||
{
|
||||
gl_glsl_set_attribs(glsl_vbo[active_index].vbo_secondary,
|
||||
glsl_vbo[active_index].buffer_secondary,
|
||||
&glsl_vbo[active_index].buffer_secondary,
|
||||
&glsl_vbo[active_index].size_secondary,
|
||||
buffer, size, attribs, attribs_size);
|
||||
}
|
||||
@ -1035,7 +1044,15 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
if (!glsl_enable || !glsl_shader->modern)
|
||||
return false;
|
||||
|
||||
GLfloat buffer[128];
|
||||
// Avoid hitting malloc on every single regular quad draw.
|
||||
GLfloat short_buffer[4 * (2 + 2 + 4 + 2)];
|
||||
GLfloat *buffer = short_buffer;
|
||||
if (coords->vertices > 4)
|
||||
buffer = (GLfloat*)calloc(coords->vertices * (2 + 2 + 4 + 2), sizeof(*buffer));
|
||||
|
||||
if (!buffer)
|
||||
return false;
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
struct glsl_attrib attribs[4];
|
||||
@ -1051,8 +1068,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->tex_coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
memcpy(buffer + size, coords->tex_coord, 2 * coords->vertices * sizeof(GLfloat));
|
||||
size += 2 * coords->vertices;
|
||||
}
|
||||
|
||||
if (uni->vertex_coord >= 0)
|
||||
@ -1063,8 +1080,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->vertex, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
memcpy(buffer + size, coords->vertex, 2 * coords->vertices * sizeof(GLfloat));
|
||||
size += 2 * coords->vertices;
|
||||
}
|
||||
|
||||
if (uni->color >= 0)
|
||||
@ -1075,8 +1092,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->color, 16 * sizeof(GLfloat));
|
||||
size += 16;
|
||||
memcpy(buffer + size, coords->color, 4 * coords->vertices * sizeof(GLfloat));
|
||||
size += 4 * coords->vertices;
|
||||
}
|
||||
|
||||
if (uni->lut_tex_coord >= 0)
|
||||
@ -1087,19 +1104,21 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->lut_tex_coord, 8 * sizeof(GLfloat));
|
||||
size += 8;
|
||||
memcpy(buffer + size, coords->lut_tex_coord, 2 * coords->vertices * sizeof(GLfloat));
|
||||
size += 2 * coords->vertices;
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
gl_glsl_set_attribs(glsl_vbo[active_index].vbo_primary,
|
||||
glsl_vbo[active_index].buffer_primary,
|
||||
&glsl_vbo[active_index].buffer_primary,
|
||||
&glsl_vbo[active_index].size_primary,
|
||||
buffer, size,
|
||||
attribs, attribs_size);
|
||||
}
|
||||
|
||||
if (buffer != short_buffer)
|
||||
free(buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user