Subject:
Re: need help on subdriver operation
From:
"Aaron J. Grier" ####@####.####
Date:
25 Oct 2005 01:40:58 +0100
Message-Id: <20051025004019.GG2236@mordor.unix.fryenet>
On Tue, Oct 18, 2005 at 09:55:54AM -0600, Greg Haerr wrote:
> > My product needs faster text draw. Pixel draw takes lot of time. I
> > was trying to bypass pixel draw and flush the whole rectangle area
> > of text drawn to framebuffer memory into display controller. when
> > ever GrText is called.
>
> Agreed.
this would be nice. other intermediate solutions would be to make a
faster drawbitmap function which would expand from 1->native bpp, and
then have GdBitMap call that.
at Frye we currently have a driver-specific DrawText, but of course we
could always use something faster. the epson S1D13506 controller we're
using supports 1bpp bitmap expansion, but I haven't had time to code for
it yet.
attached are two alternatives for a 8bpp driver-specific DrawText, which
could be probably be adapted for GdBitMap as well.
--
Aaron J. Grier | Frye Electronics, Tigard, OR | ####@####.####
/* hardware-specific text draw. */
static void FB7k_DrawText(PSD psd,MWCOORD x,MWCOORD y,
const MWUCHAR *str, int count, MWPIXELVAL fg, PMWFONT pfont)
{
#if 1
/* low-overhead byte-accessed with early bomb.
* currently the fastest of the bunch. */
extern MWPIXELVAL gr_foreground;
ADDR8 startcel = psd->addr + x + y * psd->linelen;
/* loop through the count of characters */
while (--count >= 0) {
MWUCHAR ch = *str++;
MWCOORD width, height, base;
const MWIMAGEBITS *charbitmap;
ADDR8 startline = startcel;
/* get the bitmap for the current character */
pfont->fontprocs->GetTextBits(pfont, ch, &charbitmap,
&width, &height, &base);
while (height--) {
/* read a new row from our bitmap */
MWIMAGEBITS charrow = *charbitmap++;
MWCOORD curwidth = width;
ADDR8 curpixel = startline;
/* write out bytewise if there's anything left */
while (curwidth-- > 0 && charrow != 0) {
if (MWIMAGE_TESTBIT(charrow))
*curpixel++ = gr_foreground;
else curpixel++;
charrow = MWIMAGE_SHIFTBIT(charrow);
}
/* go to the next line */
startline += psd->linelen;
}
/* head over to the next character */
startcel += width;
}
#else
/* nibble to 32-bit lookup. this is somewhat evil because we're
* directly abusing a priori knowledge of what the bitmap format
* is, but god knows we need the speed... */
extern MWPIXELVAL gr_foreground;
extern MWPIXELVAL gr_background;
ADDR8 startcel = psd->addr + x + y * psd->linelen;
/* nibble to unsigned long expansion */
const unsigned long charlut[16] = {
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
};
unsigned long fullforeground, fullbackground;
/* only need to calculate these once per call */
fullforeground = gr_foreground&0xff;
fullforeground |= fullforeground<<8;
fullforeground |= fullforeground<<16;
fullbackground = gr_background&0xff;
fullbackground |= fullbackground<<8;
fullbackground |= fullbackground<<16;
while (--count >= 0) {
char ch = *str++;
MWCOORD width, height, base;
const MWIMAGEBITS *charbitmap;
ADDR8 startline = startcel;
/* get the bitmap for the current character */
pfont->fontprocs->GetTextBits(pfont, ch, &charbitmap,
&width, &height, &base);
assert (width >= sizeof(unsigned long) + 1);
while (height--) {
/* read a row from the bitmap */
MWIMAGEBITS charrow = *charbitmap++;
MWCOORD curwidth = width;
ADDR8 curpixel = startline;
/* anything on this row? */
if (charrow == 0) goto nextrow;
/* check for alignment */
if ((unsigned long) curpixel & 1) {
if (MWIMAGE_TESTBIT(charrow))
*curpixel++ = gr_foreground;
else curpixel++;
charrow = MWIMAGE_SHIFTBIT(charrow);
curwidth--;
}
/* anything left in the next four pixels? */
if ((charrow & 0xf000) != 0) {
unsigned long brushmask =
charlut[(charrow & 0xf000)>>12];
unsigned long brush32;
brush32 = brushmask & fullforeground;
/* I hate this check, but it's cheap */
if (fullbackground != 0)
brush32 |= ~brushmask & fullbackground;
*((unsigned long *)curpixel)++ = brush32;
curwidth-=sizeof(unsigned long);
charrow=MWIMAGE_SHIFTBIT(charrow);
charrow=MWIMAGE_SHIFTBIT(charrow);
charrow=MWIMAGE_SHIFTBIT(charrow);
charrow=MWIMAGE_SHIFTBIT(charrow);
}
/* anything left? */
if (charrow == 0) goto nextrow;
/* write out bytewise whatever is left */
while (curwidth-- > 0 && charrow != 0) {
if (MWIMAGE_TESTBIT(charrow))
*curpixel++ = gr_foreground;
else curpixel++;
charrow = MWIMAGE_SHIFTBIT(charrow);
}
nextrow:
/* go to the next line */
startline += psd->linelen;
}
/* head over to the next character */
startcel += width;
}
#endif
}