Author: aandrejevic
Date: Sat Aug 27 21:55:34 2016
New Revision: 72477
URL:
http://svn.reactos.org/svn/reactos?rev=72477&view=rev
Log:
[NTVDM]
Move the framebuffer update to the start of the display cycle to reduce tearing.
Stabilize the IPS calculation.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/clock.c
trunk/reactos/subsystems/mvdm/ntvdm/clock.h
trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/clock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/cloc…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/clock.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/clock.c [iso-8859-1] Sat Aug 27 21:55:34 2016
@@ -38,8 +38,6 @@
/* VARIABLES ******************************************************************/
static LIST_ENTRY Timers;
-static ULONGLONG Cycles = 0ULL;
-static ULONGLONG CurrentIps = 20000000ULL; // 20 MIPS is a good estimate
static LARGE_INTEGER StartPerfCount, Frequency;
// static ULONG StartTickCount;
static LARGE_INTEGER Counter;
@@ -47,17 +45,28 @@
static ULONGLONG LastCycles = 0ULL;
static PHARDWARE_TIMER IpsTimer;
+ULONGLONG CurrentCycleCount = 0ULL;
+ULONGLONG CurrentIps = 20000000ULL; // 20 MIPS is a good estimate
+
/* PRIVATE FUNCTIONS **********************************************************/
static VOID FASTCALL IpsCallback(ULONGLONG ElapsedTime)
{
- CurrentIps = (Cycles - LastCycles) / ElapsedTime;
+ static INT NumCalls = 0;
+
+ ULONGLONG NewIps = 10ULL * (CurrentCycleCount - LastCycles) / ElapsedTime;
+ CurrentIps = (CurrentIps + NewIps) >> 1;
#ifdef IPS_DISPLAY
- DPRINT1("NTVDM: %I64u Instructions Per Second\n", CurrentIps);
+ NumCalls++;
+ if (NumCalls == 10)
+ {
+ DPRINT1("NTVDM: %I64u Instructions Per Second\n", CurrentIps);
+ NumCalls = 0;
+ }
#endif
- LastCycles = Cycles;
+ LastCycles = CurrentCycleCount;
}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -81,7 +90,7 @@
for (i = 0; VdmRunning && CpuRunning && (i < STEPS_PER_CYCLE);
i++)
{
CpuStep();
- ++Cycles;
+ ++CurrentCycleCount;
}
Entry = Timers.Flink;
@@ -205,16 +214,6 @@
}
}
-ULONGLONG GetCycleCount(VOID)
-{
- return Cycles;
-}
-
-ULONGLONG GetCycleSpeed(VOID)
-{
- return CurrentIps;
-}
-
BOOLEAN ClockInitialize(VOID)
{
InitializeListHead(&Timers);
@@ -231,7 +230,7 @@
/* Find the starting tick count */
// StartTickCount = GetTickCount();
- IpsTimer = CreateHardwareTimer(HARDWARE_TIMER_ENABLED, HZ_TO_NS(1), IpsCallback);
+ IpsTimer = CreateHardwareTimer(HARDWARE_TIMER_ENABLED, HZ_TO_NS(10), IpsCallback);
if (IpsTimer == NULL)
{
wprintf(L"FATAL: Cannot create IPS timer.\n");
Modified: trunk/reactos/subsystems/mvdm/ntvdm/clock.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/cloc…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/clock.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/clock.h [iso-8859-1] Sat Aug 27 21:55:34 2016
@@ -33,20 +33,21 @@
/* FUNCTIONS ******************************************************************/
+extern ULONGLONG CurrentCycleCount;
+extern ULONGLONG CurrentIps;
+
PHARDWARE_TIMER CreateHardwareTimer
(
ULONG Flags,
ULONGLONG Delay, /* nanoseconds */
PHARDWARE_TIMER_PROC Callback
);
+
VOID EnableHardwareTimer(PHARDWARE_TIMER Timer);
VOID DisableHardwareTimer(PHARDWARE_TIMER Timer);
VOID SetHardwareTimerDelay(PHARDWARE_TIMER Timer, ULONGLONG NewDelay);
VOID DestroyHardwareTimer(PHARDWARE_TIMER Timer);
-ULONGLONG GetCycleCount(VOID);
-ULONGLONG GetCycleSpeed(VOID);
-
VOID ClockUpdate(VOID);
BOOLEAN ClockInitialize(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c [iso-8859-1] Sat Aug 27
21:55:34 2016
@@ -1104,8 +1104,8 @@
{
BYTE Result = 0;
BOOLEAN Vsync, Hsync;
- ULONGLONG Cycles = GetCycleCount();
- ULONG CyclesPerMicrosecond = (ULONG)((GetCycleSpeed() + 500000ULL) /
1000000ULL);
+ ULONGLONG Cycles = CurrentCycleCount;
+ ULONG CyclesPerMicrosecond = (ULONG)((CurrentIps + 500000ULL) / 1000000ULL);
ULONG Dots = (VgaSeqRegisters[VGA_SEQ_CLOCK_REG] & 1) ? 9 : 8;
ULONG Clock = VgaGetClockFrequency() / 1000000;
ULONG HblankStart, HblankEnd;
@@ -1624,38 +1624,29 @@
{
ULONG VerticalTotal = VgaCrtcRegisters[VGA_CRTC_VERT_TOTAL_REG];
ULONG VerticalRetraceStart = VgaCrtcRegisters[VGA_CRTC_START_VERT_RETRACE_REG];
- ULONG VerticalRetraceEnd;
- BOOLEAN BeforeVSyncStart, BeforeVSyncEnd;
- ULONG CurrentCycleCount = GetCycleCount();
+ BOOLEAN BeforeVSync;
ULONG ElapsedCycles = CurrentCycleCount - HorizontalRetraceCycle;
ULONG Dots = (VgaSeqRegisters[VGA_SEQ_CLOCK_REG] & 1) ? 9 : 8;
ULONG HorizTotalDots = ((ULONG)VgaCrtcRegisters[VGA_CRTC_HORZ_TOTAL_REG] + 5) *
Dots;
ULONG HSyncsPerSecond = VgaGetClockFrequency() / HorizTotalDots;
- ULONG HSyncs = (ElapsedCycles * HSyncsPerSecond) / GetCycleSpeed();
+ ULONG HSyncs = (ElapsedCycles * HSyncsPerSecond + (CurrentIps >> 1)) /
CurrentIps;
UNREFERENCED_PARAMETER(ElapsedTime);
if (HSyncs == 0) HSyncs = 1;
-
+
VerticalTotal |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] &
VGA_CRTC_OVERFLOW_VT8) << 8;
VerticalTotal |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] &
VGA_CRTC_OVERFLOW_VT9) << 4;
VerticalRetraceStart |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] &
VGA_CRTC_OVERFLOW_VRS8) << 6;
VerticalRetraceStart |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] &
VGA_CRTC_OVERFLOW_VRS9) << 2;
- VerticalRetraceEnd = VerticalRetraceStart +
(VgaCrtcRegisters[VGA_CRTC_END_VERT_RETRACE_REG] & 0x0F);
-
/* Set the cycle */
HorizontalRetraceCycle = CurrentCycleCount;
/* Increment the scanline counter, but make sure we don't skip any part of the
vertical retrace */
- BeforeVSyncStart = (ScanlineCounter < VerticalRetraceStart);
- BeforeVSyncEnd = (ScanlineCounter < VerticalRetraceEnd);
+ BeforeVSync = (ScanlineCounter < VerticalRetraceStart);
ScanlineCounter += HSyncs;
- if (BeforeVSyncStart && ScanlineCounter >= VerticalRetraceStart)
ScanlineCounter = VerticalRetraceStart;
- else if (BeforeVSyncEnd && ScanlineCounter >= VerticalRetraceEnd)
ScanlineCounter = VerticalRetraceEnd;
-
- /* The scanline counter wraps around */
- ScanlineCounter %= VerticalTotal;
+ if (BeforeVSync && ScanlineCounter >= VerticalRetraceStart)
ScanlineCounter = VerticalRetraceStart;
if (ScanlineCounter == VerticalRetraceStart)
{
@@ -1673,8 +1664,9 @@
+ ((VgaCrtcRegisters[VGA_CRTC_PRESET_ROW_SCAN_REG] >>
5) & 3);
}
- if (ScanlineCounter == VerticalRetraceEnd)
- {
+ if (ScanlineCounter > VerticalTotal)
+ {
+ ScanlineCounter = 0;
VgaVerticalRetrace();
}
}