Greyscale library: Plugins can now put the management structure in IRAM for higher update speed. Use this in doom, mpegplayer, and zxbox. Made the api pointer part of the struct.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16066 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2008-01-13 00:11:43 +00:00
parent 43cc03457d
commit a72499a125
15 changed files with 110 additions and 90 deletions

View file

@ -214,6 +214,7 @@ static int y_off = LCD_HEIGHT/2;
#if LCD_DEPTH == 1
#define USE_GSLIB
GREY_INFO_STRUCT
struct my_lcd {
void (*update)(void);
void (*clear_display)(void);

View file

@ -118,6 +118,7 @@
#ifndef HAVE_LCD_COLOR
#include "../lib/grey.h"
GREY_INFO_STRUCT_IRAM
static unsigned char greybuffer[LCD_WIDTH] IBSS_ATTR; /* off screen buffer */
static unsigned char *gbuf;
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING

View file

@ -46,6 +46,7 @@ static unsigned char fire[LCD_HEIGHT+3][FIRE_WIDTH];
static unsigned char cooling_map[LCD_HEIGHT][FIRE_WIDTH];
#ifndef HAVE_LCD_COLOR
GREY_INFO_STRUCT
static unsigned char *gbuf;
static size_t gbuf_size = 0;
static unsigned char draw_buffer[FIRE_WIDTH];

View file

@ -82,6 +82,7 @@ PLUGIN_HEADER
#endif
/******************************* Globals ***********************************/
GREY_INFO_STRUCT
static struct plugin_api* rb; /* global api struct pointer */
static char pbuf[32]; /* global printf buffer */
static unsigned char *gbuf;

View file

@ -184,6 +184,7 @@ PLUGIN_HEADER
/* different graphics libraries */
#if LCD_DEPTH < 8
#define USEGSLIB
GREY_INFO_STRUCT
#define MYLCD(fn) grey_ub_ ## fn
#define MYLCD_UPDATE()
#define MYXLCD(fn) grey_ub_ ## fn

View file

@ -36,6 +36,12 @@
#define GREY_LIGHTGRAY GREY_BRIGHTNESS(170)
#define GREY_WHITE GREY_BRIGHTNESS(255)
/* Greyscale library management structure declaration. You need one of these
* in every plugin using the library, depending on whether the structure should
* use IRAM or not. */
#define GREY_INFO_STRUCT struct _grey_info _grey_info;
#define GREY_INFO_STRUCT_IRAM struct _grey_info _grey_info IBSS_ATTR;
/* Library initialisation and release */
bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
bool buffered, int width, int height, long *buf_taken);
@ -148,6 +154,7 @@ struct _grey_info
int bheight; /* 4-pixel or 8-pixel units */
#endif
unsigned long flags; /* various flags, see #defines */
struct plugin_api *rb; /* plugin API pointer */
#ifndef SIMULATOR
unsigned char *values; /* start of greyscale pixel values */
unsigned char *phases; /* start of greyscale pixel phases */
@ -162,8 +169,7 @@ struct _grey_info
int curfont; /* current selected font */
};
/* Global variables */
extern struct plugin_api *_grey_rb;
/* Global variable, defined in the plugin */
extern struct _grey_info _grey_info;
#endif /* HAVE_LCD_BITMAP && (LCD_DEPTH < 4) */

View file

@ -30,13 +30,10 @@
#define NEED_BOOST
#endif
/* Global variables */
struct plugin_api *_grey_rb = NULL; /* global api struct pointer */
struct _grey_info _grey_info; /* global info structure */
#ifndef SIMULATOR
#if CONFIG_LCD == LCD_SSD1815 || CONFIG_LCD == LCD_IFP7XX || CONFIG_LCD == LCD_MROBE100
#if CONFIG_LCD == LCD_SSD1815 || CONFIG_LCD == LCD_IFP7XX \
|| CONFIG_LCD == LCD_MROBE100
/* measured and interpolated curve */
/* TODO: check for iFP & m:robe 100 */
static const unsigned char lcdlinear[256] = {
@ -205,16 +202,16 @@ static inline void _deferred_update(void)
int y2 = MIN(_grey_info.y + _grey_info.height, LCD_HEIGHT);
if (y1 > 0) /* refresh part above overlay, full width */
_grey_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);
_grey_info.rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);
if (y2 < LCD_HEIGHT) /* refresh part below overlay, full width */
_grey_rb->lcd_update_rect(0, y2, LCD_WIDTH, LCD_HEIGHT - y2);
_grey_info.rb->lcd_update_rect(0, y2, LCD_WIDTH, LCD_HEIGHT - y2);
if (x1 > 0) /* refresh part to the left of overlay */
_grey_rb->lcd_update_rect(0, y1, x1, y2 - y1);
_grey_info.rb->lcd_update_rect(0, y1, x1, y2 - y1);
if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */
_grey_rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1);
_grey_info.rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1);
}
#ifndef SIMULATOR
@ -222,12 +219,12 @@ static inline void _deferred_update(void)
static void _timer_isr(void)
{
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
_grey_rb->lcd_grey_phase_blit(_grey_info.values, _grey_info.phases,
_grey_info.rb->lcd_grey_phase_blit(_grey_info.values, _grey_info.phases,
_grey_info.bx, _grey_info.y,
_grey_info.bwidth, _grey_info.height,
_grey_info.width);
#else
_grey_rb->lcd_grey_phase_blit(_grey_info.values, _grey_info.phases,
_grey_info.rb->lcd_grey_phase_blit(_grey_info.values, _grey_info.phases,
_grey_info.x, _grey_info.by,
_grey_info.width, _grey_info.bheight,
_grey_info.width);
@ -326,7 +323,7 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
unsigned *dst, *end;
#endif
_grey_rb = newrb;
_grey_info.rb = newrb;
if ((unsigned) width > LCD_WIDTH
|| (unsigned) height > LCD_HEIGHT)
@ -374,14 +371,14 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
#ifndef SIMULATOR
/* Init to white */
_grey_rb->memset(_grey_info.values, 0x80, plane_size);
_grey_info.rb->memset(_grey_info.values, 0x80, plane_size);
/* Init phases with random bits */
dst = (unsigned*)(_grey_info.phases);
end = (unsigned*)(_grey_info.phases + plane_size);
do
*dst++ = _grey_rb->rand();
*dst++ = _grey_info.rb->rand();
while (dst < end);
#endif
@ -444,46 +441,46 @@ void grey_show(bool enable)
{
_grey_info.flags |= _GREY_RUNNING;
#ifdef SIMULATOR
_grey_rb->sim_lcd_ex_init(129, _grey_get_pixel);
_grey_info.rb->sim_lcd_ex_init(129, _grey_get_pixel);
grey_update();
#else /* !SIMULATOR */
#ifdef NEED_BOOST
_grey_rb->cpu_boost(true);
_grey_info.rb->cpu_boost(true);
#endif
#if CONFIG_LCD == LCD_SSD1815
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr);
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr);
#elif CONFIG_LCD == LCD_S1D15E06
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr);
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr);
#elif CONFIG_LCD == LCD_IPOD2BPP
#ifdef IPOD_1G2G
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 95, 1, _timer_isr); /* verified */
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 95, 1, _timer_isr); /* verified */
#elif defined IPOD_3G
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 87, 1, _timer_isr); /* verified */
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 87, 1, _timer_isr); /* verified */
#else
/* FIXME: verify value */
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 80, 1, _timer_isr);
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 80, 1, _timer_isr);
#endif
#elif CONFIG_LCD == LCD_IPODMINI
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 88, 1, _timer_isr);
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 88, 1, _timer_isr);
#elif CONFIG_LCD == LCD_IFP7XX
_grey_rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr);
_grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr);
#endif /* CONFIG_LCD */
#endif /* !SIMULATOR */
_grey_rb->screen_dump_set_hook(grey_screendump_hook);
_grey_info.rb->screen_dump_set_hook(grey_screendump_hook);
}
else if (!enable && (_grey_info.flags & _GREY_RUNNING))
{
#ifdef SIMULATOR
_grey_rb->sim_lcd_ex_init(0, NULL);
_grey_info.rb->sim_lcd_ex_init(0, NULL);
#else
_grey_rb->timer_unregister();
_grey_info.rb->timer_unregister();
#ifdef NEED_BOOST
_grey_rb->cpu_boost(false);
_grey_info.rb->cpu_boost(false);
#endif
#endif
_grey_info.flags &= ~_GREY_RUNNING;
_grey_rb->screen_dump_set_hook(NULL);
_grey_rb->lcd_update(); /* restore whatever there was before */
_grey_info.rb->screen_dump_set_hook(NULL);
_grey_info.rb->lcd_update(); /* restore whatever there was before */
}
}
@ -512,7 +509,7 @@ void grey_update_rect(int x, int y, int width, int height)
if (y + height > LCD_HEIGHT)
height = LCD_HEIGHT - y;
_grey_rb->sim_lcd_ex_update_rect(x, y, width, height);
_grey_info.rb->sim_lcd_ex_update_rect(x, y, width, height);
}
#else /* !SIMULATOR */
@ -536,7 +533,7 @@ void grey_update_rect(int x, int y, int width, int height)
do
{
_grey_rb->memcpy(dst, src, width);
_grey_info.rb->memcpy(dst, src, width);
dst += _grey_info.width;
src += _grey_info.width;
}
@ -587,7 +584,7 @@ void grey_deferred_lcd_update(void)
#endif
}
else
_grey_rb->lcd_update();
_grey_info.rb->lcd_update();
}
/*** Screenshot ***/
@ -662,10 +659,10 @@ static void grey_screendump_hook(int fd)
unsigned char *clut_entry;
unsigned char linebuf[MAX(4*BMP_VARCOLORS,BMP_LINESIZE)];
_grey_rb->write(fd, bmpheader, sizeof(bmpheader)); /* write header */
_grey_info.rb->write(fd, bmpheader, sizeof(bmpheader)); /* write header */
/* build clut */
_grey_rb->memset(linebuf, 0, 4*BMP_VARCOLORS);
_grey_info.rb->memset(linebuf, 0, 4*BMP_VARCOLORS);
clut_entry = linebuf;
for (i = 0; i <= 128; i++)
@ -675,17 +672,17 @@ static void grey_screendump_hook(int fd)
*clut_entry++ = _GREY_MULUQ(BMP_RED, i) >> 7;
clut_entry++;
}
_grey_rb->write(fd, linebuf, 4*BMP_VARCOLORS);
_grey_info.rb->write(fd, linebuf, 4*BMP_VARCOLORS);
/* BMP image goes bottom -> top */
for (y = LCD_HEIGHT - 1; y >= 0; y--)
{
_grey_rb->memset(linebuf, 0, BMP_LINESIZE);
_grey_info.rb->memset(linebuf, 0, BMP_LINESIZE);
gy = y - _grey_info.y;
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
#if LCD_DEPTH == 2
lcdptr = _grey_rb->lcd_framebuffer + _GREY_MULUQ(LCD_FBWIDTH, y);
lcdptr = _grey_info.rb->lcd_framebuffer + _GREY_MULUQ(LCD_FBWIDTH, y);
for (x = 0; x < LCD_WIDTH; x += 4)
{
@ -718,7 +715,7 @@ static void grey_screendump_hook(int fd)
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
#if LCD_DEPTH == 1
mask = 1 << (y & 7);
lcdptr = _grey_rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3);
lcdptr = _grey_info.rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3);
for (x = 0; x < LCD_WIDTH; x++)
{
@ -747,7 +744,7 @@ static void grey_screendump_hook(int fd)
}
#elif LCD_DEPTH == 2
shift = 2 * (y & 3);
lcdptr = _grey_rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 2);
lcdptr = _grey_info.rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 2);
for (x = 0; x < LCD_WIDTH; x++)
{
@ -777,6 +774,6 @@ static void grey_screendump_hook(int fd)
#endif /* LCD_DEPTH */
#endif /* LCD_PIXELFORMAT */
_grey_rb->write(fd, linebuf, BMP_LINESIZE);
_grey_info.rb->write(fd, linebuf, BMP_LINESIZE);
}
}

View file

@ -61,7 +61,7 @@ void grey_clear_display(void)
int value = (_grey_info.drawmode & DRMODE_INVERSEVID) ?
_grey_info.fg_val : _grey_info.bg_val;
_grey_rb->memset(_grey_info.buffer, value,
_grey_info.rb->memset(_grey_info.buffer, value,
_GREY_MULUQ(_grey_info.width, _grey_info.height));
}
@ -194,7 +194,7 @@ void grey_hline(int x1, int x2, int y)
dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x1];
if (fillopt)
_grey_rb->memset(dst, value, x2 - x1 + 1);
_grey_info.rb->memset(dst, value, x2 - x1 + 1);
else
{
unsigned char *dst_end = dst + x2 - x1;
@ -379,7 +379,7 @@ void grey_fillrect(int x, int y, int width, int height)
do
{
if (fillopt)
_grey_rb->memset(dst, value, width);
_grey_info.rb->memset(dst, value, width);
else
{
unsigned char *dst_row = dst;
@ -539,7 +539,7 @@ void grey_gray_bitmap(const unsigned char *src, int x, int y, int width,
void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str)
{
int ch;
struct font* pf = _grey_rb->font_get(_grey_info.curfont);
struct font* pf = _grey_info.rb->font_get(_grey_info.curfont);
while ((ch = *str++) != '\0' && x < _grey_info.width)
{
@ -603,7 +603,7 @@ void grey_ub_clear_display(void)
int value = (_grey_info.drawmode & DRMODE_INVERSEVID) ?
_grey_info.fg_val : _grey_info.bg_val;
_grey_rb->memset(_grey_info.values, value,
_grey_info.rb->memset(_grey_info.values, value,
_GREY_MULUQ(_grey_info.width, _grey_info.height));
}

View file

@ -112,5 +112,5 @@ void grey_setfont(int newfont)
/* Get width and height of a text when printed with the current font */
int grey_getstringsize(const unsigned char *str, int *w, int *h)
{
return _grey_rb->font_getstringsize(str, w, h, _grey_info.curfont);
return _grey_info.rb->font_getstringsize(str, w, h, _grey_info.curfont);
}

View file

@ -45,9 +45,9 @@ void grey_scroll_left(int count)
do
{
_grey_rb->memmove(data, data + count, length);
_grey_info.rb->memmove(data, data + count, length);
data += length;
_grey_rb->memset(data, blank, count);
_grey_info.rb->memset(data, blank, count);
data += count;
}
while (data < data_end);
@ -70,8 +70,8 @@ void grey_scroll_right(int count)
do
{
_grey_rb->memmove(data + count, data, length);
_grey_rb->memset(data, blank, count);
_grey_info.rb->memmove(data + count, data, length);
_grey_info.rb->memset(data, blank, count);
data += _grey_info.width;
}
while (data < data_end);
@ -91,8 +91,9 @@ void grey_scroll_up(int count)
blank = (_grey_info.drawmode & DRMODE_INVERSEVID) ?
_grey_info.fg_val : _grey_info.bg_val;
_grey_rb->memmove(_grey_info.buffer, _grey_info.buffer + shift, length);
_grey_rb->memset(_grey_info.buffer + length, blank, shift);
_grey_info.rb->memmove(_grey_info.buffer, _grey_info.buffer + shift,
length);
_grey_info.rb->memset(_grey_info.buffer + length, blank, shift);
}
/* Scroll down */
@ -109,8 +110,9 @@ void grey_scroll_down(int count)
blank = (_grey_info.drawmode & DRMODE_INVERSEVID) ?
_grey_info.fg_val : _grey_info.bg_val;
_grey_rb->memmove(_grey_info.buffer + shift, _grey_info.buffer, length);
_grey_rb->memset(_grey_info.buffer, blank, shift);
_grey_info.rb->memmove(_grey_info.buffer + shift, _grey_info.buffer,
length);
_grey_info.rb->memset(_grey_info.buffer, blank, shift);
}
/*** Unbuffered scrolling functions ***/
@ -165,9 +167,9 @@ void grey_ub_scroll_left(int count)
do
{
_grey_rb->memmove(data, data + count, length);
_grey_info.rb->memmove(data, data + count, length);
data += length;
_grey_rb->memset(data, blank, count);
_grey_info.rb->memset(data, blank, count);
data += count;
}
while (data < data_end);
@ -191,8 +193,8 @@ void grey_ub_scroll_right(int count)
do
{
_grey_rb->memmove(data + count, data, length);
_grey_rb->memset(data, blank, count);
_grey_info.rb->memmove(data + count, data, length);
_grey_info.rb->memset(data, blank, count);
data += _grey_info.width << _GREY_BSHIFT;
}
while (data < data_end);
@ -258,10 +260,10 @@ void grey_ub_scroll_up(int count)
int blen = _GREY_MULUQ(_grey_info.height - count, _grey_info.width);
src = dst + _GREY_MULUQ(count, _grey_info.width);
_grey_rb->memmove(dst, src, blen);
_grey_info.rb->memmove(dst, src, blen);
dst += blen;
}
_grey_rb->memset(dst, blank, end - dst); /* Fill remainder at once. */
_grey_info.rb->memset(dst, blank, end - dst); /* Fill remainder at once. */
}
/* Scroll down */
@ -325,9 +327,10 @@ void grey_ub_scroll_down(int count)
int blen = _GREY_MULUQ(_grey_info.height - count, _grey_info.width);
dst -= blen;
_grey_rb->memmove(dst, start, blen);
_grey_info.rb->memmove(dst, start, blen);
}
_grey_rb->memset(start, blank, dst - start); /* Fill remainder at once. */
_grey_info.rb->memset(start, blank, dst - start);
/* Fill remainder at once. */
}
#endif /* !SIMULATOR */

