Last updated: 2026-02-12
Join the Discussion: Help shape the future of Go graphics! Share your ideas, report issues, and discuss features at our GitHub Discussions.
When I discovered that fogleman/gg — the beloved 2D graphics library for Go — hadn't been updated since 2019, I knew the Go community needed a successor. Today, gogpu/gg has grown to v0.27.1 — a modern, GPU-accelerated 2D graphics library, now part of a 380K+ line Pure Go graphics ecosystem.
The Journey
It started with a Reddit discussion about the state of graphics in Go. The community's frustration was clear: Go deserves better graphics support.
So we built it.
What is gogpu/gg?
gogpu/gg is a Pure Go 2D graphics library for:
- Server-side rendering (charts, reports, image generation)
- Desktop applications (via gogpu framework)
- Professional graphics (PDF export, 29 blend modes, premultiplied alpha)
Key Features
| Feature | Description |
|---|---|
| Similar API | Easy migration from fogleman/gg |
| Pure Go | Zero CGO, simple go build
|
| GPU Acceleration | SDF accelerator — auto-detects shapes, renders on GPU |
| CPU Rasterizer | Vello-inspired tile rasterizer (always available) |
| 29 Blend Modes | Porter-Duff (14) + Advanced Separable (11) + HSL (4) |
| Premultiplied Alpha | Industry-standard compositing (matches Skia, Cairo) |
| Fluent PathBuilder | Method chaining for path construction |
| PDF Export | Via gg-pdf recording backend |
| Streaming I/O |
EncodePNG(w io.Writer) for any output |
| Parallel Rendering | TileGrid + WorkerPool for multi-core |
| LUT Optimizations | 260x faster sRGB conversions |
| Text Rendering | HarfBuzz shaping, OpenType/TrueType, color fonts |
Quick Start
go get github.com/gogpu/gg@latest
package main
import (
"github.com/gogpu/gg"
"github.com/gogpu/gg/text"
)
func main() {
// dc = "drawing context" — the convention from fogleman/gg
dc := gg.NewContext(512, 512)
dc.ClearWithColor(gg.White)
// Draw a filled circle
dc.SetHexColor("#3498db")
dc.DrawCircle(256, 256, 100)
dc.Fill()
// Stroke a rounded rectangle
dc.SetHexColor("#e74c3c")
dc.SetLineWidth(3)
dc.DrawRoundedRectangle(156, 156, 200, 200, 20)
dc.Stroke()
// Load font and draw text
source, _ := text.NewFontSourceFromFile("arial.ttf")
defer source.Close()
dc.SetFont(source.Face(32))
dc.SetRGB(0, 0, 0)
dc.DrawString("Hello, GoGPU!", 180, 270)
dc.SavePNG("output.png")
}
Fluent PathBuilder
// Build complex paths with method chaining
path := gg.BuildPath().
Circle(100, 100, 50).
Star(250, 100, 40, 20, 5).
RoundRect(50, 170, 100, 80, 10).
Build()
GPU Acceleration (opt-in)
import _ "github.com/gogpu/gg/gpu" // opt-in GPU acceleration
dc := gg.NewContext(800, 600)
dc.DrawCircle(400, 300, 100)
dc.Fill() // GPU renders via SDF if shape detected, CPU fallback otherwise
The SDF accelerator auto-detects circles, ellipses, rectangles, and rounded rectangles from path data. Everything else falls back to the CPU rasterizer — transparently, with ~17ns overhead when no GPU is registered.
Architecture
CPU Core + GPU Accelerator
Based on analysis of 8 enterprise 2D engines (Skia, Cairo, Vello, Blend2D, tiny-skia, piet, Qt RHI, Pathfinder), we follow the same fundamental principle:
CPU rasterization is the core. GPU is an optional accelerator.
gg.Fill() / gg.Stroke()
│
├── GPUAccelerator (if registered via import _ "gg/gpu")
│ ├── SDF: circles, rects, rrects (hardware-accelerated)
│ └── Stencil-Then-Cover: general paths (coming soon)
│
└── SoftwareRenderer → internal/raster/ (always available)
├── Vello-inspired tile rasterizer
├── Analytic anti-aliasing
└── Parallel tile processing
Vello-Inspired Rasterizer
The CPU rasterizer uses the Sparse Strips algorithm, inspired by vello:
- Tile-based processing (16x16 pixel tiles)
- Backdrop computation for winding
- Analytic anti-aliasing coverage
- Parallel tile rendering across CPU cores
Three-Tier GPU Rendering (Roadmap)
| Tier | Technique | Status |
|---|---|---|
| 1 | SDF Fragment Shader (circles, rects, rrects) | Working |
| 2a | Direct Convex Fan (single draw call) | Planned |
| 2b | Stencil-Then-Cover (all paths) | Planned |
| 3 | Vello Compute (optimal, all paths) | Future |
The GoGPU Ecosystem
gogpu/gg is part of a Pure Go GPU Computing Ecosystem:
| Project | Description | Version | LOC |
|---|---|---|---|
| gogpu/gg | 2D graphics library | v0.27.1 | ~155K |
| gogpu/wgpu | Pure Go WebGPU | v0.15.0 | ~97K |
| gogpu/ui | GUI widget toolkit | v0.0.x | ~54K |
| gogpu/naga | Shader compiler (WGSL to SPIR-V/MSL/GLSL/HLSL) | v0.12.0 | ~39K |
| gogpu/gogpu | GPU framework | v0.17.0 | ~36K |
| gogpu/gg-pdf | PDF export | v0.1.0 | ~1K |
| gogpu/gg-svg | SVG export | v0.1.0 | ~1K |
Total: 380K+ lines of Pure Go — no CGO, no Rust, no C.
wgpu Backends
The Pure Go WebGPU implementation supports multiple backends:
| Backend | Status | Use Case |
|---|---|---|
| Vulkan | Stable | Cross-platform (Windows/Linux/macOS) |
| Metal | Stable | macOS/iOS |
| OpenGL ES | Stable | Windows + Linux |
| Software | Stable | Headless, CI/CD, no GPU required |
| DX12 | WIP | Windows native |
Version Highlights
| Version | Milestone |
|---|---|
| v0.1.0 – v0.9.0 | Canvas API, shapes, text, images, scene graph, GPU basics |
| v0.10.0 | Gradient rendering, arc improvements |
| v0.14.0 | Alpha masks, fluent PathBuilder, streaming I/O |
| v0.15.0 | GPU compute shaders (Sparse Strips) |
| v0.17.0 | HarfBuzz text shaping, WebP support |
| v0.20.0 | Color fonts, filter effects |
| v0.23.0 | Recording context (PDF/SVG export) |
| v0.24.0 | Premultiplied alpha pipeline |
| v0.25.0 | Vello-inspired tile rasterizer |
| v0.26.0 | Architecture: CPU core + GPU accelerator |
| v0.27.0 | SDF accelerator, GPU compute pipeline, shape detection |
| v0.27.1 | Fix text rendering over GPU shapes |
What's Next?
- Stencil-Then-Cover — GPU rendering for all path types (concave, holes, beziers)
- SDF Render Pipeline — Port SDF from compute to render pipeline (avoiding shader compiler limitations)
- Convex Fast Path — Single draw call for convex polygons
- gogpu/ui — Signals-based GUI toolkit (54K LOC, already building)
Acknowledgments
Special thanks to:
- @fogleman for the original gg that inspired this project
- The vello team for Sparse Strips research and Euler spiral flattening
- @raphlinus for confirming our vello implementation is correct
- @amortaza, @ppoage, @Nickrocky for real-world testing
- The Go community on r/golang
Links
- GitHub: https://github.com/gogpu/gg
- GoGPU Organization: https://github.com/gogpu
- Discussion: Join the conversation
- Latest Release: gogpu/gg v0.27.1
Star the repo if you find it useful! Contributions welcome.
go get github.com/gogpu/gg@latest
Top comments (0)