From 3d3bd584190a105ea857395b45bc6eac3cd262e2 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 9 Jan 2013 09:48:02 +0000 Subject: [PATCH] [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. svn path=/trunk/; revision=58147 --- reactos/drivers/base/bootvid/i386/vga.c | 111 ++++++++++++++---------- reactos/drivers/base/bootvid/precomp.h | 1 + 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/reactos/drivers/base/bootvid/i386/vga.c b/reactos/drivers/base/bootvid/i386/vga.c index 3c6d4ad8857..28a43cc9c56 100644 --- a/reactos/drivers/base/bootvid/i386/vga.c +++ b/reactos/drivers/base/bootvid/i386/vga.c @@ -70,6 +70,12 @@ BOOLEAN CarriageReturn = FALSE; 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 @@ ReadWriteMode(UCHAR Mode) 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); + __outpb(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 +FORCEINLINE SetPixel(IN ULONG Left, IN ULONG Top, IN UCHAR Color) @@ -117,15 +106,6 @@ SetPixel(IN ULONG Left, /* 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); @@ -148,6 +128,15 @@ DisplayCharacter(CHAR Character, /* 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; do @@ -280,7 +269,7 @@ VOID NTAPI VgaScroll(ULONG Scroll) { - ULONG Top, RowSize, i; + ULONG Top, RowSize; PUCHAR OldPosition, NewPosition; /* Clear the 4 planes */ @@ -291,19 +280,27 @@ VgaScroll(ULONG Scroll) /* 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 @@ PreserveRow(IN ULONG CurrentTop, /* 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 @@ BitBlt(IN ULONG Left, 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 @@ -429,6 +437,15 @@ RleBitBlt(IN ULONG Left, 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; x = Left; @@ -735,7 +752,7 @@ VidDisplayString(PUCHAR String) { /* Update current X */ curr_x = ScrollRegion[0]; - + /* Check if we're being followed by a new line */ CarriageReturn = TRUE; } diff --git a/reactos/drivers/base/bootvid/precomp.h b/reactos/drivers/base/bootvid/precomp.h index c7d55e92f8c..1a7d4a6b6e3 100644 --- a/reactos/drivers/base/bootvid/precomp.h +++ b/reactos/drivers/base/bootvid/precomp.h @@ -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