[PATCH] glamor: Use a single glTexImage2D call for core font atlas texture data

Michel Dänzer michel at daenzer.net
Thu Jul 2 02:55:04 PDT 2015


From: Michel Dänzer <michel.daenzer at amd.com>

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.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 glamor/glamor_font.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index cc0fecf..6d70031 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -45,6 +45,7 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     unsigned char       c[2];
     CharInfoPtr         glyph;
     unsigned long       count;
+    char                *bits;
 
     if (glamor_priv->glsl_version < 130)
         return NULL;
@@ -62,8 +63,6 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     if (glamor_font->realized)
         return glamor_font;
 
-    glamor_font->realized = TRUE;
-
     /* Figure out how many glyphs are in the font */
     num_cols = font->info.lastCol - font->info.firstCol + 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_height = glyph_height * num_rows;
 
+    bits = malloc(overall_width * overall_height);
+    if (!bits)
+        return NULL;
+
     /* Check whether the font has a default character */
     c[0] = font->info.lastRow + 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_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 */
     for (row = 0; row < num_rows; row++) {
         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);
 
-            if (count)
-                glTexSubImage2D(GL_TEXTURE_2D, 0, col * glyph_width_bytes, row * glyph_height,
-                                GLYPHWIDTHBYTES(glyph), GLYPHHEIGHTPIXELS(glyph),
-                                GL_RED_INTEGER, GL_UNSIGNED_BYTE, glyph->bits);
+            if (count) {
+                char *dst = bits + row * glyph_height * overall_width +
+                    col * glyph_width_bytes;
+                char *src = glyph->bits;
+                unsigned y;
+
+                for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) {
+                    memcpy(dst, src, GLYPHWIDTHBYTES(glyph));
+                    dst += overall_width;
+                    src += (GLYPHWIDTHBYTES(glyph) + 3) & ~3;
+                }
+            }
         }
     }
 
+    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;
 }
 
-- 
2.1.4



More information about the xorg-devel mailing list