Speedup for font drawing, every letter was character was calling:
authorCampbell Barton <ideasman42@gmail.com>
Sat, 17 Sep 2011 10:45:20 +0000 (10:45 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 17 Sep 2011 10:45:20 +0000 (10:45 +0000)
  glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &cur_tex);

... with shadow enabled glGetFloatv(GL_CURRENT_COLOR, color) was called twice per character as well.

Now only call glGetFloatv(GL_CURRENT_COLOR, ...) once per string and only when drawing with shadow or blur, texture bind is stored in the font.

Gives 8% overall FPS speedup when displaying heavy UI in my test.

source/blender/blenfont/intern/blf.c
source/blender/blenfont/intern/blf_glyph.c
source/blender/blenfont/intern/blf_internal_types.h

index fc812d6..577697d 100644 (file)
@@ -486,6 +486,13 @@ static void blf_draw__start(FontBLF *font)
 
        if (font->flags & BLF_ROTATION)
                glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
+
+       if(font->shadow || font->blur)
+               glGetFloatv(GL_CURRENT_COLOR, font->orig_col);
+
+       /* always bind the texture for the first glyph */
+       font->tex_bind_state= -1;
+
 }
 
 static void blf_draw__end(void)
index 9b39cb6..7a1fa8c 100644 (file)
@@ -185,7 +185,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
        memset((void *)buf, 0, tot_mem);
 
        glGenTextures(1, &gc->textures[gc->cur_tex]);
-       glBindTexture(GL_TEXTURE_2D, gc->textures[gc->cur_tex]);
+       glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state= gc->textures[gc->cur_tex]));
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -326,23 +326,25 @@ static void blf_texture_draw(float uv[2][2], float dx, float y1, float dx1, floa
        
 }
 
