forked from len0rd/rockbox
16bit LCD driver: faster drawing routines.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8098 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
ee76cc3716
commit
1d6eeea1e1
2 changed files with 82 additions and 47 deletions
|
@ -145,32 +145,33 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
|
||||||
|
|
||||||
/*** low-level drawing functions ***/
|
/*** low-level drawing functions ***/
|
||||||
|
|
||||||
static void setpixel(int x, int y) ICODE_ATTR;
|
#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
|
||||||
static void setpixel(int x, int y)
|
|
||||||
|
static void setpixel(fb_data *address) ICODE_ATTR;
|
||||||
|
static void setpixel(fb_data *address)
|
||||||
{
|
{
|
||||||
lcd_framebuffer[y][x] = fg_pattern;
|
*address = fg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearpixel(int x, int y) ICODE_ATTR;
|
static void clearpixel(fb_data *address) ICODE_ATTR;
|
||||||
static void clearpixel(int x, int y)
|
static void clearpixel(fb_data *address)
|
||||||
{
|
{
|
||||||
lcd_framebuffer[y][x] = bg_pattern;
|
*address = bg_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flippixel(int x, int y) ICODE_ATTR;
|
static void flippixel(fb_data *address) ICODE_ATTR;
|
||||||
static void flippixel(int x, int y)
|
static void flippixel(fb_data *address)
|
||||||
{
|
{
|
||||||
lcd_framebuffer[y][x] = ~lcd_framebuffer[y][x];
|
*address = ~(*address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nopixel(int x, int y) ICODE_ATTR;
|
static void nopixel(fb_data *address) ICODE_ATTR;
|
||||||
static void nopixel(int x, int y)
|
static void nopixel(fb_data *address)
|
||||||
{
|
{
|
||||||
(void)x;
|
(void)address;
|
||||||
(void)y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_pixelfunc_type* const lcd_pixelfuncs[8] = {
|
lcd_fastpixelfunc_type* const lcd_fastpixelfuncs[8] = {
|
||||||
flippixel, nopixel, setpixel, setpixel,
|
flippixel, nopixel, setpixel, setpixel,
|
||||||
nopixel, clearpixel, nopixel, clearpixel
|
nopixel, clearpixel, nopixel, clearpixel
|
||||||
};
|
};
|
||||||
|
@ -181,7 +182,7 @@ lcd_pixelfunc_type* const lcd_pixelfuncs[8] = {
|
||||||
void lcd_clear_display(void)
|
void lcd_clear_display(void)
|
||||||
{
|
{
|
||||||
fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern;
|
fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern;
|
||||||
fb_data *dst = &lcd_framebuffer[0][0];
|
fb_data *dst = LCDADDR(0, 0);
|
||||||
fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH;
|
fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -194,7 +195,7 @@ void lcd_clear_display(void)
|
||||||
void lcd_drawpixel(int x, int y)
|
void lcd_drawpixel(int x, int y)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
||||||
lcd_pixelfuncs[drawmode](x, y);
|
lcd_fastpixelfuncs[drawmode](LCDADDR(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a line */
|
/* Draw a line */
|
||||||
|
@ -206,7 +207,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
int d, dinc1, dinc2;
|
int d, dinc1, dinc2;
|
||||||
int x, xinc1, xinc2;
|
int x, xinc1, xinc2;
|
||||||
int y, yinc1, yinc2;
|
int y, yinc1, yinc2;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
||||||
|
|
||||||
deltax = abs(x2 - x1);
|
deltax = abs(x2 - x1);
|
||||||
deltay = abs(y2 - y1);
|
deltay = abs(y2 - y1);
|
||||||
|
@ -251,7 +252,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
for (i = 0; i < numpixels; i++)
|
for (i = 0; i < numpixels; i++)
|
||||||
{
|
{
|
||||||
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT))
|
||||||
pfunc(x, y);
|
pfunc(LCDADDR(x, y));
|
||||||
|
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
|
@ -272,7 +273,8 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
|
||||||
void lcd_hline(int x1, int x2, int y)
|
void lcd_hline(int x1, int x2, int y)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
fb_data *dst, *dst_end;
|
||||||
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
||||||
|
|
||||||
/* direction flip */
|
/* direction flip */
|
||||||
if (x2 < x1)
|
if (x2 < x1)
|
||||||
|
@ -292,16 +294,20 @@ void lcd_hline(int x1, int x2, int y)
|
||||||
if (x2 >= LCD_WIDTH)
|
if (x2 >= LCD_WIDTH)
|
||||||
x2 = LCD_WIDTH-1;
|
x2 = LCD_WIDTH-1;
|
||||||
|
|
||||||
|
dst = LCDADDR(x1, y);
|
||||||
|
dst_end = dst + x2 - x1;
|
||||||
|
|
||||||
do
|
do
|
||||||
pfunc(x1++, y);
|
pfunc(dst++);
|
||||||
while (x1 <= x2);
|
while (dst <= dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a vertical line (optimised) */
|
/* Draw a vertical line (optimised) */
|
||||||
void lcd_vline(int x, int y1, int y2)
|
void lcd_vline(int x, int y1, int y2)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
fb_data *dst, *dst_end;
|
||||||
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
||||||
|
|
||||||
/* direction flip */
|
/* direction flip */
|
||||||
if (y2 < y1)
|
if (y2 < y1)
|
||||||
|
@ -321,10 +327,15 @@ void lcd_vline(int x, int y1, int y2)
|
||||||
if (y2 >= LCD_HEIGHT)
|
if (y2 >= LCD_HEIGHT)
|
||||||
y2 = LCD_HEIGHT-1;
|
y2 = LCD_HEIGHT-1;
|
||||||
|
|
||||||
|
dst = LCDADDR(x, y1);
|
||||||
|
dst_end = dst + (y2 - y1) * LCD_WIDTH;
|
||||||
|
|
||||||
do
|
do
|
||||||
pfunc(x, y1++);
|
{
|
||||||
while (y1 <= y2);
|
pfunc(dst);
|
||||||
|
dst += LCD_WIDTH;
|
||||||
|
}
|
||||||
|
while (dst <= dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a rectangular box */
|
/* Draw a rectangular box */
|
||||||
|
@ -345,8 +356,8 @@ void lcd_drawrect(int x, int y, int width, int height)
|
||||||
/* Fill a rectangular area */
|
/* Fill a rectangular area */
|
||||||
void lcd_fillrect(int x, int y, int width, int height)
|
void lcd_fillrect(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int xe, ye, xc;
|
fb_data *dst, *dst_end;
|
||||||
lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
|
lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode];
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
||||||
|
@ -369,13 +380,21 @@ void lcd_fillrect(int x, int y, int width, int height)
|
||||||
if (y + height > LCD_HEIGHT)
|
if (y + height > LCD_HEIGHT)
|
||||||
height = LCD_HEIGHT - y;
|
height = LCD_HEIGHT - y;
|
||||||
|
|
||||||
ye = y + height;
|
dst = LCDADDR(x, y);
|
||||||
xe = x + width;
|
dst_end = dst + height * LCD_WIDTH;
|
||||||
for(; y < ye; y++)
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
for(xc = x; xc < xe; xc++)
|
fb_data *dst_row = dst;
|
||||||
pfunc(xc, y);
|
fb_data *row_end = dst_row + width;
|
||||||
|
|
||||||
|
do
|
||||||
|
pfunc(dst_row++);
|
||||||
|
while (dst_row < row_end);
|
||||||
|
|
||||||
|
dst += LCD_WIDTH;
|
||||||
}
|
}
|
||||||
|
while (dst < dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* About Rockbox' internal monochrome bitmap format:
|
/* About Rockbox' internal monochrome bitmap format:
|
||||||
|
@ -397,9 +416,10 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
int stride, int x, int y, int width, int height)
|
int stride, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int xe, ye, yc;
|
const unsigned char *src_end;
|
||||||
lcd_pixelfunc_type *fgfunc;
|
fb_data *dst, *dst_end;
|
||||||
lcd_pixelfunc_type *bgfunc;
|
lcd_fastpixelfunc_type *fgfunc;
|
||||||
|
lcd_fastpixelfunc_type *bgfunc;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
||||||
|
@ -426,24 +446,28 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
|
|
||||||
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
src += stride * (src_y >> 3) + src_x; /* move starting point */
|
||||||
src_y &= 7;
|
src_y &= 7;
|
||||||
|
src_end = src + width;
|
||||||
|
|
||||||
xe = x + width;
|
dst = LCDADDR(x, y);
|
||||||
ye = y + height;
|
fgfunc = lcd_fastpixelfuncs[drawmode];
|
||||||
fgfunc = lcd_pixelfuncs[drawmode];
|
bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID];
|
||||||
bgfunc = lcd_pixelfuncs[drawmode ^ DRMODE_INVERSEVID];
|
|
||||||
|
|
||||||
for (; x < xe; x++)
|
do
|
||||||
{
|
{
|
||||||
const unsigned char *src_col = src++;
|
const unsigned char *src_col = src++;
|
||||||
unsigned char data = *src_col >> src_y;
|
unsigned data = *src_col >> src_y;
|
||||||
|
fb_data *dst_col = dst++;
|
||||||
int numbits = 8 - src_y;
|
int numbits = 8 - src_y;
|
||||||
|
|
||||||
for (yc = y; yc < ye; yc++)
|
dst_end = dst_col + height * LCD_WIDTH;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
if (data & 0x01)
|
if (data & 0x01)
|
||||||
fgfunc(x, yc);
|
fgfunc(dst_col);
|
||||||
else
|
else
|
||||||
bgfunc(x, yc);
|
bgfunc(dst_col);
|
||||||
|
|
||||||
|
dst_col += LCD_WIDTH;
|
||||||
|
|
||||||
data >>= 1;
|
data >>= 1;
|
||||||
if (--numbits == 0)
|
if (--numbits == 0)
|
||||||
|
@ -453,7 +477,9 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
|
||||||
numbits = 8;
|
numbits = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (dst_col < dst_end);
|
||||||
}
|
}
|
||||||
|
while (src < src_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a full monochrome bitmap */
|
/* Draw a full monochrome bitmap */
|
||||||
|
@ -469,7 +495,7 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
int stride, int x, int y, int width, int height)
|
int stride, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int ye;
|
fb_data *dst, *dst_end;
|
||||||
|
|
||||||
/* nothing to draw? */
|
/* nothing to draw? */
|
||||||
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
|
||||||
|
@ -495,13 +521,16 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
|
||||||
height = LCD_HEIGHT - y;
|
height = LCD_HEIGHT - y;
|
||||||
|
|
||||||
src += stride * src_y + src_x; /* move starting point */
|
src += stride * src_y + src_x; /* move starting point */
|
||||||
ye = y + height;
|
dst = LCDADDR(x, y);
|
||||||
|
dst_end = dst + height * LCD_WIDTH;
|
||||||
|
|
||||||
for (; y < ye; y++)
|
do
|
||||||
{
|
{
|
||||||
memcpy(&lcd_framebuffer[y][x], src, width * sizeof(fb_data));
|
memcpy(dst, src, width * sizeof(fb_data));
|
||||||
src += stride;
|
src += stride;
|
||||||
|
dst += LCD_WIDTH;
|
||||||
}
|
}
|
||||||
|
while (dst < dst_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw a full native bitmap */
|
/* Draw a full native bitmap */
|
||||||
|
|
|
@ -135,6 +135,9 @@ extern void lcd_jump_scroll_delay(int ms);
|
||||||
/* Low-level drawing function types */
|
/* Low-level drawing function types */
|
||||||
typedef void lcd_pixelfunc_type(int x, int y);
|
typedef void lcd_pixelfunc_type(int x, int y);
|
||||||
typedef void lcd_blockfunc_type(unsigned char *address, unsigned mask, unsigned bits);
|
typedef void lcd_blockfunc_type(unsigned char *address, unsigned mask, unsigned bits);
|
||||||
|
#if LCD_DEPTH >= 8
|
||||||
|
typedef void lcd_fastpixelfunc_type(fb_data *address);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
|
||||||
|
@ -199,6 +202,9 @@ extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
|
||||||
/* low level drawing function pointer arrays */
|
/* low level drawing function pointer arrays */
|
||||||
extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
|
extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
|
||||||
extern lcd_blockfunc_type* const lcd_blockfuncs[8];
|
extern lcd_blockfunc_type* const lcd_blockfuncs[8];
|
||||||
|
#if LCD_DEPTH >= 8
|
||||||
|
extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs[8];
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void lcd_drawpixel(int x, int y);
|
extern void lcd_drawpixel(int x, int y);
|
||||||
extern void lcd_drawline(int x1, int y1, int x2, int y2);
|
extern void lcd_drawline(int x1, int y1, int x2, int y2);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue