diff mbox series

[v3] ui/sdl: Mouse event optimization

Message ID 20241104084255.1721-1-Lei.Huang@amd.com
State New
Headers show
Series [v3] ui/sdl: Mouse event optimization | expand

Commit Message

Lei Huang Nov. 4, 2024, 8:42 a.m. UTC
Use a convergence factor to make the VM's input
global coordinates more closely approach the global
coordinates of host.

Change-Id: I2c3f12f1fe7dfb9306d1fc40c4fd4d299937f4c6
Signed-off-by: Lei Huang <Lei.Huang@amd.com>
---
 ui/sdl2.c | 45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)

Comments

BALATON Zoltan Nov. 4, 2024, 10:25 a.m. UTC | #1
On Mon, 4 Nov 2024, Lei Huang wrote:
> Use a convergence factor to make the VM's input
> global coordinates more closely approach the global
> coordinates of host.
>
> Change-Id: I2c3f12f1fe7dfb9306d1fc40c4fd4d299937f4c6
> Signed-off-by: Lei Huang <Lei.Huang@amd.com>

The explanation in the comment is still not clear to me so I don't fully 
understand the problem and can't tell if this is the best fix but it's now 
grammatically OK and the patch looks OK too so

Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>

Regards,
BALATON Zoltan

> ---
> ui/sdl2.c | 45 +++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 37 insertions(+), 8 deletions(-)
>
> diff --git a/ui/sdl2.c b/ui/sdl2.c
> index bd4f5a9da14..7c815d276a2 100644
> --- a/ui/sdl2.c
> +++ b/ui/sdl2.c
> @@ -303,6 +303,35 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
>     }
> }
>
> +/*
> + * guest_x and guest_y represent the global coordinates on the VM side,
> + * while x and y represent the global coordinates on the host side.
> + * The goal of this entire process is to align the global coordinates
> + * of the VM with those of host using dx and dy. The current approach
> + * aims for precise calibration in one attempt; however, because guest_x
> + * and guest_y are non-zero values, they are not accurate values when
> + * they are counted out to become negative. Therefore, achieving perfect
> + * alignment in one attempt is impossible. Since the same calibration
> + * method is used each time, repeated attempts cannot achieve alignment
> + * either. By introducing a convergence factor, guest_x and guest_y can
> + * be made to approach host x and y indefinitely.
> + *
> + *           QEMU                             VM
> + *    calculates (dx, dy)                  (dx, dy)
> + * using (guest_x, guest_y) ------------>input driver
> + *           ^                                 |
> + *           |                                 |
> + *           |       update                    V
> + *           | (guest_x, guest_y)            input
> + *           |                            dispatcher ---> WindowManager
> + *           |                                 |             |
> + *           |                                 |             |
> + *           |             libdrm              V             |
> + * display device <-- drmModeMoveCursor <-- compositor <---- |
> + * (e.g. virtio-gpu)  (guest_x, guest_y)   calculates (guest_x, guest_y)
> + *                                         using (dx, dy)
> + */
> +#define CONVERGENCE_FACTOR 3
> static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
>                                  int x, int y, int state)
> {
> @@ -327,15 +356,15 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
>                              y, 0, surface_height(scon->surface));
>     } else {
>         if (guest_cursor) {
> -            x -= guest_x;
> -            y -= guest_y;
> -            guest_x += x;
> -            guest_y += y;
> -            dx = x;
> -            dy = y;
> +            dx = x - guest_x;
> +            dy = y - guest_y;
> +            guest_x = x;
> +            guest_y = y;
>         }
> -        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx);
> -        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy);
> +        qemu_input_queue_rel(scon->dcl.con,
> +                             INPUT_AXIS_X, dx / CONVERGENCE_FACTOR);
> +        qemu_input_queue_rel(scon->dcl.con,
> +                             INPUT_AXIS_Y, dy / CONVERGENCE_FACTOR);
>     }
>     qemu_input_event_sync();
> }
>
diff mbox series

Patch

diff --git a/ui/sdl2.c b/ui/sdl2.c
index bd4f5a9da14..7c815d276a2 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -303,6 +303,35 @@  static void sdl_mouse_mode_change(Notifier *notify, void *data)
     }
 }
 
+/*
+ * guest_x and guest_y represent the global coordinates on the VM side,
+ * while x and y represent the global coordinates on the host side.
+ * The goal of this entire process is to align the global coordinates
+ * of the VM with those of host using dx and dy. The current approach
+ * aims for precise calibration in one attempt; however, because guest_x
+ * and guest_y are non-zero values, they are not accurate values when
+ * they are counted out to become negative. Therefore, achieving perfect
+ * alignment in one attempt is impossible. Since the same calibration
+ * method is used each time, repeated attempts cannot achieve alignment
+ * either. By introducing a convergence factor, guest_x and guest_y can
+ * be made to approach host x and y indefinitely.
+ *
+ *           QEMU                             VM
+ *    calculates (dx, dy)                  (dx, dy)
+ * using (guest_x, guest_y) ------------>input driver
+ *           ^                                 |
+ *           |                                 |
+ *           |       update                    V
+ *           | (guest_x, guest_y)            input
+ *           |                            dispatcher ---> WindowManager
+ *           |                                 |             |
+ *           |                                 |             |
+ *           |             libdrm              V             |
+ * display device <-- drmModeMoveCursor <-- compositor <---- |
+ * (e.g. virtio-gpu)  (guest_x, guest_y)   calculates (guest_x, guest_y)
+ *                                         using (dx, dy)
+ */
+#define CONVERGENCE_FACTOR 3
 static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
                                  int x, int y, int state)
 {
@@ -327,15 +356,15 @@  static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
                              y, 0, surface_height(scon->surface));
     } else {
         if (guest_cursor) {
-            x -= guest_x;
-            y -= guest_y;
-            guest_x += x;
-            guest_y += y;
-            dx = x;
-            dy = y;
+            dx = x - guest_x;
+            dy = y - guest_y;
+            guest_x = x;
+            guest_y = y;
         }
-        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx);
-        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy);
+        qemu_input_queue_rel(scon->dcl.con,
+                             INPUT_AXIS_X, dx / CONVERGENCE_FACTOR);
+        qemu_input_queue_rel(scon->dcl.con,
+                             INPUT_AXIS_Y, dy / CONVERGENCE_FACTOR);
     }
     qemu_input_event_sync();
 }