1
0
Fork 0
forked from len0rd/rockbox

Use buflib for skin images. Allows much more images to be loaded

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30478 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jonathan Gordon 2011-09-08 12:38:21 +00:00
parent 4f4e91e341
commit a483c9c6f1
4 changed files with 73 additions and 27 deletions

View file

@ -22,6 +22,7 @@
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include "string-extra.h" #include "string-extra.h"
#include "core_alloc.h"
#include "misc.h" #include "misc.h"
#include "font.h" #include "font.h"
#include "system.h" #include "system.h"
@ -247,15 +248,16 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
if (pb->backdrop) if (pb->backdrop)
{ {
struct gui_img *img = pb->backdrop; struct gui_img *img = pb->backdrop;
char *img_data = core_get_data(img->buflib_handle);
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if(img->bm.format == FORMAT_MONO) { if(img->bm.format == FORMAT_MONO) {
#endif #endif
display->mono_bitmap_part(img->bm.data, display->mono_bitmap_part(img_data,
0, 0, img->bm.width, 0, 0, img->bm.width,
x, y, width, height); x, y, width, height);
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
} else { } else {
display->transparent_bitmap_part((fb_data *)img->bm.data, display->transparent_bitmap_part((fb_data *)img_data,
0, 0, 0, 0,
STRIDE(display->screen_type, STRIDE(display->screen_type,
img->bm.width, img->bm.height), img->bm.width, img->bm.height),
@ -268,9 +270,13 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
if (!pb->nobar) if (!pb->nobar)
{ {
if (pb->image) if (pb->image)
{
char *img_data = core_get_data(pb->image->buflib_handle);
pb->image->bm.data = img_data;
gui_bitmap_scrollbar_draw(display, &pb->image->bm, gui_bitmap_scrollbar_draw(display, &pb->image->bm,
x, y, width, height, x, y, width, height,
length, 0, end, flags); length, 0, end, flags);
}
else else
gui_scrollbar_draw(display, x, y, width, height, gui_scrollbar_draw(display, x, y, width, height,
length, 0, end, flags); length, 0, end, flags);
@ -281,6 +287,7 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
int xoff = 0, yoff = 0; int xoff = 0, yoff = 0;
int w = width, h = height; int w = width, h = height;
struct gui_img *img = pb->slider; struct gui_img *img = pb->slider;
char *img_data = core_get_data(img->buflib_handle);
if (flags&HORIZONTAL) if (flags&HORIZONTAL)
{ {
@ -301,12 +308,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if(img->bm.format == FORMAT_MONO) { if(img->bm.format == FORMAT_MONO) {
#endif #endif
display->mono_bitmap_part(img->bm.data, display->mono_bitmap_part(img_data,
0, 0, img->bm.width, 0, 0, img->bm.width,
x + xoff, y + yoff, w, h); x + xoff, y + yoff, w, h);
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
} else { } else {
display->transparent_bitmap_part((fb_data *)img->bm.data, display->transparent_bitmap_part((fb_data *)img_data,
0, 0, 0, 0,
STRIDE(display->screen_type, STRIDE(display->screen_type,
img->bm.width, img->bm.height), img->bm.width, img->bm.height),
@ -350,6 +357,7 @@ void clear_image_pos(struct gui_wps *gwps, struct gui_img *img)
void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage)
{ {
struct screen *display = gwps->display; struct screen *display = gwps->display;
char *img_data = core_get_data(img->buflib_handle);
if(img->always_display) if(img->always_display)
display->set_drawmode(DRMODE_FG); display->set_drawmode(DRMODE_FG);
else else
@ -358,14 +366,14 @@ void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage)
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if(img->bm.format == FORMAT_MONO) { if(img->bm.format == FORMAT_MONO) {
#endif #endif
display->mono_bitmap_part(img->bm.data, display->mono_bitmap_part(img_data,
0, img->subimage_height * subimage, 0, img->subimage_height * subimage,
img->bm.width, img->x, img->bm.width, img->x,
img->y, img->bm.width, img->y, img->bm.width,
img->subimage_height); img->subimage_height);
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
} else { } else {
display->transparent_bitmap_part((fb_data *)img->bm.data, display->transparent_bitmap_part((fb_data *)img_data,
0, img->subimage_height * subimage, 0, img->subimage_height * subimage,
STRIDE(display->screen_type, STRIDE(display->screen_type,
img->bm.width, img->bm.height), img->bm.width, img->bm.height),

View file

@ -43,16 +43,8 @@ enum skinnable_screens {
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#define MAIN_BUFFER (2*LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8)
#if (NB_SCREENS > 1) #define SKIN_BUFFER_SIZE (2048 + SKIN_FONT_SIZE) + \
#define REMOTE_BUFFER (2*(LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH*LCD_REMOTE_DEPTH/8))
#else
#define REMOTE_BUFFER 0
#endif
#define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER + SKIN_FONT_SIZE) + \
(WPS_MAX_TOKENS * \ (WPS_MAX_TOKENS * \
(sizeof(struct wps_token) + (sizeof(struct skin_element)))) (sizeof(struct wps_token) + (sizeof(struct skin_element))))
#endif #endif

View file

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "config.h" #include "config.h"
#include "core_alloc.h"
#include "file.h" #include "file.h"
#include "misc.h" #include "misc.h"
#include "plugin.h" #include "plugin.h"
@ -364,6 +365,7 @@ static int parse_image_load(struct skin_element *element,
img->always_display = false; img->always_display = false;
img->display = -1; img->display = -1;
img->using_preloaded_icons = false; img->using_preloaded_icons = false;
img->buflib_handle = -1;
/* save current viewport */ /* save current viewport */
img->vp = &curr_vp->vp; img->vp = &curr_vp->vp;
@ -885,6 +887,7 @@ static int parse_progressbar_tag(struct skin_element* element,
img->always_display = false; img->always_display = false;
img->display = -1; img->display = -1;
img->using_preloaded_icons = false; img->using_preloaded_icons = false;
img->buflib_handle = -1;
img->vp = &curr_vp->vp; img->vp = &curr_vp->vp;
struct skin_token_list *item = struct skin_token_list *item =
(struct skin_token_list *)new_skin_token_list_item(NULL, img); (struct skin_token_list *)new_skin_token_list_item(NULL, img);
@ -1389,10 +1392,20 @@ static bool check_feature_tag(const int type)
**/ **/
static void skin_data_reset(struct wps_data *wps_data) static void skin_data_reset(struct wps_data *wps_data)
{ {
wps_data->tree = NULL;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#ifndef __PCTOOL__
struct skin_token_list *list = wps_data->images;
while (list)
{
struct gui_img *img = (struct gui_img*)list->token->value.data;
if (img->buflib_handle > 0)
core_free(img->buflib_handle);
list = list->next;
}
#endif
wps_data->images = NULL; wps_data->images = NULL;
#endif #endif
wps_data->tree = NULL;
#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
if (wps_data->backdrop_id >= 0) if (wps_data->backdrop_id >= 0)
skin_backdrop_unload(wps_data->backdrop_id); skin_backdrop_unload(wps_data->backdrop_id);
@ -1430,11 +1443,33 @@ static void skin_data_reset(struct wps_data *wps_data)
} }
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) #ifndef __PCTOOL__
static int currently_loading_handle = -1;
static int buflib_move_callback(int handle, void* current, void* new)
{
(void)current;
(void)new;
if (handle == currently_loading_handle)
return BUFLIB_CB_CANNOT_MOVE;
return BUFLIB_CB_OK;
}
static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL};
static void lock_handle(int handle)
{
currently_loading_handle = handle;
}
static void unlock_handle(void)
{
currently_loading_handle = -1;
}
#endif
static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir)
{ {
(void)wps_data; /* only needed for remote targets */ (void)wps_data; /* only needed for remote targets */
char img_path[MAX_PATH]; char img_path[MAX_PATH];
int fd; int fd;
int handle;
get_image_filename(bitmap->data, bmpdir, get_image_filename(bitmap->data, bmpdir,
img_path, sizeof(img_path)); img_path, sizeof(img_path));
@ -1451,35 +1486,44 @@ static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char
if (fd < 0) if (fd < 0)
{ {
DEBUGF("Couldn't open %s\n", img_path); DEBUGF("Couldn't open %s\n", img_path);
return false; return fd;
} }
#ifndef __PCTOOL__
size_t buf_size = read_bmp_fd(fd, bitmap, 0, size_t buf_size = read_bmp_fd(fd, bitmap, 0,
format|FORMAT_RETURN_SIZE, NULL); format|FORMAT_RETURN_SIZE, NULL);
char* imgbuf = (char*)skin_buffer_alloc(buf_size); handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops);
if (!imgbuf) if (handle < 0)
{ {
#ifndef APPLICATION #ifndef APPLICATION
DEBUGF("Not enough skin buffer: need %zd more.\n", DEBUGF("Not enough skin buffer: need %zd more.\n",
buf_size - skin_buffer_freespace()); buf_size - skin_buffer_freespace());
#endif #endif
close(fd); close(fd);
return NULL; return handle;
} }
lseek(fd, 0, SEEK_SET); lseek(fd, 0, SEEK_SET);
bitmap->data = imgbuf; lock_handle(handle);
bitmap->data = core_get_data(handle);
int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL); int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL);
bitmap->data = NULL; /* do this to force a crash later if the
caller doesnt call core_get_data() */
unlock_handle();
close(fd); close(fd);
if (ret > 0) if (ret > 0)
{ {
return true; return handle;
} }
else else
{ {
/* Abort if we can't load an image */ /* Abort if we can't load an image */
DEBUGF("Couldn't load '%s'\n", img_path); DEBUGF("Couldn't load '%s'\n", img_path);
return false; core_free(handle);
return -1;
} }
#else /* !__PCTOOL__ */
close(fd);
return 1;
#endif
} }
static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
@ -1501,7 +1545,8 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
} }
else else
{ {
img->loaded = load_skin_bmp(wps_data, &img->bm, bmpdir); img->buflib_handle = load_skin_bmp(wps_data, &img->bm, bmpdir);
img->loaded = img->buflib_handle >= 0;
if (img->loaded) if (img->loaded)
img->subimage_height = img->bm.height / img->num_subimages; img->subimage_height = img->bm.height / img->num_subimages;
else else

View file

@ -77,6 +77,7 @@ struct gui_img {
short int num_subimages; /* number of sub-images */ short int num_subimages; /* number of sub-images */
short int subimage_height; /* height of each sub-image */ short int subimage_height; /* height of each sub-image */
struct bitmap bm; struct bitmap bm;
int buflib_handle;
const char *label; const char *label;
bool loaded; /* load state */ bool loaded; /* load state */
bool always_display; /* not using the preload/display mechanism */ bool always_display; /* not using the preload/display mechanism */