1
0
Fork 0
forked from len0rd/rockbox

Reduce the shocking amount of RAM my viewports implementation was using. The first version stored an array of lines for each of the 16 possible viewports (MAX_VIEWPORTS * the number of lines on the LCD with a 5-pixel high font). This version reverts back to a single global array of lines, with each viewport specifying the first and last lines as indexes into that array. This also turns out to be simpler, reducing binsize a little as well.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16735 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dave Chapman 2008-03-22 00:31:22 +00:00
parent 7ee63e22c5
commit 45b2d8802d
4 changed files with 70 additions and 67 deletions

View file

@ -1466,7 +1466,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
The return value indicates whether the line needs to be updated.
*/
static bool get_line(struct gui_wps *gwps,
int v, int line, int subline,
int line, int subline,
struct align_pos *align,
char *linebuf,
int linebuf_size)
@ -1494,8 +1494,8 @@ static bool get_line(struct gui_wps *gwps,
#endif
/* Process all tokens of the desired subline */
last_token_idx = wps_last_token_index(data, v, line, subline);
for (i = wps_first_token_index(data, v, line, subline);
last_token_idx = wps_last_token_index(data, line, subline);
for (i = wps_first_token_index(data, line, subline);
i <= last_token_idx; i++)
{
switch(data->tokens[i].type)
@ -1594,16 +1594,16 @@ static bool get_line(struct gui_wps *gwps,
return update;
}
static void get_subline_timeout(struct gui_wps *gwps, int v, int line, int subline)
static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
{
struct wps_data *data = gwps->data;
int i;
int subline_idx = wps_subline_index(data, v, line, subline);
int last_token_idx = wps_last_token_index(data, v, line, subline);
int subline_idx = wps_subline_index(data, line, subline);
int last_token_idx = wps_last_token_index(data, line, subline);
data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
for (i = wps_first_token_index(data, v, line, subline);
for (i = wps_first_token_index(data, line, subline);
i <= last_token_idx; i++)
{
switch(data->tokens[i].type)
@ -1631,7 +1631,7 @@ static void get_subline_timeout(struct gui_wps *gwps, int v, int line, int subli
/* Calculates which subline should be displayed for the specified line
Returns true iff the subline must be refreshed */
static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
static bool update_curr_subline(struct gui_wps *gwps, int line)
{
struct wps_data *data = gwps->data;
@ -1640,13 +1640,13 @@ static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
bool new_subline_refresh;
bool only_one_subline;
num_sublines = data->viewports[v].lines[line].num_sublines;
reset_subline = (data->viewports[v].lines[line].curr_subline == SUBLINE_RESET);
num_sublines = data->lines[line].num_sublines;
reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET);
new_subline_refresh = false;
only_one_subline = false;
/* if time to advance to next sub-line */
if (TIME_AFTER(current_tick, data->viewports[v].lines[line].subline_expire_time - 1) ||
if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) ||
reset_subline)
{
/* search all sublines until the next subline with time > 0
@ -1654,46 +1654,46 @@ static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
if (reset_subline)
search_start = 0;
else
search_start = data->viewports[v].lines[line].curr_subline;
search_start = data->lines[line].curr_subline;
for (search = 0; search < num_sublines; search++)
{
data->viewports[v].lines[line].curr_subline++;
data->lines[line].curr_subline++;
/* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */
if (data->viewports[v].lines[line].curr_subline == num_sublines)
if (data->lines[line].curr_subline == num_sublines)
{
if (data->viewports[v].lines[line].curr_subline == 1)
if (data->lines[line].curr_subline == 1)
only_one_subline = true;
data->viewports[v].lines[line].curr_subline = 0;
data->lines[line].curr_subline = 0;
}
/* if back where we started after search or
only one subline is defined on the line */
if (((search > 0) &&
(data->viewports[v].lines[line].curr_subline == search_start)) ||
(data->lines[line].curr_subline == search_start)) ||
only_one_subline)
{
/* no other subline with a time > 0 exists */
data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
data->lines[line].subline_expire_time = (reset_subline ?
current_tick :
data->viewports[v].lines[line].subline_expire_time) + 100 * HZ;
data->lines[line].subline_expire_time) + 100 * HZ;
break;
}
else
{
/* get initial time multiplier for this subline */
get_subline_timeout(gwps, v, line, data->viewports[v].lines[line].curr_subline);
get_subline_timeout(gwps, line, data->lines[line].curr_subline);
int subline_idx = wps_subline_index(data, v, line,
data->viewports[v].lines[line].curr_subline);
int subline_idx = wps_subline_index(data, line,
data->lines[line].curr_subline);
/* only use this subline if subline time > 0 */
if (data->sublines[subline_idx].time_mult > 0)
{
new_subline_refresh = true;
data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
current_tick : data->viewports[v].lines[line].subline_expire_time) +
data->lines[line].subline_expire_time = (reset_subline ?
current_tick : data->lines[line].subline_expire_time) +
BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult;
break;
}
@ -1909,12 +1909,9 @@ bool gui_wps_refresh(struct gui_wps *gwps,
{
display->clear_display();
for (v = 0; v < data->num_viewports; v++)
for (i = 0; i <= data->num_lines; i++)
{
for (i = 0; i < data->viewports[v].num_lines; i++)
{
data->viewports[v].lines[i].curr_subline = SUBLINE_RESET;
}
data->lines[i].curr_subline = SUBLINE_RESET;
}
}
@ -1951,23 +1948,24 @@ bool gui_wps_refresh(struct gui_wps *gwps,
}
#endif
for (line = 0; line < data->viewports[v].num_lines; line++)
for (line = data->viewports[v].first_line;
line <= data->viewports[v].last_line; line++)
{
memset(linebuf, 0, sizeof(linebuf));
update_line = false;
/* get current subline for the line */
new_subline_refresh = update_curr_subline(gwps, v, line);
new_subline_refresh = update_curr_subline(gwps, line);
subline_idx = wps_subline_index(data, v, line,
data->viewports[v].lines[line].curr_subline);
subline_idx = wps_subline_index(data, line,
data->lines[line].curr_subline);
flags = data->sublines[subline_idx].line_type;
if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
|| new_subline_refresh)
{
/* get_line tells us if we need to update the line */
update_line = get_line(gwps, v, line, data->viewports[v].lines[line].curr_subline,
update_line = get_line(gwps, line, data->lines[line].curr_subline,
&align, linebuf, sizeof(linebuf));
}
@ -2021,10 +2019,10 @@ bool gui_wps_refresh(struct gui_wps *gwps,
/* if the line is a scrolling one we don't want to update
too often, so that it has the time to scroll */
if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
write_line(display, &align, line, true);
write_line(display, &align, line - data->viewports[v].first_line, true);
}
else
write_line(display, &align, line, false);
write_line(display, &align, line - data->viewports[v].first_line, false);
}
}

View file

@ -88,7 +88,7 @@ struct align_pos {
+ (2*LCD_HEIGHT*LCD_WIDTH/8))
#define WPS_MAX_VIEWPORTS 16
#define WPS_MAX_LINES (LCD_HEIGHT/5+1)
#define WPS_MAX_LINES ((LCD_HEIGHT/5+1) * 2)
#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
#define WPS_MAX_TOKENS 1024
#define WPS_MAX_STRINGS 128
@ -321,10 +321,9 @@ struct wps_line {
struct wps_viewport {
struct viewport vp; /* The LCD viewport struct */
/* Number of lines in this viewport. During WPS parsing, this is
the index of the line being parsed. */
int num_lines;
struct wps_line lines[WPS_MAX_LINES];
/* Indexes of the first and last lines belonging to this viewport in the
lines[] array */
int first_line, last_line;
};
/* wps_data
@ -371,10 +370,16 @@ struct wps_data
bool remote_wps;
#endif
/* Number of lines in the WPS. During WPS parsing, this is
the index of the line being parsed. */
int num_lines;
/* Number of viewports in the WPS */
int num_viewports;
struct wps_viewport viewports[WPS_MAX_VIEWPORTS];
struct wps_line lines[WPS_MAX_LINES];
/* Total number of sublines in the WPS. During WPS parsing, this is
the index of the subline where the parsed tokens are added to. */
int num_sublines;
@ -403,25 +408,22 @@ bool wps_data_load(struct wps_data *wps_data,
bool isfile);
/* Returns the index of the subline in the subline array
v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
int wps_subline_index(struct wps_data *wps_data, int v, int line, int subline);
int wps_subline_index(struct wps_data *wps_data, int line, int subline);
/* Returns the index of the first subline's token in the token array
v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
int wps_first_token_index(struct wps_data *data, int v, int line, int subline);
int wps_first_token_index(struct wps_data *data, int line, int subline);
/* Returns the index of the last subline's token in the token array.
v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
int wps_last_token_index(struct wps_data *data, int v, int line, int subline);
int wps_last_token_index(struct wps_data *data, int line, int subline);
/* wps_data end */

View file

@ -502,7 +502,8 @@ static void print_line_info(struct wps_data *data)
DEBUGF("Number of viewports : %d\n", data->num_viewports);
for (v = 0; v < data->num_viewports; v++)
{
DEBUGF("vp %d: Number of lines: %d\n", v, data->viewports[v].num_lines);
DEBUGF("vp %d: First line: %d\n", v, data->viewports[v].first_line);
DEBUGF("vp %d: Last line: %d\n", v, data->viewports[v].last_line);
}
DEBUGF("Number of sublines : %d\n", data->num_sublines);
DEBUGF("Number of tokens : %d\n", data->num_tokens);
@ -517,7 +518,7 @@ static void print_line_info(struct wps_data *data)
data->viewports[v].vp.y,
data->viewports[v].vp.width,
data->viewports[v].vp.height);
for (i = 0, line = data->viewports[v].lines; i < data->viewports[v].num_lines; i++,line++)
for (i = data->viewports[v].first_line, line = &data->lines[data->viewports[v].first_line]; i <= data->viewports[v].last_line; i++,line++)
{
DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
i, line->num_sublines, line->first_subline_idx);
@ -527,7 +528,7 @@ static void print_line_info(struct wps_data *data)
{
DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
j, subline->first_token_idx,
wps_last_token_index(data, v, i, j));
wps_last_token_index(data, i, j));
if (subline->line_type & WPS_REFRESH_SCROLL)
DEBUGF(", scrolled");

View file

@ -338,11 +338,9 @@ static int skip_end_of_line(const char *wps_bufptr)
/* Starts a new subline in the current line during parsing */
static void wps_start_new_subline(struct wps_data *data)
{
struct wps_viewport* vp = &data->viewports[data->num_viewports];
data->num_sublines++;
data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
vp->lines[vp->num_lines].num_sublines++;
data->lines[data->num_lines].num_sublines++;
}
#ifdef HAVE_LCD_BITMAP
@ -586,11 +584,13 @@ static int parse_viewport(const char *wps_bufptr,
}
#endif
wps_data->viewports[wps_data->num_viewports].num_lines = 0;
wps_data->viewports[wps_data->num_viewports-1].last_line = wps_data->num_lines - 1;
wps_data->viewports[wps_data->num_viewports].first_line = wps_data->num_lines;
if (wps_data->num_sublines < WPS_MAX_SUBLINES)
{
wps_data->viewports[wps_data->num_viewports].lines[0].first_subline_idx =
wps_data->lines[wps_data->num_lines].first_subline_idx =
wps_data->num_sublines;
wps_data->sublines[wps_data->num_sublines].first_token_idx =
@ -599,7 +599,7 @@ static int parse_viewport(const char *wps_bufptr,
/* Skip the rest of the line */
return skip_end_of_line(wps_bufptr);
}
}
static int parse_image_special(const char *wps_bufptr,
@ -1072,7 +1072,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1
&& data->num_viewports < WPS_MAX_VIEWPORTS
&& data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES)
&& data->num_lines < WPS_MAX_LINES)
{
switch(*wps_bufptr++)
{
@ -1180,12 +1180,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
line++;
wps_start_new_subline(data);
data->viewports[data->num_viewports].num_lines++; /* Start a new line */
data->num_lines++; /* Start a new line */
if ((data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES) &&
if ((data->num_lines < WPS_MAX_LINES) &&
(data->num_sublines < WPS_MAX_SUBLINES))
{
data->viewports[data->num_viewports].lines[data->viewports[data->num_viewports].num_lines].first_subline_idx =
data->lines[data->num_lines].first_subline_idx =
data->num_sublines;
data->sublines[data->num_sublines].first_token_idx =
@ -1262,6 +1262,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
if (!fail && level >= 0) /* there are unclosed conditionals */
fail = PARSE_FAIL_UNCLOSED_COND;
data->viewports[data->num_viewports].last_line = data->num_lines - 1;
/* We have finished with the last viewport, so increment count */
data->num_viewports++;
@ -1512,20 +1514,20 @@ bool wps_data_load(struct wps_data *wps_data,
}
}
int wps_subline_index(struct wps_data *data, int v, int line, int subline)
int wps_subline_index(struct wps_data *data, int line, int subline)
{
return data->viewports[v].lines[line].first_subline_idx + subline;
return data->lines[line].first_subline_idx + subline;
}
int wps_first_token_index(struct wps_data *data, int v, int line, int subline)
int wps_first_token_index(struct wps_data *data, int line, int subline)
{
int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
int first_subline_idx = data->lines[line].first_subline_idx;
return data->sublines[first_subline_idx + subline].first_token_idx;
}
int wps_last_token_index(struct wps_data *data, int v, int line, int subline)
int wps_last_token_index(struct wps_data *data, int line, int subline)
{
int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
int first_subline_idx = data->lines[line].first_subline_idx;
int idx = first_subline_idx + subline;
if (idx < data->num_sublines - 1)
{