mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-23 11:18:25 +00:00
Merge pull request #1996 from heuripedes/gl-perf
(gl_raster_font) Reduce the size of the font atlas textures
This commit is contained in:
commit
c3af671a6d
@ -47,11 +47,92 @@ typedef struct
|
||||
gfx_font_raster_block_t *block;
|
||||
} gl_raster_t;
|
||||
|
||||
static void gl_raster_font_free_font(void *data);
|
||||
|
||||
static bool gl_raster_font_upload_atlas(gl_raster_t *font,
|
||||
const struct font_atlas *atlas,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
unsigned i, j;
|
||||
GLint gl_internal = GL_LUMINANCE_ALPHA;
|
||||
GLenum gl_format = GL_LUMINANCE_ALPHA;
|
||||
size_t ncomponents = 2;
|
||||
uint8_t *tmp = NULL;
|
||||
struct retro_hw_render_callback *cb = video_driver_callback();
|
||||
bool ancient = false; /* add a check here if needed */
|
||||
bool modern = font->gl->core_context ||
|
||||
(cb->context_type == RETRO_HW_CONTEXT_OPENGL &&
|
||||
cb->version_major >= 3);
|
||||
|
||||
if (ancient)
|
||||
{
|
||||
gl_internal = gl_format = GL_RGBA;
|
||||
ncomponents = 4;
|
||||
}
|
||||
#ifdef HAVE_OPENGLES
|
||||
(void)modern;
|
||||
#else
|
||||
else if (modern)
|
||||
{
|
||||
GLint swizzle[] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
||||
|
||||
gl_internal = GL_R8;
|
||||
gl_format = GL_RED;
|
||||
ncomponents = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
tmp = (uint8_t*)calloc(height, width * ncomponents);
|
||||
|
||||
if (!tmp)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < atlas->height; ++i)
|
||||
{
|
||||
const uint8_t *src = &atlas->buffer[i * atlas->width];
|
||||
uint8_t *dst = &tmp[i * width * ncomponents];
|
||||
|
||||
switch (ncomponents)
|
||||
{
|
||||
case 1:
|
||||
memcpy(dst, src, atlas->width);
|
||||
src += atlas->width;
|
||||
break;
|
||||
case 2:
|
||||
for (j = 0; j < atlas->width; ++j)
|
||||
{
|
||||
*dst++ = 0xff;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (j = 0; j < atlas->width; ++j)
|
||||
{
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0xff;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
RARCH_ERR("Unsupported number of components: %u\n", (unsigned)ncomponents);
|
||||
free(tmp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal, width, height,
|
||||
0, gl_format, GL_UNSIGNED_BYTE, tmp);
|
||||
|
||||
free(tmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void *gl_raster_font_init_font(void *data,
|
||||
const char *font_path, float font_size)
|
||||
{
|
||||
unsigned width, height;
|
||||
uint8_t *tmp_buffer;
|
||||
const struct font_atlas *atlas = NULL;
|
||||
gl_raster_t *font = (gl_raster_t*)calloc(1, sizeof(*font));
|
||||
|
||||
@ -77,39 +158,15 @@ static void *gl_raster_font_init_font(void *data,
|
||||
|
||||
atlas = font->font_driver->get_atlas(font->font_data);
|
||||
|
||||
width = next_pow2(atlas->width);
|
||||
height = next_pow2(atlas->height);
|
||||
font->tex_width = next_pow2(atlas->width);;
|
||||
font->tex_height = next_pow2(atlas->height);;
|
||||
|
||||
/* Ideally, we'd use single component textures, but the
|
||||
* difference in ways to do that between core GL and GLES/legacy GL
|
||||
* is too great to bother going down that route. */
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
tmp_buffer = (uint8_t*)malloc(atlas->width * atlas->height * 4);
|
||||
|
||||
if (tmp_buffer)
|
||||
if (!gl_raster_font_upload_atlas(font, atlas, font->tex_width, font->tex_height))
|
||||
{
|
||||
unsigned i;
|
||||
uint8_t *dst = tmp_buffer;
|
||||
const uint8_t *src = atlas->buffer;
|
||||
|
||||
for (i = 0; i < atlas->width * atlas->height; i++)
|
||||
{
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0xff;
|
||||
*dst++ = *src++;
|
||||
gl_raster_font_free_font(font);
|
||||
font = NULL;
|
||||
}
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, atlas->width,
|
||||
atlas->height, GL_RGBA, GL_UNSIGNED_BYTE, tmp_buffer);
|
||||
free(tmp_buffer);
|
||||
}
|
||||
|
||||
font->tex_width = width;
|
||||
font->tex_height = height;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, font->gl->texture[font->gl->tex_index]);
|
||||
|
||||
return font;
|
||||
|
Loading…
Reference in New Issue
Block a user