View file

@ -211,6 +211,7 @@ static int step_log2;
static unsigned max_iter;
#ifdef USEGSLIB
GREY_INFO_STRUCT
static unsigned char *gbuf;
static size_t gbuf_size = 0;
static unsigned char imgbuffer[LCD_HEIGHT];

View file

@ -23,6 +23,10 @@
#include "grey.h"
#include "mpeg_settings.h"
#ifndef HAVE_LCD_COLOR
GREY_INFO_STRUCT_IRAM
#endif
static struct event_queue stream_mgr_queue NOCACHEBSS_ATTR;
static struct queue_sender_list stream_mgr_queue_send NOCACHEBSS_ATTR;
static uint32_t stream_mgr_thread_stack[DEFAULT_STACK_SIZE*2/sizeof(uint32_t)];

View file

@ -44,6 +44,7 @@ static int redfactor = 1, greenfactor = 2, bluefactor = 3;
static int redphase = 0, greenphase = 50, bluephase = 100;
/* lower chance of gray at regular intervals */
#else
GREY_INFO_STRUCT
static unsigned char colours[256]; /* Smooth transition of shades */
static unsigned char greybuffer[LCD_HEIGHT*LCD_WIDTH]; /* off screen buffer */
static unsigned char *gbuf;

View file

@ -257,6 +257,8 @@ static void time_remote_update(void)
#endif
#if LCD_DEPTH < 4
GREY_INFO_STRUCT
static unsigned char greydata[LCD_HEIGHT][LCD_WIDTH];
static void make_grey_rect(int width, int height)

View file

@ -51,6 +51,7 @@ unsigned char image_array [ HEIGHT * WIDTH ];
static int previous_state;
#ifdef USE_GREY
GREY_INFO_STRUCT_IRAM
static unsigned char *gbuf;
static size_t gbuf_size = 0;
#endif