1
0
Fork 0
forked from len0rd/rockbox

Use new buflib extensions to avoid static allocation for track list, by shifting space out of the buffer and freeing slides as needed.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20953 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andrew Mahone 2009-05-16 00:45:13 +00:00
parent c909878f94
commit 4cd86c0e94

View file

@ -218,12 +218,6 @@ typedef fb_data pix_t;
#define EV_EXIT 9999 #define EV_EXIT 9999
#define EV_WAKEUP 1337 #define EV_WAKEUP 1337
/* maximum number of albums */
#define MAX_TRACKS 128
#define AVG_TRACK_NAME_LENGTH 20
#define UNIQBUF_SIZE (64*1024) #define UNIQBUF_SIZE (64*1024)
#define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw" #define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw"
@ -261,6 +255,7 @@ struct album_data {
}; };
struct track_data { struct track_data {
uint32_t sort;
int name_idx; int name_idx;
long seek; long seek;
}; };
@ -369,8 +364,9 @@ static struct album_data *album;
static char *album_names; static char *album_names;
static int album_count; static int album_count;
static char track_names[MAX_TRACKS * AVG_TRACK_NAME_LENGTH]; static struct track_data *tracks;
static struct track_data tracks[MAX_TRACKS]; static char *track_names;
static size_t borrowed = 0;
static int track_count; static int track_count;
static int track_index; static int track_index;
static int selected_track; static int selected_track;
@ -423,6 +419,7 @@ enum pf_states {
static int pf_state; static int pf_state;
/** code */ /** code */
static bool free_slide_prio(int prio);
static inline unsigned fade_color(pix_t c, unsigned a); static inline unsigned fade_color(pix_t c, unsigned a);
bool save_pfraw(char* filename, struct bitmap *bm); bool save_pfraw(char* filename, struct bitmap *bm);
bool load_new_slide(void); bool load_new_slide(void);
@ -780,51 +777,51 @@ char* get_track_name(const int track_index)
/** /**
Compare two unsigned ints passed via pointers. Compare two unsigned ints passed via pointers.
*/ */
int compare_uints (const void *a_v, const void *b_v) int compare_tracks (const void *a_v, const void *b_v)
{ {
uint32_t a = *(uint32_t *)a_v; uint32_t a = ((struct track_data *)a_v)->sort;
uint32_t b = *(uint32_t *)b_v; uint32_t b = ((struct track_data *)b_v)->sort;
return (int)(a - b); return (int)(a - b);
} }
/** /**
Create the track index of the given slide_index. Create the track index of the given slide_index.
*/ */
int create_track_index(const int slide_index) void create_track_index(const int slide_index)
{ {
if ( slide_index == track_index ) { if ( slide_index == track_index )
return -1; return;
} track_index = slide_index;
if (!rb->tagcache_search(&tcs, tag_title)) if (!rb->tagcache_search(&tcs, tag_title))
return -1; goto fail;
struct track_data temp_tracks[MAX_TRACKS];
uint32_t temp_tracknums[MAX_TRACKS];
rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek); rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek);
track_count=0; track_count=0;
int string_index = 0, i, track_num; int string_index = 0, track_num;
int disc_num; int disc_num;
size_t out = 0;
track_names = (char *)buflib_buffer_out(&buf_ctx, &out);
borrowed += out;
int avail = borrowed;
tracks = (struct track_data*)(track_names + borrowed);
while (rb->tagcache_get_next(&tcs)) while (rb->tagcache_get_next(&tcs))
{ {
if (track_count == MAX_TRACKS) avail -= sizeof(struct track_data);
goto fail; track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber) - 1;
track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber);
disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber); disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber);
int avail = sizeof(track_names) - string_index;
int len = 0; int len = 0;
if (disc_num < 0) if (disc_num < 0)
disc_num = 0; disc_num = 0;
retry:
if (track_num >= 0) if (track_num >= 0)
{ {
if (disc_num > 0) if (disc_num)
len = 1 + rb->snprintf(track_names + string_index , avail, len = 1 + rb->snprintf(track_names + string_index , avail,
"%d.%02d: %s", disc_num, track_num, tcs.result); "%d.%02d: %s", disc_num, track_num + 1, tcs.result);
else else
len = 1 + rb->snprintf(track_names + string_index , avail, len = 1 + rb->snprintf(track_names + string_index , avail,
"%d: %s", track_num, tcs.result); "%d: %s", track_num + 1, tcs.result);
} }
else else
{ {
@ -833,32 +830,43 @@ int create_track_index(const int slide_index)
rb->strncpy(track_names + string_index, tcs.result, avail); rb->strncpy(track_names + string_index, tcs.result, avail);
} }
if (len > avail) if (len > avail)
goto fail; {
temp_tracknums[track_count] = (disc_num << 16) + (track_num << 7) while (len > avail)
+ track_count; {
temp_tracks[track_count].name_idx = string_index; if (!free_slide_prio(0))
temp_tracks[track_count].seek = tcs.result_seek; goto fail;
out = 0;
buflib_buffer_out(&buf_ctx, &out);
avail += out;
borrowed += out;
if (track_count)
{
struct track_data *new_tracks = (struct track_data *)(out + (uintptr_t)tracks);
unsigned int bytes = track_count * sizeof(struct track_data);
rb->memmove(new_tracks, tracks, bytes);
tracks = new_tracks;
}
}
goto retry;
}
avail -= len;
tracks--;
tracks->sort = ((disc_num - 1) << 24) + (track_num << 14) + track_count;
tracks->name_idx = string_index;
tracks->seek = tcs.result_seek;
track_count++; track_count++;
string_index += len; string_index += len;
} }
rb->tagcache_search_finish(&tcs); rb->tagcache_search_finish(&tcs);
track_index = slide_index;
/* now fix the track list order */ /* now fix the track list order */
rb->qsort(temp_tracknums, track_count, sizeof(int), compare_uints); rb->qsort(tracks, track_count, sizeof(struct track_data), compare_tracks);
for (i = 0; i < track_count; i++) return;
{
track_num = 127 & temp_tracknums[i];
tracks[i].name_idx = temp_tracks[track_num].name_idx;
tracks[i].seek = temp_tracks[track_num].seek;
}
if (track_count == 0)
goto fail;
return 0;
fail: fail:
track_count = 0; track_count = 0;
return -1; return;
} }
/** /**
@ -1237,7 +1245,7 @@ static inline void free_slide(int i)
Free one slide ranked above the given priority. If no such slide can be found, Free one slide ranked above the given priority. If no such slide can be found,
return false. return false.
*/ */
static inline int free_slide_prio(int prio) static bool free_slide_prio(int prio)
{ {
if (cache_used == -1) if (cache_used == -1)
return false; return false;
@ -2523,7 +2531,12 @@ int main(void)
case PF_BACK: case PF_BACK:
if ( pf_state == pf_show_tracks ) if ( pf_state == pf_show_tracks )
{
buflib_buffer_in(&buf_ctx, borrowed);
borrowed = 0;
track_index = -1;
pf_state = pf_cover_out; pf_state = pf_cover_out;
}
if (pf_state == pf_idle || pf_state == pf_scrolling) if (pf_state == pf_idle || pf_state == pf_scrolling)
return PLUGIN_OK; return PLUGIN_OK;
break; break;