Author: tkreuzer Date: Wed Jan 9 09:48:02 2013 New Revision: 58147
URL: http://svn.reactos.org/svn/reactos?rev=58147&view=rev Log: [BOOTVID] Apply the following optimizations: - include ioaccess.h to inline port access, instead of going through hal. - Make __outpb and __outpw macros rather than stdcall function - Make SetPixel FORCEINLINE - Do not switch mode for every pixel we write, instead do it once before doing larger blt operations - use __movsb instead of manual loop plus READ/WRITE_REGISTER_UCHAR This noticeably improves performance.
Modified: trunk/reactos/drivers/base/bootvid/i386/vga.c trunk/reactos/drivers/base/bootvid/precomp.h
Modified: trunk/reactos/drivers/base/bootvid/i386/vga.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/bootvid/i386/v... ============================================================================== --- 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 09:48:02 2013 @@ -70,6 +70,12 @@ ULONG_PTR VgaRegisterBase = 0; ULONG_PTR VgaBase = 0;
+#define __outpb(Port, Value) \ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value) + +#define __outpw(Port, Value) \ + WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value) + /* PRIVATE FUNCTIONS *********************************************************/
VOID @@ -79,35 +85,18 @@ UCHAR Value;
/* Switch to graphics mode register */ - WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 5); + __outpb(0x3CE, 5);
/* Get the current register value, minus the current mode */ Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4;
/* Set the new mode */ - WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, Mode | Value); -} - -VOID -NTAPI -__outpb(IN ULONG Port, - IN ULONG Value) -{ - /* Write to the VGA Register */ - WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value); -} - -VOID -NTAPI -__outpw(IN ULONG Port, - IN ULONG Value) -{ - /* Write to the VGA Register */ - WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value); -} - -VOID -NTAPI + __outpb(0x3CF, Mode | Value); +} + + +VOID +FORCEINLINE SetPixel(IN ULONG Left, IN ULONG Top, IN UCHAR Color) @@ -116,15 +105,6 @@
/* Calculate the pixel position. */ PixelPosition = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80); - - /* Switch to mode 10 */ - ReadWriteMode(10); - - /* Clear the 4 planes (we're already in unchained mode here) */ - __outpw(0x3C4, 0xF02); - - /* Select the color don't care register */ - __outpw(0x3CE, 7);
/* Select the bitmask register and write the mask */ __outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8); @@ -147,6 +127,15 @@
/* Get the font line for this character */ FontChar = &FontData[Character * BOOTCHAR_HEIGHT]; + + /* Switch to mode 10 */ + ReadWriteMode(10); + + /* Clear the 4 planes (we're already in unchained mode here) */ + __outpw(0x3C4, 0xF02); + + /* Select the color don't care register */ + __outpw(0x3CE, 7);
/* Loop each pixel height */ i = BOOTCHAR_HEIGHT; @@ -280,7 +269,7 @@ NTAPI VgaScroll(ULONG Scroll) { - ULONG Top, RowSize, i; + ULONG Top, RowSize; PUCHAR OldPosition, NewPosition;
/* Clear the 4 planes */ @@ -291,19 +280,27 @@
/* Set Mode 1 */ ReadWriteMode(1); - + RowSize = (ScrollRegion[2] - ScrollRegion[0] + 1) / 8; + + /* Calculate the position in memory for the row */ + OldPosition = (PUCHAR)VgaBase + (ScrollRegion[1] + Scroll) * 80 + ScrollRegion[0] / 8; + NewPosition = (PUCHAR)VgaBase + ScrollRegion[1] * 80 + ScrollRegion[0] / 8;
/* Start loop */ for(Top = ScrollRegion[1]; Top <= ScrollRegion[3]; ++Top) { - /* Calculate the position in memory for the row */ - OldPosition = (PUCHAR)VgaBase + (Top + Scroll) * 80 + ScrollRegion[0] / 8; - NewPosition = (PUCHAR)VgaBase + Top * 80 + ScrollRegion[0] / 8; - +#if defined(_M_IX86) || defined(_M_AMD64) + __movsb(NewPosition, OldPosition, RowSize); +#else + ULONG i; + /* Scroll the row */ for(i = 0; i < RowSize; ++i) WRITE_REGISTER_UCHAR(NewPosition + i, READ_REGISTER_UCHAR(OldPosition + i)); +#endif + OldPosition += 80; + NewPosition += 80; } }
@@ -341,19 +338,21 @@
/* Set the count and make sure it's above 0 */ Count = TopDelta * 80; - if (Count) - { - /* Loop every pixel */ - do - { - /* Write the data back on the other position */ - WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2)); - - /* Increase both positions */ - Position2++; - Position1++; - } while (--Count); - } + +#if defined(_M_IX86) || defined(_M_AMD64) + __movsb(Position1, Position2, Count); +#else + /* Loop every pixel */ + while (Count--) + { + /* Write the data back on the other position */ + WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2)); + + /* Increase both positions */ + Position2++; + Position1++; + } +#endif }
VOID @@ -390,6 +389,15 @@ return; }
+ /* Switch to mode 10 */ + ReadWriteMode(10); + + /* Clear the 4 planes (we're already in unchained mode here) */ + __outpw(0x3C4, 0xF02); + + /* Select the color don't care register */ + __outpw(0x3CE, 7); + /* 4bpp blitting */ dy = Top; do @@ -428,6 +436,15 @@ ULONG Color, Color2; ULONG i, j; ULONG Code; + + /* Switch to mode 10 */ + ReadWriteMode(10); + + /* Clear the 4 planes (we're already in unchained mode here) */ + __outpw(0x3C4, 0xF02); + + /* Select the color don't care register */ + __outpw(0x3CE, 7);
/* Set Y height and current X value and start loop */ YDelta = Top + Height - 1; @@ -735,7 +752,7 @@ { /* Update current X */ curr_x = ScrollRegion[0]; - + /* Check if we're being followed by a new line */ CarriageReturn = TRUE; }
Modified: trunk/reactos/drivers/base/bootvid/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/bootvid/precom... ============================================================================== --- trunk/reactos/drivers/base/bootvid/precomp.h [iso-8859-1] (original) +++ trunk/reactos/drivers/base/bootvid/precomp.h [iso-8859-1] Wed Jan 9 09:48:02 2013 @@ -3,6 +3,7 @@ #include "arc/arc.h" #include "halfuncs.h" #include "drivers/bootvid/bootvid.h" +#include "ioaccess.h"
/* Define if FontData has upside down characters */ #undef CHAR_GEN_UPSIDE_DOWN