mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[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:
parent
3d3bd58419
commit
a54575d01e
1 changed files with 91 additions and 34 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue