diff options
author | Tom <tomut@yahoo.com> | 2020-11-14 13:46:16 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-11-14 22:09:48 +0100 |
commit | 53cffb5ad97c17bd7ca70c1d5021b6e30d254289 (patch) | |
tree | a82eaaec4867697035a5a33b2d965a11f29c4205 /Kernel/Devices | |
parent | 13383f3267187008f510b78ece1408c683e18e4c (diff) | |
download | serenity-53cffb5ad97c17bd7ca70c1d5021b6e30d254289.zip |
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
Diffstat (limited to 'Kernel/Devices')
-rw-r--r-- | Kernel/Devices/PS2MouseDevice.cpp | 42 | ||||
-rw-r--r-- | Kernel/Devices/PS2MouseDevice.h | 2 |
2 files changed, 24 insertions, 20 deletions
diff --git a/Kernel/Devices/PS2MouseDevice.cpp b/Kernel/Devices/PS2MouseDevice.cpp index d7f86b82a1..c05b30747c 100644 --- a/Kernel/Devices/PS2MouseDevice.cpp +++ b/Kernel/Devices/PS2MouseDevice.cpp @@ -77,19 +77,38 @@ void PS2MouseDevice::handle_irq(const RegisterState&) 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 = [&] { m_data_state = 0; #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 m_entropy_source.add_random_event(m_data.dword); 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) { case 0: if (!(byte & 0x08)) { @@ -251,26 +270,11 @@ KResultOr<size_t> PS2MouseDevice::read(FileDescription&, size_t, UserOrKernelBuf ASSERT(size > 0); size_t nread = 0; size_t remaining_space_in_buffer = static_cast<size_t>(size) - nread; - auto* backdoor = VMWareBackdoor::the(); ScopedSpinLock lock(m_queue_lock); while (!m_queue.is_empty() && remaining_space_in_buffer) { - auto raw_packet = m_queue.dequeue(); + auto packet = m_queue.dequeue(); 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 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; diff --git a/Kernel/Devices/PS2MouseDevice.h b/Kernel/Devices/PS2MouseDevice.h index de555dbc07..386e690f09 100644 --- a/Kernel/Devices/PS2MouseDevice.h +++ b/Kernel/Devices/PS2MouseDevice.h @@ -85,7 +85,7 @@ private: I8042Controller& m_controller; mutable SpinLock<u8> m_queue_lock; - CircularQueue<RawPacket, 100> m_queue; + CircularQueue<MousePacket, 100> m_queue; u8 m_data_state { 0 }; RawPacket m_data; bool m_has_wheel { false }; |