Instead of one glTexSubImage2D call for each glyph.

This significantly reduces the amount of time it takes for xterm to start
up on a fresh X server with the radeonsi driver.

v2: Use GLYPHWIDTHBYTESPADDED instead of hardcoding 4 bytes glyph
    alignment (Keith Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Michel Dänzer 2015-07-06 18:45:51 -07:00 committed by Keith Packard
parent ac94cdb9df
commit 732e3b9c08

View File

@ -45,6 +45,7 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
unsigned char c[2]; unsigned char c[2];
CharInfoPtr glyph; CharInfoPtr glyph;
unsigned long count; unsigned long count;
char *bits;
if (glamor_priv->glsl_version < 130) if (glamor_priv->glsl_version < 130)
return NULL; return NULL;
@ -62,8 +63,6 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
if (glamor_font->realized) if (glamor_font->realized)
return glamor_font; return glamor_font;
glamor_font->realized = TRUE;
/* Figure out how many glyphs are in the font */ /* Figure out how many glyphs are in the font */
num_cols = font->info.lastCol - font->info.firstCol + 1; num_cols = font->info.lastCol - font->info.firstCol + 1;
num_rows = font->info.lastRow - font->info.firstRow + 1; num_rows = font->info.lastRow - font->info.firstRow + 1;
@ -81,6 +80,10 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
overall_width = glyph_width_bytes * num_cols; overall_width = glyph_width_bytes * num_cols;
overall_height = glyph_height * num_rows; overall_height = glyph_height * num_rows;
bits = malloc(overall_width * overall_height);
if (!bits)
return NULL;
/* Check whether the font has a default character */ /* Check whether the font has a default character */
c[0] = font->info.lastRow + 1; c[0] = font->info.lastRow + 1;
c[1] = font->info.lastCol + 1; c[1] = font->info.lastCol + 1;
@ -100,12 +103,6 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* Allocate storage */
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height,
0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
/* Paint all of the glyphs */ /* Paint all of the glyphs */
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
for (col = 0; col < num_cols; col++) { for (col = 0; col < num_cols; col++) {
@ -114,13 +111,29 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
(*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph); (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph);
if (count) if (count) {
glTexSubImage2D(GL_TEXTURE_2D, 0, col * glyph_width_bytes, row * glyph_height, char *dst = bits + row * glyph_height * overall_width +
GLYPHWIDTHBYTES(glyph), GLYPHHEIGHTPIXELS(glyph), col * glyph_width_bytes;
GL_RED_INTEGER, GL_UNSIGNED_BYTE, glyph->bits); char *src = glyph->bits;
unsigned y;
for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) {
memcpy(dst, src, GLYPHWIDTHBYTES(glyph));
dst += overall_width;
src += GLYPHWIDTHBYTESPADDED(glyph);
}
}
} }
} }
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height,
0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits);
free(bits);
glamor_font->realized = TRUE;
return glamor_font; return glamor_font;
} }