Runnable demos for CopperlineOS Phase‑0 (Linux‑hosted).
This repo contains end‑to‑end examples that exercise the core services: compositord
, copperd
, blitterd
, audiomixerd
, plus the SDKs and tools.
TL;DR: build the daemons, then run these demos to see layers on screen, Copper timelines ticking, pixels blitting, and audio graphs playing.
examples/
├─ vulkan-scene/ # minimal Vulkan sample (triangle), optional DMABUF export
├─ sprite-overlay/ # create a layer, bind a sprite, animate via Copper
├─ copper-programs/ # sample Copper JSON programs
├─ audio-graph/ # tone/gain/device graph & file source demo
└─ assets/ # small test assets (generated or checked-in)
Each example has its own README.md
and Cargo.toml
/Makefile
where applicable.
- Linux with DRM/KMS access (or Wayland/X11 host mode for
compositord
). - Rust stable toolchain.
- Built/installed from the sibling repos (same workspace or side-by-side clones):
compositord
copperd
blitterd
audiomixerd
tools
(forportctl
,timeline-inspect
)- Optionally
arexx-next
(arx
CLI)
Make sure your user can access the display (KMS/Wayland/X11) and, for low latency audio, is allowed to use the audio device. Seat management via seatd/logind is recommended.
# A: compositor (own the display)
git clone https://github.com/CopperlineOS/compositord && cd compositord
cargo build --release
RUST_LOG=info ./target/release/compositord
# B: copper timeline
git clone https://github.com/CopperlineOS/copperd && cd copperd
cargo build --release
RUST_LOG=info ./target/release/copperd
# C: 2D blitter
git clone https://github.com/CopperlineOS/blitterd && cd blitterd
cargo build --release
RUST_LOG=info ./target/release/blitterd
# D: audio mixer (optional for audio demo)
git clone https://github.com/CopperlineOS/audiomixerd && cd audiomixerd
cargo build --release
RUST_LOG=info ./target/release/audiomixerd
Install tools (or run from source):
git clone https://github.com/CopperlineOS/tools && cd tools
cargo build --release
export PATH="$PWD/target/release:$PATH" # makes portctl/timeline-inspect available
Option A (Python):
python3 - <<'PY'
w,h=128,128
from PIL import Image, ImageDraw
im=Image.new('RGBA',(w,h),(0,0,0,0))
d=ImageDraw.Draw(im); d.rectangle((0,0,w-1,h-1),outline=(0,255,0,255),width=6)
im.save('/tmp/sprite.rgba','RGBA')
PY
Option B (ImageMagick):
convert -size 128x128 xc:none -fill none -stroke green -strokewidth 6 -draw 'rectangle 3,3 124,124' rgba:/tmp/sprite.rgba
Create a layer, bind the sprite, then animate it 4 px per frame:
# Create a layer
portctl /run/copperline/compositord.sock '{"cmd":"create_layer"}'
# Bind the sprite file (debug path binding)
portctl /run/copperline/compositord.sock '{"cmd":"bind_image","id":1,"path":"/tmp/sprite.rgba","w":128,"h":128,"format":"RGBA8"}'
# Place it on screen
portctl /run/copperline/compositord.sock '{"cmd":"set","id":1,"x":100,"y":360,"alpha":1.0,"z":10,"visible":true}'
Create a Copper program file and run it:
cat > /tmp/demo.json <<'JSON'
{ "version":1, "program":[
{"op":"MOVE","reg":"layer[1].x","value":100},
{"op":"MOVE","reg":"layer[1].y","value":360},
{"op":"LOOP","count":-1,"label":"loop"},
{"label":"loop"},
{"op":"WAIT","vsync":true},
{"op":"ADD","reg":"layer[1].x","delta":4},
{"op":"IRQ","tag":"tick"},
{"op":"JUMP","label":"loop"}
]}
JSON
portctl /run/copperline/copperd.sock "$(jq -c '{cmd:"load",program:.}' /tmp/demo.json)"
portctl /run/copperline/copperd.sock '{"cmd":"start","id":1}'
Watch timing:
timeline-inspect --socket /run/copperline/compositord.sock --events vsync
timeline-inspect --socket /run/copperline/copperd.sock --events irq
Build & run the triangle sample (renders behind your sprite layer):
cd examples/vulkan-scene
cargo run --release
Tone → gain → device (48 kHz, period 128):
portctl /run/copperline/audiomixerd.sock '{"cmd":"device_open","name":"default","rate":48000,"channels":2,"period":128}'
portctl /run/copperline/audiomixerd.sock '{"cmd":"create_node","type":"tone","args":{"freq":440}}'
portctl /run/copperline/audiomixerd.sock '{"cmd":"create_node","type":"gain","args":{"db":-6.0}}'
portctl /run/copperline/audiomixerd.sock '{"cmd":"create_node","type":"device_sink"}'
portctl /run/copperline/audiomixerd.sock '{"cmd":"connect","from":1,"to":2}'
portctl /run/copperline/audiomixerd.sock '{"cmd":"connect","from":2,"to":3}'
portctl /run/copperline/audiomixerd.sock '{"cmd":"start"}'
arx demo.rexx
(if usingarexx-next
) runs the same animation with a one‑file script.- Alternate path: use the Rust example from
sdk-rs/examples/overlay_sprite.rs
.
- Contains validated Copper JSON snippets: bouncers, fades, loops, fences.
- Use
copper-asm validate
to check and pretty‑print them.
- Minimal triangle with swapchain; optionally advertises a DMABUF for direct import (driver‑dependent).
- If DMABUF export isn’t available, it still renders as a background window in host mode.
- Includes a CLI that builds simple graphs and prints XRUN/stats events.
- Try changing period sizes (
64
,128
) and watchlatency-meter
jitter.
- No picture / permission denied: ensure your user has access to DRM render/primary nodes, or run in Wayland/X11 host mode (
COMPOSITORD_BACKEND=wayland|x11
). - Sockets not found: check that daemons are running and sockets are at
/run/copperline/*.sock
(or set*_SOCKET
env vars). - Audio underruns: increase period size, close other audio apps, or allow RT scheduling (via
rtkit
). - DMABUF errors: verify
w/h/format/stride/modifier
match the actual buffer.
COMPOSITORD_SOCKET
·COPPERD_SOCKET
·BLITTERD_SOCKET
·AUDIOMIXERD_SOCKET
COMPOSITORD_BACKEND=kms|wayland|x11
,COMPOSITORD_MODE=1920x1080@60
All examples are dual-licensed under Apache-2.0 OR MIT.
sdk-rs
·sdk-c
tools
—portctl
,timeline-inspect
,dmabuf-dump
copperd
·compositord
·blitterd
·audiomixerd