Releases: gogpu/compose
Releases · gogpu/compose
v0.2.0 — Mailbox Frame Delivery
Added
Server.Snapshot()— returns latest frame from each connected module. Designed for compositor render tick pattern (Android BufferQueue / Vulkan MAILBOX semantics).Frame.Sequence— monotonic frame counter mapped from wire protocol header, for change detection.- Per-module mailbox — each module's latest frame is stored server-side. Intermediate frames silently overwritten (latest-frame-wins).
Push-based delivery officially supported
Modules can call PublishFrame() at any time without waiting for OnFrameRequest. The server accepts and stores frames unconditionally. Both push and pull patterns coexist on the same connection — no mode negotiation needed.
// Compositor render tick (new pattern):
frames := srv.Snapshot()
for id, frame := range frames {
compositor.Blit(id, frame)
}
// Push module (sends whenever data changes):
client.PublishFrame(compose.Frame{Pixels: rgba, Width: 400, Height: 120})
// Pull module (renders only when asked — unchanged from v0.1.0):
client.OnFrameRequest(func() {
client.PublishFrame(renderClock())
})Architecture
Based on research across 9 production compositors (Wayland, Android SurfaceFlinger, Chromium viz, Flutter, PipeWire, Windows DWM, macOS Core Animation, Vulkan MAILBOX, X11). See ADR-002.
Backward compatible
No wire protocol changes. No handshake changes. OnFrame callback still fires on every receipt. Existing v0.1.0 code works unchanged.
v0.1.0 — First Release
compose v0.1.0
First release of gogpu/compose — Pure Go multi-process composition library.
Highlights
- Unix socket transport — cross-platform (Linux, macOS, Windows AF_UNIX)
- Wire protocol v1 — 64-byte fixed header, cache-line aligned, zero-alloc encode/decode
- LZ4 compression — 2.9 GB/s, 99.6% compression on GUI pixels
- Pull-based flow control — Wayland frame callback pattern, adaptive rate reduction
- Hot-plug — modules connect/disconnect/crash without compositor restart
- Public API —
compose.Listen(),compose.Dial(),Frame, functional options
Metrics
| Metric | Value |
|---|---|
| Total LOC | ~9,000 |
| Tests | 220+ |
| Coverage | ~98% |
| Packages | 6 (1 public + 5 internal) |
| Lint (30+ linters) | 0 issues |
| CI | Ubuntu + macOS + Windows |
| Dependencies | 1 (pierrec/lz4/v4) |
Quick Start
// Compositor
srv, _ := compose.Listen("/tmp/compose.sock")
srv.OnFrame(func(f compose.Frame) { /* blit pixels */ })
// Module
client, _ := compose.Dial("/tmp/compose.sock", compose.WithName("clock"))
client.PublishFrame(compose.Frame{Pixels: rgba, Width: 400, Height: 120})Architecture
compose/ # Public API (13 symbols)
└── internal/
├── protocol/ # Wire format (100% coverage)
├── codec/ # Raw + LZ4 (97% coverage)
├── conn/ # Module lifecycle (98.9% coverage)
├── flow/ # Pacing (100% coverage)
└── transport/socket/ # Unix sockets (95.1% coverage)
What's Next
- Phase 2: Reference examples (compositor + clock + notification binaries)
- Phase 3: Shared memory transport (zero-copy, triple-buffer)
- Phase 4: Delta frames, compression negotiation