mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:07:47 +00:00
Kernel: Fix mouse lag when VMWareBackdoor absolute mode is enabled
We won't be receiving full PS/2 mouse packets when the VMWareBackdoor absolute mouse mode is enabled. So, read just one byte every time and retrieve the latest mouse packet from VMWareBackdoor immediately. Fixes #4086
This commit is contained in:
parent
13383f3267
commit
53cffb5ad9
2 changed files with 24 additions and 20 deletions
|
@ -77,19 +77,38 @@ void PS2MouseDevice::handle_irq(const RegisterState&)
|
||||||
|
|
||||||
void PS2MouseDevice::irq_handle_byte_read(u8 byte)
|
void PS2MouseDevice::irq_handle_byte_read(u8 byte)
|
||||||
{
|
{
|
||||||
m_data.bytes[m_data_state] = byte;
|
auto* backdoor = VMWareBackdoor::the();
|
||||||
|
|
||||||
|
if (backdoor && backdoor->vmmouse_is_absolute()) {
|
||||||
|
// We won't receive complete packets with the backdoor enabled,
|
||||||
|
// we will only get one byte for each event, which we'll just
|
||||||
|
// discard. If we were to wait until we *think* that we got a
|
||||||
|
// full PS/2 packet then we would create a backlog in the VM
|
||||||
|
// because we wouldn't read the appropriate number of mouse
|
||||||
|
// packets from VMWareBackdoor.
|
||||||
|
auto mouse_packet = backdoor->receive_mouse_packet();
|
||||||
|
if (mouse_packet.has_value()) {
|
||||||
|
m_entropy_source.add_random_event(mouse_packet.value());
|
||||||
|
ScopedSpinLock lock(m_queue_lock);
|
||||||
|
m_queue.enqueue(mouse_packet.value());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto commit_packet = [&] {
|
auto commit_packet = [&] {
|
||||||
m_data_state = 0;
|
m_data_state = 0;
|
||||||
#ifdef PS2MOUSE_DEBUG
|
#ifdef PS2MOUSE_DEBUG
|
||||||
dbg() << "PS2Mouse: " << m_data.bytes[1] << ", " << m_data.bytes[2] << " " << ((m_data.bytes[0] & 1) ? "Left" : "") << " " << ((m_data.bytes[0] & 2) ? "Right" : "") << " (buffered: " << m_queue.size() << ")";
|
dbg() << "PS2Mouse: " << m_data.bytes[1] << ", " << m_data.bytes[2] << " " << ((m_data.bytes[0] & 1) ? "Left" : "") << " " << ((m_data.bytes[0] & 2) ? "Right" : "");
|
||||||
#endif
|
#endif
|
||||||
m_entropy_source.add_random_event(m_data.dword);
|
m_entropy_source.add_random_event(m_data.dword);
|
||||||
|
|
||||||
ScopedSpinLock lock(m_queue_lock);
|
ScopedSpinLock lock(m_queue_lock);
|
||||||
m_queue.enqueue(m_data);
|
m_queue.enqueue(parse_data_packet(m_data));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ASSERT(m_data_state < sizeof(m_data.bytes) / sizeof(m_data.bytes[0]));
|
||||||
|
m_data.bytes[m_data_state] = byte;
|
||||||
|
|
||||||
switch (m_data_state) {
|
switch (m_data_state) {
|
||||||
case 0:
|
case 0:
|
||||||
if (!(byte & 0x08)) {
|
if (!(byte & 0x08)) {
|
||||||
|
@ -251,26 +270,11 @@ KResultOr<size_t> PS2MouseDevice::read(FileDescription&, size_t, UserOrKernelBuf
|
||||||
ASSERT(size > 0);
|
ASSERT(size > 0);
|
||||||
size_t nread = 0;
|
size_t nread = 0;
|
||||||
size_t remaining_space_in_buffer = static_cast<size_t>(size) - nread;
|
size_t remaining_space_in_buffer = static_cast<size_t>(size) - nread;
|
||||||
auto* backdoor = VMWareBackdoor::the();
|
|
||||||
ScopedSpinLock lock(m_queue_lock);
|
ScopedSpinLock lock(m_queue_lock);
|
||||||
while (!m_queue.is_empty() && remaining_space_in_buffer) {
|
while (!m_queue.is_empty() && remaining_space_in_buffer) {
|
||||||
auto raw_packet = m_queue.dequeue();
|
auto packet = m_queue.dequeue();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
MousePacket packet;
|
|
||||||
bool is_parsed = false;
|
|
||||||
if (backdoor && backdoor->vmmouse_is_absolute()) {
|
|
||||||
auto mouse_packet = backdoor->receive_mouse_packet();
|
|
||||||
m_entropy_source.add_random_event(packet);
|
|
||||||
if (mouse_packet.has_value()) {
|
|
||||||
packet = mouse_packet.value();
|
|
||||||
is_parsed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_parsed)
|
|
||||||
packet = parse_data_packet(raw_packet);
|
|
||||||
|
|
||||||
#ifdef PS2MOUSE_DEBUG
|
#ifdef PS2MOUSE_DEBUG
|
||||||
dbg() << "PS2 Mouse Read: Buttons " << String::format("%x", packet.buttons);
|
dbg() << "PS2 Mouse Read: Buttons " << String::format("%x", packet.buttons);
|
||||||
dbg() << "PS2 Mouse: X " << packet.x << ", Y " << packet.y << ", Z " << packet.z << " Relative " << packet.buttons;
|
dbg() << "PS2 Mouse: X " << packet.x << ", Y " << packet.y << ", Z " << packet.z << " Relative " << packet.buttons;
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
|
|
||||||
I8042Controller& m_controller;
|
I8042Controller& m_controller;
|
||||||
mutable SpinLock<u8> m_queue_lock;
|
mutable SpinLock<u8> m_queue_lock;
|
||||||
CircularQueue<RawPacket, 100> m_queue;
|
CircularQueue<MousePacket, 100> m_queue;
|
||||||
u8 m_data_state { 0 };
|
u8 m_data_state { 0 };
|
||||||
RawPacket m_data;
|
RawPacket m_data;
|
||||||
bool m_has_wheel { false };
|
bool m_has_wheel { false };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue