Minor speedups for 3D view text drawing ~10-15% improved frame-rate with particle...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 30 Oct 2010 23:02:38 +0000 (23:02 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 30 Oct 2010 23:02:38 +0000 (23:02 +0000)
- ascii text drawing functions, slightly faster since they dont have to do hash lookups & utf8 conversions for each char.
- used ascii drawing functions for the view3d's number display.
- each text item was using fixed 128 chars, now only allocate the string length needed.

source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf.c
source/blender/blenfont/intern/blf_font.c
source/blender/blenfont/intern/blf_internal.h
source/blender/blenfont/intern/blf_internal_types.h
source/blender/editors/space_view3d/drawanimviz.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_intern.h

index 933d287bcff02a1fed2acd0007f6960ef35a646d..c01886be65e630338ec240a388f63b607faadd09 100644 (file)
@@ -48,10 +48,12 @@ void BLF_position(int fontid, float x, float y, float z);
 void BLF_size(int fontid, int size, int dpi);
 
 /* Draw the string using the default font, size and dpi. */
-void BLF_draw_default(float x, float y, float z, char *str);
+void BLF_draw_default(float x, float y, float z, const char *str);
+void BLF_draw_default_ascii(float x, float y, float z, const char *str);
 
 /* Draw the string using the current font. */
-void BLF_draw(int fontid, char *str);
+void BLF_draw(int fontid, const char *str);
+void BLF_draw_ascii(int fontid, const char *str);
 
 /*
  * This function return the bounding box of the string
index f6b7c5f71e6a2092ea7748a75734a5d1da71ec1b..59189abf1e346c1da4b9125fca6d355f3fadb742 100644 (file)
@@ -361,7 +361,7 @@ void BLF_blur(int fontid, int size)
                font->blur= size;
 }
 
-void BLF_draw_default(float x, float y, float z, char *str)
+void BLF_draw_default(float x, float y, float z, const char *str)
 {
        if (!str)
                return;
@@ -378,6 +378,24 @@ void BLF_draw_default(float x, float y, float z, char *str)
        BLF_position(global_font_default, x, y, z);
        BLF_draw(global_font_default, str);
 }
+/* same as above but call 'BLF_draw_ascii' */
+void BLF_draw_default_ascii(float x, float y, float z, const char *str)
+{
+       if (!str)
+               return;
+
+       if (global_font_default == -1)
+               global_font_default= blf_search("default");
+
+       if (global_font_default == -1) {
+               printf("Warning: Can't found default font!!\n");
+               return;
+       }
+
+       BLF_size(global_font_default, global_font_points, global_font_dpi);
+       BLF_position(global_font_default, x, y, z);
+       BLF_draw_ascii(global_font_default, str);
+}
 
 void BLF_rotation_default(float angle)
 {
@@ -388,32 +406,49 @@ void BLF_rotation_default(float angle)
                font->angle= angle;
 }
 
-void BLF_draw(int fontid, char *str)
-{
-       FontBLF *font;
 
+static void blf_draw__start(FontBLF *font)
+{
        /*
         * The pixmap alignment hack is handle
         * in BLF_position (old ui_rasterpos_safe).
         */
-       font= BLF_get(fontid);
-       if (font) {
-               glEnable(GL_BLEND);
-               glEnable(GL_TEXTURE_2D);
-               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-               glPushMatrix();
-               glTranslatef(font->pos[0], font->pos[1], font->pos[2]);
-               glScalef(font->aspect, font->aspect, 1.0);
+       glEnable(GL_BLEND);
+       glEnable(GL_TEXTURE_2D);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-               if (font->flags & BLF_ROTATION)
-                       glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
+       glPushMatrix();
+       glTranslatef(font->pos[0], font->pos[1], font->pos[2]);
+       glScalef(font->aspect, font->aspect, 1.0);
 
+       if (font->flags & BLF_ROTATION)
+               glRotatef(font->angle, 0.0f, 0.0f, 1.0f);
+}
+static void blf_draw__end(void)
+{
+       glPopMatrix();
+       glDisable(GL_BLEND);
+       glDisable(GL_TEXTURE_2D);
+}
+
+void BLF_draw(int fontid, const char *str)
+{
+       FontBLF *font= BLF_get(fontid);
+       if (font) {
+               blf_draw__start(font);
                blf_font_draw(font, str);
+               blf_draw__end();
+       }
+}
 
-               glPopMatrix();
-               glDisable(GL_BLEND);
-               glDisable(GL_TEXTURE_2D);
+void BLF_draw_ascii(int fontid, const char *str)
+{
+       FontBLF *font= BLF_get(fontid);
+       if (font) {
+               blf_draw__start(font);
+               blf_font_draw_ascii(font, str);
+               blf_draw__end();
        }
 }
 
index 04f40ac825b7d23adf08992cc0ed42c1447920f8..9fb40f0206d9f15201eb07d7ba7b0b9ec3817dbe 100644 (file)
@@ -92,7 +92,7 @@ void blf_font_size(FontBLF *font, int size, int dpi)
        }
 }
 
-void blf_font_draw(FontBLF *font, char *str)
+void blf_font_draw(FontBLF *font, const char *str)
 {
        unsigned int c;
        GlyphBLF *g, *g_prev;
@@ -146,6 +146,65 @@ void blf_font_draw(FontBLF *font, char *str)
        }
 }
 
