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):
compositordcopperdblitterdaudiomixerdtools(forportctl,timeline-inspect)- Optionally
arexx-next(arxCLI)
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/audiomixerdInstall 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 availableOption 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')
PYOption B (ImageMagick):
convert -size 128x128 xc:none -fill none -stroke green -strokewidth 6 -draw 'rectangle 3,3 124,124' rgba:/tmp/sprite.rgbaCreate 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 irqBuild & run the triangle sample (renders behind your sprite layer):
cd examples/vulkan-scene
cargo run --releaseTone → 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 validateto 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-meterjitter.
- 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*_SOCKETenv vars). - Audio underruns: increase period size, close other audio apps, or allow RT scheduling (via
rtkit). - DMABUF errors: verify
w/h/format/stride/modifiermatch the actual buffer.
COMPOSITORD_SOCKET·COPPERD_SOCKET·BLITTERD_SOCKET·AUDIOMIXERD_SOCKETCOMPOSITORD_BACKEND=kms|wayland|x11,COMPOSITORD_MODE=1920x1080@60
All examples are dual-licensed under Apache-2.0 OR MIT.
sdk-rs·sdk-ctools—portctl,timeline-inspect,dmabuf-dumpcopperd·compositord·blitterd·audiomixerd