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@gmail.com>
This commit is contained in:
parent
d58387cdda
commit
efe3e4f023
@ -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
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user