+/* faster version of blf_font_draw, ascii only for view dimensions */
+void blf_font_draw_ascii(FontBLF *font, const char *str)
+{
+       char c;
+       GlyphBLF *g, *g_prev;
+       FT_Vector delta;
+       FT_UInt glyph_index;
+       int pen_x, pen_y;
+       int i, has_kerning, st;
+
+       if (!font->glyph_cache)
+               return;
+
+       i= 0;
+       pen_x= 0;
+       pen_y= 0;
+       has_kerning= FT_HAS_KERNING(font->face);
+       g_prev= NULL;
+
+       /* build ascii on demand */
+       if(font->glyph_ascii_table['0']==NULL) {
+               for(i=0; i<256; i++) {
+                       g= blf_glyph_search(font->glyph_cache, i);
+                       if (!g) {
+                               glyph_index= FT_Get_Char_Index(font->face, i);
+                               g= blf_glyph_add(font, glyph_index, i);
+                       }
+                       font->glyph_ascii_table[i]= g;
+               }
+       }
+       
+       while ((c= *(str++))) {
+               g= font->glyph_ascii_table[c];
+
+               /* if we don't found a glyph, skip it. */
+               if (!g)
+                       continue;
+
+               if (has_kerning && g_prev) {
+                       delta.x= 0;
+                       delta.y= 0;
+
+                       if (font->flags & BLF_KERNING_DEFAULT)
+                               st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, ft_kerning_default, &delta);
+                       else
+                               st= FT_Get_Kerning(font->face, g_prev->idx, g->idx, FT_KERNING_UNFITTED, &delta);
+
+                       if (st == 0)
+                               pen_x += delta.x >> 6;
+               }
+
+               /* do not return this loop if clipped, we want every character tested */
+               blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
+
+               pen_x += g->advance;
+               g_prev= g;
+       }
+}
+
 void blf_font_buffer(FontBLF *font, char *str)
 {
        unsigned char *cbuf;
@@ -460,6 +519,8 @@ static void blf_font_fill(FontBLF *font)
        font->b_col[1]= 0;
        font->b_col[2]= 0;
        font->b_col[3]= 0;
+
+       memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table));
 }
 
 FontBLF *blf_font_new(char *name, char *filename)
index 844a7a3c3defa17114cf11ab701903eb97d0aaf3..c7a3cd54740b04ec77bf83480ebba2476f2ad1b7 100644 (file)
@@ -44,7 +44,8 @@ FontBLF *blf_font_new_from_mem(char *name, unsigned char *mem, int mem_size);
 void blf_font_attach_from_mem(FontBLF *font, const unsigned char *mem, int mem_size);
 
 void blf_font_size(FontBLF *font, int size, int dpi);
-void blf_font_draw(FontBLF *font, char *str);
+void blf_font_draw(FontBLF *font, const char *str);
+void blf_font_draw_ascii(FontBLF *font, const char *str);
 void blf_font_buffer(FontBLF *font, char *str);
 void blf_font_boundbox(FontBLF *font, char *str, rctf *box);
 void blf_font_width_and_height(FontBLF *font, char *str, float *width, float *height);
