atagen

monolith

public
Star0
Watch0
b563d2da1c80c99c30a88deecf70fa7ba5c00d79
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: research/wry-assessment.md

57f44a63d99fatagen2026-10-16 05:34 UTC1
# What monolith should take from jay/wry
57f44a63d99fatagen2026-10-16 05:34 UTC2
57f44a63d99fatagen2026-10-16 05:34 UTC3
Companion to `wry-reports.md`, which holds the raw findings and citations.
57f44a63d99fatagen2026-10-16 05:34 UTC4
57f44a63d99fatagen2026-10-16 05:34 UTC5
## The async runtime
57f44a63d99fatagen2026-10-16 05:34 UTC6
57f44a63d99fatagen2026-10-16 05:34 UTC7
Don't port it. Port the phase discipline.
57f44a63d99fatagen2026-10-16 05:34 UTC8
57f44a63d99fatagen2026-10-16 05:34 UTC9
Why it doesn't pay off inside a smithay compositor.
57f44a63d99fatagen2026-10-16 05:34 UTC10
57f44a63d99fatagen2026-10-16 05:34 UTC11
- Most of jay's I/O is client sockets. In smithay those belong to wayland-backend, which reads and writes through its own readiness loop in `dispatch_clients`/`flush_clients`. Moving to io_uring would leave only DRM events, udev, libinput and timers on the ring, a handful of completions per frame.
57f44a63d99fatagen2026-10-16 05:34 UTC12
- Even inside jay the raw speed win is small. A frame costs on the order of tens to low hundreds of syscalls, well under 1% of a 6.9 ms frame at 144 Hz. Input-to-photon latency is decided by when you render, not by how cheaply you wake up.
57f44a63d99fatagen2026-10-16 05:34 UTC13
- Tasks can't hold `&mut State`, so jay runs on `Rc<State>` with `Cell`/`CloneCell`/`CopyHashMap` everywhere. Smithay's handler traits hand you `&mut D`. Running both models means fighting every delegate.
57f44a63d99fatagen2026-10-16 05:34 UTC14
- There is no fallback when io_uring is unavailable (`kernel.io_uring_disabled`, hardened kernels, some sandboxes). Jay exits.
57f44a63d99fatagen2026-10-16 05:34 UTC15
- Every smithay helper that is a calloop `EventSource` (`DrmDeviceNotifier`, `LibinputInputBackend`, `XWayland`, `DrmSyncPointSource`, `DmabufSource`, the socket listener) would need rewrapping.
57f44a63d99fatagen2026-10-16 05:34 UTC16
57f44a63d99fatagen2026-10-16 05:34 UTC17
What it does well, and the calloop equivalent.
57f44a63d99fatagen2026-10-16 05:34 UTC18
57f44a63d99fatagen2026-10-16 05:34 UTC19
| jay feature | real benefit | in monolith |
57f44a63d99fatagen2026-10-16 05:34 UTC20
|---|---|---|
57f44a63d99fatagen2026-10-16 05:34 UTC21
| Four ordered phases fed by dirty queues | N events collapse into one layout and one render per pass, with deterministic ordering | Fixed stages in the post-dispatch closure (layout, derived state, animation tick, render, flush), each with a dirty set and a scheduled flag |
57f44a63d99fatagen2026-10-16 05:34 UTC22
| `now()` frozen per pass | Every animation computed in a pass sees one timestamp | Store an `Instant` in `State` at the top of the post-dispatch closure |
57f44a63d99fatagen2026-10-16 05:34 UTC23
| Async fns for sequential flows (present loop, xwm, dbus, pipewire) | Readable state machines | Explicit enum for the present loop, calloop's executor for portal and screencast flows, and x11rb/zbus/pipewire-rs for the protocols |
57f44a63d99fatagen2026-10-16 05:34 UTC24
| Cancel-on-drop tasks | Structured lifetimes | `async_task::Task` also cancels on drop |
57f44a63d99fatagen2026-10-16 05:34 UTC25
| Linked timeouts on client `sendmsg` | A stuck client can't stall the compositor | wayland-backend flushes nonblocking already |
57f44a63d99fatagen2026-10-16 05:34 UTC26
57f44a63d99fatagen2026-10-16 05:34 UTC27
## Worth taking, ranked
57f44a63d99fatagen2026-10-16 05:34 UTC28
57f44a63d99fatagen2026-10-16 05:34 UTC29
### 1. Deadline frame scheduler
57f44a63d99fatagen2026-10-16 05:34 UTC30
57f44a63d99fatagen2026-10-16 05:34 UTC31
`src/backends/metal/present.rs`, flip handling in `src/backends/metal/video.rs`.
57f44a63d99fatagen2026-10-16 05:34 UTC32
57f44a63d99fatagen2026-10-16 05:34 UTC33
Biggest latency payoff, and it slots straight into smithay because `DrmCompositor` leaves timing to the caller. Sleep until `next_vblank - pre_margin - post_margin`, then latch, render and commit.
57f44a63d99fatagen2026-10-16 05:34 UTC34
57f44a63d99fatagen2026-10-16 05:34 UTC35
- `pre_margin` is a decaying per-second max of measured wakeup-to-latch CPU time.
57f44a63d99fatagen2026-10-16 05:34 UTC36
- `post_margin` grows 500 µs per second that saw a missed flip and decays toward the device minimum otherwise.
57f44a63d99fatagen2026-10-16 05:34 UTC37
- Vblank timestamps come from queued `CRTC_SEQUENCE` events, with emulation when the driver returns `EOPNOTSUPP`.
57f44a63d99fatagen2026-10-16 05:34 UTC38
57f44a63d99fatagen2026-10-16 05:34 UTC39
This is an algorithm port, a few hundred lines. With a Vulkan renderer, GPU time needs to be covered too, either through `post_margin` misses as jay does or with timestamp queries.
57f44a63d99fatagen2026-10-16 05:34 UTC40
57f44a63d99fatagen2026-10-16 05:34 UTC41
### 2. Async shm upload pipeline
57f44a63d99fatagen2026-10-16 05:34 UTC42
57f44a63d99fatagen2026-10-16 05:34 UTC43
`src/cpu_worker.rs`, `src/gfx_apis/vulkan/transfer.rs`, `src/clientmem.rs`.
57f44a63d99fatagen2026-10-16 05:34 UTC44
57f44a63d99fatagen2026-10-16 05:34 UTC45
Smithay's GLES renderer uploads shm synchronously inside `import_shm_buffer` on the main thread. Jay keeps the commit blocked while a worker thread memcpys only damaged rows into a staging buffer, and the GPU finishes the copy on the transfer queue. Sealed memfds (`F_SEAL_SHRINK` plus a large enough size) let the worker read client memory without the thread-local SIGBUS dance. foot, software-rendered toolkits and Xwayland without glamor all take this path. Build it into monolith's `ImportMemWl` as a smithay `Blocker`.
57f44a63d99fatagen2026-10-16 05:34 UTC46
57f44a63d99fatagen2026-10-16 05:34 UTC47
### 3. Vulkan renderer internals as a reference
57f44a63d99fatagen2026-10-16 05:34 UTC48
57f44a63d99fatagen2026-10-16 05:34 UTC49
Smithay has no Vulkan renderer, so monolith writes one either way. Jay's ~10k lines are coupled to `cmm`, `theme`, `State`, the ring and the cpu worker, so lift modules and ideas rather than the crate.
57f44a63d99fatagen2026-10-16 05:34 UTC50
57f44a63d99fatagen2026-10-16 05:34 UTC51
- fp16 linear blend buffer with a resolve pass. Blending is correct and HDR-ready, and color transforms happen in one place.
57f44a63d99fatagen2026-10-16 05:34 UTC52
- Op list sorted and batched by pipeline key, one `queue_submit2` per frame.
57f44a63d99fatagen2026-10-16 05:34 UTC53
- Vertex data via buffer device address in push constants, instanced draws.
57f44a63d99fatagen2026-10-16 05:34 UTC54
- Specialization constants for EOTF, matrix and alpha mode instead of runtime branches.
57f44a63d99fatagen2026-10-16 05:34 UTC55
- Descriptor heap, then descriptor buffer, then push descriptor tiers.
57f44a63d99fatagen2026-10-16 05:34 UTC56
- Timeline semaphores mapped to DRM syncobj points, sync_file import/export for implicit sync.
57f44a63d99fatagen2026-10-16 05:34 UTC57
- Global-priority graphics and transfer queues (`src/gfx_apis/vulkan/device.rs:448-528`).
57f44a63d99fatagen2026-10-16 05:34 UTC58
- Offline shaderc compilation with hash tracking.
57f44a63d99fatagen2026-10-16 05:34 UTC59
57f44a63d99fatagen2026-10-16 05:34 UTC60
Implement smithay's `Renderer`, `Frame`, `Bind<Dmabuf>`, `Offscreen`, `ImportDma`, `ImportMemWl` and `ExportMem` so that `DrmCompositor`, `OutputDamageTracker` and the element system work unmodified. `Frame` calls append to the op list and `finish` records and submits. Jay stops at rounded rects, so blur and shadows are new work. They would be extra op kinds or custom `RenderElement`s.
57f44a63d99fatagen2026-10-16 05:34 UTC61
57f44a63d99fatagen2026-10-16 05:34 UTC62
### 4. Commit blocker taxonomy
57f44a63d99fatagen2026-10-16 05:34 UTC63
57f44a63d99fatagen2026-10-16 05:34 UTC64
Smithay already has per-client transaction queues and `Blocker`. Jay's contribution is the list of things a commit waits on, all treated uniformly.
57f44a63d99fatagen2026-10-16 05:34 UTC65
57f44a63d99fatagen2026-10-16 05:34 UTC66
- implicit dmabuf fences
57f44a63d99fatagen2026-10-16 05:34 UTC67
- syncobj acquire points
57f44a63d99fatagen2026-10-16 05:34 UTC68
- shm upload completion
57f44a63d99fatagen2026-10-16 05:34 UTC69
- prime copy completion
57f44a63d99fatagen2026-10-16 05:34 UTC70
- fifo-v1 barrier
57f44a63d99fatagen2026-10-16 05:34 UTC71
- commit-timing-v1 deadline, released by the scheduler's before-latch hook
57f44a63d99fatagen2026-10-16 05:34 UTC72
- layout transaction serial
57f44a63d99fatagen2026-10-16 05:34 UTC73
57f44a63d99fatagen2026-10-16 05:34 UTC74
Each becomes a smithay `Blocker` or pre-commit hook. The commit-timing integration with the deadline scheduler is the subtle one.
57f44a63d99fatagen2026-10-16 05:34 UTC75
57f44a63d99fatagen2026-10-16 05:34 UTC76
### 5. Two-timeline tree, transactions, multiphase animations
57f44a63d99fatagen2026-10-16 05:34 UTC77
57f44a63d99fatagen2026-10-16 05:34 UTC78
`SplitView`/`TreeLink`, `LiveTL`/`RenderTL`, `src/transactions.rs` and `src/tree_serial_groups.rs` are upstream jay. `src/presentation/` is yours.
57f44a63d99fatagen2026-10-16 05:34 UTC79
57f44a63d99fatagen2026-10-16 05:34 UTC80
`LiveTL` is what clients have been configured to and `RenderTL` is what is on screen. `RenderTL` advances only when every affected client has acked and committed, or after a 50 ms timeout. Animations are transaction effects that diff the pre and post trees at publication time. Tags are a natural fit. A tag switch changes the visibility and size of many windows at once, which is exactly the case transactions exist for.
57f44a63d99fatagen2026-10-16 05:34 UTC81
57f44a63d99fatagen2026-10-16 05:34 UTC82
- `multiphase.rs` is near-pure geometry with 1.7k lines of tests. Lift it almost verbatim.
57f44a63d99fatagen2026-10-16 05:34 UTC83
- Retained snapshots from `layout_animation.rs`, where the old texture is scaled to the animated rect while the client catches up, port as a concept onto smithay elements.
57f44a63d99fatagen2026-10-16 05:34 UTC84
- Reimplement transactions and configure serial groups against smithay's xdg-shell configure/ack and `Blocker`s.
57f44a63d99fatagen2026-10-16 05:34 UTC85
57f44a63d99fatagen2026-10-16 05:34 UTC86
### 6. Integration test harness
57f44a63d99fatagen2026-10-16 05:34 UTC87
57f44a63d99fatagen2026-10-16 05:34 UTC88
`src/it/`.
57f44a63d99fatagen2026-10-16 05:34 UTC89
57f44a63d99fatagen2026-10-16 05:34 UTC90
An in-process compositor on a headless backend, real-socket clients, zeroed timeouts, tree-invariant verification after every idle point, and golden-pixel QOI comparisons. Use wayland-client or smithay-client-toolkit in place of jay's `wl_usr`. An animation-heavy compositor needs this from the start.
57f44a63d99fatagen2026-10-16 05:34 UTC91
57f44a63d99fatagen2026-10-16 05:34 UTC92
### 7. Small items
57f44a63d99fatagen2026-10-16 05:34 UTC93
57f44a63d99fatagen2026-10-16 05:34 UTC94
- `SCHED_RR` with `SCHED_RESET_ON_FORK`, with `CAP_SYS_NICE` parked on a helper thread (`src/utils/nice.rs`, `src/pr_caps.rs`).
57f44a63d99fatagen2026-10-16 05:34 UTC95
- Tracy zones named per task.
57f44a63d99fatagen2026-10-16 05:34 UTC96
- KMS hygiene. Reset unknown properties to defaults at init, retry device init with features disabled, `TEST_ONLY` before modesets, roll back on failure.
57f44a63d99fatagen2026-10-16 05:34 UTC97
- VRR cursor throttling (`src/output_schedule.rs`), so cursor motion doesn't pin VRR at max refresh.
57f44a63d99fatagen2026-10-16 05:34 UTC98
- Lazy Xwayland startup on the first X connection.
57f44a63d99fatagen2026-10-16 05:34 UTC99
57f44a63d99fatagen2026-10-16 05:34 UTC100
## Skip
57f44a63d99fatagen2026-10-16 05:34 UTC101
57f44a63d99fatagen2026-10-16 05:34 UTC102
- Bespoke wire protocol, codegen and `wl_usr`. Smithay owns this layer.
57f44a63d99fatagen2026-10-16 05:34 UTC103
- Homegrown xcon, dbus and pipewire stacks. Use x11rb via smithay's `X11Wm`, zbus and pipewire-rs.
57f44a63d99fatagen2026-10-16 05:34 UTC104
- Forker process. `std::process::Command` uses `posix_spawn` and is safe from a threaded process. Set env, rlimits and sched policy on the `Command`.
57f44a63d99fatagen2026-10-16 05:34 UTC105
- The `Rc` plus cell utility collection, which only exists because of jay's executor.
57f44a63d99fatagen2026-10-16 05:34 UTC106
- Jay's plane assignment, which never uses overlays. `DrmCompositor` already assigns overlays.
57f44a63d99fatagen2026-10-16 05:34 UTC107
- `metal_cm` KMS color pipelines for now. It is large and driver-quirky. Keep the renderer's color math shaped so it can slot in later.
57f44a63d99fatagen2026-10-16 05:34 UTC108
- SQLite session manager, unless session restore becomes a goal.
57f44a63d99fatagen2026-10-16 05:34 UTC109
57f44a63d99fatagen2026-10-16 05:34 UTC110
## Gaps smithay leaves
57f44a63d99fatagen2026-10-16 05:34 UTC111
57f44a63d99fatagen2026-10-16 05:34 UTC112
- No tearing/async page flip control in `DrmCompositor`. Needs an upstream patch or a custom commit path.
57f44a63d99fatagen2026-10-16 05:34 UTC113
- No KMS color pipeline, CTM/gamma or HDR metadata handling.
57f44a63d99fatagen2026-10-16 05:34 UTC114
- No tearing-control-v1 or color-management-v1 protocol helpers.
57f44a63d99fatagen2026-10-16 05:34 UTC115
57f44a63d99fatagen2026-10-16 05:34 UTC116
## License
57f44a63d99fatagen2026-10-16 05:34 UTC117
57f44a63d99fatagen2026-10-16 05:34 UTC118
jay and wry are `GPL-3.0-only`. Copying code from them makes monolith GPL-3.0. Smithay is MIT, which is compatible with that. `src/presentation/` is your own new code and can be relicensed freely. Jay-authored code (scheduler, shaders, transfer path) can only be reimplemented from the design if monolith is meant to be permissive.