[Bf-blender-cvs] [efe3e4f0233] master: Save Wintab packets to a local queue as WT_PACKET events arrive or when handling mouse input. This Wintab to mouse synchronization issues, and likely prevents queue exhaustion for some Wintab implmenetations.

Nicholas Rishel noreply at git.blender.org
Sat Oct 31 00:32:27 CET 2020


Commit: efe3e4f0233d86a31ef1773de96112a8e628dfb8
Author: Nicholas Rishel
Date:   Mon May 25 20:45:26 2020 -0700
Branches: master
https://developer.blender.org/rBefe3e4f0233d86a31ef1773de96112a8e628dfb8

Save Wintab packets to a local queue as WT_PACKET events arrive or when
handling mouse input. This Wintab to mouse synchronization issues, and
likely prevents queue exhaustion for some Wintab implmenetations.

Signed-off-by: Nicholas Rishel <rishel.nick at gmail.com>

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

M	intern/ghost/intern/GHOST_SystemWin32.cpp
M	intern/ghost/intern/GHOST_SystemWin32.h
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 a4fdcc24ed8..e40934dd1ad 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -234,6 +234,11 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
   toggleConsole(1);
 }
 
+GHOST_TUns64 GHOST_SystemWin32::millisSinceStart(__int64 ms) const
+{
+  return (GHOST_TUns64)(ms - m_start * 1000 / m_freq);
+}
+
 GHOST_TUns64 GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
 {
   // Calculate the time passed since system initialization.
@@ -1591,6 +1596,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
           window->processWintabProximityEvent(inRange);
           break;
         }
+        case WT_PACKET:
+          window->updatePendingWintabEvents();
+          break;
         ////////////////////////////////////////////////////////////////////////
         // Pointer events, processed
         ////////////////////////////////////////////////////////////////////////
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 68aef3e3b30..1f9b28bb7ce 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -64,6 +64,8 @@ class GHOST_SystemWin32 : public GHOST_System {
    ** Time(r) functionality
    ***************************************************************************************/
 
+  GHOST_TUns64 millisSinceStart(__int64 ms) const;
+
   /**
    * This method converts performance counter measurements into milliseconds since the start of the
    * system process.
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index c5fe38ee678..f09be8ed6d0 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1045,6 +1045,7 @@ void GHOST_WindowWin32::initializeWintab()
     lc.lcPktData = PACKETDATA;
     lc.lcPktMode = PACKETMODE;
     lc.lcMoveMask = PACKETDATA;
+    lc.lcOptions |= CXO_MESSAGES;
     // Wacom maps y origin to the tablet's bottom
     // Invert to match Windows y origin mapping to the screen top
     lc.lcOutExtY = -lc.lcOutExtY;
@@ -1298,12 +1299,16 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
 
   GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
 
-  const int numPackets = m_wintab.packetsGet(
-      m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
-  outWintabInfo.resize(numPackets);
+  updatePendingWintabEvents();
+
+  auto &pendingEvents = m_wintab.pendingEvents;
+  size_t pendingEventSize = pendingEvents.size();
+  outWintabInfo.resize(pendingEventSize);
+
+  for (int i = 0; i < pendingEventSize; i++) {
+    PACKET pkt = pendingEvents.front();
+    pendingEvents.pop();
 
-  for (int i = 0; i < numPackets; i++) {
-    PACKET pkt = m_wintab.pkts[i];
     GHOST_TabletData tabletData = GHOST_TABLET_DATA_NONE;
     switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
       case 0:
@@ -1390,6 +1395,46 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
   return GHOST_kSuccess;
 }
 
+void GHOST_WindowWin32::updatePendingWintabEvents()
+{
+  if (!(m_wintab.packetsGet && m_wintab.context)) {
+    return;
+  }
+  GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
+
+  auto &pendingEvents = m_wintab.pendingEvents;
+
+  // Clear outdated events from queue.
+  GHOST_TUns64 currTime = system->getMilliSeconds();
+  GHOST_TUns64 timeout = 300;
+  while (!pendingEvents.empty()) {
+    GHOST_TUns64 pktTime = system->millisSinceStart(pendingEvents.front().pkTime);
+    if (currTime - pktTime > timeout) {
+      pendingEvents.pop();
+    }
+    else {
+      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++) {
+    GHOST_TUns64 pktTime = system->millisSinceStart(m_wintab.pkts[i].pkTime);
+    if (currTime - pktTime < timeout) {
+      break;
+    }
+  }
+  for (; i < numPackets; i++) {
+    pendingEvents.push(m_wintab.pkts[i]);
+  }
+}
+
 GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
 {
   if (m_user32) {
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 3cf7417e4c1..88b6e19c69d 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -35,6 +35,7 @@
 #endif
 
 #include <vector>
+#include <queue>
 
 #include <wintab.h>
 // PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first
@@ -482,6 +483,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
    */
   GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
 
+  /**
+   */
+  void updatePendingWintabEvents();
+
   GHOST_TSuccess beginFullScreen() const
   {
     return GHOST_kFailure;
@@ -625,6 +630,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
     LONG maxAzimuth = 0, maxAltitude = 0;
     /* Queue size doesn't change once set, so reuse the same buffer */
     std::vector<PACKET> pkts;
+    std::queue<PACKET> pendingEvents;
   } m_wintab;
 
   /**



More information about the Bf-blender-cvs mailing list