1
0
Fork 0
forked from len0rd/rockbox

FS#9919 pictureflow cache rework, footprint reduction, buflib use

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20203 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andrew Mahone 2009-03-04 21:23:49 +00:00
parent b727de604d
commit d8b6a950c6

View file

@ -32,6 +32,7 @@
#include "pluginbitmaps/pictureflow_logo.h"
#include "lib/grey.h"
#include "lib/feature_wrappers.h"
#include "lib/buflib.h"
PLUGIN_HEADER
@ -116,7 +117,7 @@ typedef fb_data pix_t;
#define DISPLAY_LEFT_R (PFREAL_HALF - LCD_WIDTH * PFREAL_HALF)
#define MAXSLIDE_LEFT_R (PFREAL_HALF - DISPLAY_WIDTH * PFREAL_HALF)
#define SLIDE_CACHE_SIZE 100
#define SLIDE_CACHE_SIZE 64 /* probably more than can be loaded */
#define MAX_SLIDES_COUNT 10
@ -127,8 +128,6 @@ typedef fb_data pix_t;
#define EV_WAKEUP 1337
/* maximum number of albums */
#define MAX_ALBUMS 1024
#define AVG_ALBUM_NAME_LENGTH 20
#define MAX_TRACKS 50
#define AVG_TRACK_NAME_LENGTH 20
@ -161,7 +160,8 @@ struct slide_data {
struct slide_cache {
int index; /* index of the cached slide */
int hid; /* handle ID of the cached slide */
long touched; /* last time the slide was touched */
short next; /* "next" slide, with LRU last */
short prev; /* "previous" slide */
};
struct album_data {
@ -196,7 +196,7 @@ const struct picture logos[]={
{pictureflow_logo, BMPWIDTH_pictureflow_logo, BMPHEIGHT_pictureflow_logo},
};
enum show_album_name_values { album_name_hide = 0, album_name_bottom ,
enum show_album_name_values { album_name_hide = 0, album_name_bottom,
album_name_top };
static char* show_album_name_conf[] =
{
@ -216,7 +216,8 @@ static int zoom = 100;
static bool show_fps = false;
static bool resize = true;
static int cache_version = 0;
static int show_album_name = (LCD_HEIGHT > 100) ? album_name_top : album_name_bottom;
static int show_album_name = (LCD_HEIGHT > 100)
? album_name_top : album_name_bottom;
static struct configdata config[] =
{
@ -239,7 +240,7 @@ static struct configdata config[] =
/** below we allocate the memory we want to use **/
static pix_t *buffer; /* for now it always points to the lcd framebuffer */
static uint16_t reflect_table[REFLECT_HEIGHT];
static uint8_t reflect_table[REFLECT_HEIGHT];
static struct slide_data center_slide;
static struct slide_data left_slides[MAX_SLIDES_COUNT];
static struct slide_data right_slides[MAX_SLIDES_COUNT];
@ -247,32 +248,34 @@ static int slide_frame;
static int step;
static int target;
static int fade;
static int center_index; /* index of the slide that is in the center */
static int center_index = 0; /* index of the slide that is in the center */
static int itilt;
static PFreal offsetX;
static PFreal offsetY;
static int number_of_slides;
static struct slide_cache cache[SLIDE_CACHE_SIZE];
static int slide_cache_in_use;
static int cache_free;
static int cache_used = -1;
static int cache_left_index = -1;
static int cache_right_index = -1;
static int cache_center_index = -1;
/* use long for aligning */
unsigned long thread_stack[THREAD_STACK_SIZE / sizeof(long)];
/* queue (as array) for scheduling load_surface */
static int slide_cache_stack[SLIDE_CACHE_SIZE];
static int slide_cache_stack_index;
struct mutex slide_cache_stack_lock;
static int empty_slide_hid;
unsigned int thread_id;
struct event_queue thread_q;
static long uniqbuf[UNIQBUF_SIZE];
static struct tagcache_search tcs;
static struct album_data album[MAX_ALBUMS];
static char album_names[MAX_ALBUMS*AVG_ALBUM_NAME_LENGTH];
static struct buflib_context buf_ctx;
static struct album_data *album;
static char *album_names;
static int album_count;
static char track_names[MAX_TRACKS * AVG_TRACK_NAME_LENGTH];
@ -333,6 +336,7 @@ static int pf_state;
/** code */
static inline pix_t fade_color(pix_t c, unsigned int a);
bool save_pfraw(char* filename, struct bitmap *bm);
bool load_new_slide(void);
int load_surface(int);
static inline PFreal fmul(PFreal a, PFreal b)
@ -398,7 +402,7 @@ static inline int clz(uint32_t v)
}
#else
static const char clz_lut[16] = { 4, 3, 2, 2, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 0, 0, 0, 0, 0 };
/* This clz is based on the log2(n) implementation at
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup
* It is not any faster than the one above, but trades 16B in the lookup table
@ -472,7 +476,7 @@ static inline PFreal fdiv(PFreal n, PFreal m)
#endif
/* warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! */
static const PFreal sin_tab[] = {
static const short sin_tab[] = {
0, 100, 200, 297, 392, 483, 569, 650,
724, 792, 851, 903, 946, 980, 1004, 1019,
1024, 1019, 1004, 980, 946, 903, 851, 792,
@ -562,30 +566,43 @@ void init_reflect_table(void)
*/
int create_album_index(void)
{
plugin_buf_size -= UNIQBUF_SIZE * sizeof(long);
long *uniqbuf = (long *)(plugin_buf_size + (char *)plugin_buf);
album = ((struct album_data *)uniqbuf) - 1;
rb->memset(&tcs, 0, sizeof(struct tagcache_search) );
album_count = 0;
rb->tagcache_search(&tcs, tag_album);
rb->tagcache_search_set_uniqbuf(&tcs, uniqbuf, UNIQBUF_SIZE);
int l, old_l = 0;
unsigned int l, old_l = 0;
album_names = plugin_buf;
album[0].name_idx = 0;
while (rb->tagcache_get_next(&tcs) && album_count < MAX_ALBUMS)
while (rb->tagcache_get_next(&tcs))
{
plugin_buf_size -= sizeof(struct album_data);
l = rb->strlen(tcs.result) + 1;
if ( album_count > 0 )
album[album_count].name_idx = album[album_count-1].name_idx + old_l;
album[-album_count].name_idx = album[1-album_count].name_idx + old_l;
if ( (album[album_count].name_idx + l) >
MAX_ALBUMS*AVG_ALBUM_NAME_LENGTH )
if ( l > plugin_buf_size )
/* not enough memory */
return ERROR_BUFFER_FULL;
rb->strcpy(album_names + album[album_count].name_idx, tcs.result);
album[album_count].seek = tcs.result_seek;
rb->strcpy(plugin_buf, tcs.result);
plugin_buf_size -= l;
plugin_buf = l + (char *)plugin_buf;
album[-album_count].seek = tcs.result_seek;
old_l = l;
album_count++;
}
rb->tagcache_search_finish(&tcs);
ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4);
int i;
struct album_data* tmp_album = (struct album_data*)plugin_buf;
for (i = album_count - 1; i >= 0; i--)
tmp_album[i] = album[-i];
album = tmp_album;
plugin_buf = album + album_count;
plugin_buf_size += UNIQBUF_SIZE * sizeof(long);
return (album_count > 0) ? 0 : ERROR_NO_ALBUMS;
}
@ -824,123 +841,6 @@ bool create_albumart_cache(void)
return true;
}
/**
Return the index on the stack of slide_index.
Return -1 if slide_index is not on the stack.
*/
static inline int slide_stack_get_index(const int slide_index)
{
int i = slide_cache_stack_index + 1;
while (i--) {
if ( slide_cache_stack[i] == slide_index ) return i;
};
return -1;
}
/**
Push the slide_index on the stack so the image will be loaded.
The algorithm tries to keep the center_index on top and the
slide_index as high as possible (so second if center_index is
on the stack).
*/
void slide_stack_push(const int slide_index)
{
rb->mutex_lock(&slide_cache_stack_lock);
if ( slide_cache_stack_index == -1 ) {
/* empty stack, no checks at all */
slide_cache_stack[ ++slide_cache_stack_index ] = slide_index;
rb->mutex_unlock(&slide_cache_stack_lock);
return;
}
int i = slide_stack_get_index( slide_index );
if ( i == slide_cache_stack_index ) {
/* slide_index is on top, so we do not change anything */
rb->mutex_unlock(&slide_cache_stack_lock);
return;
}
if ( i >= 0 ) {
/* slide_index is already on the stack, but not on top */
int tmp = slide_cache_stack[ slide_cache_stack_index ];
if ( tmp == center_index ) {
/* the center_index is on top of the stack so do not touch that */
if ( slide_cache_stack_index > 0 ) {
/*
but maybe it is possible to swap the given slide_index to
the second place
*/
tmp = slide_cache_stack[slide_cache_stack_index - 1];
slide_cache_stack[slide_cache_stack_index - 1] =
slide_cache_stack[i];
slide_cache_stack[i] = tmp;
}
}
else {
/*
if the center_index is not on top (i.e. already loaded) bring
the slide_index to the top
*/
slide_cache_stack[slide_cache_stack_index] = slide_cache_stack[i];
slide_cache_stack[i] = tmp;
}
}
else {
/* slide_index is not on the stack */
if ( slide_cache_stack_index >= SLIDE_CACHE_SIZE-1 ) {
/*
if we exceeded the stack size, clear the first half of the
stack
*/
slide_cache_stack_index = SLIDE_CACHE_SIZE/2;
for (i = 0; i <= slide_cache_stack_index ; i++)
slide_cache_stack[i] = slide_cache_stack[i +
slide_cache_stack_index];
}
if ( slide_cache_stack[ slide_cache_stack_index ] == center_index ) {
/* if the center_index is on top leave it there */
slide_cache_stack[ slide_cache_stack_index ] = slide_index;
slide_cache_stack[ ++slide_cache_stack_index ] = center_index;
}
else {
/* usual stack case: push the slide_index on top */
slide_cache_stack[ ++slide_cache_stack_index ] = slide_index;
}
}
rb->mutex_unlock(&slide_cache_stack_lock);
}
/**
Pop the topmost item from the stack and decrease the stack size
*/
static inline int slide_stack_pop(void)
{
rb->mutex_lock(&slide_cache_stack_lock);
int result;
if ( slide_cache_stack_index >= 0 )
result = slide_cache_stack[ slide_cache_stack_index-- ];
else
result = -1;
rb->mutex_unlock(&slide_cache_stack_lock);
return result;
}
/**
Load the slide into the cache.
Thus we have to queue the loading request in our thread while discarding the
oldest slide.
*/
static inline void request_surface(const int slide_index)
{
slide_stack_push(slide_index);
rb->queue_post(&thread_q, EV_WAKEUP, 0);
}
/**
Thread used for loading and preparing bitmaps in the background
*/
@ -957,10 +857,8 @@ void thread(void)
/* we just woke up */
break;
}
int slide_index;
while ( (slide_index = slide_stack_pop()) != -1 ) {
load_surface( slide_index );
rb->queue_wait_w_tmo(&thread_q, &ev, HZ/10);
while ( load_new_slide() ) {
rb->yield();
switch (ev.id) {
case EV_EXIT:
return;
@ -999,13 +897,15 @@ bool create_pf_thread(void)
sizeof(thread_stack),
0,
"Picture load thread"
IF_PRIO(, PRIORITY_BACKGROUND)
IF_PRIO(, MAX(PRIORITY_USER_INTERFACE / 2,
PRIORITY_REALTIME + 1))
IF_COP(, CPU)
)
) == 0) {
return false;
}
thread_is_running = true;
rb->queue_post(&thread_q, EV_WAKEUP, 0);
return true;
}
@ -1031,45 +931,201 @@ bool save_pfraw(char* filename, struct bitmap *bm)
}
/*
* The following functions implement the linked-list-in-array used to manage
* the LRU cache of slides, and the list of free cache slots.
*/
#define seek_right_while(start, cond) \
({ \
int ind_, next_ = (start); \
do { \
ind_ = next_; \
next_ = cache[ind_].next; \
} while (next_ != cache_used && (cond)); \
ind_; \
})
#define seek_left_while(start, cond) \
({ \
int ind_, next_ = (start); \
do { \
ind_ = next_; \
next_ = cache[ind_].prev; \
} while (ind_ != cache_used && (cond)); \
ind_; \
})
/**
Pop the given item from the linked list starting at *head, returning the next
item, or -1 if the list is now empty.
*/
static inline int lla_pop_item (int *head, int i)
{
int prev = cache[i].prev;
int next = cache[i].next;
if (i == next)
{
*head = -1;
return -1;
}
else if (i == *head)
*head = next;
cache[next].prev = prev;
cache[prev].next = next;
return next;
}
/**
Pop the head item from the list starting at *head, returning the index of the
item, or -1 if the list is already empty.
*/
static inline int lla_pop_head (int *head)
{
int i = *head;
if (i != -1)
lla_pop_item(head, i);
return i;
}
/**
Insert the item at index i before the one at index p.
*/
static inline void lla_insert (int i, int p)
{
int next = p;
int prev = cache[next].prev;
cache[next].prev = i;
cache[prev].next = i;
cache[i].next = next;
cache[i].prev = prev;
}
/**
Insert the item at index i at the end of the list starting at *head.
*/
static inline void lla_insert_tail (int *head, int i)
{
if (*head == -1)
{
*head = i;
cache[i].next = i;
cache[i].prev = i;
} else
lla_insert(i, *head);
}
/**
Insert the item at index i before the one at index p.
*/
static inline void lla_insert_after(int i, int p)
{
p = cache[p].next;
lla_insert(i, p);
}
/**
Insert the item at index i before the one at index p in the list starting at
*head
*/
static inline void lla_insert_before(int *head, int i, int p)
{
lla_insert(i, p);
if (*head == p)
*head = i;
}
/**
Free the used slide at index i, and its buffer, and move it to the free
slides list.
*/
static inline void free_slide(int i)
{
if (cache[i].hid != empty_slide_hid)
buflib_free(&buf_ctx, cache[i].hid);
cache[i].index = -1;
lla_pop_item(&cache_used, i);
lla_insert_tail(&cache_free, i);
if (cache_used == -1)
{
cache_right_index = -1;
cache_left_index = -1;
cache_center_index = -1;
}
}
/**
Free one slide ranked above the given priority. If no such slide can be found,
return false.
*/
static inline int free_slide_prio(int prio)
{
if (cache_used == -1)
return false;
int i, l = cache_used, r = cache[cache_used].prev, prio_max;
int prio_l = cache[l].index < center_index ?
center_index - cache[l].index : 0;
int prio_r = cache[r].index > center_index ?
cache[r].index - center_index : 0;
if (prio_l > prio_r)
{
i = l;
prio_max = prio_l;
} else {
i = r;
prio_max = prio_r;
}
if (prio_max > prio)
{
if (i == cache_left_index)
cache_left_index = cache[i].next;
if (i == cache_right_index)
cache_right_index = cache[i].prev;
free_slide(i);
return true;
} else
return false;
}
/**
Read the pfraw image given as filename and return the hid of the buffer
*/
int read_pfraw(char* filename)
int read_pfraw(char* filename, int prio)
{
struct pfraw_header bmph;
int fh = rb->open(filename, O_RDONLY);
rb->read(fh, &bmph, sizeof(struct pfraw_header));
if( fh < 0 ) {
if( fh < 0 )
return empty_slide_hid;
}
else
rb->read(fh, &bmph, sizeof(struct pfraw_header));
int size = sizeof(struct bitmap) + sizeof( pix_t ) *
bmph.width * bmph.height;
int hid = rb->bufalloc(NULL, size, TYPE_BITMAP);
if (hid < 0) {
int hid;
while (!(hid = buflib_alloc(&buf_ctx, size)) && free_slide_prio(prio));
if (!hid) {
rb->close( fh );
return -1;
return 0;
}
struct bitmap *bm;
if (rb->bufgetdata(hid, 0, (void *)&bm) < size) {
rb->close( fh );
return -1;
}
struct dim *bm = buflib_get_data(&buf_ctx, hid);
bm->width = bmph.width;
bm->height = bmph.height;
#if LCD_DEPTH > 1
bm->format = FORMAT_NATIVE;
#endif
bm->data = ((unsigned char *)bm + sizeof(struct bitmap));
pix_t *data = (pix_t*)(sizeof(struct dim) + (char *)bm);
int y;
for( y = 0; y < bm->height; y++ )
{
pix_t *d = (pix_t*)( bm->data ) + (y*bm->width);
rb->read( fh, d , sizeof( pix_t ) * bm->width );
rb->read( fh, data , sizeof( pix_t ) * bm->width );
data += bm->width;
}
rb->close( fh );
return hid;
@ -1080,21 +1136,21 @@ int read_pfraw(char* filename)
Load the surface for the given slide_index into the cache at cache_index.
*/
static inline bool load_and_prepare_surface(const int slide_index,
const int cache_index)
const int cache_index,
const int prio)
{
char tmp_path_name[MAX_PATH+1];
rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw",
slide_index);
int hid = read_pfraw(tmp_path_name);
if (hid < 0)
int hid = read_pfraw(tmp_path_name, prio);
if (!hid)
return false;
cache[cache_index].hid = hid;
if ( cache_index < SLIDE_CACHE_SIZE ) {
cache[cache_index].index = slide_index;
cache[cache_index].touched = *rb->current_tick;
}
return true;
@ -1102,48 +1158,129 @@ static inline bool load_and_prepare_surface(const int slide_index,
/**
Load the surface from a bmp and overwrite the oldest slide in the cache
if necessary.
*/
int load_surface(const int slide_index)
Load the "next" slide that we can load, freeing old slides if needed, provided
that they are further from center_index than the current slide
*/
bool load_new_slide(void)
{
long oldest_tick = *rb->current_tick;
int oldest_slide = 0;
int i;
if ( slide_cache_in_use < SLIDE_CACHE_SIZE ) { /* initial fill */
oldest_slide = slide_cache_in_use;
load_and_prepare_surface(slide_index, slide_cache_in_use++);
}
else {
for (i = 0; i < SLIDE_CACHE_SIZE; i++) { /* look for oldest slide */
if (cache[i].touched < oldest_tick) {
oldest_slide = i;
oldest_tick = cache[i].touched;
int i = -1;
if (cache_center_index != -1)
{
int next, prev;
if (cache[cache_center_index].index != center_index)
{
if (cache[cache_center_index].index < center_index)
{
cache_center_index = seek_right_while(cache_center_index,
cache[next_].index <= center_index);
prev = cache_center_index;
next = cache[cache_center_index].next;
}
else
{
cache_center_index = seek_left_while(cache_center_index,
cache[next_].index >= center_index);
next = cache_center_index;
prev = cache[cache_center_index].prev;
}
if (cache[cache_center_index].index != center_index)
{
if (cache_free == -1)
free_slide_prio(0);
i = lla_pop_head(&cache_free);
if (!load_and_prepare_surface(center_index, i, 0))
goto fail_and_refree;
if (cache[next].index == -1)
{
if (cache[prev].index == -1)
goto insert_first_slide;
else
next = cache[prev].next;
}
lla_insert(i, next);
if (cache[i].index < cache[cache_used].index)
cache_used = i;
cache_center_index = i;
cache_left_index = i;
cache_right_index = i;
return true;
}
}
if (cache[oldest_slide].hid != empty_slide_hid) {
rb->bufclose(cache[oldest_slide].hid);
cache[oldest_slide].hid = -1;
if (cache[cache_left_index].index >
cache[cache_center_index].index)
cache_left_index = cache_center_index;
if (cache[cache_right_index].index <
cache[cache_center_index].index)
cache_right_index = cache_center_index;
cache_left_index = seek_left_while(cache_left_index,
cache[ind_].index - 1 == cache[next_].index);
cache_right_index = seek_right_while(cache_right_index,
cache[ind_].index - 1 == cache[next_].index);
int prio_l = cache[cache_center_index].index -
cache[cache_left_index].index + 1;
int prio_r = cache[cache_right_index].index -
cache[cache_center_index].index + 1;
if ((prio_l < prio_r ||
cache[cache_right_index].index >= number_of_slides) &&
cache[cache_left_index].index > 0)
{
if (cache_free == -1)
free_slide_prio(prio_l);
i = lla_pop_head(&cache_free);
if (load_and_prepare_surface(cache[cache_left_index].index
- 1, i, prio_l))
{
lla_insert_before(&cache_used, i, cache_left_index);
cache_left_index = i;
return true;
}
} else if(cache[cache_right_index].index < number_of_slides - 1)
{
if (cache_free == -1)
free_slide_prio(prio_l);
i = lla_pop_head(&cache_free);
if (load_and_prepare_surface(cache[cache_right_index].index
+ 1, i, prio_r))
{
lla_insert_after(i, cache_right_index);
cache_right_index = i;
return true;
}
}
} else {
i = lla_pop_head(&cache_free);
if (load_and_prepare_surface(center_index, i, 0))
{
insert_first_slide:
cache[i].next = i;
cache[i].prev = i;
cache_center_index = i;
cache_left_index = i;
cache_right_index = i;
cache_used = i;
return true;
}
load_and_prepare_surface(slide_index, oldest_slide);
}
return oldest_slide;
fail_and_refree:
if (i != -1)
{
lla_insert_tail(&cache_free, i);
}
return false;
}
/**
Get a slide from the buffer
*/
static inline struct bitmap *get_slide(const int hid)
static inline struct dim *get_slide(const int hid)
{
if (hid < 0)
if (!hid)
return NULL;
struct bitmap *bmp;
struct dim *bmp;
ssize_t ret = rb->bufgetdata(hid, 0, (void *)&bmp);
if (ret < 0)
return NULL;
bmp = buflib_get_data(&buf_ctx, hid);
return bmp;
}
@ -1152,23 +1289,21 @@ static inline struct bitmap *get_slide(const int hid)
/**
Return the requested surface
*/
static inline struct bitmap *surface(const int slide_index)
static inline struct dim *surface(const int slide_index)
{
if (slide_index < 0)
return 0;
if (slide_index >= number_of_slides)
return 0;
int i;
for (i = 0; i < slide_cache_in_use; i++) {
/* maybe do the inverse mapping => implies dynamic allocation? */
if ( cache[i].index == slide_index ) {
/* We have already loaded our slide, so touch it and return it. */
cache[i].touched = *rb->current_tick;
return get_slide(cache[i].hid);
}
if ((i = cache_used ) != -1)
{
do {
if (cache[i].index == slide_index)
return get_slide(cache[i].hid);
i = cache[i].next;
} while (i != cache_used);
}
request_surface(slide_index);
return get_slide(empty_slide_hid);
}
@ -1293,13 +1428,13 @@ static inline pix_t fade_color(pix_t c, unsigned int a)
*/
void render_slide(struct slide_data *slide, const int alpha)
{
struct bitmap *bmp = surface(slide->slide_index);
struct dim *bmp = surface(slide->slide_index);
if (!bmp) {
return;
}
if (slide->angle > 255 || slide->angle < -255)
return;
pix_t *src = (pix_t *)bmp->data;
pix_t *src = (pix_t*)(sizeof(struct dim) + (char *)bmp);
const int sw = bmp->width;
const int sh = bmp->height;
@ -1329,7 +1464,7 @@ void render_slide(struct slide_data *slide, const int alpha)
xsnum = CAM_DIST * (slide->cx - xp) - fmuln(xp, zo, PFREAL_SHIFT - 2, 0);
xsden = fmuln(xp, sinr, PFREAL_SHIFT - 2, 0) - CAM_DIST * cosr;
xs = fdiv(xsnum, xsden);
xsnumi = -CAM_DIST_R - zo;
xsdeni = sinr;
int x;
@ -1411,11 +1546,10 @@ void render_slide(struct slide_data *slide, const int alpha)
xs = fdiv(xsnum, xsden);
} else
xs += PFREAL_ONE;
}
/* let the music play... */
rb->yield();
return;
}
@ -1425,8 +1559,11 @@ void render_slide(struct slide_data *slide, const int alpha)
*/
static inline void set_current_slide(const int slide_index)
{
int old_center_index = center_index;
step = 0;
center_index = fbound(slide_index, 0, number_of_slides - 1);
if (old_center_index != center_index)
rb->queue_post(&thread_q, EV_WAKEUP, 0);
target = center_index;
slide_frame = slide_index << 16;
reset_slides();
@ -1583,6 +1720,7 @@ void update_scroll_animation(void)
index++;
if (center_index != index) {
center_index = index;
rb->queue_post(&thread_q, EV_WAKEUP, 0);
slide_frame = index << 16;
center_slide.slide_index = center_index;
for (i = 0; i < num_slides; i++)
@ -1652,12 +1790,6 @@ void cleanup(void *parameter)
/* Turn on backlight timeout (revert to settings) */
backlight_use_settings(); /* backlight control in lib/helper.c */
int i;
for (i = 0; i < slide_cache_in_use; i++) {
rb->bufclose(cache[i].hid);
}
if ( empty_slide_hid != - 1)
rb->bufclose(empty_slide_hid);
#ifdef USEGSLIB
grey_release();
#endif
@ -1687,9 +1819,6 @@ int create_empty_slide(bool force)
return false;
}
empty_slide_hid = read_pfraw( EMPTY_SLIDE );
if (empty_slide_hid == -1 ) return false;
return true;
}
@ -2053,7 +2182,7 @@ void draw_album_text(void)
int main(void)
{
int ret;
rb->lcd_setfont(FONT_UI);
draw_splashscreen();
@ -2068,6 +2197,7 @@ int main(void)
init_reflect_table();
ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4);
ret = create_album_index();
if (ret == ERROR_BUFFER_FULL) {
rb->splash(HZ, "Not enough memory for album names");
@ -2076,7 +2206,8 @@ int main(void)
rb->splash(HZ, "No albums found. Please enable database");
return PLUGIN_ERROR;
}
ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4);
number_of_slides = album_count;
if ((cache_version != CACHE_VERSION) && !create_albumart_cache()) {
rb->splash(HZ, "Could not create album art cache");
@ -2090,6 +2221,27 @@ int main(void)
cache_version = CACHE_VERSION;
configfile_save(CONFIG_FILE, config, CONFIG_NUM_ITEMS, CONFIG_VERSION);
#ifdef USEGSLIB
long grey_buf_used;
if (!grey_init(plugin_buf, plugin_buf_size, GREY_BUFFERED|GREY_ON_COP,
LCD_WIDTH, LCD_HEIGHT, &grey_buf_used))
{
rb->splash(HZ, "Greylib init failed!");
return PLUGIN_ERROR;
}
grey_setfont(FONT_UI);
plugin_buf_size -= grey_buf_used;
plugin_buf = (void*)(grey_buf_used + (char*)plugin_buf);
#endif
buflib_init(&buf_ctx, (void *)plugin_buf, plugin_buf_size);
if (!(empty_slide_hid = read_pfraw(EMPTY_SLIDE, 0)))
{
rb->splash(HZ, "Unable to load empty slide image");
return PLUGIN_ERROR;
}
if (!create_pf_thread()) {
rb->splash(HZ, "Cannot create thread!");
return PLUGIN_ERROR;
@ -2098,27 +2250,21 @@ int main(void)
int i;
/* initialize */
int min_slide_cache = fmin(number_of_slides, SLIDE_CACHE_SIZE);
for (i = 0; i < min_slide_cache; i++) {
cache[i].hid = -1;
cache[i].touched = 0;
slide_cache_stack[i] = SLIDE_CACHE_SIZE-i-1;
for (i = 0; i < SLIDE_CACHE_SIZE; i++) {
cache[i].hid = 0;
cache[i].index = 0;
cache[i].next = i + 1;
cache[i].prev = i - 1;
}
slide_cache_stack_index = min_slide_cache-1;
slide_cache_in_use = 0;
#ifdef USEGSLIB
if (!grey_init(plugin_buf, plugin_buf_size, GREY_BUFFERED|GREY_ON_COP,
LCD_WIDTH, LCD_HEIGHT, NULL))
rb->splash(HZ, "Greylib init failed!");
grey_setfont(FONT_UI);
#endif
cache[0].prev = i - 1;
cache[i - 1].next = 0;
cache_free = 0;
buffer = LCD_BUF;
pf_state = pf_idle;
track_index = -1;
extra_fade = 0;
center_index = 0;
slide_frame = 0;
step = 0;
target = 0;
@ -2289,7 +2435,6 @@ int main(void)
enum plugin_status plugin_start(const void *parameter)
{
int ret;
(void) parameter;
#if LCD_DEPTH > 1
rb->lcd_set_backdrop(NULL);
@ -2300,7 +2445,6 @@ enum plugin_status plugin_start(const void *parameter)
rb->cpu_boost(true);
#endif
plugin_buf = rb->plugin_get_buffer(&plugin_buf_size);
ALIGN_BUFFER(plugin_buf, plugin_buf_size, 4);
ret = main();
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(false);