blob: d18122ef20f2e1ce5592ca643c5a074849d63cbe [file] [log] [blame]
Jonathan Gordondb658d92010-06-17 08:36:28 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: skin_buffer.c 25962 2010-05-12 09:31:40Z jdgordon $
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
Jonathan Gordon97857322010-11-04 10:15:33 +000011 * Copyright (C) 2010 Jonathan Gordon
Jonathan Gordondb658d92010-06-17 08:36:28 +000012 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26
Jonathan Gordon2d31d772010-07-29 12:37:48 +000027#include "skin_buffer.h"
Jonathan Gordon21e89e82011-01-27 11:27:53 +000028#include "skin_parser.h"
Jonathan Gordon2d31d772010-07-29 12:37:48 +000029
Jonathan Gordon97857322010-11-04 10:15:33 +000030/****************************************************************************
31 *
32 * This code handles buffer allocation for the entire skin system.
33 * This needs to work in 3 different situations:
34 * 1) as a stand alone library. ROCKBOX isnt defined, alloc using malloc()
35 * and free the skin elements only (no callbacks doing more allocation)
36 * 2) ROCKBOX builds for normal targets, alloc from a single big buffer
37 * which origionally came from the audio buffer, likely to run out of
38 * room with large themes. No need to free anything, just restore to
39 * the start of our buffer
40 * 3) ROCKBOX "application/hosted" builds, alloc using the hosts malloc().
41 * We need to keep track of all allocations so they can be free()'d easily
42 *
43 *
44 ****************************************************************************/
45
46
Jonathan Gordondb658d92010-06-17 08:36:28 +000047#ifdef ROCKBOX
Jonathan Gordon97857322010-11-04 10:15:33 +000048#include "config.h"
Jonathan Gordoncb56c462011-01-27 11:33:33 +000049#include "skin_debug.h"
Jonathan Gordon2d31d772010-07-29 12:37:48 +000050static size_t buf_size;
51static unsigned char *buffer_start = NULL;
52static unsigned char *buffer_front = NULL;
Jonathan Gordondb658d92010-06-17 08:36:28 +000053
Jonathan Gordon9e07ef22011-11-15 14:11:08 +000054#ifndef __PCTOOL__
55long skin_buffer_to_offset(void *pointer)
Jonathan Gordon97857322010-11-04 10:15:33 +000056{
Jonathan Gordon9e07ef22011-11-15 14:11:08 +000057 return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start;
Jonathan Gordon97857322010-11-04 10:15:33 +000058}
59
Jonathan Gordon9e07ef22011-11-15 14:11:08 +000060void* skin_buffer_from_offset(long offset)
61{
62 return offset < 0 ? NULL : buffer_start + offset;
63}
Jonathan Gordon97857322010-11-04 10:15:33 +000064#endif
65
Jonathan Gordon2d31d772010-07-29 12:37:48 +000066void skin_buffer_init(char* buffer, size_t size)
Jonathan Gordondb658d92010-06-17 08:36:28 +000067{
Jonathan Gordon2d31d772010-07-29 12:37:48 +000068 buffer_start = buffer_front = buffer;
69 buf_size = size;
Jonathan Gordondb658d92010-06-17 08:36:28 +000070}
71
72/* Allocate size bytes from the buffer */
Jonathan Gordon7e444382011-09-25 12:05:03 +000073#ifdef DEBUG_SKIN_ALLOCATIONS
74void* skin_buffer_alloc_ex(size_t size, char* debug)
75{
76 void *retval = NULL;
77 printf("%d %s\n", size, debug);
78#else
Jonathan Gordondb658d92010-06-17 08:36:28 +000079void* skin_buffer_alloc(size_t size)
80{
81 void *retval = NULL;
Jonathan Gordon7e444382011-09-25 12:05:03 +000082#endif
Jonathan Gordondcc0d7d2010-09-26 12:56:02 +000083 /* 32-bit aligned */
84 size = (size + 3) & ~3;
Jonathan Gordon2d31d772010-07-29 12:37:48 +000085 if (size > skin_buffer_freespace())
Jonathan Gordon21e89e82011-01-27 11:27:53 +000086 {
87 skin_error(MEMORY_LIMIT_EXCEEDED, NULL);
Jonathan Gordon2d31d772010-07-29 12:37:48 +000088 return NULL;
Jonathan Gordon21e89e82011-01-27 11:27:53 +000089 }
Jonathan Gordondb658d92010-06-17 08:36:28 +000090 retval = buffer_front;
91 buffer_front += size;
Jonathan Gordondb658d92010-06-17 08:36:28 +000092 return retval;
93}
Jonathan Gordon95b0cef2010-06-17 13:54:09 +000094
Jonathan Gordon95b0cef2010-06-17 13:54:09 +000095/* get the number of bytes currently being used */
96size_t skin_buffer_usage(void)
97{
Jonathan Gordon2d31d772010-07-29 12:37:48 +000098 return buffer_front - buffer_start;
Jonathan Gordon95b0cef2010-06-17 13:54:09 +000099}
100size_t skin_buffer_freespace(void)
101{
Jonathan Gordon2d31d772010-07-29 12:37:48 +0000102 return buf_size - skin_buffer_usage();
103}
Jonathan Gordon9e07ef22011-11-15 14:11:08 +0000104#else
105void* skin_buffer_alloc(size_t size)
Jonathan Gordon2d31d772010-07-29 12:37:48 +0000106{
Jonathan Gordon9e07ef22011-11-15 14:11:08 +0000107 return malloc(size);
Jonathan Gordon95b0cef2010-06-17 13:54:09 +0000108}
109#endif