Hello Navitters, a while ago, i hacked a on navit to make it a little more usable on freerunner. Once more, navit was unusable on freerunner, so i hacked again. I found that osd text is redrawing every single geo location change tick. Something like this is unacceptable for embedded - if the same is drawed. So please, navit team, check out this patch.
It preparses the osd text string, creates a little struct to use it, when it comes to draw, in hope, parsing a string ist slower than build the struct and use it. Maybe performance difference is bigger on embedded. i never get a shr dev environment working on my machine (oe build is not my friend), so i never tested it on freerunner, only on my main machine. and main imprevement: compare new string against prev generated sting and only draw, if it is not the same. carci
>From 107c0ad6c5b3fd4078a2453e92faa9b7a6a30093 Mon Sep 17 00:00:00 2001 From: Christian Anke <[email protected]> Date: Tue, 11 May 2010 20:36:38 +0200 Subject: [PATCH 1/3] osd: fix: osd_text cpu consumption reducing --- navit/navit/osd/core/osd_core.c | 403 +++++++++++++++++++++++++-------------- 1 files changed, 264 insertions(+), 139 deletions(-) diff --git a/navit/navit/osd/core/osd_core.c b/navit/navit/osd/core/osd_core.c index 46af3a2..6d9aa13 100644 --- a/navit/navit/osd/core/osd_core.c +++ b/navit/navit/osd/core/osd_core.c @@ -718,14 +718,28 @@ osd_speed_warner_new(struct navit *nav, struct osd_methods *meth, struct attr ** return (struct osd_priv *) this; } +struct osd_text_item { + int static_text; + char *text; + void *prev; + void *next; + enum attr_type section; + enum attr_type attr_typ; + void *root; + int offset; + char *format; +}; + struct osd_text { struct osd_item osd_item; int active; char *text; int align; - char last_text[16]; + char *last; + struct osd_text_item *items; }; + static char * osd_text_format_attr(struct attr *attr, char *format) { @@ -828,7 +842,7 @@ static void osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v) { struct point p, p2[4]; - char *str,*next,*last,*start,*end,*key,*subkey,*index,*value; + char *str,*last,*next,*value; int do_draw = 0; struct attr attr, vehicle_attr, maxspeed_attr; struct navigation *nav = NULL; @@ -837,6 +851,7 @@ osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v) struct map *nav_map = NULL; struct map_rect *nav_mr = NULL; struct item *item; + struct osd_text_item *oti; int offset,lines; int height=this->osd_item.font_size*13/256; int yspacing=height/2; @@ -844,178 +859,173 @@ osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v) enum attr_type attr_type; vehicle_attr.u.vehicle=NULL; - do_draw=1; - str=g_strdup(this->text); - while ((start=strstr(str, "${"))) { + oti=this->items; + str=NULL; + + while (oti) { + item=NULL; - end=strstr(str,"}"); - if (! end) - break; - *end++='\0'; value=NULL; - key=start+2; - subkey=osd_text_split(key,NULL); - if (!strcmp(key,"navigation") && subkey) { + + if (oti->static_text) { + value=g_strdup(oti->text); + } else if (oti->section == attr_navigation) { if (navit && !nav) nav = navit_get_navigation(navit); if (nav && !nav_map) nav_map = navigation_get_map(nav); - if (nav_map) - key=osd_text_split(subkey,&index); - if (nav_map && !strcmp(subkey,"item")) { - if (nav_map) - nav_mr = map_rect_new(nav_map, NULL); - if (nav_mr) { - item = map_rect_get_item(nav_mr); - } - offset=0; - if (index) - offset=atoi(index); - while (item) { - if (item->type == type_nav_none) - item=map_rect_get_item(nav_mr); - else if (!offset) - break; - else { - offset--; - item=map_rect_get_item(nav_mr); - } + if (nav_map ) + nav_mr = map_rect_new(nav_map, NULL); + if (nav_mr) + item = map_rect_get_item(nav_mr); + + offset=oti->offset; + while (item) { + if (item->type == type_nav_none) + item=map_rect_get_item(nav_mr); + else if (!offset) + break; + else { + offset--; + item=map_rect_get_item(nav_mr); } - if (item) { - dbg(1,"name %s\n", item_to_name(item->type)); - subkey=osd_text_split(key,&index); - attr_type=attr_from_name(key); - dbg(1,"type %s\n", attr_to_name(attr_type)); - if (item_attr_get(item, attr_type, &attr)) - value=osd_text_format_attr(&attr, index); - else - dbg(1,"failed\n"); + } + + if (item) { + dbg(1,"name %s\n", item_to_name(item->type)); + dbg(1,"type %s\n", attr_to_name(oti->attr_typ)); + if (item_attr_get(item, oti->attr_typ, &attr)) + value=osd_text_format_attr(&attr, oti->format); + } + } else if (oti->section == attr_vehicle) { + if (navit && !vehicle_attr.u.vehicle) { + navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL); + } + if (vehicle_attr.u.vehicle) { + if (vehicle_get_attr(vehicle_attr.u.vehicle, oti->attr_typ, &attr, NULL)) { + value=osd_text_format_attr(&attr, oti->format); } } - } else if (!strcmp(key,"tracking") && subkey) { + } else if (oti->section == attr_tracking) { if (navit) { tracking = navit_get_tracking(navit); route = navit_get_route(navit); } if (tracking) { - key=osd_text_split(subkey,&index); - if (!strcmp(subkey, "item") && key) { - item=tracking_get_current_item(tracking); - if (item && !strcmp(key,"route_speed")) { - double routespeed = -1; - int *flags=tracking_get_current_flags(tracking); - if (flags && (*flags & AF_SPEED_LIMIT) && tracking_get_attr(tracking, attr_maxspeed, &maxspeed_attr, NULL)) { - routespeed = maxspeed_attr.u.num; - value = format_speed(routespeed, ""); - } - - if (routespeed == -1) { - struct vehicleprofile *prof=navit_get_vehicleprofile(navit); - struct roadprofile *rprof=NULL; - if (prof) - rprof=vehicleprofile_get_roadprofile(prof, item->type); - if (rprof) { - routespeed=rprof->speed; - value=format_speed(routespeed,""); - } + item=tracking_get_current_item(tracking); + if (item && (oti->attr_typ == attr_speed)) { + double routespeed = -1; + int *flags=tracking_get_current_flags(tracking); + if (flags && (*flags & AF_SPEED_LIMIT) && tracking_get_attr(tracking, attr_maxspeed, &maxspeed_attr, NULL)) { + routespeed = maxspeed_attr.u.num; + value = format_speed(routespeed, ""); + } + + if (routespeed == -1) { + struct vehicleprofile *prof=navit_get_vehicleprofile(navit); + struct roadprofile *rprof=NULL; + if (prof) + rprof=vehicleprofile_get_roadprofile(prof, item->type); + if (rprof) { + routespeed=rprof->speed; + value=format_speed(routespeed,""); } - } else if (item) { - attr_type=attr_from_name(key); - if (tracking_get_attr(tracking, attr_type, &attr, NULL)) - value=osd_text_format_attr(&attr, index); } + } else if (item) { + if (tracking_get_attr(tracking, oti->attr_typ, &attr, NULL)) + value=osd_text_format_attr(&attr, oti->format); } } - } else if (!strcmp(key,"vehicle") && subkey) { - if (navit && !vehicle_attr.u.vehicle) { - navit_get_attr(navit, attr_vehicle, &vehicle_attr, NULL); - } - if (vehicle_attr.u.vehicle) { - key=osd_text_split(subkey,&index); - attr_type=attr_from_name(subkey); - if (vehicle_get_attr(vehicle_attr.u.vehicle, attr_type, &attr, NULL)) { - value=osd_text_format_attr(&attr, index); - } - } - - } else if (!strcmp(key,"navit") && subkey) { - if (navit) { - key = osd_text_split(subkey, &index); - if (!strcmp(subkey,"messages")) { - struct message *msg; - int len,offset; - char *tmp; - - msg = navit_get_messages(navit); - len = 0; - while (msg) { - len+= strlen(msg->text) + 2; - - msg = msg->next; - } - value = g_malloc(len +1); + } else if (oti->section == attr_navit) { + if (oti->attr_typ == attr_message) { + struct message *msg; + int len,offset; + char *tmp; - msg = navit_get_messages(navit); - offset = 0; - while (msg) { - tmp = g_stpcpy((value+offset), msg->text); - g_stpcpy(tmp, "\\n"); - offset += strlen(msg->text) + 2; + msg = navit_get_messages(navit); + len = 0; + while (msg) { + len+= strlen(msg->text) + 2; - msg = msg->next; - } + msg = msg->next; + } - value[len] = '\0'; + value = g_malloc(len +1); + + msg = navit_get_messages(navit); + offset = 0; + while (msg) { + tmp = g_stpcpy((value+offset), msg->text); + g_stpcpy(tmp, "\\n"); + offset += strlen(msg->text) + 2; + + msg = msg->next; } + + value[len] = '\0'; } } - *start='\0'; - next=g_strdup_printf("%s%s%s",str,value ? value:" ",end); - g_free(value); - g_free(str); + + next=g_strdup_printf("%s%s",str ? str:"",value ? value:" "); + if (value) + g_free(value); + if (str) + g_free(str); str=next; + oti=oti->next; } - lines=0; - next=str; - last=str; - while ((next=strstr(next, "\\n"))) { - last = next; - lines++; - next++; + + if ( this->last && !g_strcmp0(this->last, str) ) { + do_draw=0; + } else { + do_draw=1; + if (this->last) + g_free(this->last); + this->last = g_strdup(str); } - while (*last) { - if (! g_ascii_isspace(*last)) { + if (do_draw) { + lines=0; + next=str; + last=str; + while ((next=strstr(next, "\\n"))) { + last = next; lines++; - break; + next++; } - last++; - } - dbg(1,"this->align=%d\n", this->align); - switch (this->align & 51) { - case 1: - p.y=0; - break; - case 2: - p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing); - break; - case 16: // Grow from top to bottom - p.y = 0; - if (lines != 0) { - this->osd_item.h = (lines-1) * (height+yspacing) + height; - } else { - this->osd_item.h = 0; + while (*last) { + if (! g_ascii_isspace(*last)) { + lines++; + break; + } + last++; } - if (do_draw) { - osd_std_resize(&this->osd_item); + dbg(1,"this->align=%d\n", this->align); + switch (this->align & 51) { + case 1: + p.y=0; + break; + case 2: + p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing); + break; + case 16: // Grow from top to bottom + p.y = 0; + if (lines != 0) { + this->osd_item.h = (lines-1) * (height+yspacing) + height; + } else { + this->osd_item.h = 0; + } + + if (do_draw) { + osd_std_resize(&this->osd_item); + } + default: + p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing)/2; } - default: - p.y=(this->osd_item.h-lines*(height+yspacing)-yspacing)/2; - } - if (do_draw) { + osd_std_draw(&this->osd_item); while (str) { next=strstr(str, "\\n"); @@ -1047,6 +1057,119 @@ osd_text_draw(struct osd_text *this, struct navit *navit, struct vehicle *v) } graphics_draw_mode(this->osd_item.gr, draw_mode_end); } + g_free(str); + +} + +struct osd_text_item * +oti_new(struct osd_text_item * parent) +{ + struct osd_text_item *this; + this=g_new(struct osd_text_item, 1); + this->prev=parent; + this->next=NULL; + this->static_text=0; + this->offset=0; + this->format=NULL; + + if(!parent) { + this->root=this; + } else { + parent->next=this; + this->root=parent->root; + } + + return this; +} + +static void +osd_text_prepare(struct osd_text *this, struct navit *nav) +{ + char *str,*next,*last,*start,*end,*key,*subkey,*index; + struct osd_text_item *oti; + enum attr_type attr_type; + + oti=NULL; + str=g_strdup(this->text); + + dbg(1,"string: %s\n", str); + while ((start=strstr(str, "${"))) { + + *start='\0'; + start+=2; + + // find plain text before + if (start!=str) { + oti = oti_new(oti); + oti->static_text=1; + oti->text=g_strdup(str); + dbg(1,"before %s\n", oti->text); + + } + + end=strstr(start,"}"); + if (! end) + break; + + *end++='\0'; + key=start; + + subkey=osd_text_split(key,NULL); + dbg(1,"subkey1: %s\n", subkey); + + oti = oti_new(oti); + oti->section=attr_from_name(key); + dbg(0,"section %s\n", attr_to_name(oti->section)); + + if (( oti->section == attr_navigation || + oti->section == attr_tracking) && subkey) { + key=osd_text_split(subkey,&index); + + oti->offset=0; + if (index) + oti->offset=atoi(index); + + subkey=osd_text_split(key,&index); + + if (!strcmp(key,"route_speed")) { + oti->attr_typ=attr_speed; + } else { + oti->attr_typ=attr_from_name(key); + } + dbg(0,"attr_type %s\n", attr_to_name(oti->attr_typ)); + oti->format = g_strdup(index); + + } else if ((oti->section == attr_vehicle || oti->section == attr_navit) && subkey) { + key=osd_text_split(subkey,&index); + if (!strcmp(subkey,"messages")) { + oti->attr_typ=attr_message; + } else { + oti->attr_typ=attr_from_name(subkey); + } + dbg(0,"attr_type %s\n", attr_to_name(oti->attr_typ)); + oti->format = g_strdup(index); + } + + switch(oti->attr_typ) { + default: + navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_draw), attr_position_coord_geo, this)); + break; + } + + str=(end); + } + + if(*str!='\0'){ + oti = oti_new(oti); + oti->static_text=1; + oti->text=g_strdup(str); + dbg(1,"after %s\n", oti->text); + } + + if (oti) + this->items=oti->root; + else + this->items=NULL; } @@ -1057,6 +1180,7 @@ osd_text_init(struct osd_text *this, struct navit *nav) osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this); navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_text_draw), attr_position_coord_geo, this)); navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_std_click), attr_button, &this->osd_item)); + osd_text_prepare(this,nav); osd_text_draw(this, nav, NULL); } @@ -1078,6 +1202,7 @@ osd_text_new(struct navit *nav, struct osd_methods *meth, osd_set_std_attr(attrs, &this->osd_item, 2); this->active = -1; + this->last = NULL; attr = attr_search(attrs, NULL, attr_label); if (attr) -- 1.7.0.4
------------------------------------------------------------------------------
_______________________________________________ Navit-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/navit-users
