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/clock... ============================================================================== --- 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/clock... ============================================================================== --- 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/hardw... ============================================================================== --- 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(); } }