Skip to content

Complete and utter overhaul of the userland graphics stack - #181

Merged
FlareCoding merged 51 commits into
masterfrom
pr/major-userland-gfxlib-rework
Aug 31, 2026
Merged

Complete and utter overhaul of the userland graphics stack#181
FlareCoding merged 51 commits into
masterfrom
pr/major-userland-gfxlib-rework

Conversation

@FlareCoding

@FlareCoding FlareCoding commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Note

High Risk
Large replacement of the display path and window protocol plus kernel scheduler and poll semantics changes that affect blocking, timeouts, and timer delivery across userland and the compositor.

Overview
This PR lands the gfx2 userland graphics overhaul: a new C++ stlxdm compositor that speaks the stlxwin window protocol (Unix socket + client SHM buffers), damage-driven compose, a memcpy_presenter to /dev/gfxfb, server-side window chrome, toolkit top/dock panels, cursor sprites, and a power overlay (restart/shutdown). Config reload via SIGHUP, hotkeys, clipboard, and paced ~60 Hz compose are wired through a poll main loop in stlxdm.

Client ports and tooling: DOOM drops libstlxgfx windowing for libstlxwin (begin_frame / commit, event pump). gfxbench times blend variants on the real target. The apps build adds gfxbench, windemo, uidemo, stlxsettings and switches stlxdm to cxxapp.mk with stlxui, stlxconf, stlxgfx.

Kernel: ppoll now loops on a monotonic deadline so timeouts stay accurate across interrupts. On aarch64 and x86_64, tasks in TASK_STATE_BLOCKED have IRQs re-enabled in saved context when they resume after yield so timers keep ticking.

Docs: New Cursor skills stellux-gfx-testing and stellux-gfx2-campaign; stellux-qemu-testing drops the userland poll-timeout pacing note.

Reviewed by Cursor Bugbot for commit 5f71ea4. Bugbot is set up for automated code reviews on this repo. Configure here.

FlareCoding and others added 30 commits August 29, 2026 13:36
Host-native timings of raster loops invert on the deployment target,
where emulation makes division lowering and vector code expensive. A
benchmark that runs the blend variants on the target itself, with a
byte-identity gate across variants, lets raster changes be judged by
the numbers that matter.

Co-authored-by: Cursor <cursoragent@cursor.com>
Blend loops re-read channel offsets through the surface pointer for
every pixel and divided per channel, costing a full-screen dim tens of
milliseconds under emulation. Offsets and premultiplied source terms
are hoisted, 32bpp fills blend whole packed words, and division is
replaced with an exact truncating identity, keeping output
byte-identical while landing a 2.8x speedup where it is slowest.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
The rewritten display manager opens the scanout, binds the protocol
socket, and runs a single poll loop over the listen socket and every
client, assembling messages across short reads. The hello handshake
gates all other traffic, protocol violations disconnect the offender,
and known message types route through a dispatch that later units fill.
The display manager now serves the shared text clipboard, stores
per-window cursor selection for the sprite to honor, and asks the
focused window to close on a keybinding standing in for the missing
decoration button. Capture stays unimplemented because the wire lacks
a completion signal, recorded for the screenshot consumer to bring.
Commits latch at a paced compose tick as the protocol model assumes,
carrying their damage rectangles into a screen-space accumulator that
coarsens to a full repaint on overflow instead of losing anything.
Composition and presentation touch exactly the damaged regions, so a
small commit moves kilobytes instead of the whole frame, and an idle
desktop still never wakes.
Composition now targets a buffer the presenter hands out, tagged with
its age so the damage engine unions however many frames the target
missed. The memcpy backend owns the scanout mapping and serves
age-one targets, and a future flip chain serves age-two ones without
touching anything above the interface. Presenting a compositor-owned
buffer instead would have locked a full copy into the design.
One z-list orders every mapped window: composition walks it bottom up,
hit testing walks it top down, and a press raises the window's whole
popup subtree. Grabbing popups now behave as specified, taking
keyboard focus at map and dismissing on any outside press with focus
restored to what they displaced.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Writes to clients go nonblocking with a bounded per-client queue
flushed on writability, so a stalled client delays only itself and an
overflowing one is disconnected. Motion events coalesce by rewriting
the queue tail in place when it is a lone motion for the same window,
which keeps ordering exact while storms collapse to the latest
position. The kernel socket ring absorbs today's event rates, making
the queue headroom for the heavier flows resize will bring.
The host turns invalidations into damage and damage into minimal
repaints: dirty widgets contribute their frames, and each rect
repaints only the widgets intersecting it under ancestor clipping,
proven by a harness sweep showing a hovered button changes its own
pixels and nothing else. Input dispatch hit tests to the deepest
widget and bubbles, a consumed press grabs the pointer until release,
and unconsumed tab walks the focusables in tree order.
…riginal compositor implementation on master branch
cursor[bot]

This comment was marked as resolved.

@FlareCoding
FlareCoding merged commit 74c7e80 into master Aug 31, 2026
19 checks passed
@FlareCoding
FlareCoding deleted the pr/major-userland-gfxlib-rework branch August 31, 2026 00:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant