diff options
author | Andrew Mahone <andrew.mahone@gmail.com> | 2009-05-16 00:45:13 +0000 |
---|---|---|
committer | Andrew Mahone <andrew.mahone@gmail.com> | 2009-05-16 00:45:13 +0000 |
commit | 4cd86c0e94ff28e18b16fb7394be356dd4145e54 (patch) | |
tree | 6bd1a7a016a5a055807d1ce51f7308ac993739e1 /apps/plugins | |
parent | c909878f94073a364f9b3c75663080c044bff3b8 (diff) | |
download | rockbox-4cd86c0e94ff28e18b16fb7394be356dd4145e54.tar.gz rockbox-4cd86c0e94ff28e18b16fb7394be356dd4145e54.zip |
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
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/pictureflow/pictureflow.c | 105 |
1 files changed, 59 insertions, 46 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index 3d223f13a4..c67825453b 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c | |||
@@ -218,12 +218,6 @@ typedef fb_data pix_t; | |||
218 | #define EV_EXIT 9999 | 218 | #define EV_EXIT 9999 |
219 | #define EV_WAKEUP 1337 | 219 | #define EV_WAKEUP 1337 |
220 | 220 | ||
221 | /* maximum number of albums */ | ||
222 | |||
223 | #define MAX_TRACKS 128 | ||
224 | #define AVG_TRACK_NAME_LENGTH 20 | ||
225 | |||
226 | |||
227 | #define UNIQBUF_SIZE (64*1024) | 221 | #define UNIQBUF_SIZE (64*1024) |
228 | 222 | ||
229 | #define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw" | 223 | #define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw" |
@@ -261,6 +255,7 @@ struct album_data { | |||
261 | }; | 255 | }; |
262 | 256 | ||
263 | struct track_data { | 257 | struct track_data { |
258 | uint32_t sort; | ||
264 | int name_idx; | 259 | int name_idx; |
265 | long seek; | 260 | long seek; |
266 | }; | 261 | }; |
@@ -369,8 +364,9 @@ static struct album_data *album; | |||
369 | static char *album_names; | 364 | static char *album_names; |
370 | static int album_count; | 365 | static int album_count; |
371 | 366 | ||
372 | static char track_names[MAX_TRACKS * AVG_TRACK_NAME_LENGTH]; | 367 | static struct track_data *tracks; |
373 | static struct track_data tracks[MAX_TRACKS]; | 368 | static char *track_names; |
369 | static size_t borrowed = 0; | ||
374 | static int track_count; | 370 | static int track_count; |
375 | static int track_index; | 371 | static int track_index; |
376 | static int selected_track; | 372 | static int selected_track; |
@@ -423,6 +419,7 @@ enum pf_states { | |||
423 | static int pf_state; | 419 | static int pf_state; |
424 | 420 | ||
425 | /** code */ | 421 | /** code */ |
422 | static bool free_slide_prio(int prio); | ||
426 | static inline unsigned fade_color(pix_t c, unsigned a); | 423 | static inline unsigned fade_color(pix_t c, unsigned a); |
427 | bool save_pfraw(char* filename, struct bitmap *bm); | 424 | bool save_pfraw(char* filename, struct bitmap *bm); |
428 | bool load_new_slide(void); | 425 | bool load_new_slide(void); |
@@ -780,51 +777,51 @@ char* get_track_name(const int track_index) | |||
780 | /** | 777 | /** |
781 | Compare two unsigned ints passed via pointers. | 778 | Compare two unsigned ints passed via pointers. |
782 | */ | 779 | */ |
783 | int compare_uints (const void *a_v, const void *b_v) | 780 | int compare_tracks (const void *a_v, const void *b_v) |
784 | { | 781 | { |
785 | uint32_t a = *(uint32_t *)a_v; | 782 | uint32_t a = ((struct track_data *)a_v)->sort; |
786 | uint32_t b = *(uint32_t *)b_v; | 783 | uint32_t b = ((struct track_data *)b_v)->sort; |
787 | return (int)(a - b); | 784 | return (int)(a - b); |
788 | } | 785 | } |
789 | 786 | ||
790 | /** | 787 | /** |
791 | Create the track index of the given slide_index. | 788 | Create the track index of the given slide_index. |
792 | */ | 789 | */ |
793 | int create_track_index(const int slide_index) | 790 | void create_track_index(const int slide_index) |
794 | { | 791 | { |
795 | if ( slide_index == track_index ) { | 792 | if ( slide_index == track_index ) |
796 | return -1; | 793 | return; |
797 | } | 794 | track_index = slide_index; |
798 | 795 | ||
799 | if (!rb->tagcache_search(&tcs, tag_title)) | 796 | if (!rb->tagcache_search(&tcs, tag_title)) |
800 | return -1; | 797 | goto fail; |
801 | |||
802 | struct track_data temp_tracks[MAX_TRACKS]; | ||
803 | uint32_t temp_tracknums[MAX_TRACKS]; | ||
804 | 798 | ||
805 | rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek); | 799 | rb->tagcache_search_add_filter(&tcs, tag_album, album[slide_index].seek); |
806 | track_count=0; | 800 | track_count=0; |
807 | int string_index = 0, i, track_num; | 801 | int string_index = 0, track_num; |
808 | int disc_num; | 802 | int disc_num; |
809 | 803 | size_t out = 0; | |
804 | track_names = (char *)buflib_buffer_out(&buf_ctx, &out); | ||
805 | borrowed += out; | ||
806 | int avail = borrowed; | ||
807 | tracks = (struct track_data*)(track_names + borrowed); | ||
810 | while (rb->tagcache_get_next(&tcs)) | 808 | while (rb->tagcache_get_next(&tcs)) |
811 | { | 809 | { |
812 | if (track_count == MAX_TRACKS) | 810 | avail -= sizeof(struct track_data); |
813 | goto fail; | 811 | track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber) - 1; |
814 | track_num = rb->tagcache_get_numeric(&tcs, tag_tracknumber); | ||
815 | disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber); | 812 | disc_num = rb->tagcache_get_numeric(&tcs, tag_discnumber); |
816 | int avail = sizeof(track_names) - string_index; | ||
817 | int len = 0; | 813 | int len = 0; |
818 | if (disc_num < 0) | 814 | if (disc_num < 0) |
819 | disc_num = 0; | 815 | disc_num = 0; |
816 | retry: | ||
820 | if (track_num >= 0) | 817 | if (track_num >= 0) |
821 | { | 818 | { |
822 | if (disc_num > 0) | 819 | if (disc_num) |
823 | len = 1 + rb->snprintf(track_names + string_index , avail, | 820 | len = 1 + rb->snprintf(track_names + string_index , avail, |
824 | "%d.%02d: %s", disc_num, track_num, tcs.result); | 821 | "%d.%02d: %s", disc_num, track_num + 1, tcs.result); |
825 | else | 822 | else |
826 | len = 1 + rb->snprintf(track_names + string_index , avail, | 823 | len = 1 + rb->snprintf(track_names + string_index , avail, |
827 | "%d: %s", track_num, tcs.result); | 824 | "%d: %s", track_num + 1, tcs.result); |
828 | } | 825 | } |
829 | else | 826 | else |
830 | { | 827 | { |
@@ -833,32 +830,43 @@ int create_track_index(const int slide_index) | |||
833 | rb->strncpy(track_names + string_index, tcs.result, avail); | 830 | rb->strncpy(track_names + string_index, tcs.result, avail); |
834 | } | 831 | } |
835 | if (len > avail) | 832 | if (len > avail) |
836 | goto fail; | 833 | { |
837 | temp_tracknums[track_count] = (disc_num << 16) + (track_num << 7) | 834 | while (len > avail) |
838 | + track_count; | 835 | { |
839 | temp_tracks[track_count].name_idx = string_index; | 836 | if (!free_slide_prio(0)) |
840 | temp_tracks[track_count].seek = tcs.result_seek; | 837 | goto fail; |
838 | out = 0; | ||
839 | buflib_buffer_out(&buf_ctx, &out); | ||
840 | avail += out; | ||
841 | borrowed += out; | ||
842 | if (track_count) | ||
843 | { | ||
844 | struct track_data *new_tracks = (struct track_data *)(out + (uintptr_t)tracks); | ||
845 | unsigned int bytes = track_count * sizeof(struct track_data); | ||
846 | rb->memmove(new_tracks, tracks, bytes); | ||
847 | tracks = new_tracks; | ||
848 | } | ||
849 | } | ||
850 | goto retry; | ||
851 | } | ||
852 | |||
853 | avail -= len; | ||
854 | tracks--; | ||
855 | tracks->sort = ((disc_num - 1) << 24) + (track_num << 14) + track_count; | ||
856 | tracks->name_idx = string_index; | ||
857 | tracks->seek = tcs.result_seek; | ||
841 | track_count++; | 858 | track_count++; |
842 | string_index += len; | 859 | string_index += len; |
843 | } | 860 | } |
844 | 861 | ||
845 | rb->tagcache_search_finish(&tcs); | 862 | rb->tagcache_search_finish(&tcs); |
846 | track_index = slide_index; | ||
847 | 863 | ||
848 | /* now fix the track list order */ | 864 | /* now fix the track list order */ |
849 | rb->qsort(temp_tracknums, track_count, sizeof(int), compare_uints); | 865 | rb->qsort(tracks, track_count, sizeof(struct track_data), compare_tracks); |
850 | for (i = 0; i < track_count; i++) | 866 | return; |
851 | { | ||
852 | track_num = 127 & temp_tracknums[i]; | ||
853 | tracks[i].name_idx = temp_tracks[track_num].name_idx; | ||
854 | tracks[i].seek = temp_tracks[track_num].seek; | ||
855 | } | ||
856 | if (track_count == 0) | ||
857 | goto fail; | ||
858 | return 0; | ||
859 | fail: | 867 | fail: |
860 | track_count = 0; | 868 | track_count = 0; |
861 | return -1; | 869 | return; |
862 | } | 870 | } |
863 | 871 | ||
864 | /** | 872 | /** |
@@ -1237,7 +1245,7 @@ static inline void free_slide(int i) | |||
1237 | Free one slide ranked above the given priority. If no such slide can be found, | 1245 | Free one slide ranked above the given priority. If no such slide can be found, |
1238 | return false. | 1246 | return false. |
1239 | */ | 1247 | */ |
1240 | static inline int free_slide_prio(int prio) | 1248 | static bool free_slide_prio(int prio) |
1241 | { | 1249 | { |
1242 | if (cache_used == -1) | 1250 | if (cache_used == -1) |
1243 | return false; | 1251 | return false; |
@@ -2523,7 +2531,12 @@ int main(void) | |||
2523 | 2531 | ||
2524 | case PF_BACK: | 2532 | case PF_BACK: |
2525 | if ( pf_state == pf_show_tracks ) | 2533 | if ( pf_state == pf_show_tracks ) |
2534 | { | ||
2535 | buflib_buffer_in(&buf_ctx, borrowed); | ||
2536 | borrowed = 0; | ||
2537 | track_index = -1; | ||
2526 | pf_state = pf_cover_out; | 2538 | pf_state = pf_cover_out; |
2539 | } | ||
2527 | if (pf_state == pf_idle || pf_state == pf_scrolling) | 2540 | if (pf_state == pf_idle || pf_state == pf_scrolling) |
2528 | return PLUGIN_OK; | 2541 | return PLUGIN_OK; |
2529 | break; | 2542 | break; |