Vello: GPU-Accelerated 2D Vector Graphics for Python
Vello is a high-performance, GPU compute-centric 2D vector graphics engine for Python, powered by Linebender's Vello and wgpu.
Unlike traditional CPU renderers (like Cairo or CPU Skia) or traditional GPU renderers that rely on tessellation, Vello utilizes modern GPU Compute Shaders to perform sorting, path clipping, and antialiased rasterization in parallel on your graphics card.
✨ Features
- ⚡ Pure GPU Compute Acceleration: Path flattening, clipping, and rasterization run completely on GPU Compute Shaders.
- 🎨 Pythonic Canvas API: An intuitive, HTML5 Canvas-like API designed specifically for Python developers.
- 🚀 Zero-Copy NumPy Integration: Stream rendered frames directly into NumPy
(H, W, 4)uint8 arrays without copying memory. - ⚡ Vectorized Batch Drawing: Render tens of thousands to millions of circles, rectangles, lines, and complex polygons in a single native GPU dispatch via NumPy arrays.
- 🔺 Direct Polygon & Polyline Batches: Pass binary NumPy coordinate buffers directly to
fill_polygons_batch,stroke_polygons_batch, anddraw_polylines_batchwith compound path optimization, eliminating SVG string parsing and scene buffer overhead. - 🎥 Direct GPU Video Streaming: Stream raw RGBA buffers directly to hardware-accelerated video encoders (NVENC H.264/HEVC or libx264) via
vello.VideoWriterandCanvas.save_video(), eliminating OpenCV and PCIe bus bottlenecks. - 🌈 Rich Shading & Gradients: Full support for Solid Colors, Linear Gradients, Radial Gradients, Angular / Conical Sweep Gradients, and Image Brushes.
- 🎬 Built-in Animation & Video Export: Generate smooth animated GIF sequences or hardware-encoded MP4 videos directly.
- 📐 Vector Shapes & SVG Paths: Native support for Polygons, Polylines, Rectangles, Rounded Rectangles, Circles, Ellipses, Lines, Bézier Curves, and complete SVG path
d="..."strings. - 🔤 GPU Vector Typography: High-quality TrueType/OpenType font rendering with exact subpixel glyph positioning.
- 🎭 Compositing & Blend Modes: Full W3C blend modes (Multiply, Screen, Overlay, etc.) and compositing operations.
- 💡 Gaussian Drop Shadows: Accelerated blurred rounded rectangles for realistic UI drop shadows.
- 🧵 Non-blocking & Thread-Safe: Releases the Python GIL during GPU execution for multi-threaded performance.
- 🐧 Linux & Cloud Ready: Fully supports headless Linux servers, Docker containers, and Cloud GPU environments with NVIDIA GPUs (T4, V100, A100, H100, RTX) via Vulkan.
📦 Installation
pip install vello
🚀 Quickstart
1. Basic Drawing & PNG Export
import vello
# Create canvas with background color
canvas = vello.Canvas(800, 600, background="white")
# Fill and stroke shapes with CSS colors, hex, or RGB tuples
canvas.fill_circle(cx=400, cy=300, radius=120, fill="royalblue")
canvas.stroke_circle(cx=400, cy=300, radius=120, stroke="crimson", stroke_width=6.0)
# Draw rounded rectangle with GPU drop shadow
canvas.draw_shadow(x=50, y=50, width=200, height=100, radius=16, blur=20, color="#00000044")
canvas.fill_rounded_rect(x=50, y=50, width=200, height=100, radius=16, fill="#2ecc71")
# Draw an SVG path
canvas.fill_path("M 500 100 L 550 200 L 450 200 Z", fill="gold")
# Save directly to image
canvas.save("output.png")
2. High-Performance NumPy & Video / Game Pipelines
import vello
canvas = vello.Canvas(1920, 1080, background="black")
# Draw vector elements
canvas.fill_circle(960, 540, 200, fill="coral")
# Get a NumPy array with zero-copy buffer mapping (shape: 1080, 1920, 4)
frame = canvas.to_numpy()
print(frame.shape, frame.dtype) # (1080, 1920, 4) uint8
3. Linear & Radial Gradients
import vello
canvas = vello.Canvas(400, 400, background="black")
# Linear gradient
gradient = vello.LinearGradient(
start=(0, 0),
end=(400, 400),
stops=[
vello.ColorStop(0.0, vello.Color.from_name("red")),
vello.ColorStop(0.5, vello.Color.from_name("yellow")),
vello.ColorStop(1.0, vello.Color.from_name("blue")),
]
)
canvas.fill_rect(0, 0, 400, 400, fill=gradient)
canvas.save("gradient.png")
4. Transformations & Layer Blending
import vello
canvas = vello.Canvas(500, 500, background="white")
# Context manager for local coordinate transforms
with canvas.transform(translate=(250, 250), rotate_deg=45):
canvas.fill_rect(-50, -50, 100, 100, fill="teal")
# Blending and opacity layers
with canvas.layer(alpha=0.8, blend_mode="multiply"):
canvas.fill_circle(200, 200, 80, fill="cyan")
canvas.fill_circle(260, 200, 80, fill="magenta")
canvas.save("layers.png")
5. Vector Typography
import vello
canvas = vello.Canvas(600, 200, background="white")
# Load any TrueType or OpenType font
font = vello.Font.from_file("C:/Windows/Fonts/arial.ttf")
# Measure text bounds
width, height = font.measure_text("Vello on GPU", size=36.0)
# Draw vector text
canvas.draw_text("Vello on GPU", x=50, y=100, font=font, size=36.0, color="royalblue")
canvas.save("text.png")
6. Vectorized Batch Drawing (NumPy)
Render tens of thousands of shapes simultaneously without Python loop overhead:
import vello
import numpy as np
canvas = vello.Canvas(1000, 1000, background="black")
# 50,000 random circles [x, y, radius]
n = 50_000
data = np.zeros((n, 3), dtype=np.float32)
data[:, 0] = np.random.uniform(0, 1000, n)
data[:, 1] = np.random.uniform(0, 1000, n)
data[:, 2] = np.random.uniform(1, 5, n)
# Single native GPU call!
canvas.fill_circles_batch(data, fill="#00ffcc88")
# Rectangles batch [x0, y0, x1, y1] and Lines batch [x0, y0, x1, y1]
# Combined into a single compound path to eliminate scene buffer fragmentation:
canvas.fill_rects_batch([[10, 10, 50, 50], [60, 10, 100, 50]], fill="teal")
canvas.draw_lines_batch([[0, 0, 1000, 1000], [0, 1000, 1000, 0]], stroke="gray", stroke_width=1.0)
canvas.save("batch_primitives.png")
7. Complex Polygons & Polyline Batches (Zero-Copy NumPy)
Avoid CPU string formatting and SVG parsing bottlenecks (d="M x y L x y Z") by feeding binary coordinate buffers directly from NumPy. All polygons are automatically merged into a single compound BezPath for maximal GPU encoding efficiency:
import vello
import numpy as np
canvas = vello.Canvas(1000, 1000, background="#111118")
# Draw an arbitrary individual polygon or open polyline:
pts = np.array([[200, 100], [350, 200], [300, 400], [150, 350]], dtype=np.float64)
canvas.fill_polygon(pts, fill="gold")
canvas.stroke_polygon(pts, stroke="white", stroke_width=2.0)
# Batch rendering: List of 2D NumPy polygon arrays (varying vertex counts)
tri = np.array([[50, 50], [90, 50], [70, 90]])
quad = np.array([[120, 50], [160, 50], [170, 90], [110, 80]])
poly = np.array([[200, 50], [240, 60], [250, 90], [220, 110], [190, 80]])
canvas.fill_polygons_batch([tri, quad, poly], fill="cyan")
# Batch rendering: Uniform polygons via 3D array (e.g., 10,000 triangles of shape (10000, 3, 2))
triangles = np.random.uniform(50, 950, size=(10_000, 3, 2))
canvas.fill_polygons_batch(triangles, fill="#ff336644")
# Batch polylines (open paths, contours, GIS tracks):
lines = [np.random.uniform(0, 1000, size=(20, 2)) for _ in range(500)]
canvas.draw_polylines_batch(lines, stroke="lime", stroke_width=1.5)
canvas.save("batch_polygons.png")
8. Direct Hardware-Accelerated Video Streaming (vello.VideoWriter)
When rendering high-resolution videos (1080p / 4K at 60 FPS), traditional approaches force you to read uncompressed frames across the PCIe bus into host RAM with canvas.to_numpy() and re-encode with OpenCV.
Vello provides a direct streaming pipeline that pipes raw GPU RGBA bytes straight into hardware-accelerated encoders (NVIDIA NVENC H.264/HEVC with automatic fallback to libx264):
import vello
WIDTH, HEIGHT, FPS = 1920, 1080, 60
# Option A: Pythonic context manager streaming directly to NVENC / FFmpeg:
with vello.VideoWriter("render.mp4", WIDTH, HEIGHT, fps=FPS, codec="auto") as video:
for i in range(240): # 4 seconds at 60 FPS
canvas = vello.Canvas(WIDTH, HEIGHT, background="#0a0a14")
canvas.fill_circle(960 + (i - 120) * 4, 540, 80, fill="deepskyblue")
video.write(canvas) # Direct GPU-to-pipe stream!
# Option B: Batch export an iterable of pre-rendered Canvases:
frames = [vello.Canvas(800, 600, background="black").fill_circle(100 + i * 5, 300, 40, fill="red") for i in range(60)]
vello.Canvas.save_video(frames, "output.mp4", fps=30)
9. Animation & GIF Export
import vello
import numpy as np
frames = []
for i in range(30):
c = vello.Canvas(300, 300, background="black")
angle = (i / 30.0) * 360.0
with c.transform(translate=(150, 150), rotate_deg=angle):
c.fill_rect(-40, -40, 80, 80, fill="cyan")
frames.append(c)
# Save smooth animated GIF
vello.Canvas.save_animation(frames, "spin.gif", fps=30)
10. Headless Linux & Cloud GPU Setup (enable_vulkan_gpu)
In cloud container environments or headless Linux servers, NVIDIA drivers may not have Vulkan configured out of the box (defaulting to CPU software rendering).
Vello includes an automatic, one-line setup utility that detects your NVIDIA GPU and configures Vulkan acceleration automatically:
import vello
# Run once in your cloud notebook or script to enable 100% GPU acceleration:
vello.enable_vulkan_gpu()
# Verify active GPU hardware & physical limits:
gpu = vello.get_gpu_info()
print("Active GPU:", gpu["name"]) # e.g., 'Tesla T4' or 'RTX 4090'
print("Backend:", gpu["backend"]) # 'Vulkan'
print("Device Type:", gpu["device_type"]) # 'DiscreteGpu'
print("Max Buffer Binding:", gpu["max_storage_buffer_binding_size_mb"], "MB")
11. Millions of Vectors & GPU Buffer Scaling (gpu_buffer)
Vello automatically discovers and prioritizes your Discrete GPU (e.g. NVIDIA Tesla T4, RTX 3090/4090, AMD Radeon) over any integrated or software fallback adapters, maximizing the available hardware storage limits.
Furthermore, Vello features hardware-safe buffer clamping: it dynamically verifies your GPU's physical max_storage_buffer_binding_size so allocations never exceed your card's hardware capabilities.
By default, Vello allocates an ultra-safe 128 MB GPU bump allocator profile, ensuring smooth operation on low-power devices and integrated graphics.
When working with massive datasets (e.g. rendering 1,000,000+ vector shapes in 4K) on high-memory GPUs (such as an NVIDIA Tesla T4 with 16GB VRAM, RTX 3090/4090, or A100/H100), you can unlock large buffer capacities:
Per-Canvas Configuration:
import vello
# Allocate a high-capacity GPU bump buffer profile:
canvas = vello.Canvas(3840, 2160, background="#050510", gpu_buffer="2GB")
# Available profiles: "128MB" (default), "256MB", "512MB", "1GB", "2GB", "4GB"
Global Configuration (e.g. at the top of a Notebook):
import vello
# Check active buffer profile
print(vello.get_gpu_buffer()) # '128MB'
# Set high-capacity profile for all canvases
vello.set_gpu_buffer("2GB")
1,000,000 Vector Circles in 4K:
import vello
import numpy as np
WIDTH, HEIGHT = 3840, 2160
N = 1_000_000
# 1. Initialize canvas with 4GB buffer
canvas = vello.Canvas(WIDTH, HEIGHT, background="#050510", gpu_buffer="4GB")
# 2. Generate 1,000,000 vector circles
data = np.zeros((N, 3), dtype=np.float32, order='C')
data[:, 0] = np.random.uniform(50, WIDTH - 50, N)
data[:, 1] = np.random.uniform(50, HEIGHT - 50, N)
data[:, 2] = np.random.uniform(2.0, 5.0, N)
# 3. Render all 1,000,000 shapes directly on GPU
canvas.fill_circles_batch(data, fill="#00ffcc")
canvas.save("galaxy_1m_4k.png")
📊 Performance
Vello parallelizes vector rendering on GPU compute shaders:
- Instant scene builds: Adding thousands of vector commands takes just a few milliseconds.
- Fast GPU rendering: 1080p full frame renders take ~5-10 ms on standard GPUs (~120-200 FPS).
- GIL-free execution: Multi-threaded Python applications run concurrently without blocking.
📜 License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Metadata
Release files for vello 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vello-0.1.5.tar.gz | 32.7 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| vello-0.1.5-cp313-cp313-win_amd64.whl | CPython 3.13 | CPython 3.13 | Windows x86-64 | Details |
| vello-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.13 | CPython 3.13 | Linux glibc 2.17+ x86-64 | Details |
| vello-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.17+ x86-64 | Details |
| vello-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.17+ x86-64 | Details |
| vello-0.1.5-cp310-cp310-win_amd64.whl | CPython 3.10 | CPython 3.10 | Windows x86-64 | Details |
| vello-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | CPython 3.10 | Linux glibc 2.17+ x86-64 | Details |
Total release size: 63.0 MB
Release files / vello-0.1.5.tar.gz
| Download URL | vello-0.1.5.tar.gz |
|---|---|
| Size | 32.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a23de449af3aeadb781f6f5de5be242d7d3bf2cd5100ca2bd1a63588ec7a3afd
|
|
BLAKE2b-256 checksum How to use checksums |
dbfef4b062d905ae3b1754835f14140d696f8a413634d0908c78bed0d772ecfb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|
Release files / vello-0.1.5-cp313-cp313-win_amd64.whl
| Download URL | vello-0.1.5-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 7.8 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
1fee3775bf988ca5c40cbde4b6568a17ed0923a552198915d5c927c2397da2b1
|
|
BLAKE2b-256 checksum How to use checksums |
c7278c1c4283a6d4de5eb25ee8c700a3fc1113725731029857c99fca6cb4b96a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|
Release files / vello-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | vello-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
8d89bc83e3e2dc5a60322f32919b58c51154c2754ca9535c7fdd71df09037c05
|
|
BLAKE2b-256 checksum How to use checksums |
022eccab2f5d5d02cefd346e573b3db6afa02fefc9c08324f0c84536122edb49
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|
Release files / vello-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | vello-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
acac8e091b4865573c3da5f66a4d8c5a3df3771430df056885abcd5a13b41357
|
|
BLAKE2b-256 checksum How to use checksums |
0f50c32b348fd448dd1448587e646e4d310ceb147c562127797df7b6b2885566
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|
Release files / vello-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | vello-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
6a9e8b1606fb02c8909119c5d11820f379e58408173550ff797a85122299b842
|
|
BLAKE2b-256 checksum How to use checksums |
6fffd19d7f2f5705b70cbf0799b940e52fa4c0808eb66f4fdff8b7c22ae428a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|
Release files / vello-0.1.5-cp310-cp310-win_amd64.whl
| Download URL | vello-0.1.5-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 7.8 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
448ad77b85a9793e2c87e63f70e4e865ba7795b18ca4b6570418dc59f9e99d36
|
|
BLAKE2b-256 checksum How to use checksums |
8ad7a2c072bfe4e27f4270c6637dfe594b64d79c5fa072a8089f08e7d534e4a2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|
Release files / vello-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | vello-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
438ee38112b8cb2c6eed0a369e050381700e5968213e78283d7ded0eb66ce4ca
|
|
BLAKE2b-256 checksum How to use checksums |
d5df017eacbf427cafdef36c593666ab8b7d46aa1a78ca2baf3e7190e532789e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.0
|