index 368eb8751de9c80f7ea59100e15a5eebf532a03c..70318c51823c5083838fd23ad2c3ab03cfd722c9 100644 (file)
@@ -177,6 +177,9 @@ typedef struct FontBLF {
 
        /* current glyph cache, size and dpi. */
        GlyphCacheBLF *glyph_cache;
+       
+       /* fast ascii lookip */
+       GlyphBLF *glyph_ascii_table[256];
 
        /* freetype2 face. */
        FT_Face face;
index 52bb90aa8f05c5804af848f448cc9e09e63c463f..7035006ea7048a9387bf2dec01646b143528103e 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <math.h>
 
+#include "BLO_sys_types.h"
 
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
@@ -213,7 +214,7 @@ void draw_motion_path_instance(Scene *scene,
                        if (i == 0) {
                                sprintf(str, "%d", (i+sfra));
                                mul_v3_m4v3(co, ob->imat, mpv->co);
-                               view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE);
+                               view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII);
                        }
                        else if ((i > stepsize) && (i < len-stepsize)) { 
                                bMotionPathVert *mpvP = (mpv - stepsize);
@@ -222,7 +223,7 @@ void draw_motion_path_instance(Scene *scene,
                                if ((equals_v3v3(mpv->co, mpvP->co)==0) || (equals_v3v3(mpv->co, mpvN->co)==0)) {
                                        sprintf(str, "%d", (sfra+i));
                                        mul_v3_m4v3(co, ob->imat, mpv->co);
-                                       view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE);
+                                       view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII);
                                }
                        }
                }
@@ -280,7 +281,7 @@ void draw_motion_path_instance(Scene *scene,
                                        
                                        sprintf(str, "%d", (sfra+i));
                                        mul_v3_m4v3(co, ob->imat, mpv->co);
-                                       view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE);
+                                       view3d_cached_text_draw_add(co, str, 0, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII);
                                }
                        }
                }
index d22853716670f07f3184da5552dc4f95a4835f00..8b9e960cdb335bed085458644d020a10002d60f6 100644 (file)
@@ -558,10 +558,10 @@ static int CachedTextLevel= 0;
 typedef struct ViewCachedString {
        struct ViewCachedString *next, *prev;
        float vec[3], col[4];
-       char str[128]; 
        short mval[2];
        short xoffs;
        short flag;
+       /* str is allocated past the end */
 } ViewCachedString;
 
 void view3d_cached_text_draw_begin()
@@ -573,15 +573,18 @@ void view3d_cached_text_draw_begin()
 
 void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag)
 {
+       int alloc_len= strlen(str) + 1;
        ListBase *strings= &CachedText[CachedTextLevel-1];
-       ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString");
+       ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString) + alloc_len, "ViewCachedString");
 
        BLI_addtail(strings, vos);
-       BLI_strncpy(vos->str, str, 128);
        copy_v3_v3(vos->vec, co);
        glGetFloatv(GL_CURRENT_COLOR, vos->col);
        vos->xoffs= xoffs;
        vos->flag= flag;
+
+       /* allocate past the end */
+       memcpy(++vos, str, alloc_len);
 }
 
 void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
@@ -635,8 +638,14 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
                        }
 #endif
                        if(vos->mval[0]!=IS_CLIPPED) {
+                               const char *str= (char *)(vos+1);
                                glColor3fv(vos->col);
-                               BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str);
+                               if(vos->flag & V3D_CACHE_TEXT_ASCII) {
+                                       BLF_draw_default_ascii((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str);
+                               }
+                               else {
+                                       BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str);
+                               }
                        }
                }
                
@@ -1809,8 +1818,9 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i
 
 static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
 {
-       unsigned char *cols[2] = {baseCol, selCol};
-
+       unsigned char *cols[2];
+       cols[0]= baseCol;
+       cols[1]= selCol;
        dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
 }
 
@@ -2113,7 +2123,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        sprintf(val, conv_float, len_v3v3(v1, v2));
                                
-                               view3d_cached_text_draw_add(vmid, val, 0, 0);
+                               view3d_cached_text_draw_add(vmid, val, 0, V3D_CACHE_TEXT_ASCII);
                        }
                }
        }
@@ -2152,7 +2162,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        sprintf(val, conv_float, area);
 
-                               view3d_cached_text_draw_add(efa->cent, val, 0, 0);
+                               view3d_cached_text_draw_add(efa->cent, val, 0, V3D_CACHE_TEXT_ASCII);
                        }
                }
        }
