1
0
Fork 0
forked from len0rd/rockbox

Speed up mono bitmap drawing on horizontally packed greyscale targets (greyscale iPods). Average speedup is 80% on PP5002, and 55% on PP502x. * Simplify mono bitmap drawing in the 16 bit driver and the greylib a bit, also giving a slight speedup (3% on PP502x, 1.5% on coldfire).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21163 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2009-06-01 21:28:03 +00:00
parent aa7d43f7a6
commit c1d27d105c
3 changed files with 126 additions and 32 deletions

View file

@ -447,6 +447,7 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
src_end = src + width; src_end = src + width;
dwidth = _grey_info.width; dwidth = _grey_info.width;
dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x]; dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x];
dst_end = dst + _GREY_MULUQ(dwidth, height);
if (drmode & DRMODE_INVERSEVID) if (drmode & DRMODE_INVERSEVID)
{ {
@ -461,8 +462,6 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
unsigned data = (*src_col ^ dmask) >> src_y; unsigned data = (*src_col ^ dmask) >> src_y;
int fg, bg; int fg, bg;
dst_end = dst_col + _GREY_MULUQ(dwidth, height);
#define UPDATE_SRC do { \ #define UPDATE_SRC do { \
data >>= 1; \ data >>= 1; \
if (data == 0x001) { \ if (data == 0x001) { \

View file

@ -752,6 +752,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_y &= 7; src_y &= 7;
src_end = src + width; src_end = src + width;
dst = LCDADDR(current_vp->x + x, current_vp->y + y); dst = LCDADDR(current_vp->x + x, current_vp->y + y);
dst_end = dst + height * LCD_WIDTH;
if (drmode & DRMODE_INVERSEVID) if (drmode & DRMODE_INVERSEVID)
{ {
@ -767,8 +768,6 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
int fg, bg; int fg, bg;
long bo; long bo;
dst_end = dst_col + height * LCD_WIDTH;
#define UPDATE_SRC do { \ #define UPDATE_SRC do { \
data >>= 1; \ data >>= 1; \
if (data == 0x001) { \ if (data == 0x001) { \

View file

@ -690,10 +690,11 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
int src_y, int stride, int x, int y, int src_y, int stride, int x, int y,
int width, int height) int width, int height)
{ {
int ny, nx, ymax; const unsigned char *src_end;
const unsigned char * src_end; fb_data *dst, *dst_end;
lcd_pixelfunc_type* fgfunc; unsigned dmask = 0x100; /* bit 8 == sentinel */
lcd_pixelfunc_type* bgfunc; unsigned dst_mask;
int drmode = current_vp->drawmode;
/* nothing to draw? */ /* nothing to draw? */
if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
@ -718,42 +719,137 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
if (y + height > current_vp->height) if (y + height > current_vp->height)
height = current_vp->height - y; height = current_vp->height - y;
/* adjust for viewport */
x += current_vp->x;
y += current_vp->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; src_end = src + width;
x += current_vp->x; /* adjust for viewport */
dst = &lcd_framebuffer[current_vp->y + y][x >> 2];
dst_end = dst + height * LCD_FBWIDTH;
dst_mask = pixmask[x & 3];
if (drmode & DRMODE_INVERSEVID)
{
dmask = 0x1ff; /* bit 8 == sentinel */
drmode &= DRMODE_SOLID; /* mask out inversevid */
}
fgfunc = lcd_pixelfuncs[current_vp->drawmode];
bgfunc = lcd_pixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID];
nx = x;
do do
{ {
const unsigned char *src_col = src++; const unsigned char *src_col = src++;
unsigned data = (*src_col | 0x100) >> src_y; /* bit 8 == sentinel */ unsigned data = (*src_col ^ dmask) >> src_y;
fb_data *dst_col = dst;
int fg, bg;
long bo;
ymax = y + height; #define UPDATE_SRC do { \
ny = y; data >>= 1; \
do if (data == 0x001) { \
src_col += stride; \
data = *src_col ^ dmask; \
} \
} while (0)
switch (drmode)
{ {
if (data & 0x01) case DRMODE_COMPLEMENT:
fgfunc(nx,ny); do
else
bgfunc(nx,ny);
ny++;
data >>= 1;
if (data == 0x001)
{ {
src_col += stride; if (data & 0x01)
data = *src_col | 0x100; *dst_col ^= dst_mask;
dst_col += LCD_FBWIDTH;
UPDATE_SRC;
} }
while (dst_col < dst_end);
break;
case DRMODE_BG:
if (lcd_backdrop)
{
bo = lcd_backdrop_offset;
do
{
if (!(data & 0x01))
{
unsigned block = *dst_col;
*dst_col = block
^ ((block ^ *(dst_col + bo)) & dst_mask);
}
dst_col += LCD_FBWIDTH;
UPDATE_SRC;
}
while (dst_col < dst_end);
}
else
{
bg = bg_pattern;
do
{
if (!(data & 0x01))
{
unsigned block = *dst_col;
*dst_col = block ^ ((block ^ bg) & dst_mask);
}
dst_col += LCD_FBWIDTH;
UPDATE_SRC;
}
while (dst_col < dst_end);
}
break;
case DRMODE_FG:
fg = fg_pattern;
do
{
if (data & 0x01)
{
unsigned block = *dst_col;
*dst_col = block ^ ((block ^ fg) & dst_mask);
}
dst_col += LCD_FBWIDTH;
UPDATE_SRC;
}
while (dst_col < dst_end);
break;
case DRMODE_SOLID:
fg = fg_pattern;
if (lcd_backdrop)
{
bo = lcd_backdrop_offset;
do
{
unsigned block = *dst_col;
*dst_col = block ^ ((block ^ ((data & 0x01) ?
fg : *(dst_col + bo))) & dst_mask);
dst_col += LCD_FBWIDTH;
UPDATE_SRC;
}
while (dst_col < dst_end);
}
else
{
bg = bg_pattern;
do
{
unsigned block = *dst_col;
*dst_col = block ^ ((block ^ ((data & 0x01) ?
fg : bg)) & dst_mask);
dst_col += LCD_FBWIDTH;
UPDATE_SRC;
}
while (dst_col < dst_end);
}
break;
}
dst_mask >>= 2;
if (dst_mask == 0)
{
dst++;
dst_mask = 0xC0;
} }
while (ny < ymax);
nx++;
} }
while (src < src_end); while (src < src_end);
} }