[BOOTVID]

Rewrite DisplayCharacter. The new algorithm is much faster. It uses the VGA mask register to draws up to 8 pixels at once, completely getting rid of the inner loop. Pixel position / mask calculations and the check for opaque vs transparent background are moved out of the loops. The result is a single loop for the y coordinate containing an inlined __outbyte and memory write. A second loop in case of unaligned character writes.

svn path=/trunk/; revision=58148
This commit is contained in:
Timo Kreuzer 2013-01-09 12:40:42 +00:00
parent 3d3bd58419
commit a54575d01e

View file

@ -114,19 +114,32 @@ SetPixel(IN ULONG Left,
READ_REGISTER_UCHAR(PixelPosition) & Color);
}
#ifdef CHAR_GEN_UPSIDE_DOWN
# define GetFontPtr(_Char) &FontData[_Char * BOOTCHAR_HEIGHT] + BOOTCHAR_HEIGHT - 1;
# define FONT_PTR_DELTA (-1)
#else
# define GetFontPtr(_Char) &FontData[_Char * BOOTCHAR_HEIGHT];
# define FONT_PTR_DELTA (1)
#endif
#define SET_PIXELS(_PixelPtr, _PixelMask, _TextColor) \
/* Select the bitmask register and write the mask */ \
__outpw(0x3CE, (_PixelMask << 8) | 8); \
\
/* Set the new color */ \
WRITE_REGISTER_UCHAR(_PixelPtr, (UCHAR)_TextColor);\
VOID
NTAPI
DisplayCharacter(CHAR Character,
ULONG Left,
ULONG Top,
ULONG TextColor,
ULONG BackTextColor)
ULONG BackColor)
{
PUCHAR FontChar;
ULONG i, j, XOffset;
/* Get the font line for this character */
FontChar = &FontData[Character * BOOTCHAR_HEIGHT];
PUCHAR FontChar, PixelPtr;
ULONG Height;
UCHAR Shift;
/* Switch to mode 10 */
ReadWriteMode(10);
@ -137,40 +150,84 @@ DisplayCharacter(CHAR Character,
/* Select the color don't care register */
__outpw(0x3CE, 7);
/* Loop each pixel height */
i = BOOTCHAR_HEIGHT;
/* Calculate shift */
Shift = Left & 7;
/* Get the font and pixel pointer */
FontChar = GetFontPtr(Character);
PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);
/* Loop all pixel rows */
Height = BOOTCHAR_HEIGHT;
do
{
/* Loop each pixel width */
j = 128;
XOffset = Left;
SET_PIXELS(PixelPtr, *FontChar >> Shift, TextColor);
PixelPtr += 80;
FontChar += FONT_PTR_DELTA;
} while (--Height);
/* Check if we need to update neighbor bytes */
if (Shift)
{
/* Calculate shift for 2nd byte */
Shift = 8 - Shift;
/* Get the font and pixel pointer (2nd byte) */
FontChar = GetFontPtr(Character);
PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80) + 1;
/* Loop all pixel rows */
Height = BOOTCHAR_HEIGHT;
do
{
/* Check if we should draw this pixel */
#ifdef CHAR_GEN_UPSIDE_DOWN
if (FontChar[i] & (UCHAR)j)
#else
/* Normal character generator (top of char is first element) */
if (FontChar[BOOTCHAR_HEIGHT - i] & (UCHAR)j)
#endif
{
/* We do, use the given Text Color */
SetPixel(XOffset, Top, (UCHAR)TextColor);
}
else if (BackTextColor < 16)
{
/* This is a background pixel. */
/* We're drawing it unless it's transparent. */
SetPixel(XOffset, Top, (UCHAR)BackTextColor);
}
SET_PIXELS(PixelPtr, *FontChar << Shift, TextColor);
PixelPtr += 80;
FontChar++;
} while (--Height);
}
/* Increase X Offset */
XOffset++;
} while (j >>= 1);
/* Check if the background color is transparent */
if (BackColor >= 16)
{
/* We are done */
return;
}
/* Move to the next Y ordinate */
Top++;
} while (--i);
/* Calculate shift */
Shift = Left & 7;
/* Get the font and pixel pointer */
FontChar = GetFontPtr(Character);
PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);
/* Loop all pixel rows */
Height = BOOTCHAR_HEIGHT;
do
{
SET_PIXELS(PixelPtr, ~*FontChar >> Shift, BackColor);
PixelPtr += 80;
FontChar++;
} while (--Height);
/* Check if we need to update neighbor bytes */
if (Shift)
{
/* Calculate shift for 2nd byte */
Shift = 8 - Shift;
/* Get the font and pixel pointer (2nd byte) */
FontChar = GetFontPtr(Character);
PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80) + 1;
/* Loop all pixel rows */
Height = BOOTCHAR_HEIGHT;
do
{
SET_PIXELS(PixelPtr, ~*FontChar << Shift, BackColor);
PixelPtr += 80;
FontChar++;
} while (--Height);
}
}
VOID