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.c?rev=72477&r1=72476&r2=72477&view=diff
==============================================================================
--- 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.h?rev=72477&r1=72476&r2=72477&view=diff
==============================================================================
--- 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/hardware/video/svga.c?rev=72477&r1=72476&r2=72477&view=diff
==============================================================================
--- 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();
     }
 }


Reply via email to