[client/idd] input: complete network latency path

Isolate input sends from shared transport accounting and reserve
reliable capacity.

Prioritize QUIC execution and bound stale motion through the Windows
pipe and HID queues.
This commit is contained in:
Geoffrey McRae
2026-10-08 21:34:24 +11:00
parent 1af2f13440
commit b1dda92f09
9 changed files with 695 additions and 344 deletions

View File

@@ -38,7 +38,7 @@ const DWORD CPipeEndpoint::CLIENT_RETRY_MAX_MS = 2000;
const DWORD CPipeEndpoint::SERVER_RETRY_MS = 1000;
const DWORD CPipeEndpoint::AUTHENTICATION_TIMEOUT_MS = 2000;
const DWORD CPipeEndpoint::AUTHORIZATION_POLL_MS = 1000;
const DWORD CPipeEndpoint::WRITE_TIMEOUT_MS = 250;
const DWORD CPipeEndpoint::DEFAULT_WRITE_TIMEOUT_MS = 250;
bool CPipeEndpoint::IsDisconnectedError(DWORD error)
{
@@ -159,7 +159,7 @@ CPipeEndpoint::PipeIoResult CPipeEndpoint::WriteMessage(
m_writeEvent,
&overlapped,
&bytesWritten,
WRITE_TIMEOUT_MS);
m_writeTimeoutMs);
else if (IsDisconnectedError(error))
result = PipeIoResult::Disconnected;
else if (error == ERROR_OPERATION_ABORTED &&
@@ -199,7 +199,8 @@ bool CPipeEndpoint::Start(
const SECURITY_ATTRIBUTES * serverSecurity,
DWORD serverOpenMode,
DWORD serverPipeMode,
ThreadScheduling threadScheduling)
ThreadScheduling threadScheduling,
DWORD writeTimeoutMs)
{
Stop();
@@ -215,6 +216,7 @@ bool CPipeEndpoint::Start(
SECURITY_ATTRIBUTES {};
m_serverOpenMode = serverOpenMode;
m_serverPipeMode = serverPipeMode;
m_writeTimeoutMs = writeTimeoutMs;
m_stopEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
if (!m_stopEvent)
{

View File

@@ -74,6 +74,8 @@ public:
class CPipeEndpoint
{
public:
static const DWORD DEFAULT_WRITE_TIMEOUT_MS;
enum class Mode
{
Server,
@@ -99,7 +101,8 @@ public:
_In_opt_ const SECURITY_ATTRIBUTES * serverSecurity = nullptr,
_In_ DWORD serverOpenMode = 0,
_In_ DWORD serverPipeMode = 0,
_In_ ThreadScheduling threadScheduling = ThreadScheduling::Normal);
_In_ ThreadScheduling threadScheduling = ThreadScheduling::Normal,
_In_ DWORD writeTimeoutMs = DEFAULT_WRITE_TIMEOUT_MS);
void Stop();
void DisconnectClient();
@@ -132,7 +135,6 @@ private:
static const DWORD SERVER_RETRY_MS;
static const DWORD AUTHENTICATION_TIMEOUT_MS;
static const DWORD AUTHORIZATION_POLL_MS;
static const DWORD WRITE_TIMEOUT_MS;
static bool IsDisconnectedError(_In_ DWORD error);
PipeIoResult WaitForOverlapped(
@@ -173,6 +175,7 @@ private:
bool m_hasServerSecurity = false;
DWORD m_serverOpenMode = 0;
DWORD m_serverPipeMode = 0;
DWORD m_writeTimeoutMs = DEFAULT_WRITE_TIMEOUT_MS;
std::atomic<bool> m_running { false };
std::atomic<bool> m_connected { false };

View File

@@ -76,7 +76,12 @@ bool CInputPipeServer::Init()
if (!m_endpoint.Start(
LG_INPUT_PIPE_NAME,
CPipeEndpoint::Mode::Server,
sizeof(LGInputPipeMessage)))
sizeof(LGInputPipeMessage),
nullptr,
0,
0,
CPipeEndpoint::ThreadScheduling::Normal,
PIPE_WRITE_TIMEOUT_MS))
{
DeInit();
return false;
@@ -193,6 +198,8 @@ bool CInputPipeServer::CompactQueuedMotionLocked()
first.payload.mouseRelative.deltaX = static_cast<int32_t>(x);
first.payload.mouseRelative.deltaY = static_cast<int32_t>(y);
if (second.enqueueTicks)
first.enqueueTicks = second.enqueueTicks;
RemoveQueueItemLocked(i + 1);
++m_statRelativeCoalesced;
return true;
@@ -207,6 +214,8 @@ bool CInputPipeServer::CompactQueuedMotionLocked()
first.payload.mouseAbsolute.x = second.payload.mouseAbsolute.x;
first.payload.mouseAbsolute.y = second.payload.mouseAbsolute.y;
if (second.enqueueTicks)
first.enqueueTicks = second.enqueueTicks;
RemoveQueueItemLocked(i + 1);
++m_statAbsoluteCoalesced;
return true;
@@ -253,6 +262,9 @@ bool CInputPipeServer::QueueLocked(
{
tail.payload.mouseRelative.deltaX = static_cast<int32_t>(x);
tail.payload.mouseRelative.deltaY = static_cast<int32_t>(y);
LARGE_INTEGER enqueueTime = {};
if (QueryPerformanceCounter(&enqueueTime))
tail.enqueueTicks = enqueueTime.QuadPart;
++m_statRelativeCoalesced;
return true;
}
@@ -266,6 +278,9 @@ bool CInputPipeServer::QueueLocked(
{
tail.payload.mouseAbsolute.x = payload.mouseAbsolute.x;
tail.payload.mouseAbsolute.y = payload.mouseAbsolute.y;
LARGE_INTEGER enqueueTime = {};
if (QueryPerformanceCounter(&enqueueTime))
tail.enqueueTicks = enqueueTime.QuadPart;
++m_statAbsoluteCoalesced;
return true;
}
@@ -503,7 +518,14 @@ bool CInputPipeServer::Pop(QueueItem& item)
if (!m_queueCount)
return false;
item = m_queue[m_queueHead];
// A blocked pipe write can leave a run of stale motion queued behind it.
// Collapse that run before the next write without combining fresh motion.
if (MotionBudgetExceededLocked())
while (CompactQueuedMotionLocked())
{
}
item = m_queue[m_queueHead];
m_queueHead = (m_queueHead + 1) % QUEUE_LENGTH;
--m_queueCount;
if (m_queueCount)

View File

@@ -35,6 +35,7 @@ private:
static constexpr size_t QUEUE_LENGTH = 128;
static constexpr size_t MOTION_EMERGENCY_DEPTH = 8;
static constexpr DWORD MOTION_AGE_BUDGET_MS = 1;
static constexpr DWORD PIPE_WRITE_TIMEOUT_MS = 4;
static constexpr DWORD STATISTICS_INTERVAL_MS = 5000;
struct QueueItem

View File

@@ -385,7 +385,6 @@ struct CNetworkServer::Impl
uint32_t length = 0;
Delivery delivery = Delivery::RELIABLE;
bool accounted = true;
bool inputAck = false;
};
struct SendLimits
@@ -398,6 +397,8 @@ struct CNetworkServer::Impl
{
uint64_t claimEpoch = 0;
uint64_t sequence = 0;
int64_t previousX = 0;
int64_t previousY = 0;
int64_t cumulativeX = 0;
int64_t cumulativeY = 0;
uint16_t absoluteX = 0;
@@ -407,6 +408,18 @@ struct CNetworkServer::Impl
bool useAbsolute = false;
};
struct InputSend
{
static constexpr size_t CAPACITY =
LG_NET_ENVELOPE_WIRE_SIZE + NETWORK_INPUT_MAX_PAYLOAD;
QUIC_BUFFER buffer = {};
uint8_t data[CAPACITY] = {};
uint32_t length = 0;
bool active = false;
bool inputAck = false;
};
struct SendAccounting
{
uint32_t count;
@@ -448,6 +461,13 @@ struct CNetworkServer::Impl
FAILED,
};
enum class InputPrepareResult
{
READY,
STALE,
INVALID,
};
enum class HandshakeState
{
WAITING_HELLO,
@@ -485,7 +505,6 @@ struct CNetworkServer::Impl
Impl& owner;
CSRWLock lock;
CSRWLock inputLock;
CSRWLock inputDispatchLock;
CSRWLock inputSendLock;
HQUIC handle = nullptr;
HQUIC controlStream = nullptr;
@@ -539,6 +558,7 @@ struct CNetworkServer::Impl
uint32_t inputDatagramLimit = 0;
uint32_t inputStreamSendCount = 0;
uint64_t inputStreamSendBytes = 0;
uint32_t inputSendNext = 0;
uint16_t inputStreamServiceVersion = 0;
bool inputStreamBound = false;
bool inputClosing = false;
@@ -550,6 +570,7 @@ struct CNetworkServer::Impl
std::vector<uint8_t> inputReceiveData;
std::vector<uint8_t> inputReceivePayload;
std::shared_ptr<CNetworkSession> inputSession;
InputSend inputSends[NETWORK_INPUT_SEND_COUNT_MAX] = {};
LGNetSequenceTracker inputDatagramReceive = {};
uint64_t inputClaimantID = 0;
@@ -1619,19 +1640,44 @@ struct CNetworkServer::Impl
video.SendReady(VideoPeer(connection), videoDelivery);
}
static void ReleaseInputSendLocked(Connection& connection,
const Send& send)
static InputSend * AcquireInputSendLocked(Connection& connection)
{
if (!connection.inputStreamSendCount ||
for (uint32_t offset = 0; offset < NETWORK_INPUT_SEND_COUNT_MAX;
++offset)
{
const uint32_t index =
(connection.inputSendNext + offset) % NETWORK_INPUT_SEND_COUNT_MAX;
InputSend& send = connection.inputSends[index];
if (send.active)
continue;
send.active = true;
connection.inputSendNext =
(index + 1U) % NETWORK_INPUT_SEND_COUNT_MAX;
return &send;
}
return nullptr;
}
static void ReleaseInputSendLocked(Connection& connection,
InputSend& send)
{
if (!send.active || !connection.inputStreamSendCount ||
connection.inputStreamSendBytes < send.length)
{
DEBUG_ERROR("Network input send accounting underflow for client %u",
connection.client);
return;
}
--connection.inputStreamSendCount;
connection.inputStreamSendBytes -= send.length;
else
{
--connection.inputStreamSendCount;
connection.inputStreamSendBytes -= send.length;
}
send.buffer = {};
send.length = 0;
send.active = false;
send.inputAck = false;
}
SendResult TrySendInputPacket(Connection& connection,
@@ -1649,26 +1695,13 @@ struct CNetworkServer::Impl
LG_NET_ENVELOPE_EARLY_DATA))
return SendResult::FAILED;
const size_t packetSize =
const size_t packetSize =
LG_NET_ENVELOPE_WIRE_SIZE + payloadLength;
std::unique_ptr<Send> send(new (std::nothrow) Send());
if (!send)
if (packetSize > InputSend::CAPACITY)
return SendResult::FAILED;
try
{
send->data.resize(packetSize);
}
catch (...)
{
return SendResult::FAILED;
}
send->service = LG_NET_SERVICE_INPUT;
send->length = static_cast<uint32_t>(packetSize);
send->accounted = false;
send->inputAck = inputAck;
QUIC_STATUS status = QUIC_STATUS_SUCCESS;
InputSend * send = nullptr;
QUIC_STATUS status = QUIC_STATUS_SUCCESS;
{
LGNetPacketParameters parameters = {};
HQUIC stream = nullptr;
@@ -1687,6 +1720,12 @@ struct CNetworkServer::Impl
NETWORK_INPUT_SEND_BYTES_MAX - packetSize)
return SendResult::BLOCKED;
send = AcquireInputSendLocked(connection);
if (!send)
return SendResult::BLOCKED;
send->length = static_cast<uint32_t>(packetSize);
send->inputAck = inputAck;
++connection.inputStreamSendCount;
connection.inputStreamSendBytes += packetSize;
@@ -1702,7 +1741,7 @@ struct CNetworkServer::Impl
}
size_t wireSize = 0;
if (!lgNetPacketConstruct(send->data.data(), send->data.size(),
if (!lgNetPacketConstruct(send->data, sizeof(send->data),
&wireSize, &parameters, payload, payloadLength) ||
wireSize != packetSize)
{
@@ -1713,11 +1752,10 @@ struct CNetworkServer::Impl
return SendResult::FAILED;
}
send->buffers[0].Buffer = send->data.data();
send->buffers[0].Length = static_cast<uint32_t>(wireSize);
status = api->StreamSend(stream,
send->buffers, send->bufferCount, QUIC_SEND_FLAG_PRIORITY_WORK,
send.get());
send->buffer.Buffer = send->data;
send->buffer.Length = static_cast<uint32_t>(wireSize);
status = api->StreamSend(stream,
&send->buffer, 1, QUIC_SEND_FLAG_PRIORITY_WORK, send);
if (QUIC_FAILED(status))
{
CSRWExclusiveLock guard(connection.inputLock);
@@ -1729,7 +1767,6 @@ struct CNetworkServer::Impl
if (QUIC_FAILED(status))
return SendResult::FAILED;
send.release();
return SendResult::SENT;
}
@@ -3732,7 +3769,7 @@ retry:
uint64_t claimantID, LGNetInputClaimFlags requiredFlags)
{
CSRWExclusiveLock guard(connection.inputLock);
uint64_t& lastSequence = datagram ?
uint64_t& lastSequence = datagram ?
connection.inputDatagramSequence :
connection.inputReliableSequence;
if (!connection.inputClaimantID ||
@@ -3776,33 +3813,73 @@ retry:
return LG_INPUT_MOUSE_DELTA_MIN;
}
bool PrepareInputPointer(Connection& connection, uint64_t claimEpoch,
uint64_t sequence, bool datagram, bool relative,
InputPrepareResult PrepareInputPointer(Connection& connection,
const LGNetPacketView& packet, uint64_t sequence, bool datagram,
bool relative, int32_t wheel, LGNetPointerButtons changedButtons,
int64_t cumulativeX, int64_t cumulativeY,
LGNetPointerButtons& buttons, InputPointerMotion& motion)
LGNetPointerButtons& buttons, InputPointerMotion& motion,
std::shared_ptr<CNetworkSession>& session)
{
const bool acknowledge =
(packet.envelope.flags & LG_NET_ENVELOPE_ACK_REQUIRED) != 0;
if (!sequence)
return InputPrepareResult::INVALID;
if (datagram)
{
if (wheel || changedButtons || acknowledge ||
packet.envelope.requestID)
return InputPrepareResult::INVALID;
}
else if (acknowledge ? packet.envelope.requestID != sequence :
packet.envelope.requestID != 0)
return InputPrepareResult::INVALID;
CSRWExclusiveLock guard(connection.inputLock);
uint64_t& lastSequence = datagram ?
uint64_t& lastSequence = datagram ?
connection.inputDatagramSequence :
connection.inputReliableSequence;
session = connection.inputSession;
if (!session)
return InputPrepareResult::INVALID;
if (!connection.inputClaimantID ||
connection.inputClaimEpoch != claimEpoch ||
connection.inputClaimEpoch != packet.envelope.componentEpoch ||
!(connection.inputFlags & LG_NET_INPUT_CLAIM_POINTER) ||
sequence <= lastSequence)
return false;
return InputPrepareResult::STALE;
const bool motionApplies =
sequence > connection.inputMotionSequence;
const bool baseline = connection.inputMotionBaseline;
const bool modeChange = motionApplies && baseline &&
connection.inputMotionAbsolute == relative;
const bool buttonChange = buttons != connection.inputPointerButtons;
if (datagram)
{
if (motionApplies && (!baseline || modeChange))
return InputPrepareResult::INVALID;
}
else
{
const bool transition = wheel || changedButtons || buttonChange ||
(motionApplies && (!baseline || modeChange));
if (transition && !acknowledge)
return InputPrepareResult::INVALID;
}
lastSequence = sequence;
if (!datagram)
connection.inputMotionBaseline = true;
motion.claimEpoch = claimEpoch;
motion.claimEpoch = packet.envelope.componentEpoch;
motion.sequence = sequence;
motion.previousX = connection.inputCumulativeX;
motion.previousY = connection.inputCumulativeY;
motion.previousButtons = connection.inputPointerButtons;
if (datagram)
buttons = connection.inputPointerButtons;
else
connection.inputPointerButtons = buttons;
motion.apply = sequence > connection.inputMotionSequence;
motion.apply = motionApplies;
if (motion.apply)
{
connection.inputMotionSequence = sequence;
@@ -3827,7 +3904,7 @@ retry:
motion.absoluteX = connection.inputAbsoluteX;
motion.absoluteY = connection.inputAbsoluteY;
}
return true;
return InputPrepareResult::READY;
}
InputResult SendInputRelativeMotion(Connection& connection,
@@ -3835,26 +3912,22 @@ retry:
const InputPointerMotion& motion, int32_t wheel,
LGNetPointerButtons buttons)
{
int64_t cumulativeX = 0;
int64_t cumulativeY = 0;
{
CSRWSharedLock guard(connection.inputLock);
cumulativeX = connection.inputCumulativeX;
cumulativeY = connection.inputCumulativeY;
}
int64_t cumulativeX = motion.previousX;
int64_t cumulativeY = motion.previousY;
InputResult result = InputResult::STALE;
for (uint32_t chunk = 0; chunk < NETWORK_INPUT_RECOVERY_LIMIT; ++chunk)
{
int64_t nextX = cumulativeX;
int64_t nextY = cumulativeY;
const int32_t deltaX = InputCumulativeStep(
int64_t nextX = cumulativeX;
int64_t nextY = cumulativeY;
const int32_t deltaX = InputCumulativeStep(
motion.cumulativeX, cumulativeX, nextX);
const int32_t deltaY = InputCumulativeStep(
const int32_t deltaY = InputCumulativeStep(
motion.cumulativeY, cumulativeY, nextY);
const bool final =
(nextX == motion.cumulativeX && nextY == motion.cumulativeY) ||
chunk + 1U == NETWORK_INPUT_RECOVERY_LIMIT;
const bool reached =
nextX == motion.cumulativeX && nextY == motion.cumulativeY;
const bool final =
reached || chunk + 1U == NETWORK_INPUT_RECOVERY_LIMIT;
result = session->SendMouseRelative(deltaX, deltaY,
final ? wheel : 0, final ? buttons : motion.previousButtons);
@@ -3864,7 +3937,14 @@ retry:
cumulativeX = nextX;
cumulativeY = nextY;
if (final)
{
if (!reached)
{
cumulativeX = motion.cumulativeX;
cumulativeY = motion.cumulativeY;
}
break;
}
}
{
@@ -3980,14 +4060,20 @@ retry:
packet.envelope.requestID)
return false;
if (!ValidateInputOwner(connection, packet.envelope.componentEpoch,
keyboard.sequence, false, 0, LG_NET_INPUT_CLAIM_KEYBOARD))
return true;
uint8_t keys[NETWORK_KEYBOARD_KEY_COUNT] = {};
uint8_t keys[NETWORK_KEYBOARD_KEY_COUNT] = {};
std::shared_ptr<CNetworkSession> session = {};
uint8_t modifiers = 0;
{
CSRWExclusiveLock guard(connection.inputLock);
connection.keyboardModifiers =
if (!connection.inputClaimantID ||
connection.inputClaimEpoch !=
packet.envelope.componentEpoch ||
!(connection.inputFlags & LG_NET_INPUT_CLAIM_KEYBOARD) ||
keyboard.sequence <= connection.inputReliableSequence)
return true;
connection.inputReliableSequence = keyboard.sequence;
connection.keyboardModifiers =
static_cast<uint8_t>(keyboard.modifiers);
if (keyboard.usage < 224 || keyboard.usage > 231)
connection.keyboardKeys[keyboard.usage] =
@@ -4004,12 +4090,6 @@ retry:
}
if (count > NETWORK_KEYBOARD_KEY_COUNT)
memset(keys, NETWORK_KEYBOARD_ROLLOVER, sizeof(keys));
}
std::shared_ptr<CNetworkSession> session = {};
uint8_t modifiers = 0;
{
CSRWSharedLock guard(connection.inputLock);
session = connection.inputSession;
modifiers = connection.keyboardModifiers;
}
@@ -4035,84 +4115,27 @@ retry:
(extent - 1U));
}
static bool InputPointerEnvelopeValid(Connection& connection,
const LGNetPacketView& packet, uint64_t sequence, bool datagram,
bool relative, int32_t wheel, LGNetPointerButtons buttons,
LGNetPointerButtons changedButtons)
{
const bool acknowledge =
(packet.envelope.flags & LG_NET_ENVELOPE_ACK_REQUIRED) != 0;
if (!sequence)
return false;
if (datagram)
{
if (wheel || changedButtons || acknowledge ||
packet.envelope.requestID)
return false;
}
else if (acknowledge ? packet.envelope.requestID != sequence :
packet.envelope.requestID != 0)
return false;
bool current;
bool motionApplies;
bool baseline;
bool modeChange;
bool buttonChange;
{
CSRWSharedLock guard(connection.inputLock);
const uint64_t lastSequence = datagram ?
connection.inputDatagramSequence :
connection.inputReliableSequence;
current = connection.inputClaimantID &&
connection.inputClaimEpoch == packet.envelope.componentEpoch &&
(connection.inputFlags & LG_NET_INPUT_CLAIM_POINTER) &&
sequence > lastSequence;
motionApplies = sequence > connection.inputMotionSequence;
baseline = connection.inputMotionBaseline;
modeChange = motionApplies && baseline &&
connection.inputMotionAbsolute == relative;
buttonChange = buttons != connection.inputPointerButtons;
}
if (!current)
return true;
if (datagram)
return !motionApplies || (baseline && !modeChange);
const bool transition = wheel || changedButtons || buttonChange ||
(motionApplies && (!baseline || modeChange));
if (transition && !acknowledge)
return false;
return true;
}
bool HandleInputPointer(Connection& connection,
const LGNetPacketView& packet, bool datagram)
{
InputResult result = InputResult::STALE;
std::shared_ptr<CNetworkSession> session = {};
{
CSRWSharedLock guard(connection.inputLock);
session = connection.inputSession;
}
if (!session)
return false;
if (packet.envelope.messageType ==
LG_NET_INPUT_MESSAGE_MOUSE_RELATIVE)
{
LGNetInputRelative relative = {};
if (lgNetInputRelativeDecode(&relative, packet.payload,
packet.payloadLength) != LG_NET_PARSE_OK || relative.wheelX ||
!InputPointerEnvelopeValid(connection, packet, relative.sequence,
datagram, true, relative.wheelY, relative.buttons,
relative.changedButtons))
packet.payloadLength) != LG_NET_PARSE_OK || relative.wheelX)
return false;
InputPointerMotion motion;
if (!PrepareInputPointer(connection,
packet.envelope.componentEpoch, relative.sequence, datagram,
true, relative.cumulativeX, relative.cumulativeY,
relative.buttons, motion))
InputPointerMotion motion = {};
const InputPrepareResult prepared = PrepareInputPointer(connection,
packet, relative.sequence, datagram, true, relative.wheelY,
relative.changedButtons, relative.cumulativeX,
relative.cumulativeY, relative.buttons, motion, session);
if (prepared == InputPrepareResult::INVALID)
return false;
if (prepared == InputPrepareResult::STALE)
return true;
if (datagram && !motion.apply)
return true;
@@ -4131,18 +4154,18 @@ retry:
{
LGNetInputAbsolute absolute = {};
if (lgNetInputAbsoluteDecode(&absolute, packet.payload,
packet.payloadLength) != LG_NET_PARSE_OK || absolute.wheelX ||
!InputPointerEnvelopeValid(connection, packet, absolute.sequence,
datagram, false, absolute.wheelY, absolute.buttons,
absolute.changedButtons))
packet.payloadLength) != LG_NET_PARSE_OK || absolute.wheelX)
return false;
InputPointerMotion motion;
InputPointerMotion motion = {};
motion.absoluteX = NormalizeAbsolute(absolute.x, absolute.width);
motion.absoluteY = NormalizeAbsolute(absolute.y, absolute.height);
if (!PrepareInputPointer(connection,
packet.envelope.componentEpoch, absolute.sequence, datagram,
false, absolute.cumulativeX, absolute.cumulativeY,
absolute.buttons, motion))
const InputPrepareResult prepared = PrepareInputPointer(connection,
packet, absolute.sequence, datagram, false, absolute.wheelY,
absolute.changedButtons, absolute.cumulativeX,
absolute.cumulativeY, absolute.buttons, motion, session);
if (prepared == InputPrepareResult::INVALID)
return false;
if (prepared == InputPrepareResult::STALE)
return true;
if (datagram && !motion.apply)
return true;
@@ -4183,7 +4206,6 @@ retry:
return false;
}
CSRWExclusiveLock dispatchGuard(connection.inputDispatchLock);
switch (packet.envelope.messageType)
{
case LG_NET_INPUT_MESSAGE_CLAIM:
@@ -5898,13 +5920,15 @@ retry:
case QUIC_STREAM_EVENT_SEND_COMPLETE:
{
std::unique_ptr<Send> send(
static_cast<Send *>(event->SEND_COMPLETE.ClientContext));
InputSend& send = *static_cast<InputSend *>(
event->SEND_COMPLETE.ClientContext);
bool inputAck = false;
{
CSRWExclusiveLock guard(connection.inputLock);
ReleaseInputSendLocked(connection, *send);
inputAck = send.inputAck;
ReleaseInputSendLocked(connection, send);
connection.inputLEDWaitForSendReady = false;
if (send->inputAck)
if (inputAck)
connection.inputAckInFlight = false;
}
if (owner.TrySendPendingInputAck(connection) == SendResult::FAILED ||
@@ -6253,7 +6277,8 @@ retry:
QUIC_REGISTRATION_CONFIG registrationConfig = {};
registrationConfig.AppName = "looking-glass-idd";
registrationConfig.ExecutionProfile = QUIC_EXECUTION_PROFILE_LOW_LATENCY;
registrationConfig.ExecutionProfile =
QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME;
QUIC_STATUS status = api->RegistrationOpen(
&registrationConfig, &registration);
if (QUIC_FAILED(status))

View File

@@ -248,6 +248,8 @@ static bool CompactQueuedMotion(_Inout_ HIDDeviceContext * context)
previous->x = static_cast<int16_t>(x);
previous->y = static_cast<int16_t>(y);
if (second.enqueueTicks)
first.enqueueTicks = second.enqueueTicks;
RemoveQueuedReport(context, i + 1);
++context->statistics.relativeCoalesced;
return true;
@@ -265,6 +267,8 @@ static bool CompactQueuedMotion(_Inout_ HIDDeviceContext * context)
continue;
CopyMemory(first.data, second.data, second.size);
if (second.enqueueTicks)
first.enqueueTicks = second.enqueueTicks;
first.size = second.size;
RemoveQueuedReport(context, i + 1);
++context->statistics.staleAbsoluteCompacted;
@@ -311,6 +315,9 @@ static NTSTATUS QueueReport(
{
previous->x = static_cast<int16_t>(x);
previous->y = static_cast<int16_t>(y);
LARGE_INTEGER enqueueTime = {};
if (QueryPerformanceCounter(&enqueueTime))
tail.enqueueTicks = enqueueTime.QuadPart;
++context->statistics.relativeCoalesced;
return STATUS_SUCCESS;
}
@@ -326,6 +333,9 @@ static NTSTATUS QueueReport(
!previous->wheel && !current->wheel)
{
CopyMemory(tail.data, data, size);
LARGE_INTEGER enqueueTime = {};
if (QueryPerformanceCounter(&enqueueTime))
tail.enqueueTicks = enqueueTime.QuadPart;
tail.size = size;
++context->statistics.absoluteCoalesced;
return STATUS_SUCCESS;
@@ -361,9 +371,9 @@ static NTSTATUS ReadReport(
_In_ WDFREQUEST request,
_Out_ bool * complete)
{
HIDQueuedReport report = {};
HIDQueuedReport report = {};
bool haveReport = false;
*complete = true;
*complete = true;
NTSTATUS status;
{
@@ -372,13 +382,22 @@ static NTSTATUS ReadReport(
status = STATUS_DEVICE_NOT_READY;
else if (context->reportCount)
{
// If Windows stopped issuing reads temporarily, deliver one current
// aggregate instead of replaying every stale motion report accumulated
// while it was stalled. Transitions remain ordered and are never
// compacted.
if (MotionBudgetExceeded(context))
while (CompactQueuedMotion(context))
{
}
PopReport(context, &report);
haveReport = true;
status = STATUS_SUCCESS;
status = STATUS_SUCCESS;
}
else
{
status = WdfRequestForwardToIoQueue(request, context->reportQueue);
status = WdfRequestForwardToIoQueue(request, context->reportQueue);
*complete = !NT_SUCCESS(status);
}
}