perf(gui): scene-dirty compositor + cursor overlay + 60 FPS pacer + animations

Rework the compositor so it stops repainting the whole screen every frame,
tripling the frame rate (17 -> 54 FPS at HD) and adding smooth animation.

- Scene-dirty skipping (gui/gui_desktop.c): the full scene is recomposited only
  when something other than the bare pointer changed -- input, an open animation,
  or a ~10 Hz heartbeat for live content (clock, graphs). Idle and pointer-only
  frames skip the recomposite entirely.
- Cursor save-under (gui/gui_cursor.c): the pointer is an overlay that stashes
  and restores the pixels beneath it, so moving the mouse never forces a full
  repaint -- pointer motion runs at the frame cap.
- 60 FPS frame pacer: each iteration is timed against the monotonic clock and
  padded to a 16.666 ms budget with the new ktime_delay_us() (HPET-precise
  busy-wait), giving consistent pacing instead of a free-running spin.
- Window open animation (gui/gui_wm.c): new windows grow from 60% to full size
  with a cubic ease-out over ~160 ms; gui_wm_update() drives it and reports
  while any window is still animating so the compositor keeps redrawing.
- Default display mode set to 1280x720 (HD) -- the sweet spot where the
  software compositor sustains a near-60 FPS cursor with headroom for effects.

Kernel: kernel/time/ktime.c gains ktime_delay_us(), a precise HPET-based delay
(bounded PIT fallback) used by the pacer.

Verified live (screenshotted): boots to 1280x720, logs in, tray reads ~54 FPS
(green) while the pointer moves, no cursor ghosting, windows render cleanly.
Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
This commit is contained in:
subhobhai943andClaude Opus 4.8 committed 2026-08-25 23:05:44 +05:30
1 parent 4ecf119377
commit 2c2e2d536e
8 files changed
+200 -13

No files matched your search

+6
View File
@@ -10,4 +10,10 @@ int gui_cursor_get_x(void);
int gui_cursor_get_y(void);
void gui_cursor_draw(void);
// Overlay compositing: restore the pixels under the previous cursor position,
// then stash-and-draw the cursor at the current one. Lets the compositor move
// the pointer at full frame rate without repainting the whole scene.
void gui_cursor_restore_under(void);
void gui_cursor_composite(void);
#endif // _GUI_CURSOR_H
+12
View File
@@ -70,6 +70,14 @@ typedef struct gui_window {
void* user_data;
// Open animation: the window grows from a fraction of its final size to
// full over a short interval. anim_open_ns == 0 means no animation running.
uint64_t anim_open_ns; // ktime_ns() when the open animation began
int target_w; // final geometry the animation resolves to
int target_h;
int center_x; // fixed centre the growth expands around
int center_y;
void (*paint)(struct gui_window* win);
void (*handle_event)(struct gui_window* win, const gui_event_t* ev);
} gui_window_t;
@@ -80,6 +88,10 @@ void gui_wm_init(void);
void gui_wm_set_workarea(int width, int height);
gui_window_t* gui_wm_create_window(const char* title, int x, int y, int w, int h);
// Advance any running open animations; returns true while at least one window
// is still animating (so the compositor keeps redrawing during the effect).
bool gui_wm_update(void);
void gui_wm_destroy_window(int win_id);
void gui_wm_focus_window(int win_id);
gui_window_t* gui_wm_get_window(int win_id);
+4
View File
@@ -14,4 +14,8 @@ uint64_t ktime_ms(void);
const char* ktime_source(void); // "HPET" or "PIT"
bool ktime_is_highres(void); // true when backed by the HPET
// Busy-wait for the given number of microseconds against the monotonic clock.
// Precise when HPET-backed; used by the compositor's 60 FPS frame pacer.
void ktime_delay_us(uint64_t us);
#endif // _KERNEL_KTIME_H