Complete and utter overhaul of the userland graphics stack - #181
Merged
Conversation
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>
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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++
stlxdmcompositor that speaks thestlxwinwindow protocol (Unix socket + client SHM buffers), damage-driven compose, amemcpy_presenterto/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 apollmain loop instlxdm.Client ports and tooling: DOOM drops
libstlxgfxwindowing forlibstlxwin(begin_frame/commit, event pump).gfxbenchtimes blend variants on the real target. The apps build addsgfxbench,windemo,uidemo,stlxsettingsand switchesstlxdmtocxxapp.mkwithstlxui,stlxconf,stlxgfx.Kernel:
ppollnow loops on a monotonic deadline so timeouts stay accurate across interrupts. On aarch64 and x86_64, tasks inTASK_STATE_BLOCKEDhave IRQs re-enabled in saved context when they resume after yield so timers keep ticking.Docs: New Cursor skills
stellux-gfx-testingandstellux-gfx2-campaign;stellux-qemu-testingdrops 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.