@@ -2194,13 +2204,13 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                /* Vec 1 */
                                sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v4, v1, v2)));
                                interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f);
-                               view3d_cached_text_draw_add(fvec, val, 0, 0);
+                               view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII);
                        }
                        if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) {
                                /* Vec 2 */
                                sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v1, v2, v3)));
                                interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f);
-                               view3d_cached_text_draw_add(fvec, val, 0, 0);
+                               view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII);
                        }
                        if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) {
                                /* Vec 3 */
@@ -2209,14 +2219,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v2, v3, v1)));
                                interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f);
-                               view3d_cached_text_draw_add(fvec, val, 0, 0);
+                               view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII);
                        }
                                /* Vec 4 */
                        if(efa->v4) {
                                if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) {
                                        sprintf(val,"%.3f", RAD2DEG(angle_v3v3v3(v3, v4, v1)));
                                        interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f);
-                                       view3d_cached_text_draw_add(fvec, val, 0, 0);
+                                       view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII);
                                }
                        }
                }
@@ -3827,16 +3837,24 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                        char *val_pos= val;
                                        val[0]= '\0';
 
-                                       if(part->draw&PART_DRAW_NUM)
-                                               val_pos += sprintf(val, "%i", a);
-
-                                       if((part->draw & PART_DRAW_HEALTH) && a < totpart && part->phystype==PART_PHYS_BOIDS)
-                                               sprintf(val_pos, (val_pos==val) ? "%.2f" : ":%.2f", pa_health);
+                                       if(part->draw&PART_DRAW_NUM) {
+                                               if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) {
+                                                       sprintf(val_pos, "%d:%.2f", a, pa_health);
+                                               }
+                                               else {
+                                                       sprintf(val_pos, "%d", a);
+                                               }
+                                       }
+                                       else {
+                                               if(a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype==PART_PHYS_BOIDS)) {
+                                                       sprintf(val_pos, "%.2f", pa_health);
+                                               }
+                                       }
 
                                        /* in path drawing state.co is the end point */
                                        /* use worldspace beause object matrix is already applied */
                                        mul_v3_m4v3(vec_txt, ob->imat, state.co);
-                                       view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE);
+                                       view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII);
                                }
                        }
                }
@@ -3925,12 +3943,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                        for(a=0, pa=psys->particles; a<totpart; a++, pa++){
                                float vec_txt[3];
-                               val[0]= '\0';
-
                                sprintf(val, "%i", a);
                                /* use worldspace beause object matrix is already applied */
                                mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co);
-                               view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE);
+                               view3d_cached_text_draw_add(vec_txt, val, 10, V3D_CACHE_TEXT_WORLDSPACE|V3D_CACHE_TEXT_ASCII);
                        }
                }
        }
@@ -5513,11 +5529,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data)
                glVertex3fv(v);                 
                glEnd();
                if (axis==0)
-                       view3d_cached_text_draw_add(v, "px", 0, 0);
+                       view3d_cached_text_draw_add(v, "px", 0, V3D_CACHE_TEXT_ASCII);
                else if (axis==1)
-                       view3d_cached_text_draw_add(v, "py", 0, 0);
+                       view3d_cached_text_draw_add(v, "py", 0, V3D_CACHE_TEXT_ASCII);
                else
-                       view3d_cached_text_draw_add(v, "pz", 0, 0);
+                       view3d_cached_text_draw_add(v, "pz", 0, V3D_CACHE_TEXT_ASCII);
        }
        glLineWidth (1.0f);
        setlinestyle(0);
index 0d8b97a66edb331cc3ae52307302600da373052f..92167f0f45eea4f724b390bdd17b0072607c98ba 100644 (file)
@@ -115,8 +115,9 @@ void drawaxes(float size, char drawtype);
 void view3d_cached_text_draw_begin(void);
 void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag);
 void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]);
-#define V3D_CACHE_TEXT_ZBUF 1
-#define V3D_CACHE_TEXT_WORLDSPACE 2
+#define V3D_CACHE_TEXT_ZBUF                    (1<<0)
+#define V3D_CACHE_TEXT_WORLDSPACE      (1<<1)
+#define V3D_CACHE_TEXT_ASCII           (1<<2)
 
 /* drawarmature.c */
 int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag);