[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 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;
}

View file

@ -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