CopperlineOS 2D blitter service.
blitterd performs fast 2D buffer operations—rect fill, rect copy, and format convert—on shared GPU buffers (DMABUFs). In Phase‑0 it uses Vulkan transfer/compute queues to move pixels with minimal CPU involvement. The service exposes a tiny JSON protocol over a Unix domain socket.
TL;DR: move pixels fast and predictably, without dragging a full graphics stack into the hot path.
The compositor (compositord) wants clean, ready‑to‑draw surfaces. Apps shouldn’t have to carry bespoke GPU code just to clear/copy/convert textures. blitterd centralises those operations so they’re consistent, low‑latency, and zero‑copy across the system.
- Zero‑copy pipelines via DMABUF import/export.
- Deterministic execution with optional fences and completion events.
- Simple JSON API (binary ring in later phases).
- Future‑proof path to FPGA offload for “Blitter‑2.0”.
- Phase‑0 JSON protocol: stable‑ish (v0)
- Backends: Vulkan transfer/compute on Linux
- Language: Rust
- License: MIT OR Apache‑2.0
flowchart LR
subgraph Apps
A1[Producer app] -- DMABUF --> B[blitterd]
A2[Tools/CLI] -- JSON over UDS --> B
end
B -- writes DMABUF --> C[compositord]
subgraph Kernel/Drivers
DRM[KMS/DRM] --> C
VK[Vulkan driver] --> B
end
COP[copperd] -. orchestrates timing .-> C
- Apps or
compositordhandblitterdDMABUF FDs (or, in debug mode, file paths). blitterdruns the operation (fill/copy/convert) on the GPU’s transfer/compute queue.- Results are visible to
compositordon the next latch/commit.
- Surface: a DMABUF (preferred) or debug file-backed buffer with
w,h,format,stride,modifier. - Job: a one‑shot operation that may batch multiple ops and signal a fence/event on completion.
- Region:
{x, y, w, h}rectangle in pixels; coordinates are top‑left origin. - Format: e.g.,
RGBA8,BGRA8(Phase‑0); YUV/NV12 in later revisions.
Socket (default): /run/copperline/blitterd.sock
Configurable via BLITTERD_SOCKET.
{"cmd":"ping"}→{"ok":true,"name":"blitterd","version":"0.1.0"}{"cmd":"rect_fill","dst":<surface>,"rect":{"x":0,"y":0,"w":128,"h":128},"color":{"r":255,"g":0,"b":255,"a":255}}{"cmd":"rect_copy","src":<surface>,"dst":<surface>,"src_rect":{"x":0,"y":0,"w":128,"h":128},"dst_xy":{"x":200,"y":100}}{"cmd":"convert","src":<surface>,"dst":<surface>}(format/stride may differ; sizes must match){"cmd":"batch","ops":[ ... ]}(run multiple ops as one job){"cmd":"subscribe","events":["complete","error"]}
Surface objects (DMABUF recommended):
{
"fd": 17,
"w": 1920,
"h": 1080,
"format": "RGBA8",
"stride": 7680,
"modifier": "LINEAR"
}Debug file surfaces (for quick demos; slower, copies via staging):
{
"path": "/tmp/sprite.rgba",
"w": 128,
"h": 128,
"format": "RGBA8",
"stride": 512
}{"event":"complete","job":123,"usec":4213}{"event":"error","job":123,"message":"description"}
Notes
- Rects are clipped to destination bounds.
- Overlapping
src/dstwithrect_copyis implementation‑defined in v0 (avoid or useblitwhen available). - Color components are 0–255 in v0; HDR/linear color is planned for later.
# 1) Start compositord (in another terminal) and create a layer bound to /tmp/sprite.rgba
portctl /run/copperline/compositord.sock '{"cmd":"create_layer"}'
portctl /run/copperline/compositord.sock '{"cmd":"bind_image","id":1,"path":"/tmp/sprite.rgba","w":256,"h":256,"format":"RGBA8"}'
portctl /run/copperline/compositord.sock '{"cmd":"set","id":1,"x":100,"y":100,"alpha":1.0,"z":5,"visible":true}'
# 2) Fill a magenta square into the file via blitterd
portctl /run/copperline/blitterd.sock '{"cmd":"rect_fill","dst":{"path":"/tmp/sprite.rgba","w":256,"h":256,"format":"RGBA8","stride":1024}, "rect":{"x":0,"y":0,"w":256,"h":256}, "color":{"r":255,"g":0,"b":255,"a":255}}'You should see a 256×256 magenta square appear at (100,100).
- Allocate a DMABUF in your app (or request one from
compositord—API to be finalised). - Bind it to a layer in
compositord. - Send its FD as the
dstsurface toblitterdand issuerect_fill/rect_copy. - The layer updates on the next vsync commit without staging copies.
# Prereqs: Rust stable, Vulkan loader/headers, libdrm for DMABUF helpers
git clone https://github.com/CopperlineOS/blitterd
cd blitterd
cargo build --release
RUST_LOG=info ./target/release/blitterdEnvironment variables:
BLITTERD_SOCKET=/run/copperline/blitterd.sockBLITTERD_DEVICE=auto|/dev/dri/renderD128BLITTERD_DEBUG_FILES=0|1(enable file‑backed surfaces)
- Crates:
blitterd-core(ops & scheduler),blitterd-ipc(JSON protocol),blitterd-backend(Vulkan),blitterd-bin(daemon). - Ops: implemented as GPU pipelines (transfer for copy/fill; compute for format convert).
- Sync: implicit within a job; explicit external fences planned (shared with
copperdtimelines). - Validation: surface dims/format/stride/modifier are checked; out‑of‑bounds rects are clipped.
- Performance: batches coalesce ops to minimize barriers; device selection prefers a render node.
Supported formats (v0): RGBA8, BGRA8 (more via feature flags).
Planned: NV12, RGB10A2, sRGB awareness, color‑managed convert.
- v0.1:
rect_fill,rect_copy,convert(RGBA/BGRA), debug file surfaces. - v0.2:
blit(scale/nearest and linear), per‑op alpha modulate, tiled ops. - v0.3: YUV/NV12 ↔ RGBA convert, partial damage guidance to
compositord. - v0.4: FPGA Blitter‑2.0 backend with DMA command ring.
- v0.5: Security caps (FD quotas, rate limits), binary protocol.
RFCs will appear in CopperlineOS/rfcs.
We welcome issues and PRs!
- Read
CONTRIBUTING.md. - Check good first issue / help wanted labels.
- Protocol/format additions → open an RFC and link it in your PR.
Code of Conduct: CODE_OF_CONDUCT.md.
blitterd handles FDs received from untrusted clients—validate everything.
Prefer running as an unprivileged user with access to a render node (/dev/dri/renderD*), not as root.
Report vulnerabilities to [email protected] (placeholder) or via GitHub advisories. See SECURITY.md.
Dual‑licensed under Apache‑2.0 OR MIT.
compositord: Vulkan/KMS compositor + layer registerscopperd: timeline engine (drives per‑frame changes)ports: message‑port protocol & client libsexamples: DMABUF demos and integration tests