bitmap drawing: Use extra bit in mask to avoid nested if() in switch-cases.

Speeds up alpha bitmap drawing by up to 10%. mono bitmap drawing is also a tiny bit faster.

Change-Id: I5a9379740c1a0091de9c621aabbe57d767ce2905
This commit is contained in:
Thomas Martitz 2013-02-08 23:33:54 +01:00
parent ca634a0ac0
commit 1430b07894
2 changed files with 86 additions and 88 deletions

View file

@ -667,13 +667,17 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
drmode &= DRMODE_SOLID; /* mask out inversevid */ drmode &= DRMODE_SOLID; /* mask out inversevid */
} }
/* Use extra bit to avoid if () in the switch-cases below */
if ((drmode & DRMODE_BG) && lcd_backdrop)
drmode |= DRMODE_INT_MOD;
/* go through each column and update each pixel */ /* go through each column and update each pixel */
do do
{ {
const unsigned char *src_col = src++; const unsigned char *src_col = src++;
unsigned data = (*src_col ^ dmask) >> src_y; unsigned data = (*src_col ^ dmask) >> src_y;
int fg, bg; int fg, bg;
long bo; uintptr_t bo;
dst = dst_col; dst = dst_col;
dst_col += COL_INC; dst_col += COL_INC;
@ -701,33 +705,30 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
while (--row); while (--row);
break; break;
case DRMODE_BG: case DRMODE_BG|DRMODE_INT_MOD:
if (lcd_backdrop) bo = lcd_backdrop_offset;
do
{ {
bo = lcd_backdrop_offset; if (!(data & 0x01))
do *dst = *(fb_data *)((long)dst + bo);
{
if (!(data & 0x01))
*dst = *(fb_data *)((long)dst + bo);
dst += ROW_INC; dst += ROW_INC;
UPDATE_SRC; UPDATE_SRC;
}
while (--row);
} }
else while (--row);
break;
case DRMODE_BG:
bg = current_vp->bg_pattern;
do
{ {
bg = current_vp->bg_pattern; if (!(data & 0x01))
do *dst = bg;
{
if (!(data & 0x01))
*dst = bg;
dst += ROW_INC; dst += ROW_INC;
UPDATE_SRC; UPDATE_SRC;
}
while (--row);
} }
while (--row);
break; break;
case DRMODE_FG: case DRMODE_FG:
@ -743,31 +744,29 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
while (--row); while (--row);
break; break;
case DRMODE_SOLID|DRMODE_INT_MOD:
fg = current_vp->fg_pattern;
bo = lcd_backdrop_offset;
do
{
*dst = (data & 0x01) ? fg
: *(fb_data *)((long)dst + bo);
dst += ROW_INC;
UPDATE_SRC;
}
while (--row);
break;
case DRMODE_SOLID: case DRMODE_SOLID:
fg = current_vp->fg_pattern; fg = current_vp->fg_pattern;
if (lcd_backdrop) bg = current_vp->bg_pattern;
do
{ {
bo = lcd_backdrop_offset; *dst = (data & 0x01) ? fg : bg;
do dst += ROW_INC;
{ UPDATE_SRC;
*dst = (data & 0x01) ? fg
: *(fb_data *)((long)dst + bo);
dst += ROW_INC;
UPDATE_SRC;
}
while (--row);
}
else
{
bg = current_vp->bg_pattern;
do
{
*dst = (data & 0x01) ? fg : bg;
dst += ROW_INC;
UPDATE_SRC;
}
while (--row);
} }
while (--row);
break; break;
} }
} }
@ -945,6 +944,9 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
{ {
drmode = DRMODE_BG; drmode = DRMODE_BG;
} }
/* Use extra bit to avoid if () in the switch-cases below */
if ((drmode & DRMODE_BG) && lcd_backdrop)
drmode |= DRMODE_INT_MOD;
dst_row = FBADDR(x, y); dst_row = FBADDR(x, y);
@ -977,6 +979,8 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
/* go through the rows and update each pixel */ /* go through the rows and update each pixel */
do do
{ {
unsigned bg;
uintptr_t bo;
col = width; col = width;
dst = dst_row; dst = dst_row;
dst_row += ROW_INC; dst_row += ROW_INC;
@ -1025,33 +1029,28 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
} }
while (--col); while (--col);
break; break;
case DRMODE_BG|DRMODE_INT_MOD:
bo = lcd_backdrop_offset;
do
{
fb_data c = *(fb_data *)((uintptr_t)dst + bo);
*dst = blend_two_colors(c, *image, data & ALPHA_COLOR_LOOKUP_SIZE );
dst += COL_INC;
image += STRIDE_MAIN(1, stride_image);
UPDATE_SRC_ALPHA;
}
while (--col);
break;
case DRMODE_BG: case DRMODE_BG:
if(lcd_backdrop) bg = current_vp->bg_pattern;
do
{ {
uintptr_t bo = lcd_backdrop_offset; *dst = blend_two_colors(bg, *image, data & ALPHA_COLOR_LOOKUP_SIZE );
do dst += COL_INC;
{ image += STRIDE_MAIN(1, stride_image);
*dst = blend_two_colors(*(fb_data *)((uintptr_t)dst + bo), UPDATE_SRC_ALPHA;
*image, data & ALPHA_COLOR_LOOKUP_SIZE );
dst += COL_INC;
image += STRIDE_MAIN(1, stride_image);
UPDATE_SRC_ALPHA;
}
while (--col);
}
else
{
do
{
*dst = blend_two_colors(current_vp->bg_pattern,
*image, data & ALPHA_COLOR_LOOKUP_SIZE );
dst += COL_INC;
image += STRIDE_MAIN(1, stride_image);
UPDATE_SRC_ALPHA;
}
while (--col);
} }
while (--col);
break; break;
case DRMODE_FG: case DRMODE_FG:
do do
@ -1062,30 +1061,27 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
} }
while (--col); while (--col);
break; break;
case DRMODE_SOLID|DRMODE_INT_MOD:
bo = lcd_backdrop_offset;
do
{
fb_data *c = (fb_data *)((uintptr_t)dst + bo);
*dst = blend_color(*c, data & ALPHA_COLOR_LOOKUP_SIZE );
dst += COL_INC;
UPDATE_SRC_ALPHA;
}
while (--col);
break;
case DRMODE_SOLID: case DRMODE_SOLID:
if(lcd_backdrop) bg = current_vp->bg_pattern;
do
{ {
uintptr_t bo = lcd_backdrop_offset; *dst = blend_color(bg,
do data & ALPHA_COLOR_LOOKUP_SIZE );
{ dst += COL_INC;
*dst = blend_color(*(fb_data *)((uintptr_t)dst + bo), UPDATE_SRC_ALPHA;
data & ALPHA_COLOR_LOOKUP_SIZE );
dst += COL_INC;
UPDATE_SRC_ALPHA;
}
while (--col);
}
else
{
do
{
*dst = blend_color(current_vp->bg_pattern,
data & ALPHA_COLOR_LOOKUP_SIZE );
dst += COL_INC;
UPDATE_SRC_ALPHA;
}
while (--col);
} }
while (--col);
break; break;
} }
#ifdef ALPHA_BITMAP_READ_WORDS #ifdef ALPHA_BITMAP_READ_WORDS

View file

@ -289,6 +289,8 @@ extern void lcd_jump_scroll_delay(int ms);
#define DRMODE_FG 2 #define DRMODE_FG 2
#define DRMODE_SOLID 3 #define DRMODE_SOLID 3
#define DRMODE_INVERSEVID 4 /* used as bit modifier for basic modes */ #define DRMODE_INVERSEVID 4 /* used as bit modifier for basic modes */
/* Internal drawmode modifiers. DO NOT use with set_drawmode() */
#define DRMODE_INT_MOD 8
/* 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);