[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
This commit is contained in:
Timo Kreuzer 2013-01-09 09:48:02 +00:00
parent 44d9d33649
commit 3d3bd58419
2 changed files with 65 additions and 47 deletions

View file

@ -70,6 +70,12 @@ BOOLEAN CarriageReturn = FALSE;
ULONG_PTR VgaRegisterBase = 0; ULONG_PTR VgaRegisterBase = 0;
ULONG_PTR VgaBase = 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 *********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
VOID VOID
@ -79,35 +85,18 @@ ReadWriteMode(UCHAR Mode)
UCHAR Value; UCHAR Value;
/* Switch to graphics mode register */ /* Switch to graphics mode register */
WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 5); __outpb(0x3CE, 5);
/* Get the current register value, minus the current mode */ /* Get the current register value, minus the current mode */
Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4; Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4;
/* Set the new mode */ /* 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 VOID
NTAPI FORCEINLINE
__outpw(IN ULONG Port,
IN ULONG Value)
{
/* Write to the VGA Register */
WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value);
}
VOID
NTAPI
SetPixel(IN ULONG Left, SetPixel(IN ULONG Left,
IN ULONG Top, IN ULONG Top,
IN UCHAR Color) IN UCHAR Color)
@ -117,15 +106,6 @@ SetPixel(IN ULONG Left,
/* Calculate the pixel position. */ /* Calculate the pixel position. */
PixelPosition = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80); 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 */ /* Select the bitmask register and write the mask */
__outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8); __outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8);
@ -148,6 +128,15 @@ DisplayCharacter(CHAR Character,
/* Get the font line for this character */ /* Get the font line for this character */
FontChar = &FontData[Character * BOOTCHAR_HEIGHT]; 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 */ /* Loop each pixel height */
i = BOOTCHAR_HEIGHT; i = BOOTCHAR_HEIGHT;
do do
@ -280,7 +269,7 @@ VOID
NTAPI NTAPI
VgaScroll(ULONG Scroll) VgaScroll(ULONG Scroll)
{ {
ULONG Top, RowSize, i; ULONG Top, RowSize;
PUCHAR OldPosition, NewPosition; PUCHAR OldPosition, NewPosition;
/* Clear the 4 planes */ /* Clear the 4 planes */
@ -291,19 +280,27 @@ VgaScroll(ULONG Scroll)
/* Set Mode 1 */ /* Set Mode 1 */
ReadWriteMode(1); ReadWriteMode(1);
RowSize = (ScrollRegion[2] - ScrollRegion[0] + 1) / 8; 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 */ /* Start loop */
for(Top = ScrollRegion[1]; Top <= ScrollRegion[3]; ++Top) for(Top = ScrollRegion[1]; Top <= ScrollRegion[3]; ++Top)
{ {
/* Calculate the position in memory for the row */ #if defined(_M_IX86) || defined(_M_AMD64)
OldPosition = (PUCHAR)VgaBase + (Top + Scroll) * 80 + ScrollRegion[0] / 8; __movsb(NewPosition, OldPosition, RowSize);
NewPosition = (PUCHAR)VgaBase + Top * 80 + ScrollRegion[0] / 8; #else
ULONG i;
/* Scroll the row */ /* Scroll the row */
for(i = 0; i < RowSize; ++i) for(i = 0; i < RowSize; ++i)
WRITE_REGISTER_UCHAR(NewPosition + i, READ_REGISTER_UCHAR(OldPosition + 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 */ /* Set the count and make sure it's above 0 */
Count = TopDelta * 80; 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 */ #if defined(_M_IX86) || defined(_M_AMD64)
Position2++; __movsb(Position1, Position2, Count);
Position1++; #else
} while (--Count); /* 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 VOID
@ -390,6 +389,15 @@ BitBlt(IN ULONG Left,
return; 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 */ /* 4bpp blitting */
dy = Top; dy = Top;
do do
@ -429,6 +437,15 @@ RleBitBlt(IN ULONG Left,
ULONG i, j; ULONG i, j;
ULONG Code; 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 */ /* Set Y height and current X value and start loop */
YDelta = Top + Height - 1; YDelta = Top + Height - 1;
x = Left; x = Left;
@ -735,7 +752,7 @@ VidDisplayString(PUCHAR String)
{ {
/* Update current X */ /* Update current X */
curr_x = ScrollRegion[0]; curr_x = ScrollRegion[0];
/* Check if we're being followed by a new line */ /* Check if we're being followed by a new line */
CarriageReturn = TRUE; CarriageReturn = TRUE;
} }

View file

@ -3,6 +3,7 @@
#include "arc/arc.h" #include "arc/arc.h"
#include "halfuncs.h" #include "halfuncs.h"
#include "drivers/bootvid/bootvid.h" #include "drivers/bootvid/bootvid.h"
#include "ioaccess.h"
/* Define if FontData has upside down characters */ /* Define if FontData has upside down characters */
#undef CHAR_GEN_UPSIDE_DOWN #undef CHAR_GEN_UPSIDE_DOWN