Author: hbelusca
Date: Mon Nov 17 00:12:20 2014
New Revision: 65424
URL: http://svn.reactos.org/svn/reactos?rev=65424&view=rev
Log:
[NTVDM]
- Do not recalculate at each refresh the new resolution that usually does not
change (if it changes because of a modification of some VGA register, we detect
that, and we change the vga mode). So keep the current resolution and use it in
paint functions.
- Really reenter a new text/graphic mode when needed (ie. when alphanumeric bit
and computed resolution change), this avoids useless console screenbuffers
recreations (and flickering), things go faster, yet the VGA registers are still
updated (as expected). See r65379, r65018 and r65015 for more details.
Modified:
trunk/reactos/subsystems/ntvdm/hardware/vga.c
Modified: trunk/reactos/subsystems/ntvdm/hardware/vga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/hardware/vga.c?rev=65424&r1=65423&r2=65424&view=diff
==============================================================================
--- trunk/reactos/subsystems/ntvdm/hardware/vga.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/hardware/vga.c [iso-8859-1] Mon Nov 17
00:12:20 2014
@@ -284,12 +284,14 @@
static BOOLEAN CursorChanged = FALSE;
static BOOLEAN PaletteChanged = FALSE;
-static
-enum SCREEN_MODE
+typedef enum _SCREEN_MODE
{
TEXT_MODE,
GRAPHICS_MODE
-} ScreenMode = TEXT_MODE;
+} SCREEN_MODE, *PSCREEN_MODE;
+
+static SCREEN_MODE ScreenMode = TEXT_MODE;
+static COORD CurrResolution = {0};
static SMALL_RECT UpdateRectangle = { 0, 0, 0, 0 };
@@ -920,8 +922,6 @@
static BOOL VgaEnterTextMode(PCOORD Resolution)
{
- DPRINT1("VgaEnterTextMode\n");
-
/* Switch to the text buffer */
VgaSetActiveScreenBuffer(TextConsoleBuffer);
@@ -977,7 +977,20 @@
static VOID VgaChangeMode(VOID)
{
- COORD Resolution = VgaGetDisplayResolution();
+ COORD NewResolution = VgaGetDisplayResolution();
+ SCREEN_MODE NewScreenMode =
+ !(VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) ? TEXT_MODE
+ :
GRAPHICS_MODE;
+
+ /*
+ * No need to switch to a different screen mode + resolution
+ * if the new ones are the same as the old ones.
+ */
+ if ((ScreenMode == NewScreenMode) &&
+ (CurrResolution.X == NewResolution.X && CurrResolution.Y ==
NewResolution.Y))
+ {
+ goto Quit;
+ }
if (ScreenMode == GRAPHICS_MODE)
{
@@ -990,11 +1003,16 @@
VgaLeaveTextMode();
}
+ /* Update the current resolution */
+ CurrResolution = NewResolution;
+
+ /* The new screen mode will be updated via the VgaEnterText/GraphicsMode
functions */
+
/* Check if the new mode is alphanumeric */
- if (!(VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA))
+ if (NewScreenMode == TEXT_MODE)
{
/* Enter new text mode */
- if (!VgaEnterTextMode(&Resolution))
+ if (!VgaEnterTextMode(&CurrResolution))
{
DisplayMessage(L"An unexpected VGA error occurred while switching
into text mode. Error: %u", GetLastError());
EmulatorTerminate();
@@ -1004,7 +1022,7 @@
else
{
/* Enter graphics mode */
- if (!VgaEnterGraphicsMode(&Resolution))
+ if (!VgaEnterGraphicsMode(&CurrResolution))
{
DisplayMessage(L"An unexpected VGA error occurred while switching
into graphics mode. Error: %u", GetLastError());
EmulatorTerminate();
@@ -1012,12 +1030,14 @@
}
}
+Quit:
+
/* Trigger a full update of the screen */
NeedsUpdate = TRUE;
UpdateRectangle.Left = 0;
- UpdateRectangle.Top = 0;
- UpdateRectangle.Right = Resolution.X;
- UpdateRectangle.Bottom = Resolution.Y;
+ UpdateRectangle.Top = 0;
+ UpdateRectangle.Right = CurrResolution.X;
+ UpdateRectangle.Bottom = CurrResolution.Y;
/* Reset the mode change flag */
ModeChanged = FALSE;
@@ -1026,7 +1046,6 @@
static VOID VgaUpdateFramebuffer(VOID)
{
SHORT i, j, k;
- COORD Resolution = VgaGetDisplayResolution();
DWORD AddressSize = VgaGetAddressSize();
DWORD Address = MAKEWORD(VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG],
VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG]);
@@ -1058,7 +1077,7 @@
}
/* Loop through the scanlines */
- for (i = 0; i < Resolution.Y; i++)
+ for (i = 0; i < CurrResolution.Y; i++)
{
if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_OE) && (i & 1))
{
@@ -1067,7 +1086,7 @@
}
/* Loop through the pixels */
- for (j = 0; j < Resolution.X; j++)
+ for (j = 0; j < CurrResolution.X; j++)
{
BYTE PixelData = 0;
@@ -1189,13 +1208,13 @@
if (DoubleWidth && DoubleHeight)
{
/* Now check if the resulting pixel data has changed */
- if (GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2)]
!= PixelData)
+ if (GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j *
2)] != PixelData)
{
/* Yes, write the new value */
- GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2)] =
PixelData;
- GraphicsBuffer[(i * 2 * Resolution.X * 2) + (j * 2 +
1)] = PixelData;
- GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j *
2)] = PixelData;
- GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j *
2 + 1)] = PixelData;
+ GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j *
2)] = PixelData;
+ GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2
+ 1)] = PixelData;
+ GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) +
(j * 2)] = PixelData;
+ GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) +
(j * 2 + 1)] = PixelData;
/* Mark the specified pixel as changed */
VgaMarkForUpdate(i, j);
@@ -1204,11 +1223,11 @@
else if (DoubleWidth && !DoubleHeight)
{
/* Now check if the resulting pixel data has changed */
- if (GraphicsBuffer[(i * Resolution.X * 2) + (j * 2)] !=
PixelData)
+ if (GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)]
!= PixelData)
{
/* Yes, write the new value */
- GraphicsBuffer[(i * Resolution.X * 2) + (j * 2)] =
PixelData;
- GraphicsBuffer[(i * Resolution.X * 2) + (j * 2 + 1)] =
PixelData;
+ GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] =
PixelData;
+ GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2 +
1)] = PixelData;
/* Mark the specified pixel as changed */
VgaMarkForUpdate(i, j);
@@ -1217,11 +1236,11 @@
else if (!DoubleWidth && DoubleHeight)
{
/* Now check if the resulting pixel data has changed */
- if (GraphicsBuffer[(i * 2 * Resolution.X) + j] !=
PixelData)
+ if (GraphicsBuffer[(i * 2 * CurrResolution.X) + j] !=
PixelData)
{
/* Yes, write the new value */
- GraphicsBuffer[(i * 2 * Resolution.X) + j] = PixelData;
- GraphicsBuffer[((i * 2 + 1) * Resolution.X) + j] =
PixelData;
+ GraphicsBuffer[(i * 2 * CurrResolution.X) + j] =
PixelData;
+ GraphicsBuffer[((i * 2 + 1) * CurrResolution.X) + j] =
PixelData;
/* Mark the specified pixel as changed */
VgaMarkForUpdate(i, j);
@@ -1230,10 +1249,10 @@
else // if (!DoubleWidth && !DoubleHeight)
{
/* Now check if the resulting pixel data has changed */
- if (GraphicsBuffer[i * Resolution.X + j] != PixelData)
+ if (GraphicsBuffer[i * CurrResolution.X + j] != PixelData)
{
/* Yes, write the new value */
- GraphicsBuffer[i * Resolution.X + j] = PixelData;
+ GraphicsBuffer[i * CurrResolution.X + j] = PixelData;
/* Mark the specified pixel as changed */
VgaMarkForUpdate(i, j);
@@ -1268,10 +1287,10 @@
CHAR_CELL CharInfo;
/* Loop through the scanlines */
- for (i = 0; i < Resolution.Y; i++)
+ for (i = 0; i < CurrResolution.Y; i++)
{
/* Loop through the characters */
- for (j = 0; j < Resolution.X; j++)
+ for (j = 0; j < CurrResolution.X; j++)
{
CurrentAddr = LOWORD((Address + j) * AddressSize);
@@ -1282,11 +1301,11 @@
CharInfo.Attributes = VgaMemory[CurrentAddr + VGA_BANK_SIZE];
/* Now check if the resulting character data has changed */
- if ((CharBuffer[i * Resolution.X + j].Char != CharInfo.Char) ||
- (CharBuffer[i * Resolution.X + j].Attributes !=
CharInfo.Attributes))
+ if ((CharBuffer[i * CurrResolution.X + j].Char !=
CharInfo.Char) ||
+ (CharBuffer[i * CurrResolution.X + j].Attributes !=
CharInfo.Attributes))
{
/* Yes, write the new value */
- CharBuffer[i * Resolution.X + j] = CharInfo;
+ CharBuffer[i * CurrResolution.X + j] = CharInfo;
/* Mark the specified cell as changed */
VgaMarkForUpdate(i, j);
@@ -1787,7 +1806,6 @@
VOID VgaRefreshDisplay(VOID)
{
HANDLE ConsoleBufferHandle = NULL;
- COORD Resolution;
/* Set the vertical retrace flag */
InVerticalRetrace = TRUE;
@@ -1802,17 +1820,14 @@
/* Change the text cursor appearance */
if (CursorChanged) VgaUpdateTextCursor();
- /* Retrieve the current resolution */
- Resolution = VgaGetDisplayResolution();
-
if (PaletteChanged)
{
/* Trigger a full update of the screen */
NeedsUpdate = TRUE;
UpdateRectangle.Left = 0;
- UpdateRectangle.Top = 0;
- UpdateRectangle.Right = Resolution.X;
- UpdateRectangle.Bottom = Resolution.Y;
+ UpdateRectangle.Top = 0;
+ UpdateRectangle.Right = CurrResolution.X;
+ UpdateRectangle.Bottom = CurrResolution.Y;
PaletteChanged = FALSE;
}