summaryrefslogtreecommitdiff
path: root/Kernel/Devices
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-11-14 13:46:16 -0700
committerAndreas Kling <kling@serenityos.org>2020-11-14 22:09:48 +0100
commit53cffb5ad97c17bd7ca70c1d5021b6e30d254289 (patch)
treea82eaaec4867697035a5a33b2d965a11f29c4205 /Kernel/Devices
parent13383f3267187008f510b78ece1408c683e18e4c (diff)
downloadserenity-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.cpp42
-rw-r--r--Kernel/Devices/PS2MouseDevice.h2
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 };