pidisp

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2026 License: MIT Imports: 6 Imported by: 0

README

pidisp

Go Reference

A Go module for opening a display on a Raspberry Pi and rendering image.RGBA frames with zero-copy double-buffering.

No CGO, no libdrm, no X11 — just raw Linux ioctls and mmap.

Backends

Backend Path Speed (800×480, Pi 2) Requirements
DRM/KMS /dev/dri/card* ~1.66 ms/frame DRM master (console, no display server)
fbdev /dev/fb0 ~53 ms/frame (16 bpp) Read/write on /dev/fb0

Open tries DRM first (card0, card1, card2) and falls back to fbdev automatically.

Usage

Zero-copy rendering (v1.1.0+)

Render directly into hardware-mapped memory on DRM (no per-frame memcopy):

import "github.com/amnonbc/pidisp"

d, err := pidisp.Open(pidisp.Options{Rotate: true})
if err != nil {
    log.Fatal(err)
}
defer d.Close()

// Get the back buffer and render into it
buf := d.BackBuffer()
// draw into buf ...

// Flip to display the rendered frame
d.Flip()

On DRM, rendering is directly into hardware-mapped memory. On fbdev, Flip() copies the back buffer to the hardware framebuffer.

Legacy API (Blit)

For backward compatibility, the old Blit() method is still available:

img := image.NewRGBA(image.Rect(0, 0, d.Width(), d.Height()))
// draw into img ...
d.Blit(img)  // deprecated; use BackBuffer/Flip instead

Cross-compilation

# Pi 2/3 (ARMv7)
GOOS=linux GOARCH=arm GOARM=7 go build ./...

# Pi 1 (ARMv6)
GOOS=linux GOARCH=arm GOARM=6 go build ./...

# Pi 4/5 (ARM64)
GOOS=linux GOARCH=arm64 go build ./...

DRM/KMS setup (Pi OS)

Add to /boot/config.txt:

dtoverlay=vc4-kms-v3d

Run the process on the console with no display server active (DRM requires DRM master).

Comparison with other libraries

Other Go framebuffer libraries exist, but pidisp fills a specific niche:

Feature pidisp Others (gonutz/different55/etc)
DRM/KMS support ✓ (with hardware rotation) ✗ fbdev only
Double-buffering ✓ (zero-copy on DRM) ✗ single buffer
Auto-fallback ✓ tries DRM, falls back to fbdev ✗ single backend
Hardware acceleration ✓ ABGR8888 zero-copy, plane rotation ✗ per-pixel software operations
Performance (Pi 2) 1.66 ms/frame (DRM), ~53 ms/frame (fbdev) ~53 ms/frame
CGO-free ✓ raw ioctls only varies
Modern Pi OS support ✓ (DRM default) ⚠️ (fbdev deprecated)

When to use pidisp:

  • Raspberry Pi graphics without a display server
  • Any Linux system with DRM/KMS display hardware
  • High-performance graphics (~32× faster than fbdev on DRM-capable hardware)
  • Simple API that abstracts away backend selection

Limitations:

  • Linux only (DRM/fbdev not available on other platforms)
  • Requires DRM master for DRM backend (console-only, no display server)
  • image.RGBA format only (no color space conversion)

Sub-packages

  • drm — DRM/KMS backend; ABGR8888 + hardware rotation for maximum performance
  • fb — fbdev fallback; supports 16 bpp (RGB565 with Bayer dithering) and 32 bpp

Alternatives

Documentation

Overview

Package pidisp opens a display on a Raspberry Pi (or any Linux system) and renders image.RGBA frames onto it using double buffering.

It tries DRM/KMS first (via the drm sub-package) and falls back to the Linux framebuffer (/dev/fb0) automatically. Callers only see the Display interface; the backend is chosen at runtime.

Basic usage (zero-copy)

d, err := pidisp.Open(pidisp.Options{Rotate: true})
if err != nil {
    log.Fatal(err)
}
defer d.Close()

buf := d.BackBuffer()
// ... draw into buf ...
d.Flip()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewTestImage

func NewTestImage(width, height int) *image.RGBA

NewTestImage returns an RGBA image filled with a non-trivial pattern (R=x, G=y, B=x+y, A=255). Used by tests in the drm and fb sub-packages.

Types

type Display

type Display interface {
	// Width returns the display width in pixels.
	Width() int

	// Height returns the display height in pixels.
	Height() int

	// BackBuffer returns the non-active buffer for rendering.
	// The returned buffer may be drawn into directly.
	// Call Flip to make the back buffer active (displayed).
	BackBuffer() *image.RGBA

	// Flip makes the back buffer the active (displayed) buffer
	// and prepares a fresh back buffer for the next frame.
	Flip()

	// Blit copies img to the display. Deprecated: use BackBuffer and Flip instead.
	Blit(img *image.RGBA)

	// Close releases all resources held by the display.
	Close()
}

Display is a handle to an open hardware display. Obtain one via Open; release it with [Close].

func Open

func Open(opts Options) (Display, error)

Open opens the best available display device and returns a Display.

It tries /dev/dri/card0, card1, and card2 in order (unless opts.ForceFB is set), using the first DRM device that supports modesetting. If DRM is unavailable it opens /dev/fb0 instead.

type Options

type Options struct {
	// Rotate requests 180° rotation of the output.
	// On DRM/KMS devices this is offloaded to hardware; on fbdev it is done
	// in software.
	Rotate bool

	// ForceFB skips DRM detection and opens /dev/fb0 directly. Useful for
	// testing the fbdev path on a machine that supports both.
	ForceFB bool

	// Debug logs DRM device information (plane formats, connector details)
	// before opening the display.
	Debug bool
}

Options controls how the display is opened.

Directories

Path Synopsis
Package drm drives a display via the Linux DRM/KMS kernel subsystem using raw ioctls — no libdrm or CGO required.
Package drm drives a display via the Linux DRM/KMS kernel subsystem using raw ioctls — no libdrm or CGO required.
Package fb drives a Linux framebuffer device such as /dev/fb0 using a single ioctl and mmap — no external dependencies, no DRM master required.
Package fb drives a Linux framebuffer device such as /dev/fb0 using a single ioctl and mmap — no external dependencies, no DRM master required.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL