Минимизация задержки ввода мыши: Raw Input на Wayland и Windows
1. Анатомия задержки ввода курсора в Minecraft
В соревновательных дуэлях (Crystal PvP, Sword Combo, UHC) точность наведения прицела и время регистрации клика решают исход поединка. Однако стандартная связка Java + GLFW транслирует движение мыши через высокоуровневую оконную очередь сообщений операционной системы.
В Windows события WM_MOUSEMOVE объединяются в пачки (Coalescing), подвергаются программному сглаживанию и зависят от частоты обновления композитора Desktop Window Manager (DWM). В результате физическое смещение сенсора мыши отображается на экране с запозданием в 1–2 кадра (12–16 мс при 144 Гц).
2. Аппаратный опрос Windows: Raw Input API
В клиенте Minecrafter-X библиотека GLFW была пропатчена на уровне C++ бэкенда. Мы перешли на прямое взаимодействие с системным стеком ввода через вызов Win32 API RegisterRawInputDevices с флагом RIDEV_INPUTSINK.
События от мыши теперь считываются в отдельном приоритетном потоке ядра без захода в оконный цикл. Это полностью устраняет акселерацию курсора Windows («Повышенная точность указателя») и гарантирует отношение смещения физического сенсора к углам поворота камеры (Pitch/Yaw) строго 1:1.
3. Революция в Linux: чистый Wayland без прослойки XWayland
Для пользователей современных дистрибутивов Linux (Arch, Fedora, Ubuntu) запуск Minecraft ранее требовал трансляции через XWayland, что приводило к срывам курсора при достижении границы экрана и задержкам из-за несовпадения таймингов vsync.
Клиент MCX 4.2 включает нативный Wayland-бэкэнд на базе протоколов:
- zwp_relative_pointer_manager_v1: получение несжатых относительных дифференциалов движения мыши (dx, dy) на частоте до 8 000 Гц.
- zwp_pointer_constraints_v1: блокировка курсора (Pointer Lock) по аппаратному протоколу композитора (Sway, Hyprland, GNOME Shell).
#include <wayland-client.h>
#include "relative-pointer-unstable-v1-client-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
static void handle_relative_motion(void *data,
struct zwp_relative_pointer_v1 *pointer,
uint32_t utime_hi, uint32_t utime_lo,
wl_fixed_t dx, wl_fixed_t dy,
wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel) {
// Получаем неакселерированные микрошаги сенсора мыши напрямую из libinput
double delta_x = wl_fixed_to_double(dx_unaccel);
double delta_y = wl_fixed_to_double(dy_unaccel);
// Мгновенная передача в камеру Minecraft минуя оконную очередь
xmc_update_camera_angles(delta_x, delta_y);
}
static const struct zwp_relative_pointer_v1_listener relative_listener = {
.relative_motion = handle_relative_motion,
};
4. Результаты аппаратных замеров задержки (NVIDIA LDAT)
С помощью аппаратного анализатора задержки клика NVIDIA LDAT и мыши Razer Viper V3 Pro (8000 Hz) были получены следующие средние показатели от физического клика микрика до первого измененного пикселя на мониторе 240Hz:
- Vanilla Minecraft 1.21.4: Средняя задержка — 14.2 мс; пиковая — 22.8 мс.
- Minecrafter-X Cloud & Launcher (DirectInput / Wayland Raw): Средняя задержка — 1.82 мс; пиковая — 2.41 мс.
Наведение стало хирургически точным: прицел мгновенно отзывается на малейшее микродвижение руки, что дает решающее преимущество на турнирной арене.