diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2011-09-08 12:38:21 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2011-09-08 12:38:21 +0000 |
commit | a483c9c6f1e6674eb2b5dcf01e21a7ab4c77e24f (patch) | |
tree | 302bc4b8550d2d81b489fb8f0f93bd5356dc7ead | |
parent | 4f4e91e341058c1ea1ddd3d36f67ae276fe545ad (diff) | |
download | rockbox-a483c9c6f1e6674eb2b5dcf01e21a7ab4c77e24f.tar.gz rockbox-a483c9c6f1e6674eb2b5dcf01e21a7ab4c77e24f.zip |
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
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 20 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_engine.h | 10 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 69 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 1 |
4 files changed, 73 insertions, 27 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 49f9f86133..f7a0888afc 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include <stdio.h> | 23 | #include <stdio.h> |
24 | #include "string-extra.h" | 24 | #include "string-extra.h" |
25 | #include "core_alloc.h" | ||
25 | #include "misc.h" | 26 | #include "misc.h" |
26 | #include "font.h" | 27 | #include "font.h" |
27 | #include "system.h" | 28 | #include "system.h" |
@@ -247,15 +248,16 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) | |||
247 | if (pb->backdrop) | 248 | if (pb->backdrop) |
248 | { | 249 | { |
249 | struct gui_img *img = pb->backdrop; | 250 | struct gui_img *img = pb->backdrop; |
251 | char *img_data = core_get_data(img->buflib_handle); | ||
250 | #if LCD_DEPTH > 1 | 252 | #if LCD_DEPTH > 1 |
251 | if(img->bm.format == FORMAT_MONO) { | 253 | if(img->bm.format == FORMAT_MONO) { |
252 | #endif | 254 | #endif |
253 | display->mono_bitmap_part(img->bm.data, | 255 | display->mono_bitmap_part(img_data, |
254 | 0, 0, img->bm.width, | 256 | 0, 0, img->bm.width, |
255 | x, y, width, height); | 257 | x, y, width, height); |
256 | #if LCD_DEPTH > 1 | 258 | #if LCD_DEPTH > 1 |
257 | } else { | 259 | } else { |
258 | display->transparent_bitmap_part((fb_data *)img->bm.data, | 260 | display->transparent_bitmap_part((fb_data *)img_data, |
259 | 0, 0, | 261 | 0, 0, |
260 | STRIDE(display->screen_type, | 262 | STRIDE(display->screen_type, |
261 | img->bm.width, img->bm.height), | 263 | img->bm.width, img->bm.height), |
@@ -268,9 +270,13 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) | |||
268 | if (!pb->nobar) | 270 | if (!pb->nobar) |
269 | { | 271 | { |
270 | if (pb->image) | 272 | if (pb->image) |
273 | { | ||
274 | char *img_data = core_get_data(pb->image->buflib_handle); | ||
275 | pb->image->bm.data = img_data; | ||
271 | gui_bitmap_scrollbar_draw(display, &pb->image->bm, | 276 | gui_bitmap_scrollbar_draw(display, &pb->image->bm, |
272 | x, y, width, height, | 277 | x, y, width, height, |
273 | length, 0, end, flags); | 278 | length, 0, end, flags); |
279 | } | ||
274 | else | 280 | else |
275 | gui_scrollbar_draw(display, x, y, width, height, | 281 | gui_scrollbar_draw(display, x, y, width, height, |
276 | length, 0, end, flags); | 282 | length, 0, end, flags); |
@@ -281,6 +287,7 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) | |||
281 | int xoff = 0, yoff = 0; | 287 | int xoff = 0, yoff = 0; |
282 | int w = width, h = height; | 288 | int w = width, h = height; |
283 | struct gui_img *img = pb->slider; | 289 | struct gui_img *img = pb->slider; |
290 | char *img_data = core_get_data(img->buflib_handle); | ||
284 | 291 | ||
285 | if (flags&HORIZONTAL) | 292 | if (flags&HORIZONTAL) |
286 | { | 293 | { |
@@ -301,12 +308,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) | |||
301 | #if LCD_DEPTH > 1 | 308 | #if LCD_DEPTH > 1 |
302 | if(img->bm.format == FORMAT_MONO) { | 309 | if(img->bm.format == FORMAT_MONO) { |
303 | #endif | 310 | #endif |
304 | display->mono_bitmap_part(img->bm.data, | 311 | display->mono_bitmap_part(img_data, |
305 | 0, 0, img->bm.width, | 312 | 0, 0, img->bm.width, |
306 | x + xoff, y + yoff, w, h); | 313 | x + xoff, y + yoff, w, h); |
307 | #if LCD_DEPTH > 1 | 314 | #if LCD_DEPTH > 1 |
308 | } else { | 315 | } else { |
309 | display->transparent_bitmap_part((fb_data *)img->bm.data, | 316 | display->transparent_bitmap_part((fb_data *)img_data, |
310 | 0, 0, | 317 | 0, 0, |
311 | STRIDE(display->screen_type, | 318 | STRIDE(display->screen_type, |
312 | img->bm.width, img->bm.height), | 319 | img->bm.width, img->bm.height), |
@@ -350,6 +357,7 @@ void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) | |||
350 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) | 357 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) |
351 | { | 358 | { |
352 | struct screen *display = gwps->display; | 359 | struct screen *display = gwps->display; |
360 | char *img_data = core_get_data(img->buflib_handle); | ||
353 | if(img->always_display) | 361 | if(img->always_display) |
354 | display->set_drawmode(DRMODE_FG); | 362 | display->set_drawmode(DRMODE_FG); |
355 | else | 363 | else |
@@ -358,14 +366,14 @@ void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) | |||
358 | #if LCD_DEPTH > 1 | 366 | #if LCD_DEPTH > 1 |
359 | if(img->bm.format == FORMAT_MONO) { | 367 | if(img->bm.format == FORMAT_MONO) { |
360 | #endif | 368 | #endif |
361 | display->mono_bitmap_part(img->bm.data, | 369 | display->mono_bitmap_part(img_data, |
362 | 0, img->subimage_height * subimage, | 370 | 0, img->subimage_height * subimage, |
363 | img->bm.width, img->x, | 371 | img->bm.width, img->x, |
364 | img->y, img->bm.width, | 372 | img->y, img->bm.width, |
365 | img->subimage_height); | 373 | img->subimage_height); |
366 | #if LCD_DEPTH > 1 | 374 | #if LCD_DEPTH > 1 |
367 | } else { | 375 | } else { |
368 | display->transparent_bitmap_part((fb_data *)img->bm.data, | 376 | display->transparent_bitmap_part((fb_data *)img_data, |
369 | 0, img->subimage_height * subimage, | 377 | 0, img->subimage_height * subimage, |
370 | STRIDE(display->screen_type, | 378 | STRIDE(display->screen_type, |
371 | img->bm.width, img->bm.height), | 379 | img->bm.width, img->bm.height), |
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index 52ec19d5f9..c8104f9304 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h | |||
@@ -43,16 +43,8 @@ enum skinnable_screens { | |||
43 | 43 | ||
44 | 44 | ||
45 | #ifdef HAVE_LCD_BITMAP | 45 | #ifdef HAVE_LCD_BITMAP |
46 | #define MAIN_BUFFER (2*LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) | ||
47 | 46 | ||
48 | #if (NB_SCREENS > 1) | 47 | #define SKIN_BUFFER_SIZE (2048 + SKIN_FONT_SIZE) + \ |
49 | #define REMOTE_BUFFER (2*(LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH*LCD_REMOTE_DEPTH/8)) | ||
50 | #else | ||
51 | #define REMOTE_BUFFER 0 | ||
52 | #endif | ||
53 | |||
54 | |||
55 | #define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER + SKIN_FONT_SIZE) + \ | ||
56 | (WPS_MAX_TOKENS * \ | 48 | (WPS_MAX_TOKENS * \ |
57 | (sizeof(struct wps_token) + (sizeof(struct skin_element)))) | 49 | (sizeof(struct wps_token) + (sizeof(struct skin_element)))) |
58 | #endif | 50 | #endif |
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 373309ff51..a866101c1c 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <string.h> | 24 | #include <string.h> |
25 | #include <stdlib.h> | 25 | #include <stdlib.h> |
26 | #include "config.h" | 26 | #include "config.h" |
27 | #include "core_alloc.h" | ||
27 | #include "file.h" | 28 | #include "file.h" |
28 | #include "misc.h" | 29 | #include "misc.h" |
29 | #include "plugin.h" | 30 | #include "plugin.h" |
@@ -364,6 +365,7 @@ static int parse_image_load(struct skin_element *element, | |||
364 | img->always_display = false; | 365 | img->always_display = false; |
365 | img->display = -1; | 366 | img->display = -1; |
366 | img->using_preloaded_icons = false; | 367 | img->using_preloaded_icons = false; |
368 | img->buflib_handle = -1; | ||
367 | 369 | ||
368 | /* save current viewport */ | 370 | /* save current viewport */ |
369 | img->vp = &curr_vp->vp; | 371 | img->vp = &curr_vp->vp; |
@@ -885,6 +887,7 @@ static int parse_progressbar_tag(struct skin_element* element, | |||
885 | img->always_display = false; | 887 | img->always_display = false; |
886 | img->display = -1; | 888 | img->display = -1; |
887 | img->using_preloaded_icons = false; | 889 | img->using_preloaded_icons = false; |
890 | img->buflib_handle = -1; | ||
888 | img->vp = &curr_vp->vp; | 891 | img->vp = &curr_vp->vp; |
889 | struct skin_token_list *item = | 892 | struct skin_token_list *item = |
890 | (struct skin_token_list *)new_skin_token_list_item(NULL, img); | 893 | (struct skin_token_list *)new_skin_token_list_item(NULL, img); |
@@ -1389,10 +1392,20 @@ static bool check_feature_tag(const int type) | |||
1389 | **/ | 1392 | **/ |
1390 | static void skin_data_reset(struct wps_data *wps_data) | 1393 | static void skin_data_reset(struct wps_data *wps_data) |
1391 | { | 1394 | { |
1392 | wps_data->tree = NULL; | ||
1393 | #ifdef HAVE_LCD_BITMAP | 1395 | #ifdef HAVE_LCD_BITMAP |
1396 | #ifndef __PCTOOL__ | ||
1397 | struct skin_token_list *list = wps_data->images; | ||
1398 | while (list) | ||
1399 | { | ||
1400 | struct gui_img *img = (struct gui_img*)list->token->value.data; | ||
1401 | if (img->buflib_handle > 0) | ||
1402 | core_free(img->buflib_handle); | ||
1403 | list = list->next; | ||
1404 | } | ||
1405 | #endif | ||
1394 | wps_data->images = NULL; | 1406 | wps_data->images = NULL; |
1395 | #endif | 1407 | #endif |
1408 | wps_data->tree = NULL; | ||
1396 | #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 | 1409 | #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 |
1397 | if (wps_data->backdrop_id >= 0) | 1410 | if (wps_data->backdrop_id >= 0) |
1398 | skin_backdrop_unload(wps_data->backdrop_id); | 1411 | skin_backdrop_unload(wps_data->backdrop_id); |
@@ -1430,11 +1443,33 @@ static void skin_data_reset(struct wps_data *wps_data) | |||
1430 | } | 1443 | } |
1431 | 1444 | ||
1432 | #ifdef HAVE_LCD_BITMAP | 1445 | #ifdef HAVE_LCD_BITMAP |
1433 | static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) | 1446 | #ifndef __PCTOOL__ |
1447 | static int currently_loading_handle = -1; | ||
1448 | static int buflib_move_callback(int handle, void* current, void* new) | ||
1449 | { | ||
1450 | (void)current; | ||
1451 | (void)new; | ||
1452 | if (handle == currently_loading_handle) | ||
1453 | return BUFLIB_CB_CANNOT_MOVE; | ||
1454 | return BUFLIB_CB_OK; | ||
1455 | } | ||
1456 | static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL}; | ||
1457 | static void lock_handle(int handle) | ||
1458 | { | ||
1459 | currently_loading_handle = handle; | ||
1460 | } | ||
1461 | static void unlock_handle(void) | ||
1462 | { | ||
1463 | currently_loading_handle = -1; | ||
1464 | } | ||
1465 | #endif | ||
1466 | |||
1467 | static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) | ||
1434 | { | 1468 | { |
1435 | (void)wps_data; /* only needed for remote targets */ | 1469 | (void)wps_data; /* only needed for remote targets */ |
1436 | char img_path[MAX_PATH]; | 1470 | char img_path[MAX_PATH]; |
1437 | int fd; | 1471 | int fd; |
1472 | int handle; | ||
1438 | get_image_filename(bitmap->data, bmpdir, | 1473 | get_image_filename(bitmap->data, bmpdir, |
1439 | img_path, sizeof(img_path)); | 1474 | img_path, sizeof(img_path)); |
1440 | 1475 | ||
@@ -1451,35 +1486,44 @@ static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char | |||
1451 | if (fd < 0) | 1486 | if (fd < 0) |
1452 | { | 1487 | { |
1453 | DEBUGF("Couldn't open %s\n", img_path); | 1488 | DEBUGF("Couldn't open %s\n", img_path); |
1454 | return false; | 1489 | return fd; |
1455 | } | 1490 | } |
1491 | #ifndef __PCTOOL__ | ||
1456 | size_t buf_size = read_bmp_fd(fd, bitmap, 0, | 1492 | size_t buf_size = read_bmp_fd(fd, bitmap, 0, |
1457 | format|FORMAT_RETURN_SIZE, NULL); | 1493 | format|FORMAT_RETURN_SIZE, NULL); |
1458 | char* imgbuf = (char*)skin_buffer_alloc(buf_size); | 1494 | handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops); |
1459 | if (!imgbuf) | 1495 | if (handle < 0) |
1460 | { | 1496 | { |
1461 | #ifndef APPLICATION | 1497 | #ifndef APPLICATION |
1462 | DEBUGF("Not enough skin buffer: need %zd more.\n", | 1498 | DEBUGF("Not enough skin buffer: need %zd more.\n", |
1463 | buf_size - skin_buffer_freespace()); | 1499 | buf_size - skin_buffer_freespace()); |
1464 | #endif | 1500 | #endif |
1465 | close(fd); | 1501 | close(fd); |
1466 | return NULL; | 1502 | return handle; |
1467 | } | 1503 | } |
1468 | lseek(fd, 0, SEEK_SET); | 1504 | lseek(fd, 0, SEEK_SET); |
1469 | bitmap->data = imgbuf; | 1505 | lock_handle(handle); |
1506 | bitmap->data = core_get_data(handle); | ||
1470 | int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL); | 1507 | int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL); |
1471 | 1508 | bitmap->data = NULL; /* do this to force a crash later if the | |
1509 | caller doesnt call core_get_data() */ | ||
1510 | unlock_handle(); | ||
1472 | close(fd); | 1511 | close(fd); |
1473 | if (ret > 0) | 1512 | if (ret > 0) |
1474 | { | 1513 | { |
1475 | return true; | 1514 | return handle; |
1476 | } | 1515 | } |
1477 | else | 1516 | else |
1478 | { | 1517 | { |
1479 | /* Abort if we can't load an image */ | 1518 | /* Abort if we can't load an image */ |
1480 | DEBUGF("Couldn't load '%s'\n", img_path); | 1519 | DEBUGF("Couldn't load '%s'\n", img_path); |
1481 | return false; | 1520 | core_free(handle); |
1521 | return -1; | ||
1482 | } | 1522 | } |
1523 | #else /* !__PCTOOL__ */ | ||
1524 | close(fd); | ||
1525 | return 1; | ||
1526 | #endif | ||
1483 | } | 1527 | } |
1484 | 1528 | ||
1485 | static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) | 1529 | 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) | |||
1501 | } | 1545 | } |
1502 | else | 1546 | else |
1503 | { | 1547 | { |
1504 | img->loaded = load_skin_bmp(wps_data, &img->bm, bmpdir); | 1548 | img->buflib_handle = load_skin_bmp(wps_data, &img->bm, bmpdir); |
1549 | img->loaded = img->buflib_handle >= 0; | ||
1505 | if (img->loaded) | 1550 | if (img->loaded) |
1506 | img->subimage_height = img->bm.height / img->num_subimages; | 1551 | img->subimage_height = img->bm.height / img->num_subimages; |
1507 | else | 1552 | else |
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 136ec2921a..e996c96613 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h | |||
@@ -77,6 +77,7 @@ struct gui_img { | |||
77 | short int num_subimages; /* number of sub-images */ | 77 | short int num_subimages; /* number of sub-images */ |
78 | short int subimage_height; /* height of each sub-image */ | 78 | short int subimage_height; /* height of each sub-image */ |
79 | struct bitmap bm; | 79 | struct bitmap bm; |
80 | int buflib_handle; | ||
80 | const char *label; | 81 | const char *label; |
81 | bool loaded; /* load state */ | 82 | bool loaded; /* load state */ |
82 | bool always_display; /* not using the preload/display mechanism */ | 83 | bool always_display; /* not using the preload/display mechanism */ |