mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Closes #8326 `check_redraw_requests` switched the event loop to `ControlFlow::Poll` every time it called `request_redraw`, and only ever restored a sleeping control flow when a *timed* repaint was still pending. Once the last scheduled repaint had been consumed the `Poll` was never undone, so the loop kept spinning. This is most visible on Wayland, where `RedrawRequested` is only delivered after the compositor sends a frame callback: between the request and the callback eframe burns 100% of a CPU core, so simply moving the mouse over a reactive app pegs a core. `request_redraw` already wakes the event loop on its own, so the `Poll` is not needed. Drop it, and always set an explicit sleeping control flow at the end of `check_redraw_requests`: `WaitUntil` for the earliest scheduled repaint, `Wait` when nothing is scheduled. **Measured effect of this patch** Two byte-identical eframe apps (a 400-row scrolling page, free-running at 60fps), toggling only whether `eframe` resolves to stock 0.36.0 or this patch. Same machine and session, native Wayland (niri, wgpu/Vulkan). Whole-process CPU is `utime+stime` from `/proc/self/stat`, so it counts every thread — what a system monitor sees. | configuration | whole process | |---|---| | eframe 0.34.3, Wayland | ~12% of a core | | stock 0.36.0, Wayland | **99–100% of a core** | | stock 0.36.0, XWayland (same binary) | ~15% of a core | | **0.36.0 + this patch, Wayland** | **15–16% of a core** | The patch restores the 0.34 baseline and matches the XWayland figure for the same binary — ~6.5× less CPU — with frame delivery unchanged at 60fps. Two details worth noting: the same 0.36 binary is already fine on XWayland, so this isn't application repaint behaviour; and the per-frame *closure* cost rises slightly (1.55 to 2.15 ms) because those frames now run on a CPU that isn't being held at max clocks by the spin loop. * [X] I have followed the instructions in the PR template