Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
- index 304ebf1..0b843a5 100644
- --- a/apps/gui/skin_engine/skin_render.c
- +++ b/apps/gui/skin_engine/skin_render.c
- @@ -27,6 +27,10 @@
- #include "strlcat.h"
- #include "config.h"
- +
- +#include "thread.h"
- +extern struct thread_entry threads[MAXTHREADS];
- +
- #include "kernel.h"
- #ifdef HAVE_ALBUMART
- #include "albumart.h"
- @@ -68,8 +72,8 @@ struct skin_draw_info {
- int offset; /* used by the playlist viewer */
- };
- -typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info);
- -bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info);
- +static int alternator_change_line(struct skin_element* alternator,
- + struct skin_draw_info *info, bool* line_changed);
- #ifdef HAVE_LCD_BITMAP
- static void skin_render_playlistviewer(struct playlistviewer* viewer,
- @@ -375,14 +379,29 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
- {
- bool needs_update = false;
- int last_value, value;
- + bool in_changed_alternator = false;
- + struct skin_element *child;
- + struct conditional *conditional;
- + int old_refresh_mode = info->refresh_type;
- +
- + if (line->type == LINE_ALTERNATOR)
- + {
- + line = line->children[alternator_change_line(line, info,
- + &in_changed_alternator)];
- + if (line->children_count == 0)
- + return in_changed_alternator;
- + if (in_changed_alternator)
- + {
- + info->refresh_type = SKIN_REFRESH_ALL;
- + info->force_redraw = true;
- + }
- +
- + }
- if (line->children_count == 0)
- return false; /* empty line, do nothing */
- + child = line->children[0];
- - struct skin_element *child = line->children[0];
- - struct conditional *conditional;
- - skin_render_func func = skin_render_line;
- - int old_refresh_mode = info->refresh_type;
- while (child)
- {
- switch (child->type)
- @@ -411,20 +430,15 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
- if (last_value >= 0 && value != last_value && last_value < child->children_count)
- do_tags_in_hidden_conditional(child->children[last_value], info);
- }
- - if (child->children[value]->type == LINE_ALTERNATOR)
- - {
- - func = skin_render_alternator;
- - }
- - else if (child->children[value]->type == LINE)
- - func = skin_render_line;
- -
- if (value != last_value)
- {
- info->refresh_type = SKIN_REFRESH_ALL;
- info->force_redraw = true;
- }
- -
- - if (func(child->children[value], info))
- + struct thread_entry *t = &threads[thread_get_current()];
- + if (thread_stack_usage(t) > 90)
- + panicf("skin engine: rendering stack overflow");
- + if (skin_render_line(child->children[value], info))
- needs_update = true;
- else
- needs_update = needs_update || (last_value != value);
- @@ -475,6 +489,12 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
- child = child->next;
- }
- + if (in_changed_alternator)
- + {
- + info->refresh_type = old_refresh_mode;
- + info->force_redraw = false;
- + needs_update = true;
- + }
- return needs_update;
- }
- @@ -483,6 +503,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
- struct skin_element *element=line;
- struct wps_token *token;
- int retval = DEFAULT_SUBLINE_TIME_MULTIPLIER*TIMEOUT_UNIT;
- +restart: /* we are really using tail recursion so do it with a messy goto
- + to prevent stack overusage */
- if (element->type == LINE)
- {
- if (element->children_count == 0)
- @@ -504,9 +526,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
- element->children_count);
- if (val >= 0)
- {
- - retval = get_subline_timeout(gwps, element->children[val]);
- - if (retval >= 0)
- - return retval;
- + element = element->children[val];
- + goto restart;
- }
- }
- element = element->next;
- @@ -514,11 +535,11 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
- return retval;
- }
- -bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
- +static int alternator_change_line(struct skin_element* element,
- + struct skin_draw_info *info, bool* line_changed)
- {
- bool changed_lines = false;
- struct line_alternator *alternator = (struct line_alternator*)element->data;
- - unsigned old_refresh = info->refresh_type;
- if (info->refresh_type == SKIN_REFRESH_ALL)
- {
- alternator->current_line = element->children_count-1;
- @@ -561,13 +582,9 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
- alternator->current_line = try_line;
- alternator->next_change_tick = current_tick + rettimeout;
- }
- -
- - info->refresh_type = SKIN_REFRESH_ALL;
- - info->force_redraw = true;
- }
- - bool ret = skin_render_line(element->children[alternator->current_line], info);
- - info->refresh_type = old_refresh;
- - return changed_lines || ret;
- + *line_changed = changed_lines;
- + return alternator->current_line;
- }
- static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
- @@ -575,7 +592,6 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
- {
- struct screen *display = gwps->display;
- char linebuf[MAX_LINE];
- - skin_render_func func = skin_render_line;
- struct skin_element* line = viewport;
- struct skin_draw_info info = {
- .gwps = gwps,
- @@ -613,14 +629,8 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
- align->left = info.buf;
- align->center = NULL;
- align->right = NULL;
- -
- -
- - if (line->type == LINE_ALTERNATOR)
- - func = skin_render_alternator;
- - else if (line->type == LINE)
- - func = skin_render_line;
- -
- - needs_update = func(line, &info);
- +
- + needs_update = skin_render_line(line, &info);
- /* only update if the line needs to be, and there is something to write */
- if (refresh_type && needs_update)
- @@ -722,7 +732,6 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
- {
- struct screen *display = gwps->display;
- char linebuf[MAX_LINE];
- - skin_render_func func = skin_render_line;
- struct skin_element* line;
- struct skin_draw_info info = {
- .gwps = gwps,
- @@ -774,13 +783,7 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
- align->center = NULL;
- align->right = NULL;
- -
- - if (line->type == LINE_ALTERNATOR)
- - func = skin_render_alternator;
- - else if (line->type == LINE)
- - func = skin_render_line;
- -
- - needs_update = func(line, &info);
- + needs_update = skin_render_line(line, &info);
- /* only update if the line needs to be, and there is something to write */
- if (refresh_type && needs_update)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement