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/…
==============================================================================
--- 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/preco…
==============================================================================
--- 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