[Bf-blender-cvs] [3a1d1aaa86d] master: Synchronize Wintab and Win32 time.

Nicholas Rishel noreply at git.blender.org
Thu Dec 17 00:49:15 CET 2020


Commit: 3a1d1aaa86d0d7cc6aaf0e6633d557bbcdd0b514
Author: Nicholas Rishel
Date:   Wed Dec 16 15:32:18 2020 -0800
Branches: master
https://developer.blender.org/rB3a1d1aaa86d0d7cc6aaf0e6633d557bbcdd0b514

Synchronize Wintab and Win32 time.

Time is synchronized by the difference between the WT_PACKET receive
time and the last received PACKET's pkTime. This is used to prevent
Wintab packets from being prematurely expired.

===================================================================

M	intern/ghost/intern/GHOST_SystemWin32.cpp
M	intern/ghost/intern/GHOST_WindowWin32.cpp
M	intern/ghost/intern/GHOST_WindowWin32.h

===================================================================

diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index d2aebab026f..2bf1d0c2d35 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1614,7 +1614,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
           break;
         }
         case WT_PACKET:
-          window->updatePendingWintabEvents();
+          window->updateWintabEventsSyncTime();
           break;
         ////////////////////////////////////////////////////////////////////////
         // Pointer events, processed
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index af02663985d..a4cbf66b22d 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1292,7 +1292,7 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
 
   GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
 
-  updatePendingWintabEvents();
+  updateWintabEvents();
 
   auto &pendingEvents = m_wintab.pendingEvents;
   size_t pendingEventSize = pendingEvents.size();
@@ -1388,6 +1388,44 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
   return GHOST_kSuccess;
 }
 
+void GHOST_WindowWin32::updateWintabEvents()
+{
+  readWintabEvents();
+  // When a Wintab device is used to leave window focus, some of it's packets are periodically not
+  // queued in time to be flushed. Reading packets needs to occur before expiring packets to clear
+  // these from the queue.
+  expireWintabEvents();
+}
+
+void GHOST_WindowWin32::updateWintabEventsSyncTime()
+{
+  readWintabEvents();
+
+  if (!m_wintab.pendingEvents.empty()) {
+    auto lastEvent = m_wintab.pendingEvents.back();
+    m_wintab.sysTimeOffset = ::GetTickCount() - lastEvent.pkTime;
+  }
+
+  expireWintabEvents();
+}
+
+void GHOST_WindowWin32::readWintabEvents()
+{
+  if (!(m_wintab.packetsGet && m_wintab.context)) {
+    return;
+  }
+
+  auto &pendingEvents = m_wintab.pendingEvents;
+
+  /* Get new packets. */
+  const int numPackets = m_wintab.packetsGet(
+      m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
+
+  for (int i = 0; i < numPackets; i++) {
+    pendingEvents.push(m_wintab.pkts[i]);
+  }
+}
+
 /* Wintab (per documentation but may vary with implementation) does not update when its event
  * buffer is full. This is an issue because we need some synchronization point between Wintab
  * events and Win32 events, so we can't drain and process the queue immediately. We need to
@@ -1396,17 +1434,12 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
  * mode from the Wintab API alone. There is no guaranteed ordering between Wintab and Win32 mouse
  * events and no documented time stamp shared between the two, so we synchronize on mouse button
  * events. */
-void GHOST_WindowWin32::updatePendingWintabEvents()
+void GHOST_WindowWin32::expireWintabEvents()
 {
-  if (!(m_wintab.packetsGet && m_wintab.context)) {
-    return;
-  }
-
   auto &pendingEvents = m_wintab.pendingEvents;
 
-  /* Clear outdated events from queue. */
-  DWORD currTime = ::GetTickCount();
-  DWORD millisTimeout = 500;
+  DWORD currTime = ::GetTickCount() - m_wintab.sysTimeOffset;
+  DWORD millisTimeout = 300;
   while (!pendingEvents.empty()) {
     DWORD pkTime = pendingEvents.front().pkTime;
 
@@ -1417,24 +1450,6 @@ void GHOST_WindowWin32::updatePendingWintabEvents()
       break;
     }
   }
-
-  /* Get new packets. */
-  const int numPackets = m_wintab.packetsGet(
-      m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
-
-  int i = 0;
-  /* Don't queue outdated packets, such events can include packets that occurred before the current
-   * window lost and regained focus. */
-  for (; i < numPackets; i++) {
-    DWORD pkTime = m_wintab.pkts[i].pkTime;
-
-    if (currTime < pkTime + millisTimeout) {
-      break;
-    }
-  }
-  for (; i < numPackets; i++) {
-    pendingEvents.push(m_wintab.pkts[i]);
-  }
 }
 
 GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index a761d7d84dc..829bbdea051 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -486,9 +486,14 @@ class GHOST_WindowWin32 : public GHOST_Window {
   GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
 
   /**
-   * Updates stored pending Wintab events.
+   * Updates pending Wintab events and syncs Wintab time with OS time.
    */
-  void updatePendingWintabEvents();
+  void updateWintabEventsSyncTime();
+
+  /**
+   * Updates pending Wintab events.
+   */
+  void updateWintabEvents();
 
   GHOST_TSuccess beginFullScreen() const
   {
@@ -629,6 +634,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
     GHOST_TUns8 numSysButtons = 0;
     /** Cursors currently in contact mapped to system buttons */
     DWORD sysButtonsPressed = 0;
+    DWORD sysTimeOffset = 0;
     LONG maxPressure = 0;
     LONG maxAzimuth = 0, maxAltitude = 0;
     /** Reusable buffer to read in Wintab Packets. */
@@ -642,6 +648,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
    */
   void initializeWintab();
 
+  void readWintabEvents();
+
+  void expireWintabEvents();
+
   /**
    * Convert Wintab system mapped (mouse) buttons into Ghost button mask.
    * \param cursor: The Wintab cursor associated to the button.



More information about the Bf-blender-cvs mailing list