-static void blf_texture5_draw(float uv[2][2], float x1, float y1, float x2, float y2)
+static void blf_texture5_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
 {
-       float soft[25]= {
-               1/60.0f, 1/60.0f, 2/60.0f, 1/60.0f, 1/60.0f, 
-               1/60.0f, 3/60.0f, 5/60.0f, 3/60.0f, 1/60.0f, 
-               2/60.0f, 5/60.0f, 8/60.0f, 5/60.0f, 2/60.0f, 
-               1/60.0f, 3/60.0f, 5/60.0f, 3/60.0f, 1/60.0f, 
-               1/60.0f, 1/60.0f, 2/60.0f, 1/60.0f, 1/60.0f};
+       float soft[25]= {1/60.0f, 1/60.0f, 2/60.0f, 1/60.0f, 1/60.0f,
+                        1/60.0f, 3/60.0f, 5/60.0f, 3/60.0f, 1/60.0f,
+                        2/60.0f, 5/60.0f, 8/60.0f, 5/60.0f, 2/60.0f,
+                        1/60.0f, 3/60.0f, 5/60.0f, 3/60.0f, 1/60.0f,
+                        1/60.0f, 1/60.0f, 2/60.0f, 1/60.0f, 1/60.0f};
        
        float color[4], *fp= soft;
        int dx, dy;
-       
-       glGetFloatv(GL_CURRENT_COLOR, color);
+
+       color[0]= shadow_col[0];
+       color[1]= shadow_col[1];
+       color[2]= shadow_col[2];
        
        for(dx=-2; dx<3; dx++) {
                for(dy=-2; dy<3; dy++, fp++) {
-                       glColor4f(color[0], color[1], color[2], fp[0]*color[3]);
+                       color[3]= *(fp) * shadow_col[3];
+                       glColor4fv(color);
                        blf_texture_draw(uv, x1+dx, y1+dy, x2+dx, y2+dy);
                }
        }
@@ -350,17 +352,23 @@ static void blf_texture5_draw(float uv[2][2], float x1, float y1, float x2, floa
        glColor4fv(color);
 }
 
-static void blf_texture3_draw(float uv[2][2], float x1, float y1, float x2, float y2)
+static void blf_texture3_draw(const float shadow_col[4], float uv[2][2], float x1, float y1, float x2, float y2)
 {
-       float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
+       float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f,
+                       2/16.0f,4/16.0f, 2/16.0f,
+                       1/16.0f, 2/16.0f, 1/16.0f};
+
        float color[4], *fp= soft;
        int dx, dy;
-       
-       glGetFloatv(GL_CURRENT_COLOR, color);
-       
+
+       color[0]= shadow_col[0];
+       color[1]= shadow_col[1];
+       color[2]= shadow_col[2];
+
        for(dx=-1; dx<2; dx++) {
                for(dy=-1; dy<2; dy++, fp++) {
-                       glColor4f(color[0], color[1], color[2], fp[0]*color[3]);
+                       color[3]= *(fp) * shadow_col[3];
+                       glColor4fv(color);
                        blf_texture_draw(uv, x1+dx, y1+dy, x2+dx, y2+dy);
                }
        }
@@ -370,18 +378,15 @@ static void blf_texture3_draw(float uv[2][2], float x1, float y1, float x2, floa
 
 int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
 {
-       GlyphCacheBLF *gc;
-       GLint cur_tex;
        float dx, dx1;
        float y1, y2;
        float xo, yo;
-       float color[4];
 
        if ((!g->width) || (!g->height))
                return(1);
 
        if (g->build_tex == 0) {
-               gc= font->glyph_cache;
+               GlyphCacheBLF *gc= font->glyph_cache;
 
                if (font->max_tex_size == -1)
                        glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size);
@@ -453,22 +458,27 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
                        return(0);
        }
 
-       glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &cur_tex);
-       if (cur_tex != g->tex)
-               glBindTexture(GL_TEXTURE_2D, g->tex);
+       if (font->tex_bind_state != g->tex) {
+               glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state= g->tex));
+       }
 
        if (font->flags & BLF_SHADOW) {
-               glGetFloatv(GL_CURRENT_COLOR, color);
-               glColor4fv(font->shadow_col);
-
-               if (font->shadow == 3)
-                       blf_texture3_draw(g->uv, dx, y1, dx1, y2);
-               else if (font->shadow == 5)
-                       blf_texture5_draw(g->uv, dx, y1, dx1, y2);
-               else
-                       blf_texture_draw(g->uv, dx, y1, dx1, y2);
 
-               glColor4fv(color);
+               switch(font->shadow) {
+                       case 3:
+                               blf_texture3_draw(font->shadow_col, g->uv, dx, y1, dx1, y2);
+                               break;
+                       case 5:
+                               blf_texture5_draw(font->shadow_col, g->uv, dx, y1, dx1, y2);
+                               break;
+                       default:
+                               glColor4fv(font->shadow_col);
+                               blf_texture_draw(g->uv, dx, y1, dx1, y2);
+                               break;
+               }
+
+               glColor4fv(font->orig_col);
+
                x= xo;
                y= yo;
 
@@ -478,12 +488,17 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
                y2= y + g->pos_y - g->height;
        }
 
-       if (font->blur==3)
-               blf_texture3_draw(g->uv, dx, y1, dx1, y2);
-       else if (font->blur==5)
-               blf_texture5_draw(g->uv, dx, y1, dx1, y2);
-       else
-               blf_texture_draw(g->uv, dx, y1, dx1, y2);
+       switch(font->blur) {
+               case 3:
+                       blf_texture3_draw(font->orig_col, g->uv, dx, y1, dx1, y2);
+                       break;
+               case 5:
+                       blf_texture5_draw(font->orig_col, g->uv, dx, y1, dx1, y2);
+                       break;
+               default:
+                       blf_texture_draw(g->uv, dx, y1, dx1, y2);
+                       break;
+       }
 
        return(1);
 }
index 9840e64..1450ad3 100644 (file)
@@ -161,7 +161,10 @@ typedef struct FontBLF {
 
        /* shadow color. */
        float shadow_col[4];
-       
+
+       /* store color here when drawing shadow or blur. */
+       float orig_col[4];
+
        /* Multiplied this matrix with the current one before
         * draw the text! see blf_draw__start.
         */
@@ -179,6 +182,9 @@ typedef struct FontBLF {
        /* max texture size. */
        int max_tex_size;
 
+       /* current opengl texture  bind, avoids calling glGet */
+       int tex_bind_state;
+
        /* font options. */
        int flags;