Author: tkreuzer
Date: Wed Jan 9 12:40:42 2013
New Revision: 58148
URL:
http://svn.reactos.org/svn/reactos?rev=58148&view=rev
Log:
[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.
Modified:
trunk/reactos/drivers/base/bootvid/i386/vga.c
Modified: trunk/reactos/drivers/base/bootvid/i386/vga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/bootvid/i386/…
==============================================================================
--- trunk/reactos/drivers/base/bootvid/i386/vga.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/base/bootvid/i386/vga.c [iso-8859-1] Wed Jan 9 12:40:42 2013
@@ -114,19 +114,32 @@
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)
-{
- PUCHAR FontChar;
- ULONG i, j, XOffset;
-
- /* Get the font line for this character */
- FontChar = &FontData[Character * BOOTCHAR_HEIGHT];
+ ULONG BackColor)
+{
+ PUCHAR FontChar, PixelPtr;
+ ULONG Height;
+ UCHAR Shift;
/* Switch to mode 10 */
ReadWriteMode(10);
@@ -137,40 +150,84 @@
/* 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);
- }
-
- /* Increase X Offset */
- XOffset++;
- } while (j >>= 1);
-
- /* Move to the next Y ordinate */
- Top++;
- } while (--i);
+ SET_PIXELS(PixelPtr, *FontChar << Shift, TextColor);
+ PixelPtr += 80;
+ FontChar++;
+ } while (--Height);
+ }
+
+ /* Check if the background color is transparent */
+ if (BackColor >= 16)
+ {
+ /* We are done */
+ return;
+ }
+
+ /* 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