2D Graphics Library for Go
Pure Go | GPU Accelerated | Production Ready
Part of the GoGPU ecosystem
gg is a 2D graphics library for Go designed to power IDEs, browsers, and graphics-intensive applications. Built with modern patterns inspired by vello and tiny-skia, it delivers production-grade rendering with zero CGO dependencies.
GoGPU.+.gg_.Three-Tier.GPU.Rendering.2026-02-15.22-05-02.mp4
Three-tier GPU rendering: SDF shapes, convex polygons, and stencil+cover paths in a single render pass. Pure Go, Vulkan backend, zero CGO. (source)
| Category | Capabilities |
|---|---|
| Rendering | Immediate and retained mode, three-tier GPU acceleration (SDF, Convex, Stencil+Cover), Vello analytic AA, CPU fallback |
| Shapes | Rectangles, circles, ellipses, arcs, bezier curves, polygons, stars |
| Text | TrueType fonts, MSDF rendering, emoji support, bidirectional text, HarfBuzz shaping |
| Compositing | 29 blend modes (Porter-Duff, Advanced, HSL), layer isolation |
| Images | 7 pixel formats, PNG/JPEG/WebP I/O, mipmaps, affine transforms |
| Vector Export | Recording system with PDF and SVG backends |
| Performance | Tile-based parallel rendering, LRU caching |
go get github.com/gogpu/ggRequirements: Go 1.25+
package main
import (
"github.com/gogpu/gg"
"github.com/gogpu/gg/text"
)
func main() {
// Create drawing context
dc := gg.NewContext(512, 512)
defer dc.Close()
dc.ClearWithColor(gg.White)
// Draw shapes
dc.SetHexColor("#3498db")
dc.DrawCircle(256, 256, 100)
dc.Fill()
// Render text
source, _ := text.NewFontSourceFromFile("arial.ttf")
defer source.Close()
dc.SetFont(source.Face(32))
dc.SetColor(gg.Black)
dc.DrawString("Hello, GoGPU!", 180, 260)
dc.SavePNG("output.png")
}// Default software renderer — high-quality CPU rasterizer
dc := gg.NewContext(800, 600)
defer dc.Close()gg supports optional GPU acceleration through the GPUAccelerator interface with
a three-tier rendering pipeline:
| Tier | Method | Best For |
|---|---|---|
| SDF | Signed Distance Field | Circles, ellipses, rectangles, rounded rects |
| Convex | Direct vertex emission | Convex polygons, single draw call |
| Stencil+Cover | Fan tessellation + stencil buffer | Arbitrary complex paths, EvenOdd/NonZero fill |
When no GPU is registered, rendering uses the high-quality CPU rasterizer (default).
import (
"github.com/gogpu/gg"
_ "github.com/gogpu/gg/gpu" // opt-in GPU acceleration
)
func main() {
// GPU automatically used when available, falls back to CPU
dc := gg.NewContext(800, 600)
defer dc.Close()
dc.DrawCircle(400, 300, 100)
dc.Fill() // tries GPU first, falls back to CPU transparently
}For zero-copy rendering directly to a GPU surface (e.g., in a gogpu window),
use ggcanvas.Canvas.RenderDirect — see the
gogpu integration example. The example uses
event-driven rendering with AnimationToken for power-efficient VSync (0% CPU when idle).
// Use existing pixmap
pm := gg.NewPixmap(800, 600)
dc := gg.NewContext(800, 600, gg.WithPixmap(pm)) gg (Public API)
│
┌───────────────────┼───────────────────┐
│ │ │
Immediate Mode Retained Mode Resources
(Context API) (Scene Graph) (Images, Fonts)
│ │ │
└───────────────────┼───────────────────┘
│
┌──────────────┴──────────────┐
│ │
CPU Raster GPUAccelerator
(always available) (opt-in via gg/gpu)
│ │
internal/raster ┌──────────┼──────────┐
│ │ │
SDF Convex Stencil+Cover
(Tier 1) (Tier 2) (Tier 3)
| Component | Location | Description |
|---|---|---|
| CPU Raster | internal/raster |
Core analytic AA rasterizer (Vello-based) |
| GPU Accelerator | internal/gpu |
Three-tier GPU pipeline (SDF, Convex, Stencil+Cover) |
| GPU Registration | gpu/ |
Public opt-in via import _ "github.com/gogpu/gg/gpu" |
| Software | Root gg package |
Default CPU renderer |
Canvas-style drawing with transformation stack:
dc := gg.NewContext(800, 600)
defer dc.Close()
// Transforms
dc.Push()
dc.Translate(400, 300)
dc.Rotate(math.Pi / 4)
dc.DrawRectangle(-50, -50, 100, 100)
dc.SetRGB(0.2, 0.5, 0.8)
dc.Fill()
dc.Pop()
// Bezier paths
dc.MoveTo(100, 100)
dc.QuadraticTo(200, 50, 300, 100)
dc.CubicTo(350, 150, 350, 250, 300, 300)
dc.SetLineWidth(3)
dc.Stroke()Type-safe path construction with method chaining:
path := gg.BuildPath().
MoveTo(100, 100).
LineTo(200, 100).
QuadTo(250, 150, 200, 200).
CubicTo(150, 250, 100, 250, 50, 200).
Close().
Circle(300, 150, 50).
Star(400, 150, 40, 20, 5).
Build()
dc.SetPath(path)
dc.Fill()GPU-optimized scene graph for complex applications:
import "github.com/gogpu/gg/render"
s := render.NewScene()
s.SetFillColor(color.RGBA{R: 255, A: 200})
s.Circle(150, 200, 100)
s.Fill()
s.SetFillColor(color.RGBA{B: 255, A: 200})
s.Circle(250, 200, 100)
s.Fill()
renderer := scene.NewRenderer(800, 600)
renderer.Render(target, s)Full Unicode support with font fallback and optional HarfBuzz-level shaping:
// Font composition
mainFont, _ := text.NewFontSourceFromFile("Roboto.ttf")
emojiFont, _ := text.NewFontSourceFromFile("NotoEmoji.ttf")
defer mainFont.Close()
defer emojiFont.Close()
multiFace, _ := text.NewMultiFace(
mainFont.Face(24),
text.NewFilteredFace(emojiFont.Face(24), text.RangeEmoji),
)
dc.SetFont(multiFace)
dc.DrawString("Hello World! Nice day!", 50, 100)
// Optional: enable HarfBuzz shaping for ligatures, kerning, complex scripts
shaper := text.NewGoTextShaper()
text.SetShaper(shaper)
defer text.SetShaper(nil)
// Text layout with wrapping
opts := text.LayoutOptions{
MaxWidth: 400,
WrapMode: text.WrapWordChar,
Alignment: text.AlignCenter,
}
layout := text.LayoutText("Long text...", face, 16, opts)Full color emoji support with CBDT/CBLC (bitmap) and COLR/CPAL (vector) formats:
175 colors from Segoe UI Emoji COLR/CPAL palette
// Extract color emoji from font
extractor, _ := emoji.NewCBDTExtractor(cbdtData, cblcData)
glyph, _ := extractor.GetGlyph(glyphID, ppem)
img, _ := png.Decode(bytes.NewReader(glyph.Data))
// Parse COLR/CPAL vector layers
parser, _ := emoji.NewCOLRParser(colrData, cpalData)
glyph, _ := parser.GetGlyph(glyphID, paletteIndex)
for _, layer := range glyph.Layers {
// Render each layer with layer.Color
}See examples/color_emoji/ for a complete example.
29 blend modes with isolated layers:
dc.PushLayer(gg.BlendOverlay, 0.7)
dc.SetRGB(1, 0, 0)
dc.DrawCircle(150, 200, 100)
dc.Fill()
dc.SetRGB(0, 0, 1)
dc.DrawCircle(250, 200, 100)
dc.Fill()
dc.PopLayer()Sophisticated compositing with masks:
dc.DrawCircle(200, 200, 100)
dc.Fill()
mask := dc.AsMask()
dc2 := gg.NewContext(400, 400)
dc2.SetMask(mask)
dc2.DrawRectangle(0, 0, 400, 400)
dc2.Fill() // Only visible through maskRecord drawing operations and export to PDF or SVG:
import (
"github.com/gogpu/gg/recording"
_ "github.com/gogpu/gg-pdf" // Register PDF backend
_ "github.com/gogpu/gg-svg" // Register SVG backend
)
// Create recorder
rec := recording.NewRecorder(800, 600)
// Draw using familiar API
rec.SetColor(gg.Blue)
rec.DrawCircle(400, 300, 100)
rec.Fill()
// Finish recording and play back to a raster backend
r := rec.FinishRecording()
backend := raster.NewBackend()
r.Playback(backend)
backend.SaveToFile("output.png")The drawing type is named Context following industry conventions:
| Library | Drawing Type |
|---|---|
| HTML5 Canvas | CanvasRenderingContext2D |
| Cairo | cairo_t (context) |
| Apple CoreGraphics | CGContext |
| piet (Rust) | RenderContext |
In HTML5, Canvas is the element while Context performs drawing (canvas.getContext("2d")). The Context contains drawing state and provides the drawing API.
Convention: dc for drawing context, ctx for context.Context:
dc := gg.NewContext(512, 512) // dc = drawing context| Operation | Time | Notes |
|---|---|---|
| sRGB to Linear | 0.16ns | 260x faster than math.Pow |
| LayerCache.Get | 90ns | Thread-safe LRU |
| DirtyRegion.Mark | 10.9ns | Lock-free atomic |
| MSDF lookup | <10ns | Zero-allocation |
| Path iteration | 438ns | iter.Seq, 0 allocs |
gg is part of the GoGPU ecosystem.
| Project | Description |
|---|---|
| gogpu/gogpu | GPU framework with windowing and input |
| gogpu/wgpu | Pure Go WebGPU implementation |
| gogpu/naga | Shader compiler (WGSL to SPIR-V, MSL, GLSL) |
| gogpu/gg | 2D graphics (this repo) |
| gogpu/gg-pdf | PDF export backend for recording |
| gogpu/gg-svg | SVG export backend for recording |
| gogpu/ui | GUI toolkit (planned) |
- ARCHITECTURE.md — System architecture
- ROADMAP.md — Development milestones
- CHANGELOG.md — Release notes
- CONTRIBUTING.md — Contribution guidelines
- pkg.go.dev — API reference
- GoGPU: From Idea to 100K Lines in Two Weeks
- Pure Go 2D Graphics Library with GPU Acceleration
- GoGPU Announcement
Contributions welcome! See CONTRIBUTING.md for guidelines.
Priority areas:
- API feedback and testing
- Examples and documentation
- Performance benchmarks
- Cross-platform testing
MIT License — see LICENSE for details.
gg — 2D Graphics for Go