summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-09-08 12:38:21 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-09-08 12:38:21 +0000
commita483c9c6f1e6674eb2b5dcf01e21a7ab4c77e24f (patch)
tree302bc4b8550d2d81b489fb8f0f93bd5356dc7ead
parent4f4e91e341058c1ea1ddd3d36f67ae276fe545ad (diff)
downloadrockbox-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.c20
-rw-r--r--apps/gui/skin_engine/skin_engine.h10
-rw-r--r--apps/gui/skin_engine/skin_parser.c69
-rw-r--r--apps/gui/skin_engine/wps_internals.h1
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)
350void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) 357void 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 **/
1390static void skin_data_reset(struct wps_data *wps_data) 1393static 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
1433static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) 1446#ifndef __PCTOOL__
1447static int currently_loading_handle = -1;
1448static 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}
1456static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL};
1457static void lock_handle(int handle)
1458{
1459 currently_loading_handle = handle;
1460}
1461static void unlock_handle(void)
1462{
1463 currently_loading_handle = -1;
1464}
1465#endif
1466
1467static 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
1485static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) 1529static 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 */