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/…
==============================================================================
--- 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;
}