native

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package native provides a Pure Go GPU-accelerated rendering backend using gogpu/wgpu.

Package native provides a GPU-accelerated rendering backend using gogpu/wgpu.

Package native provides a GPU-accelerated rendering backend using gogpu/wgpu.

Package native provides a GPU-accelerated rendering backend using gogpu/wgpu.

Package native provides a Pure Go GPU-accelerated rendering backend.

This backend leverages WebGPU for hardware-accelerated 2D graphics rendering. It uses the gogpu/wgpu Pure Go WebGPU implementation (zero CGO), which supports Vulkan, Metal, and DX12 backends depending on the platform.

Architecture Overview

The native backend implements a vello-style GPU rendering pipeline:

Scene Commands -> Decoder -> HybridPipeline (Flatten → Coarse → Fine) -> GPU -> Composite

Key components:

  • NativeBackend: Main entry point implementing backend.RenderBackend
  • GPUSceneRenderer: Scene-to-GPU pipeline with HybridPipeline rasterization
  • HybridPipeline: 3-stage path rasterization (Flatten, Coarse, Fine)
  • MemoryManager: GPU texture memory with LRU eviction (configurable budget)
  • TextureAtlas: Shelf-packing for efficient GPU memory usage
  • PipelineCache: Pre-compiled GPU pipelines for all 29 blend modes
  • ShaderModules: WGSL compute shaders for tile rasterization and blending

HybridPipeline (vello-style)

Scene rendering uses a 3-stage tile-based pipeline inspired by Linebender's vello:

  1. Flatten: Bezier curves are flattened to line segments using Wang's formula
  2. Coarse: Line segments are binned into 4×4 pixel tiles with winding info
  3. Fine: Each tile's coverage is computed with anti-aliased edges

The pipeline automatically selects GPU or CPU execution per stage based on workload size. This hybrid approach provides optimal performance across different path complexities.

Example tile data for a circle:

Tile(X=10, Y=5): Coverage[16]=[32, 128, 255, 255, ...]  // 4×4 pixel coverage
Tile(X=11, Y=5): Coverage[16]=[255, 255, 255, 192, ...] // Adjacent tile
... (sparse tiles only where path intersects)

Blend Modes

All 29 standard blend modes are supported via WGSL shaders:

Standard modes:

  • Normal, Multiply, Screen, Overlay
  • Darken, Lighten, ColorDodge, ColorBurn
  • HardLight, SoftLight, Difference, Exclusion

HSL modes:

  • Hue, Saturation, Color, Luminosity

Porter-Duff compositing:

  • Clear, Copy, Destination
  • SourceOver, DestinationOver
  • SourceIn, DestinationIn
  • SourceOut, DestinationOut
  • SourceAtop, DestinationAtop
  • Xor, Plus

Registration and Selection

The native backend is automatically registered when this package is imported:

import _ "github.com/gogpu/gg/backend/native"

The backend will be preferred over the software backend when available. If GPU initialization fails, the system will fall back to software rendering.

Basic Usage

Automatic backend selection (recommended):

b := backend.Default()  // Returns native if available, otherwise software
if err := b.Init(); err != nil {
    log.Fatal(err)
}
defer b.Close()

Explicit native backend selection:

b := backend.Get(backend.BackendNative)
if b == nil {
    log.Fatal("native backend not available")
}
if err := b.Init(); err != nil {
    log.Fatal(err)
}
defer b.Close()

Rendering Scenes

Build and render a scene:

// Create scene using SceneBuilder
builder := scene.NewSceneBuilder()
builder.FillRect(0, 0, 800, 600, scene.SolidBrush(gg.White))
builder.FillCircle(400, 300, 100, scene.SolidBrush(gg.Red))

// Add a blended layer
builder.Layer(scene.BlendMultiply, 0.8, nil, func(lb *scene.SceneBuilder) {
    lb.FillRect(300, 200, 200, 200, scene.SolidBrush(gg.Blue))
})

s := builder.Build()

// Render to pixmap
pm := gg.NewPixmap(800, 600)
if err := b.RenderScene(pm, s); err != nil {
    log.Printf("Render error: %v", err)
}

// Save result
pm.SavePNG("output.png")

Direct Scene Construction

Lower-level scene construction:

s := scene.NewScene()
rect := scene.NewRectShape(10, 10, 80, 80)
s.Fill(scene.FillNonZero, scene.IdentityAffine(), scene.SolidBrush(gg.Red), rect)

circle := scene.NewCircleShape(50, 50, 30)
s.Fill(scene.FillNonZero, scene.TranslateAffine(100, 0), scene.SolidBrush(gg.Blue), circle)

pm := gg.NewPixmap(200, 100)
b.RenderScene(pm, s)

Performance Characteristics

The GPU backend excels at:

  • Large canvases (1080p and above)
  • Many shapes with the same blend mode
  • Complex layer compositing
  • Parallel processing of independent draws

Software backend may be faster for:

  • Small canvases (< 256x256)
  • Single shape renders
  • Frequent GPU-CPU data transfers

Memory Management

The backend uses an LRU-based memory manager with configurable budget:

// Configure via GPUSceneRendererConfig
config := GPUSceneRendererConfig{
    Width:          1920,
    Height:         1080,
    MaxLayers:      16,     // Maximum layer stack depth
    MemoryBudgetMB: 256,    // GPU texture memory budget
}

When memory budget is exceeded, least-recently-used textures are evicted.

Current Status (v0.16.0)

The GPU pipeline uses vello-style HybridPipeline architecture. The following components are fully implemented and tested:

  • HybridPipeline: 3-stage path rasterization (Flatten → Coarse → Fine)
  • Tile-based sparse coverage (4×4 pixel tiles)
  • GPU/CPU automatic selection per stage
  • Fill rule support (NonZero, EvenOdd)
  • Anti-aliased coverage calculation
  • Pipeline cache for all blend modes
  • WGSL compute shaders (flatten.wgsl, coarse.wgsl, fine.wgsl)
  • Memory management with LRU eviction
  • Layer stack management
  • Clip region support

GPU compute shader execution uses CPU fallback until HAL bridge is complete. This will be enabled when core↔HAL device/queue bridge is implemented:

  • HAL device/queue wiring to HybridPipeline
  • Texture readback (for downloading GPU results to CPU)
  • Buffer mapping (for uploading vertex/uniform data)

All data flow through the pipeline is correct and tested.

Requirements

  • Go 1.25+ (for generic features)
  • gogpu/wgpu module (github.com/gogpu/wgpu)
  • A GPU that supports Vulkan, Metal, or DX12 (for actual GPU rendering)

Thread Safety

NativeBackend and GPUSceneRenderer are safe for concurrent use from multiple goroutines. Internal synchronization is handled via mutexes.

Error Handling

Common errors returned by this package:

  • ErrNotInitialized: Backend must be initialized before use
  • ErrNoGPU: No compatible GPU found
  • ErrDeviceLost: GPU device was lost (requires re-initialization)
  • ErrNilTarget: Target pixmap is nil
  • ErrNilScene: Scene is nil
  • ErrRendererClosed: Renderer has been closed
  • ErrEmptyScene: Scene contains no draw commands

Benchmarking

Run benchmarks to compare GPU vs Software performance:

go test -bench=. ./backend/native/...

Key benchmarks:

  • BenchmarkClear1080p: Full canvas clear comparison
  • BenchmarkRect100: 100 rectangles comparison
  • BenchmarkCircle50: Circle rendering comparison
  • BenchmarkLayers4: Layer compositing comparison
  • BenchmarkPipelineCreation: GPU pipeline cache performance
  • github.com/gogpu/gg: Core 2D graphics library
  • github.com/gogpu/gg/scene: Scene graph and retained mode API
  • github.com/gogpu/gg/backend: Backend interface and registry
  • github.com/gogpu/wgpu: Pure Go WebGPU implementation

References

Package wgpu provides GPU-accelerated rendering using WebGPU.

Package wgpu provides GPU-accelerated rendering using WebGPU.

Package wgpu provides GPU-accelerated rendering using WebGPU.

Package native provides a GPU-accelerated rendering backend using gogpu/wgpu.

Package native provides a GPU-accelerated rendering backend using gogpu/wgpu.

Package wgpu provides GPU-accelerated rendering backend using WebGPU.

Package wgpu provides GPU-accelerated rendering using WebGPU.

Package native provides a GPU-accelerated rendering backend using gogpu/wgpu.

Index

Constants

View Source
const (
	// DefaultAtlasSize is the default atlas dimension (2048x2048).
	DefaultAtlasSize = 2048

	// MinAtlasSize is the minimum atlas dimension (256x256).
	MinAtlasSize = 256

	// DefaultShelfPadding is the padding between shelves.
	DefaultShelfPadding = 1
)

Default atlas settings.

View Source
const (
	// FDot6One is 1.0 in FDot6 representation (2^6 = 64).
	FDot6One FDot6 = 64

	// FDot6Half is 0.5 in FDot6 representation (2^5 = 32).
	FDot6Half FDot6 = 32

	// FDot6Shift is the number of fractional bits in FDot6.
	FDot6Shift = 6

	// FDot6Mask is the mask for the fractional part of FDot6.
	FDot6Mask = FDot6One - 1
)

Fixed-point constants for FDot6.

View Source
const (
	// FDot16One is 1.0 in FDot16 representation (2^16 = 65536).
	FDot16One FDot16 = 1 << 16

	// FDot16Half is 0.5 in FDot16 representation (2^15 = 32768).
	FDot16Half FDot16 = 1 << 15

	// FDot16Shift is the number of fractional bits in FDot16.
	FDot16Shift = 16

	// FDot16Mask is the mask for the fractional part of FDot16.
	FDot16Mask = FDot16One - 1
)

Fixed-point constants for FDot16.

View Source
const (
	// DefaultMaxMemoryMB is the default maximum GPU memory budget (256 MB).
	DefaultMaxMemoryMB = 256

	// DefaultEvictionThreshold is when eviction starts (80% of budget).
	DefaultEvictionThreshold = 0.8

	// MinMemoryMB is the minimum allowed memory budget (16 MB).
	MinMemoryMB = 16
)

Default memory limits.

View Source
const (
	// Standard blend modes (0-11)
	ShaderBlendNormal     uint32 = 0
	ShaderBlendMultiply   uint32 = 1
	ShaderBlendScreen     uint32 = 2
	ShaderBlendOverlay    uint32 = 3
	ShaderBlendDarken     uint32 = 4
	ShaderBlendLighten    uint32 = 5
	ShaderBlendColorDodge uint32 = 6
	ShaderBlendColorBurn  uint32 = 7
	ShaderBlendHardLight  uint32 = 8
	ShaderBlendSoftLight  uint32 = 9
	ShaderBlendDifference uint32 = 10
	ShaderBlendExclusion  uint32 = 11

	// HSL blend modes (12-15)
	ShaderBlendHue        uint32 = 12
	ShaderBlendSaturation uint32 = 13
	ShaderBlendColor      uint32 = 14
	ShaderBlendLuminosity uint32 = 15

	// Porter-Duff modes (16-28)
	ShaderBlendClear           uint32 = 16
	ShaderBlendCopy            uint32 = 17
	ShaderBlendDestination     uint32 = 18
	ShaderBlendSourceOver      uint32 = 19
	ShaderBlendDestinationOver uint32 = 20
	ShaderBlendSourceIn        uint32 = 21
	ShaderBlendDestinationIn   uint32 = 22
	ShaderBlendSourceOut       uint32 = 23
	ShaderBlendDestinationOut  uint32 = 24
	ShaderBlendSourceAtop      uint32 = 25
	ShaderBlendDestinationAtop uint32 = 26
	ShaderBlendXor             uint32 = 27
	ShaderBlendPlus            uint32 = 28
)

Blend mode constants matching scene.BlendMode values. These are used for GPU shader uniform values.

View Source
const DefaultCoarseThreshold = 100

DefaultCoarseThreshold is the minimum segments for GPU coarse rasterization.

View Source
const DefaultFineThreshold = 100

DefaultFineThreshold is the minimum tile entries for GPU fine rasterization.

View Source
const DefaultFlattenThreshold = 50

DefaultFlattenThreshold is the minimum path elements for GPU flattening.

View Source
const DefaultGPUSegmentThreshold = 100

DefaultGPUSegmentThreshold is the minimum number of segments to use GPU. Below this threshold, CPU is typically faster due to GPU dispatch overhead.

DefaultTextureUsage is the default usage for textures created without specific flags.

View Source
const FlattenMaxSegmentsPerCurve = 64

FlattenMaxSegmentsPerCurve is the maximum segments generated per curve.

View Source
const FlattenTolerance = 0.25

FlattenTolerance is the default tolerance for curve flattening. Smaller values produce more accurate curves but more segments.

View Source
const MaxCoeffShift = 6

MaxCoeffShift limits the number of subdivisions for a curve. We store 1<<shift in a signed byte (int8), so max value is 1<<6 = 64. This limits the number of line segments per curve.

View Source
const TileHeight = TileSize

TileHeight is the height of a tile in pixels (matches TileSize).

View Source
const TileMask = TileSize - 1

TileMask is TileSize - 1 for efficient modulo.

View Source
const TileShift = 2

TileShift is log2(TileSize) for efficient division.

View Source
const TileSize = 4

TileSize is the width and height of a tile in pixels. 4×4 is optimal for cache efficiency and SIMD processing.

View Source
const TileWidth = TileSize

TileWidth is the width of a tile in pixels (matches TileSize).

Variables

View Source
var (
	// ErrAtlasFull is returned when the atlas cannot fit the requested region.
	ErrAtlasFull = errors.New("wgpu: texture atlas is full")

	// ErrAtlasClosed is returned when operating on a closed atlas.
	ErrAtlasClosed = errors.New("wgpu: texture atlas is closed")

	// ErrRegionOutOfBounds is returned when a region is outside atlas bounds.
	ErrRegionOutOfBounds = errors.New("wgpu: region is outside atlas bounds")
)

Atlas-related errors.

View Source
var (
	// ErrBufferDestroyed is returned when operating on a destroyed buffer.
	ErrBufferDestroyed = errors.New("native: buffer has been destroyed")

	// ErrNilBuffer is returned when creating operations without a buffer.
	ErrNilBuffer = errors.New("native: buffer is nil")

	// ErrInvalidBufferSize is returned when buffer size is invalid.
	ErrInvalidBufferSize = errors.New("native: invalid buffer size")

	// ErrBufferAlreadyMapped is returned when attempting to map an already mapped buffer.
	ErrBufferAlreadyMapped = errors.New("native: buffer is already mapped or mapping is pending")

	// ErrBufferNotMapped is returned when attempting to access unmapped buffer data.
	ErrBufferNotMapped = errors.New("native: buffer is not mapped")

	// ErrBufferMapPending is returned when accessing a buffer with pending map operation.
	ErrBufferMapPending = errors.New("native: buffer mapping is pending")

	// ErrInvalidMapMode is returned when mapping with an invalid mode.
	ErrInvalidMapMode = errors.New("native: invalid map mode")

	// ErrInvalidMapRange is returned when the map range is out of bounds.
	ErrInvalidMapRange = errors.New("native: map range out of bounds")

	// ErrMapUsageMismatch is returned when mapping mode doesn't match buffer usage.
	ErrMapUsageMismatch = errors.New("native: map mode does not match buffer usage flags")

	// ErrMappingFailed is returned when buffer mapping fails.
	ErrMappingFailed = errors.New("native: buffer mapping failed")

	// ErrCallbackNil is returned when MapAsync is called with nil callback.
	ErrCallbackNil = errors.New("native: map callback is nil")
)

Buffer errors.

View Source
var (
	// ErrEncoderNotRecording is returned when recording operations are called
	// on an encoder that is not in the Recording state.
	ErrEncoderNotRecording = errors.New("native: encoder not in recording state")

	// ErrEncoderLocked is returned when operations are called on an encoder
	// that is locked (a pass is in progress).
	ErrEncoderLocked = errors.New("native: encoder is locked (pass in progress)")

	// ErrEncoderFinished is returned when operations are called on an encoder
	// that has already been finished.
	ErrEncoderFinished = errors.New("native: encoder already finished")

	// ErrEncoderConsumed is returned when operations are called on an encoder
	// that has been submitted to the queue.
	ErrEncoderConsumed = errors.New("native: encoder has been consumed")

	// ErrNilDevice is returned when creating an encoder without a device.
	ErrNilDevice = errors.New("native: device is nil")

	// ErrNilEncoder is returned when operations reference a nil encoder.
	ErrNilEncoder = errors.New("native: command encoder is nil")

	// ErrNilCoreBuffer is returned when a buffer operation references nil.
	ErrNilCoreBuffer = errors.New("native: core buffer is nil")

	// ErrCopyRangeOutOfBounds is returned when a copy operation exceeds buffer bounds.
	ErrCopyRangeOutOfBounds = errors.New("native: copy range out of bounds")

	// ErrCopyOverlap is returned when source and destination buffers overlap.
	ErrCopyOverlap = errors.New("native: source and destination buffers overlap")

	// ErrCopyOffsetNotAligned is returned when offset is not properly aligned.
	ErrCopyOffsetNotAligned = errors.New("native: copy offset must be 4-byte aligned")

	// ErrCopySizeNotAligned is returned when size is not properly aligned.
	ErrCopySizeNotAligned = errors.New("native: copy size must be 4-byte aligned")
)

Command encoder errors.

View Source
var (
	// ErrComputePassEnded is returned when operations are called on an ended compute pass.
	ErrComputePassEnded = errors.New("native: compute pass has already ended")

	// ErrComputePassNotRecording is returned when operations are called on a pass not recording.
	ErrComputePassNotRecording = errors.New("native: compute pass is not recording")

	// ErrNilComputePipeline is returned when SetPipeline is called with nil.
	ErrNilComputePipeline = errors.New("native: compute pipeline is nil")

	// ErrNilComputeBindGroup is returned when SetBindGroup is called with nil.
	ErrNilComputeBindGroup = errors.New("native: bind group is nil")

	// ErrComputeBindGroupIndexOutOfRange is returned when bind group index exceeds maximum.
	ErrComputeBindGroupIndexOutOfRange = errors.New("native: bind group index exceeds maximum (3)")

	// ErrNilDispatchBuffer is returned when DispatchIndirect is called with nil buffer.
	ErrNilDispatchBuffer = errors.New("native: dispatch indirect buffer is nil")

	// ErrDispatchOffsetNotAligned is returned when dispatch offset is not 4-byte aligned.
	ErrDispatchOffsetNotAligned = errors.New("native: dispatch offset must be 4-byte aligned")

	// ErrWorkgroupCountZero is returned when any workgroup dimension is zero.
	ErrWorkgroupCountZero = errors.New("native: workgroup count must be greater than zero")

	// ErrWorkgroupCountExceedsLimit is returned when workgroup count exceeds device limits.
	ErrWorkgroupCountExceedsLimit = errors.New("native: workgroup count exceeds device limit")
)

Compute pass errors.

View Source
var (
	// ErrNotInitialized is returned when operations are called before Init.
	ErrNotInitialized = errors.New("wgpu: backend not initialized")

	// ErrNoGPU is returned when no GPU adapter is available.
	ErrNoGPU = errors.New("wgpu: no GPU adapter available")

	// ErrDeviceLost is returned when the GPU device is lost.
	ErrDeviceLost = errors.New("wgpu: GPU device lost")

	// ErrNotImplemented is returned for stub operations not yet implemented.
	ErrNotImplemented = errors.New("wgpu: operation not implemented")

	// ErrInvalidDimensions is returned when width or height is invalid.
	ErrInvalidDimensions = errors.New("wgpu: invalid dimensions")

	// ErrNilTarget is returned when target pixmap is nil.
	ErrNilTarget = errors.New("wgpu: nil target pixmap")

	// ErrNilScene is returned when scene is nil.
	ErrNilScene = errors.New("wgpu: nil scene")
)

Package errors for wgpu backend.

View Source
var (
	// ErrTextureReleased is returned when operating on a released texture.
	ErrTextureReleased = errors.New("wgpu: texture has been released")

	// ErrTextureSizeMismatch is returned when pixmap size doesn't match texture.
	ErrTextureSizeMismatch = errors.New("wgpu: pixmap size does not match texture")

	// ErrNilPixmap is returned when pixmap is nil.
	ErrNilPixmap = errors.New("wgpu: pixmap is nil")

	// ErrTextureReadbackNotSupported is returned when readback is not available.
	ErrTextureReadbackNotSupported = errors.New("wgpu: texture readback not supported (stub)")
)

Texture-related errors.

View Source
var (
	// ErrMemoryBudgetExceeded is returned when allocation would exceed budget.
	ErrMemoryBudgetExceeded = errors.New("wgpu: memory budget exceeded")

	// ErrMemoryManagerClosed is returned when operating on a closed manager.
	ErrMemoryManagerClosed = errors.New("wgpu: memory manager closed")

	// ErrTextureNotFound is returned when a texture is not found in the manager.
	ErrTextureNotFound = errors.New("wgpu: texture not found in manager")
)

Memory management errors.

View Source
var (
	// ErrPipelineCacheNilDevice is returned when creating a cache without a device.
	ErrPipelineCacheNilDevice = errors.New("native: device is nil")

	// ErrPipelineCacheNilDescriptor is returned when creating a pipeline with nil descriptor.
	ErrPipelineCacheNilDescriptor = errors.New("native: pipeline descriptor is nil")

	// ErrPipelineCacheNilShader is returned when creating a pipeline with nil shader module.
	ErrPipelineCacheNilShader = errors.New("native: shader module is nil")
)

Pipeline cache errors.

View Source
var (
	// ErrPassEnded is returned when operations are called on an ended pass.
	ErrPassEnded = errors.New("native: render pass has already ended")

	// ErrPassNotRecording is returned when operations are called on a pass that is not recording.
	ErrPassNotRecording = errors.New("native: render pass is not recording")

	// ErrNilPipeline is returned when SetPipeline is called with nil.
	ErrNilPipeline = errors.New("native: pipeline is nil")

	// ErrNilBindGroup is returned when SetBindGroup is called with nil.
	ErrNilBindGroup = errors.New("native: bind group is nil")

	// ErrBindGroupIndexOutOfRange is returned when bind group index exceeds maximum.
	ErrBindGroupIndexOutOfRange = errors.New("native: bind group index exceeds maximum (3)")

	// ErrNilVertexBuffer is returned when SetVertexBuffer is called with nil.
	ErrNilVertexBuffer = errors.New("native: vertex buffer is nil")

	// ErrNilIndexBuffer is returned when SetIndexBuffer is called with nil.
	ErrNilIndexBuffer = errors.New("native: index buffer is nil")

	// ErrNilIndirectBuffer is returned when indirect draw is called with nil buffer.
	ErrNilIndirectBuffer = errors.New("native: indirect buffer is nil")

	// ErrIndirectOffsetNotAligned is returned when indirect offset is not 4-byte aligned.
	ErrIndirectOffsetNotAligned = errors.New("native: indirect offset must be 4-byte aligned")
)

Render pass errors.

View Source
var (
	// ErrRendererClosed is returned when operating on a closed renderer.
	ErrRendererClosed = errors.New("wgpu: renderer closed")

	// ErrEmptyScene is returned when rendering an empty scene.
	ErrEmptyScene = errors.New("wgpu: empty scene")

	// ErrLayerStackUnderflow is returned when popping more layers than pushed.
	ErrLayerStackUnderflow = errors.New("wgpu: layer stack underflow")
)

Renderer-specific errors.

View Source
var (
	// ErrNilTextPipeline is returned when operating on a nil pipeline.
	ErrNilTextPipeline = errors.New("wgpu: text pipeline is nil")

	// ErrTextPipelineNotInitialized is returned when pipeline is not initialized.
	ErrTextPipelineNotInitialized = errors.New("wgpu: text pipeline not initialized")

	// ErrNoQuadsToRender is returned when RenderText is called with empty quads.
	ErrNoQuadsToRender = errors.New("wgpu: no quads to render")

	// ErrQuadBufferOverflow is returned when too many quads are submitted.
	ErrQuadBufferOverflow = errors.New("wgpu: quad buffer overflow")

	// ErrInvalidAtlasIndex is returned when referencing invalid atlas.
	ErrInvalidAtlasIndex = errors.New("wgpu: invalid atlas index")
)

Text rendering errors.

View Source
var (
	// ErrTextureDestroyed is returned when operating on a destroyed texture.
	ErrTextureDestroyed = errors.New("native: texture has been destroyed")

	// ErrTextureViewDestroyed is returned when operating on a destroyed texture view.
	ErrTextureViewDestroyed = errors.New("native: texture view has been destroyed")

	// ErrNilHALDevice is returned when creating a texture without a device.
	ErrNilHALDevice = errors.New("native: device is nil")

	// ErrNilTexture is returned when creating a view without a texture.
	ErrNilTexture = errors.New("native: texture is nil")

	// ErrInvalidTextureSize is returned when texture dimensions are invalid.
	ErrInvalidTextureSize = errors.New("native: invalid texture size")

	// ErrDefaultViewCreationFailed is returned when lazy default view creation fails.
	ErrDefaultViewCreationFailed = errors.New("native: failed to create default view")
)

Texture errors.

View Source
var ErrNilBackend = errors.New("wgpu: backend is nil")

ErrNilBackend is returned when backend is nil.

Functions

func BlendModeToShader

func BlendModeToShader(mode scene.BlendMode) uint32

BlendModeToShader converts a scene.BlendMode to the shader constant value. The values are designed to match directly, so this is primarily for type safety.

func BlendTileSIMD

func BlendTileSIMD(
	buffer []uint8,
	bufferStride int,
	baseX, baseY int,
	coverage *TileCoverage16,
	color [4]uint8,
)

BlendTileSIMD performs alpha blending for a 4×4 tile using SIMD. Uses U16x16 for processing all 16 pixels at once.

func CheckDeviceLimits

func CheckDeviceLimits(deviceID core.DeviceID) error

CheckDeviceLimits verifies that the device meets minimum requirements. This can be used to validate GPU capabilities before rendering.

func CheckGPUComputeSupport

func CheckGPUComputeSupport(device hal.Device) bool

CheckGPUComputeSupport checks if GPU compute shaders are supported. This can be used to determine if GPU rasterization is viable before creating a rasterizer.

func ChopCubicAtYExtrema added in v0.20.2

func ChopCubicAtYExtrema(src [4]GeomPoint, dst *[10]GeomPoint) int

ChopCubicAtYExtrema chops a cubic Bezier at its Y extrema (if any).

A cubic Bezier can have up to 2 Y extrema. This function splits the curve at all extrema to produce 1-3 monotonic cubic segments.

Parameters:

  • src: 4 control points [p0, p1, p2, p3]
  • dst: output array, must have capacity for 10 points

Returns:

  • number of chops (0, 1, or 2)
  • 0 means dst[0..4] contains the original (already monotonic)
  • 1 means dst[0..4] and dst[3..7] are two monotonic cubics
  • 2 means dst[0..4], dst[3..7], and dst[6..10] are three monotonic cubics

func ChopQuadAtYExtrema added in v0.20.2

func ChopQuadAtYExtrema(src [3]GeomPoint, dst *[5]GeomPoint) int

ChopQuadAtYExtrema chops a quadratic Bezier at its Y extremum (if any).

A quadratic Bezier can have at most one Y extremum. If the curve is not monotonic in Y, this function splits it at the extremum point.

Parameters:

  • src: 3 control points [p0, p1, p2]
  • dst: output array, must have capacity for 5 points

Returns:

  • number of chops (0 or 1)
  • 0 means dst[0..3] contains the original (already monotonic)
  • 1 means dst[0..3] and dst[2..5] are two monotonic quads

The control points are structured as:

  • dst[0] = first quad start
  • dst[1] = first quad control
  • dst[2] = first quad end = second quad start (shared)
  • dst[3] = second quad control
  • dst[4] = second quad end

func CompileShaderToSPIRV

func CompileShaderToSPIRV(wgslSource string) ([]uint32, error)

CompileShaderToSPIRV compiles WGSL source to SPIR-V uint32 slice. This is the common shader compilation logic used by all GPU rasterizers.

func CreateShaderModule

func CreateShaderModule(device hal.Device, label string, spirvCode []uint32) (hal.ShaderModule, error)

CreateShaderModule creates a HAL shader module from SPIR-V code.

func CubicIsYMonotonic added in v0.20.2

func CubicIsYMonotonic(p0, p1, p2, p3 GeomPoint) bool

CubicIsYMonotonic returns true if the cubic is monotonic in Y. A cubic is Y-monotonic if it has no Y extrema in (0, 1).

func FDot6CanConvertToFDot16 added in v0.20.2

func FDot6CanConvertToFDot16(v FDot6) bool

FDot6CanConvertToFDot16 returns true if the FDot6 value can be converted to FDot16 without overflow.

func FDot6Ceil added in v0.20.2

func FDot6Ceil(v FDot6) int32

FDot6Ceil returns the ceiling of an FDot6.

func FDot6Floor added in v0.20.2

func FDot6Floor(v FDot6) int32

FDot6Floor returns the integer part (floor) of an FDot6.

func FDot6Round added in v0.20.2

func FDot6Round(v FDot6) int32

FDot6Round returns the nearest integer to an FDot6.

func FDot6SmallScale added in v0.20.2

func FDot6SmallScale(value uint8, dot6 FDot6) uint8

FDot6SmallScale scales a byte value by an FDot6 factor (0 to 64). Used for alpha blending calculations.

func FDot6ToFloat32 added in v0.20.2

func FDot6ToFloat32(v FDot6) float32

FDot6ToFloat32 converts an FDot6 to float32.

func FDot6ToFloat64 added in v0.20.2

func FDot6ToFloat64(v FDot6) float64

FDot6ToFloat64 converts an FDot6 to float64.

func FDot6UpShift added in v0.20.2

func FDot6UpShift(v FDot6, upShift int) int32

FDot6UpShift performs a left shift on an FDot6 value. Used in cubic edge coefficient computation.

func FDot16CeilToInt added in v0.20.2

func FDot16CeilToInt(v FDot16) int32

FDot16CeilToInt returns the ceiling of an FDot16.

func FDot16FloorToInt added in v0.20.2

func FDot16FloorToInt(v FDot16) int32

FDot16FloorToInt returns the integer part (floor) of an FDot16.

func FDot16RoundToInt added in v0.20.2

func FDot16RoundToInt(v FDot16) int32

FDot16RoundToInt returns the nearest integer to an FDot16.

func FDot16ToFloat32 added in v0.20.2

func FDot16ToFloat32(v FDot16) float32

FDot16ToFloat32 converts an FDot16 to float32.

func FDot16ToFloat64 added in v0.20.2

func FDot16ToFloat64(v FDot16) float64

FDot16ToFloat64 converts an FDot16 to float64.

func FillPath added in v0.20.2

func FillPath(
	eb *EdgeBuilder,
	width, height int,
	fillRule FillRule,
	callback func(y int, runs *AlphaRuns),
)

FillPath is a convenience function that creates a filler and fills a path. For repeated fills, create a filler once and reuse it.

func FillRuleToGPU

func FillRuleToGPU(rule scene.FillStyle) uint32

FillRuleToGPU converts scene.FillStyle to GPU constant.

func FillToBuffer added in v0.20.2

func FillToBuffer(
	eb *EdgeBuilder,
	width, height int,
	fillRule FillRule,
	buffer []uint8,
)

FillToBuffer fills a path and writes coverage to a buffer. The buffer must have width * height elements. Coverage values are written as 0-255 alpha values.

func FinalizeTileSIMD

func FinalizeTileSIMD(
	tileWinding *TileWinding16,
	coverage *TileCoverage16,
	fillRule scene.FillStyle,
)

FinalizeTileSIMD converts winding values to coverage using SIMD. Supports both NonZero and EvenOdd fill rules.

func GetBlendShaderSource

func GetBlendShaderSource() string

GetBlendShaderSource returns the WGSL source for the blend shader.

func GetBlitShaderSource

func GetBlitShaderSource() string

GetBlitShaderSource returns the WGSL source for the blit shader.

func GetCompositeShaderSource

func GetCompositeShaderSource() string

GetCompositeShaderSource returns the WGSL source for the composite shader.

func GetMSDFTextShaderSource

func GetMSDFTextShaderSource() string

GetMSDFTextShaderSource returns the WGSL source for the MSDF text shader.

func GetStripShaderSource

func GetStripShaderSource() string

GetStripShaderSource returns the WGSL source for the strip shader.

func HashComputePipelineDescriptor added in v0.20.0

func HashComputePipelineDescriptor(desc *ComputePipelineDescriptor) uint64

HashComputePipelineDescriptor computes an FNV-1a hash for a compute pipeline descriptor.

func HashRenderPipelineDescriptor added in v0.20.0

func HashRenderPipelineDescriptor(desc *RenderPipelineDescriptor) uint64

HashRenderPipelineDescriptor computes an FNV-1a hash for a render pipeline descriptor.

The hash includes all fields that affect rendering behavior:

  • Shader modules and entry points
  • Vertex buffer layouts and attributes
  • Primitive topology and rasterization state
  • Color and depth formats
  • Blend state
  • Sample count

func InitTileWindingSIMD

func InitTileWindingSIMD(tileWinding *TileWinding16, backdrop float32)

InitTileWindingSIMD initializes tile winding from backdrop using SIMD.

func PixelToTile

func PixelToTile(px, py int32) (tx, ty int32)

PixelToTile converts pixel coordinates to tile coordinates. Uses arithmetic shift which provides floor division for negative numbers.

func PixelToTileF

func PixelToTileF(px, py float32) (tx, ty int32)

PixelToTileF converts float pixel coordinates to tile coordinates. Uses floor semantics for correct handling of negative coordinates.

func ProcessSegmentSIMD

func ProcessSegmentSIMD(
	line LineSegment,
	tileX, tileY uint16,
	tileWinding *TileWinding16,
)

ProcessSegmentSIMD processes a line segment's contribution to a tile using SIMD. This is a vectorized version of processSegment for the FineRasterizer.

func QuadIsYMonotonic added in v0.20.2

func QuadIsYMonotonic(p0, p1, p2 GeomPoint) bool

QuadIsYMonotonic returns true if the quadratic is monotonic in Y. A quadratic is Y-monotonic if its control point's Y is between the endpoints' Y values. This is more permissive than isNotMonotonic to handle curves flattened at extrema.

func ShaderToBlendMode

func ShaderToBlendMode(shaderMode uint32) scene.BlendMode

ShaderToBlendMode converts a shader blend mode constant to scene.BlendMode.

func ValidateBlendModeMapping

func ValidateBlendModeMapping() error

ValidateBlendModeMapping verifies that shader constants match scene.BlendMode values. Returns an error if any mismatch is found.

Types

type ActiveEdge

type ActiveEdge struct {
	Edge *Edge
	X    float32 // Current X position at current scanline
}

ActiveEdge holds an edge with its current X position.

type ActiveEdgeTable

type ActiveEdgeTable struct {
	// contains filtered or unexported fields
}

ActiveEdgeTable manages active edges during scanline conversion.

func NewActiveEdgeTable

func NewActiveEdgeTable() *ActiveEdgeTable

NewActiveEdgeTable creates a new active edge table.

func (*ActiveEdgeTable) Active

func (aet *ActiveEdgeTable) Active() []ActiveEdge

Active returns the list of active edges for iteration.

func (*ActiveEdgeTable) InsertEdge

func (aet *ActiveEdgeTable) InsertEdge(e *Edge, y float32)

InsertEdge adds an edge to the active list.

func (*ActiveEdgeTable) Len

func (aet *ActiveEdgeTable) Len() int

Len returns the number of active edges.

func (*ActiveEdgeTable) RemoveExpired

func (aet *ActiveEdgeTable) RemoveExpired(y float32)

RemoveExpired removes edges that end at or before the given Y.

func (*ActiveEdgeTable) Reset

func (aet *ActiveEdgeTable) Reset()

Reset clears the active edge table.

func (*ActiveEdgeTable) SortByX

func (aet *ActiveEdgeTable) SortByX()

SortByX sorts active edges by their current X position.

func (*ActiveEdgeTable) UpdateX

func (aet *ActiveEdgeTable) UpdateX(y float32)

UpdateX updates X positions for all active edges at the new Y.

type AlphaRuns added in v0.20.2

type AlphaRuns struct {
	// contains filtered or unexported fields
}

AlphaRuns provides run-length-encoded (RLE) storage for coverage values.

This is efficient for paths with long horizontal spans of constant coverage. Instead of storing per-pixel alpha values, it stores runs of consecutive pixels with the same alpha.

The implementation follows tiny-skia's alpha_runs.rs pattern but with Go 1.25+ iterators for efficient traversal.

Usage:

ar := NewAlphaRuns(width)
ar.Reset()
ar.Add(10, 128, 20, 128) // Add coverage from x=10, 20 pixels wide
for x, alpha := range ar.Iter() {
    // Process pixel at x with alpha value
}

func NewAlphaRuns added in v0.20.2

func NewAlphaRuns(width int) *AlphaRuns

NewAlphaRuns creates a new AlphaRuns buffer for the given width.

func (*AlphaRuns) Add added in v0.20.2

func (ar *AlphaRuns) Add(x int, startAlpha uint8, middleCount int, endAlpha uint8)

Add inserts coverage into the buffer.

Parameters:

  • x: starting x coordinate
  • startAlpha: alpha for first pixel (fractional left edge)
  • middleCount: number of full-coverage pixels
  • endAlpha: alpha for last pixel (fractional right edge)

The method accumulates coverage - multiple Add calls can contribute to the same pixels. This is essential for correct winding rule handling.

func (*AlphaRuns) AddWithCoverage added in v0.20.2

func (ar *AlphaRuns) AddWithCoverage(x int, startAlpha uint8, middleCount int, endAlpha uint8, maxValue uint8)

AddWithCoverage inserts coverage with a specified maximum value. This is useful when the coverage itself represents partial opacity.

func (*AlphaRuns) Clear added in v0.20.2

func (ar *AlphaRuns) Clear()

Clear sets all alpha values to zero and resets to a single run.

func (*AlphaRuns) CopyTo added in v0.20.2

func (ar *AlphaRuns) CopyTo(dst []uint8)

CopyTo copies the coverage values to a destination slice. The destination must have at least ar.width elements.

func (*AlphaRuns) GetAlpha added in v0.20.2

func (ar *AlphaRuns) GetAlpha(x int) uint8

GetAlpha returns the alpha value at position x. Returns 0 if x is out of bounds.

func (*AlphaRuns) IsEmpty added in v0.20.2

func (ar *AlphaRuns) IsEmpty() bool

IsEmpty returns true if the scanline contains only a single run of alpha 0.

func (*AlphaRuns) Iter added in v0.20.2

func (ar *AlphaRuns) Iter() iter.Seq2[int, uint8]

Iter returns an iterator over all runs with non-zero alpha. Each iteration yields the X position and alpha value. This uses Go 1.25+ iter.Seq2 for efficient iteration.

func (*AlphaRuns) IterRuns added in v0.20.2

func (ar *AlphaRuns) IterRuns() iter.Seq[alphaRun]

IterRuns returns an iterator over runs (not individual pixels). More efficient when processing entire runs at once.

func (*AlphaRuns) Reset added in v0.20.2

func (ar *AlphaRuns) Reset()

Reset reinitializes the buffer for a new scanline. This is O(1) - it doesn't clear the entire buffer.

func (*AlphaRuns) SetOffset added in v0.20.2

func (ar *AlphaRuns) SetOffset(offset int)

SetOffset sets the offset for the next Add call. Use 0 when starting a new scanline.

func (*AlphaRuns) Width added in v0.20.2

func (ar *AlphaRuns) Width() int

Width returns the scanline width.

type AnalyticFiller added in v0.20.2

type AnalyticFiller struct {
	// contains filtered or unexported fields
}

AnalyticFiller computes per-pixel coverage using exact geometric calculations.

Unlike supersampling approaches that sample multiple points per pixel, analytic AA computes the exact area of the shape within each pixel using trapezoidal integration. This provides higher quality anti-aliasing with no supersampling overhead.

The algorithm is based on vello's CPU fine rasterizer (fine.rs), which uses the following approach:

  1. For each edge crossing a pixel row, compute the Y range it covers
  2. Find the X intersections at the top and bottom of the pixel
  3. Compute the trapezoidal area within the pixel bounds
  4. Accumulate coverage based on winding direction

Usage:

filler := NewAnalyticFiller(width, height)
filler.Fill(edgeBuilder, FillRuleNonZero, func(y int, runs *AlphaRuns) {
    // Blend alpha runs to the destination row
})

func NewAnalyticFiller added in v0.20.2

func NewAnalyticFiller(width, height int) *AnalyticFiller

NewAnalyticFiller creates a new analytic filler for the given dimensions.

func (*AnalyticFiller) AlphaRuns added in v0.20.2

func (af *AnalyticFiller) AlphaRuns() *AlphaRuns

AlphaRuns returns the alpha runs for the last processed scanline.

func (*AnalyticFiller) Coverage added in v0.20.2

func (af *AnalyticFiller) Coverage() []float32

Coverage returns the raw coverage buffer for the last processed scanline. Values are in [0, 1] range. The buffer is reused between scanlines.

func (*AnalyticFiller) Fill added in v0.20.2

func (af *AnalyticFiller) Fill(
	eb *EdgeBuilder,
	fillRule FillRule,
	callback func(y int, runs *AlphaRuns),
)

Fill renders a path using analytic coverage calculation.

Parameters:

  • eb: EdgeBuilder containing the path edges
  • fillRule: NonZero or EvenOdd fill rule
  • callback: called for each scanline with the alpha runs

The callback receives the Y coordinate and AlphaRuns for that scanline. The caller is responsible for blending the runs to the destination.

func (*AnalyticFiller) Height added in v0.20.2

func (af *AnalyticFiller) Height() int

Height returns the filler height.

func (*AnalyticFiller) Reset added in v0.20.2

func (af *AnalyticFiller) Reset()

Reset clears the filler state for reuse.

func (*AnalyticFiller) Width added in v0.20.2

func (af *AnalyticFiller) Width() int

Width returns the filler width.

type AnalyticFillerAdapter added in v0.20.2

type AnalyticFillerAdapter struct {
	// contains filtered or unexported fields
}

AnalyticFillerAdapter adapts the core.AnalyticFiller to gg.AnalyticFillerInterface. This allows the SoftwareRenderer to use analytic anti-aliasing without creating an import cycle.

Usage:

renderer := gg.NewSoftwareRenderer(800, 600)
adapter := native.NewAnalyticFillerAdapter(800, 600)
renderer.SetAnalyticFiller(adapter)

func NewAnalyticFillerAdapter added in v0.20.2

func NewAnalyticFillerAdapter(width, height int) *AnalyticFillerAdapter

NewAnalyticFillerAdapter creates a new adapter for analytic anti-aliasing. Parameters:

  • width, height: the dimensions of the rendering surface

The adapter is reusable for multiple Fill calls.

func (*AnalyticFillerAdapter) Fill added in v0.20.2

func (a *AnalyticFillerAdapter) Fill(
	path *gg.Path,
	fillRule gg.FillRule,
	callback func(y int, iter func(yield func(x int, alpha uint8) bool)),
)

Fill renders the path using analytic coverage calculation. This implements gg.AnalyticFillerInterface.

func (*AnalyticFillerAdapter) Reset added in v0.20.2

func (a *AnalyticFillerAdapter) Reset()

Reset clears the adapter state for reuse. This implements gg.AnalyticFillerInterface.

type AtlasRegion

type AtlasRegion struct {
	// X is the left edge of the region.
	X int
	// Y is the top edge of the region.
	Y int
	// Width is the region width.
	Width int
	// Height is the region height.
	Height int
}

AtlasRegion represents a rectangular region in a texture atlas.

func (AtlasRegion) Contains

func (r AtlasRegion) Contains(x, y int) bool

Contains returns true if the point (x, y) is inside the region.

func (AtlasRegion) IsValid

func (r AtlasRegion) IsValid() bool

IsValid returns true if the region has valid dimensions.

func (AtlasRegion) String

func (r AtlasRegion) String() string

String returns a string representation of the region.

type BindGroup added in v0.20.0

type BindGroup struct {
	// contains filtered or unexported fields
}

BindGroup represents a collection of resources bound together.

Bind groups contain:

  • Uniform buffers
  • Storage buffers
  • Texture bindings
  • Sampler bindings

BindGroup is a placeholder type that will be expanded when bind group creation is implemented.

func (*BindGroup) Destroy added in v0.20.0

func (bg *BindGroup) Destroy()

Destroy releases the bind group resources.

func (*BindGroup) ID added in v0.20.0

func (bg *BindGroup) ID() uint64

ID returns the bind group's unique identifier.

func (*BindGroup) IsDestroyed added in v0.20.0

func (bg *BindGroup) IsDestroyed() bool

IsDestroyed returns true if the bind group has been destroyed.

func (*BindGroup) Label added in v0.20.0

func (bg *BindGroup) Label() string

Label returns the bind group's debug label.

type BindGroupBuilder

type BindGroupBuilder struct {
	// contains filtered or unexported fields
}

BindGroupBuilder helps construct bind groups for rendering.

func NewBindGroupBuilder

func NewBindGroupBuilder(device core.DeviceID, layout StubBindGroupLayoutID) *BindGroupBuilder

NewBindGroupBuilder creates a new bind group builder.

func (*BindGroupBuilder) Build

func (b *BindGroupBuilder) Build() StubBindGroupID

Build creates the bind group. Currently returns a stub.

type BlendComponent added in v0.20.0

type BlendComponent struct {
	// SrcFactor is the source blend factor.
	SrcFactor types.BlendFactor

	// DstFactor is the destination blend factor.
	DstFactor types.BlendFactor

	// Operation is the blend operation.
	Operation types.BlendOperation
}

BlendComponent describes a blend component (color or alpha).

type BlendParams

type BlendParams struct {
	Mode    uint32  // Blend mode enum value
	Alpha   float32 // Layer opacity (0.0 - 1.0)
	Padding [2]float32
}

BlendParams represents the uniform buffer structure for blend shaders. This matches the BlendParams struct in blend.wgsl.

type BlendState added in v0.20.0

type BlendState struct {
	// Color is the color blending configuration.
	Color BlendComponent

	// Alpha is the alpha blending configuration.
	Alpha BlendComponent
}

BlendState describes the color blending configuration.

type Buffer added in v0.20.0

type Buffer struct {
	// contains filtered or unexported fields
}

Buffer represents a GPU buffer resource.

Buffer wraps a hal.Buffer and provides Go-idiomatic access with async buffer mapping support. This follows the wgpu pattern where buffer mapping is asynchronous and requires device polling.

Thread Safety: Buffer is safe for concurrent access. All state mutations are protected by a mutex. The mapping callback is invoked from the polling goroutine.

Lifecycle:

  1. Create via CreateBuffer()
  2. Use MapAsync() to initiate mapping
  3. Poll with PollMapAsync() until complete
  4. Access data with GetMappedRange()
  5. Call Unmap() when done
  6. Call Destroy() when the buffer is no longer needed

func CreateBuffer added in v0.20.0

func CreateBuffer(device hal.Device, desc *BufferDescriptor) (*Buffer, error)

CreateBuffer creates a new buffer from a device.

This is a helper function for creating buffers using the HAL API directly. It handles validation and wraps the buffer in a Buffer.

Parameters:

  • device: The device to create the buffer on.
  • desc: The buffer descriptor.

Returns the new Buffer and nil on success. Returns nil and an error if:

  • The device is nil
  • The descriptor is nil
  • Buffer size is invalid
  • Buffer creation fails

func CreateBufferSimple added in v0.20.0

func CreateBufferSimple(
	device hal.Device,
	size uint64,
	usage types.BufferUsage,
	label string,
) (*Buffer, error)

CreateBufferSimple creates a buffer with common defaults.

This is a convenience function for creating simple buffers.

Parameters:

  • device: The device to create the buffer on.
  • size: Buffer size in bytes.
  • usage: Buffer usage flags.
  • label: Optional debug label.

Returns the new Buffer and nil on success. Returns nil and an error if creation fails.

func CreateStagingBuffer added in v0.20.0

func CreateStagingBuffer(
	device hal.Device,
	size uint64,
	forUpload bool,
	label string,
) (*Buffer, error)

CreateStagingBuffer creates a staging buffer for CPU-GPU data transfer.

Staging buffers are used to transfer data between CPU and GPU:

  • For uploads: Create with MapWrite | CopySrc, map, write, copy to GPU buffer
  • For readback: Create with MapRead | CopyDst, copy from GPU, map, read

Parameters:

  • device: The device to create the buffer on.
  • size: Buffer size in bytes.
  • forUpload: If true, creates upload staging buffer (MapWrite | CopySrc). If false, creates readback staging buffer (MapRead | CopyDst).
  • label: Optional debug label.

Returns the new Buffer and nil on success. Returns nil and an error if creation fails.

func NewBuffer added in v0.20.0

func NewBuffer(halBuffer hal.Buffer, device hal.Device, desc *BufferDescriptor) *Buffer

NewBuffer creates a new Buffer from a buffer handle.

This is typically called by CreateBuffer() after successfully creating the underlying buffer.

Parameters:

  • halBuffer: The underlying buffer (ownership transferred)
  • device: The parent device (retained for operations)
  • desc: The buffer descriptor (copied)

Returns the new Buffer.

func (*Buffer) Descriptor added in v0.20.0

func (b *Buffer) Descriptor() BufferDescriptor

Descriptor returns a copy of the buffer descriptor.

func (*Buffer) Destroy added in v0.20.0

func (b *Buffer) Destroy()

Destroy releases the buffer and any associated resources.

After calling Destroy(), the buffer should not be used. If the buffer is mapped, it will be unmapped first.

This method is idempotent - calling it multiple times is safe.

func (*Buffer) GetMappedRange added in v0.20.0

func (b *Buffer) GetMappedRange(offset, size uint64) ([]byte, error)

GetMappedRange returns the mapped data slice.

The returned slice is only valid while the buffer is mapped. Do not use the slice after calling Unmap().

Parameters:

  • offset: Byte offset within the mapped range
  • size: Number of bytes to access

Returns the data slice and nil on success. Returns nil and an error if:

  • The buffer has been destroyed
  • The buffer is not mapped
  • The range is outside the mapped region

func (*Buffer) IsDestroyed added in v0.20.0

func (b *Buffer) IsDestroyed() bool

IsDestroyed returns true if the buffer has been destroyed.

func (*Buffer) Label added in v0.20.0

func (b *Buffer) Label() string

Label returns the buffer's debug label.

func (*Buffer) MapAsync added in v0.20.0

func (b *Buffer) MapAsync(mode types.MapMode, offset, size uint64, callback func(BufferMapAsyncStatus)) error

MapAsync initiates an async map operation.

The callback is invoked when mapping completes or fails. The buffer must have appropriate usage flags (MapRead for read, MapWrite for write).

After MapAsync returns successfully, the map state transitions to Pending. Poll the device with PollMapAsync() until the callback is invoked and the state becomes Mapped.

Parameters:

  • mode: MapModeRead or MapModeWrite
  • offset: Byte offset in the buffer (must be aligned)
  • size: Number of bytes to map (must be aligned)
  • callback: Function called when mapping completes

Returns nil on success (mapping initiated). Returns an error if:

  • The buffer has been destroyed
  • The buffer is already mapped or mapping is pending
  • The mode doesn't match buffer usage flags
  • The range is out of bounds
  • The callback is nil

func (*Buffer) MapState added in v0.20.0

func (b *Buffer) MapState() BufferMapState

MapState returns the current mapping state.

func (*Buffer) PollMapAsync added in v0.20.0

func (b *Buffer) PollMapAsync() bool

PollMapAsync polls for map completion.

Call this method repeatedly after MapAsync() until it returns true, indicating that mapping is complete (either success or failure). The callback provided to MapAsync will be invoked when mapping completes.

Returns true if mapping is complete (success or failure). Returns false if mapping is still pending.

func (*Buffer) Raw added in v0.20.0

func (b *Buffer) Raw() hal.Buffer

Raw returns the underlying buffer handle.

Returns nil if the buffer has been destroyed. Use with caution - the caller should ensure the buffer is not destroyed while the handle is in use.

func (*Buffer) Size added in v0.20.0

func (b *Buffer) Size() uint64

Size returns the buffer size in bytes.

func (*Buffer) Unmap added in v0.20.0

func (b *Buffer) Unmap() error

Unmap unmaps the buffer, making changes visible to GPU.

After unmapping, the buffer returns to the Unmapped state. Any slices returned by GetMappedRange become invalid.

Returns nil on success. Returns an error if the buffer has been destroyed. If the buffer is already unmapped, this is a no-op.

func (*Buffer) Usage added in v0.20.0

func (b *Buffer) Usage() types.BufferUsage

Usage returns the buffer usage flags.

type BufferDescriptor added in v0.20.0

type BufferDescriptor struct {
	// Label is an optional debug name.
	Label string

	// Size is the buffer size in bytes.
	Size uint64

	// Usage specifies how the buffer will be used.
	Usage types.BufferUsage

	// MappedAtCreation creates the buffer pre-mapped for writing.
	MappedAtCreation bool
}

BufferDescriptor describes a buffer to create.

type BufferMapAsyncStatus added in v0.20.0

type BufferMapAsyncStatus int

BufferMapAsyncStatus represents the result of an async map operation.

const (
	// BufferMapAsyncStatusSuccess indicates mapping completed successfully.
	BufferMapAsyncStatusSuccess BufferMapAsyncStatus = iota
	// BufferMapAsyncStatusValidationError indicates a validation error.
	BufferMapAsyncStatusValidationError
	// BufferMapAsyncStatusUnknown indicates an unknown error.
	BufferMapAsyncStatusUnknown
	// BufferMapAsyncStatusDeviceLost indicates the device was lost.
	BufferMapAsyncStatusDeviceLost
	// BufferMapAsyncStatusDestroyedBeforeCallback indicates buffer was destroyed.
	BufferMapAsyncStatusDestroyedBeforeCallback
	// BufferMapAsyncStatusUnmappedBeforeCallback indicates buffer was unmapped.
	BufferMapAsyncStatusUnmappedBeforeCallback
	// BufferMapAsyncStatusMappingAlreadyPending indicates another map is pending.
	BufferMapAsyncStatusMappingAlreadyPending
	// BufferMapAsyncStatusOffsetOutOfRange indicates offset is out of range.
	BufferMapAsyncStatusOffsetOutOfRange
	// BufferMapAsyncStatusSizeOutOfRange indicates size is out of range.
	BufferMapAsyncStatusSizeOutOfRange
)

func (BufferMapAsyncStatus) String added in v0.20.0

func (s BufferMapAsyncStatus) String() string

String returns the string representation of BufferMapAsyncStatus.

type BufferMapState added in v0.20.0

type BufferMapState int

BufferMapState represents the mapping state of a buffer.

const (
	// BufferMapStateUnmapped means the buffer is not mapped.
	BufferMapStateUnmapped BufferMapState = iota
	// BufferMapStatePending means a map operation is pending.
	BufferMapStatePending
	// BufferMapStateMapped means the buffer is mapped.
	BufferMapStateMapped
)

func (BufferMapState) String added in v0.20.0

func (s BufferMapState) String() string

String returns the string representation of BufferMapState.

type CoarseRasterizer

type CoarseRasterizer struct {
	// contains filtered or unexported fields
}

CoarseRasterizer performs coarse rasterization of line segments into tiles. It bins segments into the tiles they intersect and tracks winding information.

func NewCoarseRasterizer

func NewCoarseRasterizer(width, height uint16) *CoarseRasterizer

NewCoarseRasterizer creates a new coarse rasterizer for the given dimensions.

func (*CoarseRasterizer) BinCurveEdges added in v0.20.2

func (cr *CoarseRasterizer) BinCurveEdges(eb *EdgeBuilder) map[uint64]*CurveTileBin

BinCurveEdges bins curve edges from an EdgeBuilder to tiles based on their Y bounds. Unlike RasterizeLineSegments, this preserves curve information for analytic rendering.

Returns a map from tile coordinates (as uint64 key) to the edges that intersect each tile. This is used by FineRasterizer.RasterizeCurves for retained mode rendering.

func (*CoarseRasterizer) CalculateBackdrop

func (cr *CoarseRasterizer) CalculateBackdrop() []int32

CalculateBackdrop calculates the backdrop winding for fine rasterization. Returns a slice of backdrop values indexed by [y * columns + x].

func (*CoarseRasterizer) Entries

func (cr *CoarseRasterizer) Entries() []CoarseTileEntry

Entries returns the coarse tile entries.

func (*CoarseRasterizer) EntriesAtLocation

func (cr *CoarseRasterizer) EntriesAtLocation(x, y uint16) []CoarseTileEntry

EntriesAtLocation returns all entries at the given tile location.

func (*CoarseRasterizer) Grid

func (cr *CoarseRasterizer) Grid() *TileGrid

Grid returns the tile grid after rasterization.

func (*CoarseRasterizer) NewIterator

func (cr *CoarseRasterizer) NewIterator() *CoarseTileIterator

NewIterator creates an iterator for the coarse tile entries.

func (*CoarseRasterizer) Rasterize

func (cr *CoarseRasterizer) Rasterize(segments *SegmentList)

Rasterize performs coarse rasterization of segments into tiles. It determines which tiles each segment intersects and calculates winding.

func (*CoarseRasterizer) Reset

func (cr *CoarseRasterizer) Reset()

Reset clears the rasterizer state for reuse.

func (*CoarseRasterizer) Segments

func (cr *CoarseRasterizer) Segments() *SegmentList

Segments returns the segment list.

func (*CoarseRasterizer) SortEntries

func (cr *CoarseRasterizer) SortEntries()

SortEntries sorts the entries for efficient rendering. Tiles are sorted by Y, then X, then line index.

func (*CoarseRasterizer) TileColumns

func (cr *CoarseRasterizer) TileColumns() uint16

TileColumns returns the number of tile columns.

func (*CoarseRasterizer) TileRows

func (cr *CoarseRasterizer) TileRows() uint16

TileRows returns the number of tile rows.

type CoarseTileEntry

type CoarseTileEntry struct {
	X       uint16 // Tile X coordinate
	Y       uint16 // Tile Y coordinate
	LineIdx uint32 // Index into segment list
	Winding bool   // True if segment contributes winding at this tile
}

CoarseTileEntry represents a tile with its associated line segment. This is used during the coarse rasterization phase before fine rasterization.

type CoarseTileIterator

type CoarseTileIterator struct {
	// contains filtered or unexported fields
}

CoarseTileIterator provides iteration over coarse tiles in sorted order.

func (*CoarseTileIterator) HasNext

func (it *CoarseTileIterator) HasNext() bool

HasNext returns true if there are more entries.

func (*CoarseTileIterator) Next

func (it *CoarseTileIterator) Next() *CoarseTileEntry

Next returns the next tile entry or nil if done.

func (*CoarseTileIterator) Reset

func (it *CoarseTileIterator) Reset()

Reset resets the iterator to the beginning.

type CommandBuffer

type CommandBuffer struct {
	// contains filtered or unexported fields
}

CommandBuffer represents a finished command buffer ready for submission.

func NewCommandBuffer

func NewCommandBuffer(id StubCommandBufferID) *CommandBuffer

NewCommandBuffer wraps a command buffer ID.

func (*CommandBuffer) ID

ID returns the underlying command buffer ID.

type CommandEncoder

type CommandEncoder struct {
	// contains filtered or unexported fields
}

CommandEncoder wraps GPU command encoding operations. It provides a high-level interface for building command buffers that can be submitted to the GPU queue.

CommandEncoder accumulates render passes and compute passes, then produces a command buffer when Finish is called.

func NewCommandEncoder

func NewCommandEncoder(device core.DeviceID) *CommandEncoder

NewCommandEncoder creates a new command encoder for the given device.

func (*CommandEncoder) BeginComputePass

func (e *CommandEncoder) BeginComputePass() *ComputePass

BeginComputePass begins a new compute pass.

func (*CommandEncoder) BeginRenderPass

func (e *CommandEncoder) BeginRenderPass(target *GPUTexture, clearTarget bool) *RenderPass

BeginRenderPass begins a new render pass targeting the specified texture. If clearTarget is true, the texture is cleared to transparent before drawing.

func (*CommandEncoder) CopyTextureToBuffer

func (e *CommandEncoder) CopyTextureToBuffer(src *GPUTexture, dst StubBufferID, bytesPerRow uint32)

CopyTextureToBuffer copies a texture to a buffer for readback.

func (*CommandEncoder) CopyTextureToTexture

func (e *CommandEncoder) CopyTextureToTexture(src, dst *GPUTexture, width, height int)

CopyTextureToTexture copies a region from one texture to another.

func (*CommandEncoder) Finish

func (e *CommandEncoder) Finish() StubCommandBufferID

Finish completes the command encoder and returns the command buffer. The encoder cannot be used after calling Finish.

func (*CommandEncoder) PassCount

func (e *CommandEncoder) PassCount() int

PassCount returns the number of passes recorded.

type CompositeParams

type CompositeParams struct {
	LayerCount uint32 // Number of layers to composite
	Width      uint32 // Output width
	Height     uint32 // Output height
	Padding    uint32 // Alignment padding
}

CompositeParams represents the uniform buffer structure for composite shaders. This matches the CompositeParams struct in composite.wgsl.

type ComputeCommandBuilder

type ComputeCommandBuilder struct {
	// contains filtered or unexported fields
}

ComputeCommandBuilder provides a fluent API for building compute commands.

func NewComputeCommandBuilder

func NewComputeCommandBuilder(device core.DeviceID) *ComputeCommandBuilder

NewComputeCommandBuilder creates a new compute command builder.

func (*ComputeCommandBuilder) Dispatch

func (b *ComputeCommandBuilder) Dispatch(x, y, z uint32) *ComputeCommandBuilder

Dispatch dispatches workgroups.

func (*ComputeCommandBuilder) DispatchForSize

func (b *ComputeCommandBuilder) DispatchForSize(size, groupSize uint32) *ComputeCommandBuilder

DispatchForSize calculates and dispatches for a work size.

func (*ComputeCommandBuilder) Finish

Finish ends the pass and returns the command buffer.

func (*ComputeCommandBuilder) SetBindGroup

func (b *ComputeCommandBuilder) SetBindGroup(index uint32, bindGroup StubBindGroupID) *ComputeCommandBuilder

SetBindGroup sets a bind group.

func (*ComputeCommandBuilder) SetPipeline

SetPipeline sets the compute pipeline.

type ComputePass

type ComputePass struct {
	// contains filtered or unexported fields
}

ComputePass represents an active compute pass for dispatch commands.

func (*ComputePass) DispatchWorkgroups

func (p *ComputePass) DispatchWorkgroups(workgroupCountX, workgroupCountY, workgroupCountZ uint32)

DispatchWorkgroups dispatches compute work. workgroupCountX/Y/Z: number of workgroups in each dimension

func (*ComputePass) DispatchWorkgroupsForSize

func (p *ComputePass) DispatchWorkgroupsForSize(workSize, workgroupSize uint32)

DispatchWorkgroupsForSize calculates and dispatches workgroups for a given work size. workSize: total number of work items workgroupSize: number of items per workgroup (typically 64 or 256)

func (*ComputePass) End

func (p *ComputePass) End()

End finishes the compute pass.

func (*ComputePass) SetBindGroup

func (p *ComputePass) SetBindGroup(index uint32, bindGroup StubBindGroupID)

SetBindGroup sets a bind group at the specified index.

func (*ComputePass) SetPipeline

func (p *ComputePass) SetPipeline(pipeline StubComputePipelineID)

SetPipeline sets the compute pipeline for subsequent dispatch calls.

type ComputePassDescriptor added in v0.20.0

type ComputePassDescriptor struct {
	// Label is an optional debug name for the compute pass.
	Label string

	// TimestampWrites are timestamp queries to write at pass boundaries (optional).
	TimestampWrites *ComputePassTimestampWrites
}

ComputePassDescriptor describes a compute pass.

type ComputePassEncoder added in v0.20.0

type ComputePassEncoder struct {
	// contains filtered or unexported fields
}

ComputePassEncoder records compute commands within a compute pass.

ComputePassEncoder wraps core.CoreComputePassEncoder and provides Go-idiomatic access with immediate error returns. Commands recorded include:

  • SetPipeline: Set the compute pipeline for subsequent dispatch calls
  • SetBindGroup: Bind resource groups (buffers, textures) to shaders
  • DispatchWorkgroups: Execute compute shader workgroups
  • DispatchWorkgroupsIndirect: Execute with GPU-generated parameters

Thread Safety: ComputePassEncoder is NOT safe for concurrent use. All commands must be recorded from a single goroutine. The pass must be ended with End() before the parent command encoder can continue recording.

Lifecycle:

  1. Created by CoreCommandEncoder.BeginComputePass()
  2. Record commands (SetPipeline, SetBindGroup, DispatchWorkgroups, etc.)
  3. Call End() to complete the pass

State Machine:

Recording -> End() -> Ended

func (*ComputePassEncoder) DispatchCount added in v0.20.0

func (p *ComputePassEncoder) DispatchCount() uint32

DispatchCount returns the number of dispatch calls made during this pass.

func (*ComputePassEncoder) DispatchWorkgroups added in v0.20.0

func (p *ComputePassEncoder) DispatchWorkgroups(x, y, z uint32) error

DispatchWorkgroups dispatches compute workgroups.

This executes the compute shader with the specified number of workgroups. The total number of shader invocations is:

x * y * z * workgroup_size

where workgroup_size is defined in the compute shader.

Parameters:

  • x, y, z: The number of workgroups to dispatch in each dimension.

Returns nil on success. Returns an error if:

  • The pass has ended
  • Any dimension is zero (optional validation)

func (*ComputePassEncoder) DispatchWorkgroupsIndirect added in v0.20.0

func (p *ComputePassEncoder) DispatchWorkgroupsIndirect(indirectBuffer *Buffer, indirectOffset uint64) error

DispatchWorkgroupsIndirect dispatches compute workgroups with GPU-generated parameters.

The dispatch parameters are read from the indirect buffer at the specified offset. The buffer must contain a DispatchIndirectArgs structure:

struct DispatchIndirectArgs {
    x: u32,     // Number of workgroups in X
    y: u32,     // Number of workgroups in Y
    z: u32,     // Number of workgroups in Z
}

Parameters:

  • indirectBuffer: Buffer containing DispatchIndirectArgs.
  • indirectOffset: Byte offset into the buffer (must be 4-byte aligned).

Returns nil on success. Returns an error if:

  • The pass has ended
  • The buffer is nil
  • The offset is not 4-byte aligned

func (*ComputePassEncoder) End added in v0.20.0

func (p *ComputePassEncoder) End() error

End completes the compute pass.

After calling End(), the compute pass encoder cannot be used for further recording. The parent command encoder returns to the Recording state.

Returns nil on success. Returns an error if the pass has already ended.

func (*ComputePassEncoder) IsEnded added in v0.20.0

func (p *ComputePassEncoder) IsEnded() bool

IsEnded returns true if the pass has been ended.

func (*ComputePassEncoder) SetBindGroup added in v0.20.0

func (p *ComputePassEncoder) SetBindGroup(index uint32, bindGroup *BindGroup, dynamicOffsets []uint32) error

SetBindGroup binds a bind group for the given index.

Bind groups provide resources (buffers, textures) to compute shaders. WebGPU supports up to 4 bind groups (indices 0-3).

Parameters:

  • index: The bind group index (0, 1, 2, or 3).
  • bindGroup: The bind group to bind.
  • dynamicOffsets: Dynamic offsets for dynamic uniform/storage buffers (optional).

Returns nil on success. Returns an error if:

  • The pass has ended
  • The index exceeds maximum (3)
  • The bind group is nil

func (*ComputePassEncoder) SetPipeline added in v0.20.0

func (p *ComputePassEncoder) SetPipeline(pipeline *ComputePipeline) error

SetPipeline sets the compute pipeline for subsequent dispatch calls.

The pipeline defines the compute shader to execute and its bind group layouts. A pipeline must be bound before any dispatch call.

Parameters:

  • pipeline: The compute pipeline to bind.

Returns nil on success. Returns an error if:

  • The pass has ended
  • The pipeline is nil

func (*ComputePassEncoder) State added in v0.20.0

State returns the current pass state.

type ComputePassState added in v0.20.0

type ComputePassState int

ComputePassState represents the state of a compute pass encoder.

const (
	// ComputePassStateRecording means the pass is actively recording commands.
	ComputePassStateRecording ComputePassState = iota

	// ComputePassStateEnded means the pass has been ended.
	ComputePassStateEnded
)

func (ComputePassState) String added in v0.20.0

func (s ComputePassState) String() string

String returns the string representation of ComputePassState.

type ComputePassTimestampWrites added in v0.20.0

type ComputePassTimestampWrites struct {
	// QuerySet is the query set to write timestamps to.
	QuerySet core.QuerySetID

	// BeginningOfPassWriteIndex is the query index for pass start.
	BeginningOfPassWriteIndex *uint32

	// EndOfPassWriteIndex is the query index for pass end.
	EndOfPassWriteIndex *uint32
}

ComputePassTimestampWrites describes timestamp query writes for a compute pass.

type ComputePipeline added in v0.20.0

type ComputePipeline struct {
	// contains filtered or unexported fields
}

ComputePipeline represents a GPU compute pipeline.

Compute pipelines define:

  • The compute shader to execute
  • Bind group layouts for resource bindings
  • Pipeline layout

ComputePipeline is a placeholder type that will be expanded when pipeline creation is implemented.

func (*ComputePipeline) Destroy added in v0.20.0

func (p *ComputePipeline) Destroy()

Destroy releases the pipeline resources.

func (*ComputePipeline) ID added in v0.20.0

func (p *ComputePipeline) ID() uint64

ID returns the pipeline's unique identifier.

func (*ComputePipeline) IsDestroyed added in v0.20.0

func (p *ComputePipeline) IsDestroyed() bool

IsDestroyed returns true if the pipeline has been destroyed.

func (*ComputePipeline) Label added in v0.20.0

func (p *ComputePipeline) Label() string

Label returns the pipeline's debug label.

func (*ComputePipeline) WorkgroupSize added in v0.20.0

func (p *ComputePipeline) WorkgroupSize() [3]uint32

WorkgroupSize returns the compute shader's workgroup size. Returns [x, y, z] dimensions.

type ComputePipelineDescriptor added in v0.20.0

type ComputePipelineDescriptor struct {
	// Label is an optional debug name.
	Label string

	// ComputeShader is the compute shader module.
	ComputeShader *ShaderModule

	// EntryPoint is the compute shader entry point function name.
	// Defaults to "main" if empty.
	EntryPoint string
}

ComputePipelineDescriptor describes a compute pipeline to create.

type CoreCommandBuffer added in v0.20.0

type CoreCommandBuffer struct {
	// contains filtered or unexported fields
}

CoreCommandBuffer is a finished command recording ready for submission.

Command buffers are created by CoreCommandEncoder.Finish() and submitted to a Queue for execution.

func (*CoreCommandBuffer) CoreBuffer added in v0.20.0

func (cb *CoreCommandBuffer) CoreBuffer() *core.CoreCommandBuffer

CoreBuffer returns the underlying core command buffer. Returns nil if the buffer was created without a core encoder.

func (*CoreCommandBuffer) Label added in v0.20.0

func (cb *CoreCommandBuffer) Label() string

Label returns the command buffer's debug label.

type CoreCommandEncoder added in v0.20.0

type CoreCommandEncoder struct {
	// contains filtered or unexported fields
}

CoreCommandEncoder records GPU commands for later submission to a queue.

This is the core command encoder that wraps core.CoreCommandEncoder. It provides a higher-level API with Go-style immediate error handling.

CoreCommandEncoder follows the WebGPU command encoding pattern:

  1. Create encoder via NewCoreCommandEncoder()
  2. Record commands (copy operations, begin/end passes)
  3. Call Finish() to get a CoreCommandBuffer
  4. Submit CoreCommandBuffer to a Queue

State machine:

Recording -> (BeginRenderPass/BeginComputePass) -> Locked
Locked    -> (EndPass)                          -> Recording
Recording -> Finish()                           -> Finished
Finished  -> (submitted to queue)               -> Consumed

CoreCommandEncoder is NOT safe for concurrent use. Each encoder should be used from a single goroutine.

func NewCoreCommandEncoder added in v0.20.0

func NewCoreCommandEncoder(backend *NativeBackend, label string) (*CoreCommandEncoder, error)

NewCoreCommandEncoder creates a new command encoder from a backend.

The encoder is created in the Recording state, ready to record commands.

Parameters:

  • backend: The native backend to create the encoder on.
  • label: Debug label for the encoder (optional, can be empty).

Returns the encoder and nil on success. Returns nil and an error if the backend is not initialized.

func NewCoreCommandEncoderWithDevice added in v0.20.0

func NewCoreCommandEncoderWithDevice(device *core.Device, label string) (*CoreCommandEncoder, error)

NewCoreCommandEncoderWithDevice creates a command encoder using a core.Device.

This version creates a real wgpu command encoder.

Parameters:

  • device: The core.Device to create the encoder on.
  • label: Debug label for the encoder (optional).

Returns the encoder and nil on success. Returns nil and an error if the device is invalid or creation fails.

func (*CoreCommandEncoder) BeginComputePass added in v0.20.0

func (e *CoreCommandEncoder) BeginComputePass(desc *ComputePassDescriptor) (*ComputePassEncoder, error)

BeginComputePass starts a compute pass with the given descriptor.

The encoder must be in the Recording state. After this call, the encoder transitions to the Locked state. The encoder returns to Recording state when the compute pass ends.

Parameters:

  • desc: Compute pass descriptor (optional, can be nil for defaults).

Returns the compute pass encoder and nil on success. Returns nil and an error if:

  • The encoder is not in Recording state
  • Compute pass creation fails

func (*CoreCommandEncoder) BeginRenderPass added in v0.20.0

func (e *CoreCommandEncoder) BeginRenderPass(desc *RenderPassDescriptor) (*RenderPassEncoder, error)

BeginRenderPass starts a render pass with the given descriptor.

The encoder must be in the Recording state. After this call, the encoder transitions to the Locked state. The encoder returns to Recording state when the render pass ends.

Parameters:

  • desc: Render pass descriptor specifying color attachments and options.

Returns the render pass encoder and nil on success. Returns nil and an error if:

  • The encoder is not in Recording state
  • The descriptor is nil
  • Render pass creation fails

func (*CoreCommandEncoder) ClearBuffer added in v0.20.0

func (e *CoreCommandEncoder) ClearBuffer(buffer *core.Buffer, offset, size uint64) error

ClearBuffer clears a region of a buffer to zero.

The encoder must be in the Recording state.

Parameters:

  • buffer: Buffer to clear.
  • offset: Byte offset to start clearing (must be 4-byte aligned).
  • size: Number of bytes to clear (must be 4-byte aligned, or 0 for entire buffer).

Returns nil on success. Returns an error if validation fails or the encoder state is invalid.

func (*CoreCommandEncoder) CopyBufferToBuffer added in v0.20.0

func (e *CoreCommandEncoder) CopyBufferToBuffer(src, dst *core.Buffer, srcOffset, dstOffset, size uint64) error

CopyBufferToBuffer copies data from one buffer to another.

The encoder must be in the Recording state.

Parameters:

  • src: Source buffer.
  • srcOffset: Byte offset in the source buffer.
  • dst: Destination buffer.
  • dstOffset: Byte offset in the destination buffer.
  • size: Number of bytes to copy.

Validation:

  • Both offsets and size must be 4-byte aligned.
  • Source and destination ranges must not overlap.
  • Ranges must be within buffer bounds.

Returns nil on success. Returns an error if validation fails or the encoder state is invalid.

func (*CoreCommandEncoder) CopyBufferToTexture added in v0.20.0

func (e *CoreCommandEncoder) CopyBufferToTexture(source *ImageCopyBuffer, destination *ImageCopyTexture, copySize types.Extent3D) error

CopyBufferToTexture copies data from a buffer to a texture.

The encoder must be in the Recording state.

Parameters:

  • source: Buffer copy source descriptor.
  • destination: Texture copy destination descriptor.
  • copySize: Size of the copy region.

Returns nil on success. Returns an error if validation fails or the encoder state is invalid.

func (*CoreCommandEncoder) CopyTextureToBuffer added in v0.20.0

func (e *CoreCommandEncoder) CopyTextureToBuffer(source *ImageCopyTexture, destination *ImageCopyBuffer, copySize types.Extent3D) error

CopyTextureToBuffer copies data from a texture to a buffer.

The encoder must be in the Recording state.

Parameters:

  • source: Texture copy source descriptor.
  • destination: Buffer copy destination descriptor.
  • copySize: Size of the copy region.

Returns nil on success. Returns an error if validation fails or the encoder state is invalid.

func (*CoreCommandEncoder) CopyTextureToTexture added in v0.20.0

func (e *CoreCommandEncoder) CopyTextureToTexture(source, destination *ImageCopyTexture, copySize types.Extent3D) error

CopyTextureToTexture copies data from one texture to another.

The encoder must be in the Recording state.

Parameters:

  • source: Source texture copy descriptor.
  • destination: Destination texture copy descriptor.
  • copySize: Size of the copy region.

Returns nil on success. Returns an error if validation fails or the encoder state is invalid.

func (*CoreCommandEncoder) Finish added in v0.20.0

func (e *CoreCommandEncoder) Finish() (*CoreCommandBuffer, error)

Finish completes recording and returns a command buffer.

The encoder must be in the Recording state (no active passes). After this call, the encoder transitions to the Finished state and cannot be used for further recording.

Returns the command buffer and nil on success. Returns nil and an error if the encoder is not in Recording state.

func (*CoreCommandEncoder) Label added in v0.20.0

func (e *CoreCommandEncoder) Label() string

Label returns the encoder's debug label.

func (*CoreCommandEncoder) Status added in v0.20.0

Status returns the current encoder status.

type CubicEdge added in v0.20.2

type CubicEdge struct {
	// TopY is the curve's overall top scanline (for AET insertion timing).
	// This is set once at creation and never changes, unlike line.FirstY
	// which changes as we step through curve segments.
	TopY int32

	// BottomY is the curve's overall bottom scanline.
	BottomY int32
	// contains filtered or unexported fields
}

CubicEdge represents a cubic Bezier curve for scanline conversion. Uses forward differencing for O(1) per-step evaluation.

A cubic Bezier is defined by:

p(t) = (1-t)^3 * p0 + 3*t*(1-t)^2 * p1 + 3*t^2*(1-t) * p2 + t^3 * p3

Rewritten in polynomial form:

p(t) = A*t^3 + B*t^2 + C*t + D
where:
A = -p0 + 3*p1 - 3*p2 + p3
B = 3*p0 - 6*p1 + 3*p2
C = -3*p0 + 3*p1
D = p0

func NewCubicEdge added in v0.20.2

func NewCubicEdge(p0, p1, p2, p3 CurvePoint, shift int) *CubicEdge

NewCubicEdge creates a cubic edge from control points. Returns nil if the curve has no vertical extent.

Parameters:

  • p0: start point
  • p1: first control point
  • p2: second control point
  • p3: end point
  • shift: AA shift (0 for no AA, 2 for 4x AA quality)

func (*CubicEdge) CurveCount added in v0.20.2

func (c *CubicEdge) CurveCount() int8

CurveCount returns the remaining number of segments. For cubic, this is negative (counts up to 0).

func (*CubicEdge) Line added in v0.20.2

func (c *CubicEdge) Line() *LineEdge

Line returns the current line segment for AET processing.

func (*CubicEdge) Update added in v0.20.2

func (c *CubicEdge) Update() bool

Update advances the cubic curve to the next line segment. Returns true if a valid segment was produced.

Forward differencing for cubic:

newx = oldx + (dx >> dshift)
dx += ddx >> ddshift
ddx += dddx  // Third derivative is constant!

func (*CubicEdge) Winding added in v0.20.2

func (c *CubicEdge) Winding() int8

Winding returns the winding direction.

type CurveAwareAET added in v0.20.2

type CurveAwareAET struct {
	// contains filtered or unexported fields
}

CurveAwareAET is an Active Edge Table that handles all edge types.

Unlike a simple line-based AET, this table can hold LineEdge, QuadraticEdge, and CubicEdge types. Curve edges are stepped through their segments during scanline traversal using forward differencing.

The AET maintains edges sorted by their current X position, which is essential for correct scanline rasterization and winding number calculation.

Usage:

aet := NewCurveAwareAET()
for y := yMin; y < yMax; y++ {
    aet.RemoveExpired(y)
    for edge := range eb.EdgesStartingAt(y) {
        aet.Insert(edge)
    }
    aet.StepCurves()
    aet.SortByX()
    // Process edges in X order
}

func NewCurveAwareAET added in v0.20.2

func NewCurveAwareAET() *CurveAwareAET

NewCurveAwareAET creates a new curve-aware Active Edge Table.

func (*CurveAwareAET) AdvanceX added in v0.20.2

func (aet *CurveAwareAET) AdvanceX()

AdvanceX advances all edges to the next scanline. This updates the X position based on the slope (DX).

func (*CurveAwareAET) ComputeSpans added in v0.20.2

func (aet *CurveAwareAET) ComputeSpans(_ int32, fillRule FillRule, callback func(x, width int, coverage float32))

ComputeSpans computes the horizontal spans for the current scanline. This implements the core of scanline rasterization:

  1. For each pair of edges, compute the winding contribution
  2. Apply fill rule to determine coverage
  3. Return spans with their coverage values

The callback is called for each span with x, width, and coverage.

func (*CurveAwareAET) EdgeAt added in v0.20.2

func (aet *CurveAwareAET) EdgeAt(i int) *CurveEdgeVariant

EdgeAt returns the edge at index i. Panics if i is out of bounds.

func (*CurveAwareAET) Edges added in v0.20.2

func (aet *CurveAwareAET) Edges() []CurveEdgeVariant

Edges returns the slice of edge variants for processing. The edges are in X-sorted order after SortByX() is called.

func (*CurveAwareAET) ForEach added in v0.20.2

func (aet *CurveAwareAET) ForEach(fn func(edge *CurveEdgeVariant) bool)

ForEach calls fn for each edge in the AET. Iteration stops if fn returns false.

func (*CurveAwareAET) Insert added in v0.20.2

func (aet *CurveAwareAET) Insert(e CurveEdgeVariant)

Insert adds an edge to the AET. The edge's current line segment is used for initial positioning.

func (*CurveAwareAET) IsEmpty added in v0.20.2

func (aet *CurveAwareAET) IsEmpty() bool

IsEmpty returns true if there are no active edges.

func (*CurveAwareAET) Len added in v0.20.2

func (aet *CurveAwareAET) Len() int

Len returns the number of active edges.

func (*CurveAwareAET) RemoveExpired added in v0.20.2

func (aet *CurveAwareAET) RemoveExpired(y int32)

RemoveExpired removes edges that have ended before scanline y. An edge is expired when its LastY < y.

func (*CurveAwareAET) RemoveExpiredSubpixel added in v0.20.2

func (aet *CurveAwareAET) RemoveExpiredSubpixel(ySubpixel int32)

RemoveExpiredSubpixel removes edges that have completely ended. Uses the edge's overall BottomY (not current segment) for expiration.

This is used when coordinates are in sub-pixel space with AA scaling. An edge is expired when its BottomY <= ySubpixel.

func (*CurveAwareAET) Reset added in v0.20.2

func (aet *CurveAwareAET) Reset()

Reset clears the AET for reuse.

func (*CurveAwareAET) SortByX added in v0.20.2

func (aet *CurveAwareAET) SortByX()

SortByX sorts all edges by their current X position. This is essential for correct scanline processing.

func (*CurveAwareAET) StepCurves added in v0.20.2

func (aet *CurveAwareAET) StepCurves()

StepCurves advances curve edges to their next line segment. This should be called once per scanline after RemoveExpired.

For each curve edge whose current segment has ended, Update() is called to compute the next segment. This is where forward differencing happens.

type CurveEdge added in v0.20.2

type CurveEdge interface {
	// Update advances the curve to the next line segment.
	// Returns true if a valid segment was produced, false if done.
	Update() bool

	// Line returns the current line segment for AET processing.
	Line() *LineEdge

	// CurveCount returns the remaining number of segments.
	CurveCount() int8

	// Winding returns the winding direction (+1 or -1).
	Winding() int8
}

CurveEdge is the interface implemented by curve edges (quadratic, cubic). It allows polymorphic handling of different curve types in the AET.

type CurveEdgeVariant added in v0.20.2

type CurveEdgeVariant struct {
	Type      EdgeType
	Line      *LineEdge
	Quadratic *QuadraticEdge
	Cubic     *CubicEdge
}

CurveEdgeVariant wraps different edge types for uniform handling in the AET. This is Go's equivalent of Rust's enum Edge { Line, Quadratic, Cubic }.

func NewCubicEdgeVariant added in v0.20.2

func NewCubicEdgeVariant(p0, p1, p2, p3 CurvePoint, shift int) *CurveEdgeVariant

NewCubicEdgeVariant creates a CurveEdgeVariant for a cubic.

func NewLineEdgeVariant added in v0.20.2

func NewLineEdgeVariant(p0, p1 CurvePoint, shift int) *CurveEdgeVariant

NewLineEdgeVariant creates a CurveEdgeVariant for a line.

func NewQuadraticEdgeVariant added in v0.20.2

func NewQuadraticEdgeVariant(p0, p1, p2 CurvePoint, shift int) *CurveEdgeVariant

NewQuadraticEdgeVariant creates a CurveEdgeVariant for a quadratic.

func (*CurveEdgeVariant) AsLine added in v0.20.2

func (e *CurveEdgeVariant) AsLine() *LineEdge

AsLine returns the LineEdge for this edge, regardless of type. All edge types contain a LineEdge for AET compatibility.

func (*CurveEdgeVariant) BottomY added in v0.20.2

func (e *CurveEdgeVariant) BottomY() int32

BottomY returns the curve's overall bottom Y coordinate. For line edges, this is the same as LastY + 1. For curve edges, this is the curve's original bottom Y.

func (*CurveEdgeVariant) TopY added in v0.20.2

func (e *CurveEdgeVariant) TopY() int32

TopY returns the curve's overall top Y coordinate (for AET insertion timing). For line edges, this is the same as FirstY. For curve edges, this is the curve's original top Y before stepping.

func (*CurveEdgeVariant) Update added in v0.20.2

func (e *CurveEdgeVariant) Update() bool

Update advances a curve edge to the next line segment. Returns true if a valid segment was produced. For line edges, always returns false (no more segments).

type CurvePoint added in v0.20.2

type CurvePoint struct {
	X, Y float32
}

CurvePoint represents a 2D point for curve edge construction. Using separate type to avoid coupling with scene.Point.

type CurveTileBin added in v0.20.2

type CurveTileBin struct {
	Edges    []CurveEdgeVariant
	Backdrop int32
}

CurveTileBin holds curve edges binned to a specific tile.

type DispatchIndirectArgs added in v0.20.0

type DispatchIndirectArgs struct {
	// X is the number of workgroups in the X dimension.
	X uint32

	// Y is the number of workgroups in the Y dimension.
	Y uint32

	// Z is the number of workgroups in the Z dimension.
	Z uint32
}

DispatchIndirectArgs represents the arguments for indirect dispatch.

This structure is read from the GPU buffer at the offset specified in DispatchWorkgroupsIndirect.

func (DispatchIndirectArgs) Size added in v0.20.0

func (d DispatchIndirectArgs) Size() uint64

Size returns the byte size of DispatchIndirectArgs.

type DrawIndexedIndirectArgs added in v0.20.0

type DrawIndexedIndirectArgs struct {
	// IndexCount is the number of indices to draw.
	IndexCount uint32

	// InstanceCount is the number of instances to draw.
	InstanceCount uint32

	// FirstIndex is the first index in the index buffer.
	FirstIndex uint32

	// BaseVertex is added to each index before vertex lookup.
	BaseVertex int32

	// FirstInstance is the first instance index.
	FirstInstance uint32
}

DrawIndexedIndirectArgs represents the arguments for indirect indexed draw.

This structure is read from the GPU buffer at the offset specified in DrawIndexedIndirect.

func (DrawIndexedIndirectArgs) Size added in v0.20.0

Size returns the byte size of DrawIndexedIndirectArgs.

type DrawIndirectArgs added in v0.20.0

type DrawIndirectArgs struct {
	// VertexCount is the number of vertices to draw.
	VertexCount uint32

	// InstanceCount is the number of instances to draw.
	InstanceCount uint32

	// FirstVertex is the first vertex index.
	FirstVertex uint32

	// FirstInstance is the first instance index.
	FirstInstance uint32
}

DrawIndirectArgs represents the arguments for indirect draw.

This structure is read from the GPU buffer at the offset specified in DrawIndirect.

func (DrawIndirectArgs) Size added in v0.20.0

func (d DrawIndirectArgs) Size() uint64

Size returns the byte size of DrawIndirectArgs.

type Edge

type Edge struct {
	// contains filtered or unexported fields
}

Edge represents a line segment for scanline conversion. Edges are derived from path segments (lines, curves flattened to lines) and used by the Active Edge Table algorithm.

func NewEdge

func NewEdge(x0, y0, x1, y1 float32) *Edge

NewEdge creates a new edge from two points. Returns nil if the edge is horizontal (no Y extent).

func NewEdgeWithWinding

func NewEdgeWithWinding(x0, y0, x1, y1 float32, winding int8) *Edge

NewEdgeWithWinding creates a new edge with explicit winding.

func (*Edge) ContainsY

func (e *Edge) ContainsY(y float32) bool

ContainsY returns true if Y is within the edge's Y range (inclusive).

func (*Edge) Height

func (e *Edge) Height() float32

Height returns the vertical extent of the edge.

func (*Edge) IsActiveAt

func (e *Edge) IsActiveAt(y float32) bool

IsActiveAt returns true if the edge is active at the given Y coordinate. An edge is active when yMin <= y < yMax.

func (*Edge) XAtY

func (e *Edge) XAtY(y float32) float32

XAtY calculates the X coordinate at a given Y value. This is the core calculation for scanline intersection.

type EdgeBuilder added in v0.20.2

type EdgeBuilder struct {
	// contains filtered or unexported fields
}

EdgeBuilder converts paths to typed edges for analytic anti-aliasing.

By default, EdgeBuilder preserves curve information (QuadraticEdge, CubicEdge) which enables higher quality anti-aliasing by evaluating curve coverage analytically.

Alternatively, with flattenCurves=true, all curves are converted to line segments at build time. This is simpler and more reliable for the AnalyticFiller.

The builder ensures all edges are Y-monotonic by chopping curves at their Y extrema before creating edge objects.

Usage:

eb := NewEdgeBuilder(2) // 4x AA quality
eb.SetFlattenCurves(true) // Flatten curves to lines
eb.BuildFromScenePath(path, scene.IdentityAffine())

for edge := range eb.AllEdges() {
    // Process edges sorted by top Y
}

Reference: tiny-skia/src/edge_builder.rs

func NewEdgeBuilder added in v0.20.2

func NewEdgeBuilder(aaShift int) *EdgeBuilder

NewEdgeBuilder creates a new edge builder with specified AA quality.

Parameters:

  • aaShift: anti-aliasing shift (0 = no AA, 2 = 4x AA quality)

Higher shift values provide better AA quality but require more memory and computation.

func (*EdgeBuilder) AAShift added in v0.20.2

func (eb *EdgeBuilder) AAShift() int

AAShift returns the anti-aliasing shift value.

func (*EdgeBuilder) AllEdges added in v0.20.2

func (eb *EdgeBuilder) AllEdges() iter.Seq[CurveEdgeVariant]

AllEdges returns an iterator over all edges sorted by top Y coordinate.

This uses Go 1.25+ iter.Seq for efficient iteration. Edges are yielded in scanline order (top to bottom), which is required for Active Edge Table processing.

Usage:

for edge := range eb.AllEdges() {
    line := edge.AsLine()
    // Process edge.Line().FirstY, etc.
}

func (*EdgeBuilder) Bounds added in v0.20.2

func (eb *EdgeBuilder) Bounds() scene.Rect

Bounds returns the bounding rectangle of all edges.

func (*EdgeBuilder) BuildFromScenePath added in v0.20.2

func (eb *EdgeBuilder) BuildFromScenePath(path *scene.Path, transform scene.Affine)

BuildFromScenePath processes a scene.Path and creates typed edges.

This is the main entry point for path processing. It:

  1. Iterates through path verbs
  2. Applies transform to all points
  3. Chops curves at Y extrema for monotonicity
  4. Creates appropriate edge types

Parameters:

  • path: the path to process
  • transform: affine transformation to apply to all points

func (*EdgeBuilder) CubicEdgeCount added in v0.20.2

func (eb *EdgeBuilder) CubicEdgeCount() int

CubicEdgeCount returns the number of cubic edges.

func (*EdgeBuilder) CubicEdges added in v0.20.2

func (eb *EdgeBuilder) CubicEdges() iter.Seq[*CubicEdge]

CubicEdges returns an iterator over cubic edges only.

func (*EdgeBuilder) EdgeCount added in v0.20.2

func (eb *EdgeBuilder) EdgeCount() int

EdgeCount returns the total number of edges.

func (*EdgeBuilder) FlattenCurves added in v0.20.2

func (eb *EdgeBuilder) FlattenCurves() bool

FlattenCurves returns whether curve flattening is enabled.

func (*EdgeBuilder) IsEmpty added in v0.20.2

func (eb *EdgeBuilder) IsEmpty() bool

IsEmpty returns true if no edges have been added.

func (*EdgeBuilder) LineEdgeCount added in v0.20.2

func (eb *EdgeBuilder) LineEdgeCount() int

LineEdgeCount returns the number of line edges.

func (*EdgeBuilder) LineEdges added in v0.20.2

func (eb *EdgeBuilder) LineEdges() iter.Seq[*LineEdge]

LineEdges returns an iterator over line edges only.

func (*EdgeBuilder) QuadraticEdgeCount added in v0.20.2

func (eb *EdgeBuilder) QuadraticEdgeCount() int

QuadraticEdgeCount returns the number of quadratic edges.

func (*EdgeBuilder) QuadraticEdges added in v0.20.2

func (eb *EdgeBuilder) QuadraticEdges() iter.Seq[*QuadraticEdge]

QuadraticEdges returns an iterator over quadratic edges only.

func (*EdgeBuilder) Reset added in v0.20.2

func (eb *EdgeBuilder) Reset()

Reset clears the builder for reuse without deallocating memory.

func (*EdgeBuilder) SetFlattenCurves added in v0.20.2

func (eb *EdgeBuilder) SetFlattenCurves(flatten bool)

SetFlattenCurves enables or disables curve flattening mode. When enabled, all curves are converted to line segments at build time. This is simpler and more reliable for AnalyticFiller.

type EdgeList

type EdgeList struct {
	// contains filtered or unexported fields
}

EdgeList is a collection of edges with utility methods.

func NewEdgeList

func NewEdgeList() *EdgeList

NewEdgeList creates a new empty edge list.

func (*EdgeList) Add

func (el *EdgeList) Add(e *Edge)

Add adds an edge to the list.

func (*EdgeList) AddLine

func (el *EdgeList) AddLine(x0, y0, x1, y1 float32)

AddLine adds a line segment as an edge.

func (*EdgeList) Bounds

func (el *EdgeList) Bounds() (minX, minY, maxX, maxY float32)

Bounds returns the bounding rectangle of all edges.

func (*EdgeList) Edges

func (el *EdgeList) Edges() []Edge

Edges returns the underlying slice.

func (*EdgeList) Len

func (el *EdgeList) Len() int

Len returns the number of edges.

func (*EdgeList) Reset

func (el *EdgeList) Reset()

Reset clears the edge list for reuse.

func (*EdgeList) SortByYMin

func (el *EdgeList) SortByYMin()

SortByYMin sorts edges by their minimum Y coordinate.

type EdgeRange added in v0.20.2

type EdgeRange struct {
	StartX    int32   // Left X of the span
	EndX      int32   // Right X of the span
	Winding   int32   // Accumulated winding number
	Coverage  float32 // Accumulated coverage
	EdgeCount int     // Number of edges in this range
}

EdgeRange represents a range of edges for a scanline span.

type EdgeType added in v0.20.2

type EdgeType int

EdgeType represents the type of an edge for polymorphic handling.

const (
	// EdgeTypeLine represents a simple line edge.
	EdgeTypeLine EdgeType = iota

	// EdgeTypeQuadratic represents a quadratic Bezier edge.
	EdgeTypeQuadratic

	// EdgeTypeCubic represents a cubic Bezier edge.
	EdgeTypeCubic
)

type FDot6 added in v0.20.2

type FDot6 = int32

FDot6 is a 26.6 fixed-point number (6 fractional bits). Used for intermediate calculations in edge setup where sub-pixel precision (1/64 pixel) is sufficient.

Range: approximately -33 million to +33 million with 1/64 precision.

func FDot6FromFloat32 added in v0.20.2

func FDot6FromFloat32(f float32) FDot6

FDot6FromFloat32 converts a float32 to FDot6. Values are scaled by 64 and truncated toward zero.

func FDot6FromFloat64 added in v0.20.2

func FDot6FromFloat64(f float64) FDot6

FDot6FromFloat64 converts a float64 to FDot6.

func FDot6FromInt added in v0.20.2

func FDot6FromInt(n int32) FDot6

FDot6FromInt converts an integer to FDot6. The integer must fit in 26 bits (approximately -33M to +33M).

type FDot8 added in v0.20.2

type FDot8 = int32

FDot8 is a 24.8 fixed-point number (8 fractional bits). Used for anti-aliased coverage values.

func FDot8FromFDot16 added in v0.20.2

func FDot8FromFDot16(v FDot16) FDot8

FDot8FromFDot16 converts an FDot16 to FDot8 with rounding.

type FDot16 added in v0.20.2

type FDot16 = int32

FDot16 is a 16.16 fixed-point number (16 fractional bits). Used for positions, slopes, and forward differencing coefficients where higher precision is needed.

Range: approximately -32768 to +32768 with 1/65536 precision.

func FDot6Div added in v0.20.2

func FDot6Div(a, b FDot6) FDot16

FDot6Div divides two FDot6 values and returns an FDot16. This is used for computing slopes (dx / dy). If the numerator fits in 16 bits, uses fast path.

func FDot6ToFDot16 added in v0.20.2

func FDot6ToFDot16(v FDot6) FDot16

FDot6ToFDot16 converts an FDot6 to FDot16. This is a left shift by 10 bits (16 - 6 = 10).

func FDot6ToFixedDiv2 added in v0.20.2

func FDot6ToFixedDiv2(v FDot6) FDot16

FDot6ToFixedDiv2 converts an FDot6 to FDot16 divided by 2. This is used in quadratic edge setup to avoid overflow. The result is (value / 2) in FDot16 representation.

func FDot16Div added in v0.20.2

func FDot16Div(numer, denom int32) FDot16

FDot16Div divides two FDot6/FDot16 values and returns an FDot16. Uses 64-bit intermediate to avoid overflow.

func FDot16FastDiv added in v0.20.2

func FDot16FastDiv(a, b FDot6) FDot16

FDot16FastDiv divides two FDot6 values using fast 32-bit math. Only valid when the numerator fits in 16 bits.

func FDot16FromFloat32 added in v0.20.2

func FDot16FromFloat32(f float32) FDot16

FDot16FromFloat32 converts a float32 to FDot16.

func FDot16FromFloat64 added in v0.20.2

func FDot16FromFloat64(f float64) FDot16

FDot16FromFloat64 converts a float64 to FDot16.

func FDot16Mul added in v0.20.2

func FDot16Mul(a, b FDot16) FDot16

FDot16Mul multiplies two FDot16 values. Uses 64-bit intermediate to avoid overflow, then truncates.

type FillRule added in v0.20.2

type FillRule int

FillRule determines how overlapping paths are filled.

const (
	// FillRuleNonZero fills regions where the winding number is non-zero.
	// This is the default fill rule and handles self-intersecting paths well.
	FillRuleNonZero FillRule = iota

	// FillRuleEvenOdd fills regions where the winding number is odd.
	// This creates a checkerboard pattern for self-intersecting paths.
	FillRuleEvenOdd
)

func (FillRule) String added in v0.20.2

func (fr FillRule) String() string

String returns the string representation of the fill rule.

type FineRasterizer

type FineRasterizer struct {
	// contains filtered or unexported fields
}

FineRasterizer performs fine rasterization with analytic anti-aliasing. It calculates exact sub-pixel coverage for each tile based on the segments that cross it and the fill rule.

func NewFineRasterizer

func NewFineRasterizer(width, height uint16) *FineRasterizer

NewFineRasterizer creates a new fine rasterizer for the given dimensions.

func (*FineRasterizer) FillRule

func (fr *FineRasterizer) FillRule() scene.FillStyle

FillRule returns the current fill rule.

func (*FineRasterizer) Grid

func (fr *FineRasterizer) Grid() *TileGrid

Grid returns the tile grid with computed coverage.

func (*FineRasterizer) Rasterize

func (fr *FineRasterizer) Rasterize(
	coarse *CoarseRasterizer,
	segments *SegmentList,
	backdrop []int32,
)

Rasterize performs fine rasterization on coarse tile entries. It calculates analytic anti-aliased coverage for each pixel.

func (*FineRasterizer) RasterizeCurves added in v0.20.2

func (fr *FineRasterizer) RasterizeCurves(curveBins map[uint64]*CurveTileBin)

RasterizeCurves processes curve edges directly without pre-flattening. This is the retained mode rendering path for scene graph rendering.

Unlike Rasterize() which works with pre-flattened LineSegments, this method accepts curve edges from EdgeBuilder and steps through their segments during tile processing using forward differencing.

Parameters:

  • curveBins: Map of tile coordinates (as uint64 key) to curve edge bins (from BinCurveEdges)

The output is stored in the FineRasterizer's TileGrid.

func (*FineRasterizer) RenderToBuffer

func (fr *FineRasterizer) RenderToBuffer(
	buffer []uint8,
	width, height int,
	stride int,
	color [4]uint8,
)

RenderToBuffer renders the tile grid to a pixel buffer. The buffer is in RGBA format with the given stride (bytes per row).

func (*FineRasterizer) RenderToBufferSIMD

func (fr *FineRasterizer) RenderToBufferSIMD(
	buffer []uint8,
	width, height int,
	stride int,
	color [4]uint8,
)

RenderToBufferSIMD renders the tile grid using SIMD-optimized blending.

func (*FineRasterizer) Reset

func (fr *FineRasterizer) Reset()

Reset clears the rasterizer state for reuse.

func (*FineRasterizer) SetFillRule

func (fr *FineRasterizer) SetFillRule(rule scene.FillStyle)

SetFillRule sets the fill rule for coverage calculation.

type FlattenContext

type FlattenContext struct {
	// contains filtered or unexported fields
}

FlattenContext provides reusable state for path flattening. Use this to reduce allocations when flattening multiple paths.

func NewFlattenContext

func NewFlattenContext() *FlattenContext

NewFlattenContext creates a new flattening context.

func (*FlattenContext) FlattenPathTo

func (ctx *FlattenContext) FlattenPathTo(path *scene.Path, transform scene.Affine, tolerance float32)

FlattenPathTo flattens a path into the context's segment list.

This avoids allocating a new SegmentList for each path.

func (*FlattenContext) Reset

func (ctx *FlattenContext) Reset()

Reset clears the context for reuse.

func (*FlattenContext) Segments

func (ctx *FlattenContext) Segments() *SegmentList

Segments returns the flattened segments.

type GPUAffineTransform

type GPUAffineTransform struct {
	A        float32 // Scale X
	B        float32 // Shear Y
	C        float32 // Shear X
	D        float32 // Scale Y
	E        float32 // Translate X
	F        float32 // Translate Y
	Padding1 float32
	Padding2 float32
}

GPUAffineTransform represents an affine transform for GPU. Must match AffineTransform in flatten.wgsl. Matrix layout (column-major): | a c e | | b d f | | 0 0 1 |

func ConvertAffineToGPU

func ConvertAffineToGPU(t scene.Affine) GPUAffineTransform

ConvertAffineToGPU converts a scene.Affine to GPU format.

type GPUCoarseConfig

type GPUCoarseConfig struct {
	ViewportWidth  uint32 // Viewport width in pixels
	ViewportHeight uint32 // Viewport height in pixels
	TileColumns    uint32 // Number of tile columns
	TileRows       uint32 // Number of tile rows
	SegmentCount   uint32 // Number of segments to process
	MaxEntries     uint32 // Maximum number of tile entries
	Padding1       uint32 // Padding for alignment
	Padding2       uint32 // Padding for alignment
}

GPUCoarseConfig contains GPU coarse rasterization configuration. Must match CoarseConfig in coarse.wgsl.

type GPUCoarseRasterizer

type GPUCoarseRasterizer struct {
	// contains filtered or unexported fields
}

GPUCoarseRasterizer performs coarse rasterization (tile binning) on the GPU. It creates compute pipelines and manages GPU buffers for segment-to-tile mapping.

func NewGPUCoarseRasterizer

func NewGPUCoarseRasterizer(device hal.Device, queue hal.Queue, width, height uint16) (*GPUCoarseRasterizer, error)

NewGPUCoarseRasterizer creates a new GPU coarse rasterizer. Returns an error if GPU compute is not supported.

func (*GPUCoarseRasterizer) Destroy

func (r *GPUCoarseRasterizer) Destroy()

Destroy releases all GPU resources.

func (*GPUCoarseRasterizer) GetTileEntries

func (r *GPUCoarseRasterizer) GetTileEntries(coarse *CoarseRasterizer) []GPUTileSegmentRef

GetTileEntries returns tile entries from a CoarseRasterizer. This is a convenience method that converts CPU coarse entries to GPU format.

func (*GPUCoarseRasterizer) IsInitialized

func (r *GPUCoarseRasterizer) IsInitialized() bool

IsInitialized returns whether the rasterizer is initialized.

func (*GPUCoarseRasterizer) IsShaderReady

func (r *GPUCoarseRasterizer) IsShaderReady() bool

IsShaderReady returns whether the shader compiled successfully.

func (*GPUCoarseRasterizer) Rasterize

func (r *GPUCoarseRasterizer) Rasterize(segments *SegmentList) ([]GPUTileSegmentRef, error)

Rasterize performs coarse rasterization on the GPU. It takes segments and produces tile entries.

Note: Phase 6.2 implementation. Full GPU dispatch requires buffer binding which needs HAL API extensions. Currently falls back to CPU-computed entries.

func (*GPUCoarseRasterizer) SPIRVCode

func (r *GPUCoarseRasterizer) SPIRVCode() []uint32

SPIRVCode returns the compiled SPIR-V code (for debugging/verification).

func (*GPUCoarseRasterizer) TileColumns

func (r *GPUCoarseRasterizer) TileColumns() uint16

TileColumns returns the number of tile columns.

func (*GPUCoarseRasterizer) TileRows

func (r *GPUCoarseRasterizer) TileRows() uint16

TileRows returns the number of tile rows.

type GPUCursorState

type GPUCursorState struct {
	CurX   float32 // Current cursor X
	CurY   float32 // Current cursor Y
	StartX float32 // Subpath start X (for Close)
	StartY float32 // Subpath start Y (for Close)
}

GPUCursorState tracks the cursor position per path element. Must match CursorState in flatten.wgsl.

type GPUFineConfig

type GPUFineConfig struct {
	ViewportWidth  uint32 // Viewport width in pixels
	ViewportHeight uint32 // Viewport height in pixels
	TileColumns    uint32 // Number of tile columns
	TileRows       uint32 // Number of tile rows
	TileCount      uint32 // Number of tiles to process
	FillRule       uint32 // 0 = NonZero, 1 = EvenOdd
	Padding1       uint32 // Padding for alignment
	Padding2       uint32 // Padding for alignment
}

GPUFineConfig contains GPU fine rasterization configuration. Must match Config in fine.wgsl.

type GPUFineRasterizer

type GPUFineRasterizer struct {
	// contains filtered or unexported fields
}

GPUFineRasterizer performs fine rasterization on the GPU. It creates compute pipelines and manages GPU buffers for coverage calculation.

Note: This is Phase 6.1 implementation. Full GPU buffer binding requires HAL API extensions to expose buffer handles. Currently this serves as infrastructure and data flow verification.

func NewGPUFineRasterizer

func NewGPUFineRasterizer(device hal.Device, queue hal.Queue, width, height uint16) (*GPUFineRasterizer, error)

NewGPUFineRasterizer creates a new GPU fine rasterizer. Returns an error if GPU compute is not supported.

func (*GPUFineRasterizer) Destroy

func (r *GPUFineRasterizer) Destroy()

Destroy releases all GPU resources.

func (*GPUFineRasterizer) IsInitialized

func (r *GPUFineRasterizer) IsInitialized() bool

IsInitialized returns whether the rasterizer is initialized.

func (*GPUFineRasterizer) IsShaderReady

func (r *GPUFineRasterizer) IsShaderReady() bool

IsShaderReady returns whether the shader compiled successfully.

func (*GPUFineRasterizer) Rasterize

func (r *GPUFineRasterizer) Rasterize(
	coarse *CoarseRasterizer,
	segments *SegmentList,
	backdrop []int32,
	fillRule scene.FillStyle,
) ([]uint8, error)

Rasterize performs fine rasterization on the GPU. It takes the coarse rasterizer output and produces coverage values.

Note: Phase 6.1 implementation. Full GPU dispatch requires buffer binding which needs HAL API extensions. Currently falls back to CPU-computed coverage.

func (*GPUFineRasterizer) SPIRVCode

func (r *GPUFineRasterizer) SPIRVCode() []uint32

SPIRVCode returns the compiled SPIR-V code (for debugging/verification).

type GPUFlattenConfig

type GPUFlattenConfig struct {
	ElementCount   uint32  // Number of path elements
	Tolerance      float32 // Flattening tolerance
	MaxSegments    uint32  // Maximum total segments
	TileSize       uint32  // Tile size in pixels
	ViewportWidth  uint32  // Viewport width
	ViewportHeight uint32  // Viewport height
	Padding1       uint32
	Padding2       uint32
}

GPUFlattenConfig contains GPU flattening configuration. Must match FlattenConfig in flatten.wgsl.

type GPUFlattenRasterizer

type GPUFlattenRasterizer struct {
	// contains filtered or unexported fields
}

GPUFlattenRasterizer performs curve flattening on the GPU. It converts Bezier curves to monotonic line segments using Wang's formula.

Note: Phase 6.3 implementation. Full GPU dispatch requires additional cursor tracking infrastructure. Currently provides CPU fallback using the existing flatten.go algorithms.

func NewGPUFlattenRasterizer

func NewGPUFlattenRasterizer(device hal.Device, queue hal.Queue, maxPaths, maxSegments int) (*GPUFlattenRasterizer, error)

NewGPUFlattenRasterizer creates a new GPU flatten rasterizer. maxPaths: Maximum number of path elements to process maxSegments: Maximum number of output segments

func (*GPUFlattenRasterizer) ComputeCursorStates

func (r *GPUFlattenRasterizer) ComputeCursorStates(path *scene.Path) []GPUCursorState

ComputeCursorStates computes cursor states for each path element. This tracks the cursor position (curX, curY) and subpath start (startX, startY) for each element, which is needed by the GPU shader.

func (*GPUFlattenRasterizer) ConvertPathToGPU

func (r *GPUFlattenRasterizer) ConvertPathToGPU(path *scene.Path) ([]GPUPathElement, []float32)

ConvertPathToGPU converts a scene.Path to GPU buffer format. Returns elements and points arrays suitable for GPU upload.

func (*GPUFlattenRasterizer) Destroy

func (r *GPUFlattenRasterizer) Destroy()

Destroy releases all GPU resources.

func (*GPUFlattenRasterizer) EstimateSegmentCount

func (r *GPUFlattenRasterizer) EstimateSegmentCount(path *scene.Path, transform scene.Affine, tolerance float32) int

EstimateSegmentCount estimates the number of segments for a path. Uses Wang's formula to estimate without actually flattening.

func (*GPUFlattenRasterizer) Flatten

func (r *GPUFlattenRasterizer) Flatten(path *scene.Path, transform scene.Affine, tolerance float32) (*SegmentList, error)

Flatten flattens a path to monotonic line segments. Uses CPU fallback (matching existing flatten.go algorithm).

Parameters:

  • path: The input path to flatten
  • transform: Affine transformation to apply to all points
  • tolerance: Flattening tolerance (use 0 for default)

Returns a SegmentList containing all flattened line segments.

func (*GPUFlattenRasterizer) FlattenWithContext

func (r *GPUFlattenRasterizer) FlattenWithContext(
	path *scene.Path,
	transform scene.Affine,
	tolerance float32,
) *SegmentList

FlattenWithContext flattens a path using a provided context for efficiency. This avoids allocating a new SegmentList for each path.

func (*GPUFlattenRasterizer) IsInitialized

func (r *GPUFlattenRasterizer) IsInitialized() bool

IsInitialized returns whether the rasterizer is initialized.

func (*GPUFlattenRasterizer) IsShaderReady

func (r *GPUFlattenRasterizer) IsShaderReady() bool

IsShaderReady returns whether the shader compiled successfully.

func (*GPUFlattenRasterizer) MaxPaths

func (r *GPUFlattenRasterizer) MaxPaths() int

MaxPaths returns the maximum number of path elements.

func (*GPUFlattenRasterizer) MaxSegments

func (r *GPUFlattenRasterizer) MaxSegments() int

MaxSegments returns the maximum number of output segments.

func (*GPUFlattenRasterizer) SPIRVCode

func (r *GPUFlattenRasterizer) SPIRVCode() []uint32

SPIRVCode returns the compiled SPIR-V code (for debugging/verification).

func (*GPUFlattenRasterizer) SetTolerance

func (r *GPUFlattenRasterizer) SetTolerance(tolerance float32)

SetTolerance sets the flattening tolerance.

func (*GPUFlattenRasterizer) Tolerance

func (r *GPUFlattenRasterizer) Tolerance() float32

Tolerance returns the current flattening tolerance.

type GPUInfo

type GPUInfo struct {
	// Name is the GPU name (e.g., "NVIDIA GeForce RTX 3080").
	Name string
	// Vendor is the GPU vendor.
	Vendor string
	// DeviceType is the type of GPU (discrete, integrated, etc.).
	DeviceType types.DeviceType
	// Backend is the graphics API in use (Vulkan, Metal, DX12).
	Backend types.Backend
	// Driver is the driver version string.
	Driver string
}

GPUInfo contains information about the selected GPU.

func (*GPUInfo) String

func (g *GPUInfo) String() string

String returns a human-readable description of the GPU.

type GPUPathElement

type GPUPathElement struct {
	Verb       uint32 // Path verb type (0=MoveTo, 1=LineTo, 2=QuadTo, 3=CubicTo, 4=Close)
	PointStart uint32 // Start index in points array
	PointCount uint32 // Number of points for this element
	Padding    uint32
}

GPUPathElement represents a path element for GPU processing. Must match PathElement in flatten.wgsl.

type GPURasterizer

type GPURasterizer interface {
	// Rasterize performs fine rasterization and returns coverage values.
	Rasterize(
		coarse *CoarseRasterizer,
		segments *SegmentList,
		backdrop []int32,
		fillRule scene.FillStyle,
	) ([]uint8, error)

	// Destroy releases GPU resources.
	Destroy()
}

GPURasterizer is the interface for GPU-accelerated rasterization.

type GPURasterizerStats

type GPURasterizerStats struct {
	// GPUAvailable indicates if GPU is available
	GPUAvailable bool

	// TotalCalls is the total number of rasterization calls
	TotalCalls uint64

	// GPUCalls is the number of calls that used GPU
	GPUCalls uint64

	// CPUCalls is the number of calls that used CPU
	CPUCalls uint64

	// SegmentThreshold is the threshold for GPU usage
	SegmentThreshold int
}

GPURasterizerStats contains statistics about GPU rasterization.

type GPURenderer

type GPURenderer struct {
	// contains filtered or unexported fields
}

GPURenderer is a GPU-backed renderer for immediate mode drawing. It implements the gg.Renderer interface.

Note: This is a stub implementation. The actual GPU rendering will be implemented in TASK-110.

func (*GPURenderer) Close

func (r *GPURenderer) Close()

Close releases renderer resources. Note: This is a stub implementation.

func (*GPURenderer) Fill

func (r *GPURenderer) Fill(pixmap *gg.Pixmap, path *gg.Path, paint *gg.Paint) error

Fill fills a path with the given paint.

Phase 1 Implementation: Uses software rasterization via SoftwareRenderer. Future phases will add GPU texture upload and native GPU path rendering.

func (*GPURenderer) Height

func (r *GPURenderer) Height() int

Height returns the renderer height.

func (*GPURenderer) Stroke

func (r *GPURenderer) Stroke(pixmap *gg.Pixmap, path *gg.Path, paint *gg.Paint) error

Stroke strokes a path with the given paint.

Phase 1 Implementation: Uses software rasterization via SoftwareRenderer. Future phases will add GPU texture upload and native GPU stroke expansion.

func (*GPURenderer) Width

func (r *GPURenderer) Width() int

Width returns the renderer width.

type GPUResources

type GPUResources struct {
	Device         hal.Device
	ShaderModule   hal.ShaderModule
	PipelineLayout hal.PipelineLayout
	BindLayouts    []hal.BindGroupLayout
	Pipelines      []hal.ComputePipeline
}

DestroyGPUResources safely destroys common GPU resources. This is a helper for the cleanup pattern used by all GPU rasterizers.

func (*GPUResources) Destroy

func (r *GPUResources) Destroy()

Destroy cleans up all GPU resources in the correct order.

type GPUSceneRenderer

type GPUSceneRenderer struct {
	// contains filtered or unexported fields
}

GPUSceneRenderer renders scenes using GPU acceleration. It implements the full render pipeline: scene decoding, path rasterization, coverage calculation, and layer compositing.

The renderer uses HybridPipeline which automatically selects between GPU and CPU execution for each stage based on workload size.

GPUSceneRenderer is safe for concurrent use from multiple goroutines.

func NewGPUSceneRenderer

func NewGPUSceneRenderer(backend *NativeBackend, config GPUSceneRendererConfig) (*GPUSceneRenderer, error)

NewGPUSceneRenderer creates a new GPU scene renderer. The renderer is configured for the specified dimensions.

Returns an error if the backend is not initialized or configuration is invalid.

func (*GPUSceneRenderer) Close

func (r *GPUSceneRenderer) Close()

Close releases all renderer resources.

func (*GPUSceneRenderer) Height

func (r *GPUSceneRenderer) Height() int

Height returns the renderer height.

func (*GPUSceneRenderer) LayerDepth

func (r *GPUSceneRenderer) LayerDepth() int

LayerDepth returns the current layer stack depth.

func (*GPUSceneRenderer) MemoryStats

func (r *GPUSceneRenderer) MemoryStats() MemoryStats

MemoryStats returns GPU memory usage statistics.

func (*GPUSceneRenderer) RenderScene

func (r *GPUSceneRenderer) RenderScene(s *scene.Scene) error

RenderScene renders a complete scene to the internal target texture. After rendering, use DownloadPixmap to retrieve the result.

For cancellable rendering, use RenderSceneWithContext.

func (*GPUSceneRenderer) RenderSceneWithContext

func (r *GPUSceneRenderer) RenderSceneWithContext(ctx context.Context, s *scene.Scene) error

RenderSceneWithContext renders a complete scene to the internal target texture with cancellation support.

The context can be used to cancel long-running renders. When canceled, the function returns ctx.Err() and the texture may contain partial results.

func (*GPUSceneRenderer) RenderToPixmap

func (r *GPUSceneRenderer) RenderToPixmap(target *gg.Pixmap, s *scene.Scene) error

RenderToPixmap renders a scene directly to a pixmap. This is a convenience method that renders and downloads in one call.

For cancellable rendering, use RenderToPixmapWithContext.

func (*GPUSceneRenderer) RenderToPixmapWithContext

func (r *GPUSceneRenderer) RenderToPixmapWithContext(ctx context.Context, target *gg.Pixmap, s *scene.Scene) error

RenderToPixmapWithContext renders a scene directly to a pixmap with cancellation support. This is a convenience method that renders and downloads in one call.

The context can be used to cancel long-running renders. When canceled, the function returns ctx.Err() and the target may contain partial results.

func (*GPUSceneRenderer) Resize

func (r *GPUSceneRenderer) Resize(width, height int) error

Resize resizes the renderer to new dimensions. All layer textures are released and the target texture is reallocated.

func (*GPUSceneRenderer) Width

func (r *GPUSceneRenderer) Width() int

Width returns the renderer width.

type GPUSceneRendererConfig

type GPUSceneRendererConfig struct {
	// Width is the render target width in pixels.
	Width int

	// Height is the render target height in pixels.
	Height int

	// MaxLayers is the maximum layer stack depth (default: 16).
	MaxLayers int

	// MemoryBudgetMB is the texture memory budget in MB (default: 128).
	MemoryBudgetMB int
}

GPUSceneRendererConfig holds configuration for creating a GPUSceneRenderer.

type GPUSegment

type GPUSegment struct {
	X0      float32 // Start X coordinate
	Y0      float32 // Start Y coordinate
	X1      float32 // End X coordinate
	Y1      float32 // End Y coordinate
	Winding int32   // Winding direction: +1 or -1
	TileY0  int32   // Starting tile Y (precomputed)
	TileY1  int32   // Ending tile Y (precomputed)
	Padding int32   // Padding for alignment
}

GPUSegment is the GPU-compatible layout of LineSegment. Must match the Segment struct in fine.wgsl.

type GPUSegmentCount

type GPUSegmentCount struct {
	Count    uint32 // Number of segments for this element
	Offset   uint32 // Prefix sum offset
	Padding1 uint32
	Padding2 uint32
}

GPUSegmentCount holds segment count per path element. Must match SegmentCount in flatten.wgsl.

type GPUTexture

type GPUTexture struct {
	// contains filtered or unexported fields
}

GPUTexture represents a GPU texture resource. It wraps the underlying wgpu texture and provides a high-level interface for texture operations including upload and download.

GPUTexture is safe for concurrent read access. Write operations (Upload, Close) should be synchronized externally.

func CreateTexture

func CreateTexture(backend *NativeBackend, config TextureConfig) (*GPUTexture, error)

CreateTexture creates a new GPU texture with the given configuration. The texture is uninitialized and should be filled with UploadPixmap.

Note: This is a stub implementation. The actual GPU texture creation will be implemented when wgpu texture support is complete.

func CreateTextureFromPixmap

func CreateTextureFromPixmap(backend *NativeBackend, pixmap *gg.Pixmap, label string) (*GPUTexture, error)

CreateTextureFromPixmap creates a GPU texture from a pixmap, uploading the pixel data immediately.

func (*GPUTexture) Close

func (t *GPUTexture) Close()

Close releases the GPU texture resources. The texture should not be used after Close is called.

func (*GPUTexture) DownloadPixmap

func (t *GPUTexture) DownloadPixmap() (*gg.Pixmap, error)

DownloadPixmap downloads pixel data from GPU to a new Pixmap. This operation requires the texture to have CopySrc usage.

Note: This is a stub implementation that returns an error. GPU readback requires staging buffers and synchronization.

func (*GPUTexture) Format

func (t *GPUTexture) Format() TextureFormat

Format returns the texture format.

func (*GPUTexture) Height

func (t *GPUTexture) Height() int

Height returns the texture height in pixels.

func (*GPUTexture) IsReleased

func (t *GPUTexture) IsReleased() bool

IsReleased returns true if the texture has been released.

func (*GPUTexture) Label

func (t *GPUTexture) Label() string

Label returns the debug label.

func (*GPUTexture) SetMemoryManager

func (t *GPUTexture) SetMemoryManager(m *MemoryManager)

SetMemoryManager sets the memory manager for tracking. This is called internally when allocating through MemoryManager.

func (*GPUTexture) SizeBytes

func (t *GPUTexture) SizeBytes() uint64

SizeBytes returns the texture size in bytes.

func (*GPUTexture) String

func (t *GPUTexture) String() string

String returns a string representation of the texture.

func (*GPUTexture) TextureID

func (t *GPUTexture) TextureID() core.TextureID

TextureID returns the underlying wgpu texture ID. Returns a zero ID for stub textures.

func (*GPUTexture) UploadPixmap

func (t *GPUTexture) UploadPixmap(pixmap *gg.Pixmap) error

UploadPixmap uploads pixel data from a Pixmap to the GPU texture. The pixmap dimensions must match the texture dimensions.

Note: This is a stub implementation. The actual GPU upload will be implemented when wgpu queue.WriteTexture is available.

func (*GPUTexture) UploadRegion

func (t *GPUTexture) UploadRegion(x, y int, pixmap *gg.Pixmap) error

UploadRegion uploads pixel data to a region of the texture. This is useful for texture atlas updates.

Note: This is a stub implementation.

func (*GPUTexture) ViewID

func (t *GPUTexture) ViewID() core.TextureViewID

ViewID returns the texture view ID. Returns a zero ID for stub textures.

func (*GPUTexture) Width

func (t *GPUTexture) Width() int

Width returns the texture width in pixels.

type GPUTileInfo

type GPUTileInfo struct {
	TileX    uint32 // Tile X coordinate
	TileY    uint32 // Tile Y coordinate
	StartIdx uint32 // Start index in tile_segments
	Count    uint32 // Number of segments for this tile
	Backdrop int32  // Accumulated winding from left
	Padding1 uint32 // Padding for alignment
	Padding2 uint32 // Padding for alignment
	Padding3 uint32 // Padding for alignment
}

GPUTileInfo contains tile processing information. Must match TileInfo in fine.wgsl.

type GPUTileSegmentRef

type GPUTileSegmentRef struct {
	TileX       uint32 // Tile X coordinate
	TileY       uint32 // Tile Y coordinate
	SegmentIdx  uint32 // Index into segments array
	WindingFlag uint32 // Whether this contributes winding (0 or 1)
}

GPUTileSegmentRef maps a segment to a tile. Must match TileSegmentRef in fine.wgsl.

type GeomPoint added in v0.20.2

type GeomPoint struct {
	X, Y float32
}

GeomPoint represents a 2D point for geometry calculations. Using a local type to avoid coupling with scene.Point and CurvePoint.

func ZeroGeomPoint added in v0.20.2

func ZeroGeomPoint() GeomPoint

ZeroGeomPoint returns the origin point.

type GridRasterParams

type GridRasterParams struct {
	Color        [4]float32 // Fill color (RGBA normalized)
	TargetWidth  int32      // Target texture width
	TargetHeight int32      // Target texture height
	TileCount    int32      // Number of tiles in grid
}

GridRasterParams contains parameters for tile grid rasterization.

type HALAdapter

type HALAdapter struct {
	// contains filtered or unexported fields
}

HALAdapter implements gpucore.GPUAdapter using gogpu/wgpu/hal directly. It provides a bridge between the gpucore abstraction and the HAL layer.

Thread Safety: HALAdapter is safe for concurrent use from multiple goroutines. All resource operations are protected by a mutex.

func NewHALAdapter

func NewHALAdapter(device hal.Device, queue hal.Queue, limits *types.Limits) *HALAdapter

NewHALAdapter creates a new HALAdapter wrapping the given device and queue. The limits parameter provides the adapter's capability limits. If limits is nil, default limits are used.

func (*HALAdapter) BeginComputePass

func (a *HALAdapter) BeginComputePass() gpucore.ComputePassEncoder

BeginComputePass begins a compute pass.

func (*HALAdapter) CreateBindGroup

func (a *HALAdapter) CreateBindGroup(layout gpucore.BindGroupLayoutID, entries []gpucore.BindGroupEntry) (gpucore.BindGroupID, error)

CreateBindGroup creates a bind group.

func (*HALAdapter) CreateBindGroupLayout

func (a *HALAdapter) CreateBindGroupLayout(desc *gpucore.BindGroupLayoutDesc) (gpucore.BindGroupLayoutID, error)

CreateBindGroupLayout creates a bind group layout.

func (*HALAdapter) CreateBuffer

func (a *HALAdapter) CreateBuffer(size int, usage gpucore.BufferUsage) (gpucore.BufferID, error)

CreateBuffer creates a GPU buffer.

func (*HALAdapter) CreateComputePipeline

func (a *HALAdapter) CreateComputePipeline(desc *gpucore.ComputePipelineDesc) (gpucore.ComputePipelineID, error)

CreateComputePipeline creates a compute pipeline.

func (*HALAdapter) CreatePipelineLayout

func (a *HALAdapter) CreatePipelineLayout(layouts []gpucore.BindGroupLayoutID) (gpucore.PipelineLayoutID, error)

CreatePipelineLayout creates a pipeline layout.

func (*HALAdapter) CreateShaderModule

func (a *HALAdapter) CreateShaderModule(spirv []uint32, label string) (gpucore.ShaderModuleID, error)

CreateShaderModule creates a shader module from SPIR-V bytecode.

func (*HALAdapter) CreateTexture

func (a *HALAdapter) CreateTexture(width, height int, format gpucore.TextureFormat) (gpucore.TextureID, error)

CreateTexture creates a GPU texture.

func (*HALAdapter) DestroyBindGroup

func (a *HALAdapter) DestroyBindGroup(id gpucore.BindGroupID)

DestroyBindGroup releases a bind group.

func (*HALAdapter) DestroyBindGroupLayout

func (a *HALAdapter) DestroyBindGroupLayout(id gpucore.BindGroupLayoutID)

DestroyBindGroupLayout releases a bind group layout.

func (*HALAdapter) DestroyBuffer

func (a *HALAdapter) DestroyBuffer(id gpucore.BufferID)

DestroyBuffer releases a GPU buffer.

func (*HALAdapter) DestroyComputePipeline

func (a *HALAdapter) DestroyComputePipeline(id gpucore.ComputePipelineID)

DestroyComputePipeline releases a compute pipeline.

func (*HALAdapter) DestroyPipelineLayout

func (a *HALAdapter) DestroyPipelineLayout(id gpucore.PipelineLayoutID)

DestroyPipelineLayout releases a pipeline layout.

func (*HALAdapter) DestroyShaderModule

func (a *HALAdapter) DestroyShaderModule(id gpucore.ShaderModuleID)

DestroyShaderModule releases a shader module.

func (*HALAdapter) DestroyTexture

func (a *HALAdapter) DestroyTexture(id gpucore.TextureID)

DestroyTexture releases a GPU texture.

func (*HALAdapter) MaxBufferSize

func (a *HALAdapter) MaxBufferSize() uint64

MaxBufferSize returns the maximum buffer size in bytes.

func (*HALAdapter) MaxWorkgroupSize

func (a *HALAdapter) MaxWorkgroupSize() [3]uint32

MaxWorkgroupSize returns the maximum workgroup size in each dimension.

func (*HALAdapter) ReadBuffer

func (a *HALAdapter) ReadBuffer(id gpucore.BufferID, offset, size uint64) ([]byte, error)

ReadBuffer reads data from a buffer. This operation requires a staging buffer and GPU-CPU synchronization.

func (*HALAdapter) ReadTexture

func (a *HALAdapter) ReadTexture(id gpucore.TextureID) ([]byte, error)

ReadTexture reads data from a texture.

func (*HALAdapter) Submit

func (a *HALAdapter) Submit()

Submit submits recorded commands to the GPU.

func (*HALAdapter) SupportsCompute

func (a *HALAdapter) SupportsCompute() bool

SupportsCompute returns whether compute shaders are supported.

func (*HALAdapter) WaitIdle

func (a *HALAdapter) WaitIdle()

WaitIdle waits for all GPU operations to complete.

func (*HALAdapter) WriteBuffer

func (a *HALAdapter) WriteBuffer(id gpucore.BufferID, offset uint64, data []byte)

WriteBuffer writes data to a buffer.

func (*HALAdapter) WriteTexture

func (a *HALAdapter) WriteTexture(id gpucore.TextureID, data []byte)

WriteTexture writes data to a texture.

type HybridFineRasterizer

type HybridFineRasterizer struct {
	// contains filtered or unexported fields
}

HybridFineRasterizer automatically selects between GPU and CPU rasterization based on workload size and GPU availability.

func NewHybridFineRasterizer

func NewHybridFineRasterizer(width, height uint16, config HybridFineRasterizerConfig) *HybridFineRasterizer

NewHybridFineRasterizer creates a hybrid rasterizer that automatically selects between GPU and CPU based on workload.

func (*HybridFineRasterizer) Destroy

func (h *HybridFineRasterizer) Destroy()

Destroy releases all resources.

func (*HybridFineRasterizer) FillRule

func (h *HybridFineRasterizer) FillRule() scene.FillStyle

FillRule returns the current fill rule.

func (*HybridFineRasterizer) Grid

func (h *HybridFineRasterizer) Grid() *TileGrid

Grid returns the tile grid with computed coverage.

func (*HybridFineRasterizer) IsGPUAvailable

func (h *HybridFineRasterizer) IsGPUAvailable() bool

IsGPUAvailable returns whether GPU rasterization is available.

func (*HybridFineRasterizer) Rasterize

func (h *HybridFineRasterizer) Rasterize(
	coarse *CoarseRasterizer,
	segments *SegmentList,
	backdrop []int32,
)

Rasterize performs fine rasterization, automatically selecting GPU or CPU.

func (*HybridFineRasterizer) Reset

func (h *HybridFineRasterizer) Reset()

Reset clears the rasterizer state for reuse.

func (*HybridFineRasterizer) SetFillRule

func (h *HybridFineRasterizer) SetFillRule(rule scene.FillStyle)

SetFillRule sets the fill rule for coverage calculation.

func (*HybridFineRasterizer) Stats

Stats returns statistics about rasterization calls. Note: Currently returns static info; could track actual call counts.

type HybridFineRasterizerConfig

type HybridFineRasterizerConfig struct {
	// Device and Queue for GPU operations (nil to use CPU only)
	Device hal.Device
	Queue  hal.Queue

	// SegmentThreshold is the minimum segments to use GPU (0 = use default)
	SegmentThreshold int

	// ForceGPU forces GPU even for small workloads (for testing)
	ForceGPU bool

	// ForceCPU disables GPU entirely (for testing/fallback)
	ForceCPU bool
}

HybridFineRasterizerConfig configures the hybrid rasterizer.

type HybridPipeline

type HybridPipeline struct {
	// contains filtered or unexported fields
}

HybridPipeline integrates all three GPU shaders into a unified pipeline: Flatten (path -> segments) -> Coarse (segments -> tile bins) -> Fine (tile bins -> coverage)

The pipeline automatically selects GPU or CPU for each stage based on workload size and GPU availability.

func NewHybridPipeline

func NewHybridPipeline(width, height uint16, config HybridPipelineConfig) *HybridPipeline

NewHybridPipeline creates a new hybrid pipeline that integrates all GPU stages.

func (*HybridPipeline) Destroy

func (p *HybridPipeline) Destroy()

Destroy releases all GPU resources.

func (*HybridPipeline) Grid

func (p *HybridPipeline) Grid() *TileGrid

Grid returns the tile grid with computed coverage.

func (*HybridPipeline) IsGPUAvailable

func (p *HybridPipeline) IsGPUAvailable() bool

IsGPUAvailable returns whether any GPU stage is available.

func (*HybridPipeline) IsStageGPUAvailable

func (p *HybridPipeline) IsStageGPUAvailable(stage PipelineStage) bool

IsStageGPUAvailable returns whether a specific stage has GPU available.

func (*HybridPipeline) RasterizePath

func (p *HybridPipeline) RasterizePath(
	path *scene.Path,
	transform scene.Affine,
	fillRule scene.FillStyle,
) *TileGrid

RasterizePath runs the full pipeline: path -> segments -> tile bins -> coverage.

Parameters:

  • path: The input path to rasterize
  • transform: Affine transformation to apply
  • fillRule: Fill rule for coverage calculation

Returns the tile grid with computed coverage.

func (*HybridPipeline) Reset

func (p *HybridPipeline) Reset()

Reset clears all rasterizer state for reuse.

func (*HybridPipeline) ResetStats

func (p *HybridPipeline) ResetStats()

ResetStats resets all statistics counters.

func (*HybridPipeline) SetFillRule

func (p *HybridPipeline) SetFillRule(rule scene.FillStyle)

SetFillRule sets the fill rule for coverage calculation.

func (*HybridPipeline) SetTolerance

func (p *HybridPipeline) SetTolerance(tolerance float32)

SetTolerance sets the flattening tolerance.

func (*HybridPipeline) Stats

Stats returns statistics about pipeline execution.

type HybridPipelineConfig

type HybridPipelineConfig struct {
	// Device and Queue for GPU operations (nil to use CPU only)
	Device hal.Device
	Queue  hal.Queue

	// Stage-specific thresholds (0 = use defaults)
	FlattenThreshold int // Min path elements for GPU flatten
	CoarseThreshold  int // Min segments for GPU coarse
	FineThreshold    int // Min tile entries for GPU fine

	// MaxPaths is the maximum path elements for flatten (0 = default 1024)
	MaxPaths int

	// MaxSegments is the maximum segments for flatten (0 = default MaxPaths * 64)
	MaxSegments int

	// Force flags for testing
	ForceGPU bool // Force GPU for all stages (ignores thresholds)
	ForceCPU bool // Force CPU for all stages (disables GPU)

	// Tolerance for curve flattening (0 = use default)
	Tolerance float32
}

HybridPipelineConfig configures the hybrid pipeline.

type HybridPipelineStats

type HybridPipelineStats struct {
	// GPU availability per stage
	FlattenGPUAvailable bool
	CoarseGPUAvailable  bool
	FineGPUAvailable    bool

	// Call counts per stage
	FlattenTotalCalls uint64
	FlattenGPUCalls   uint64
	FlattenCPUCalls   uint64

	CoarseTotalCalls uint64
	CoarseGPUCalls   uint64
	CoarseCPUCalls   uint64

	FineTotalCalls uint64
	FineGPUCalls   uint64
	FineCPUCalls   uint64

	// Thresholds
	FlattenThreshold int
	CoarseThreshold  int
	FineThreshold    int

	// Last operation details
	LastPathElements   int
	LastSegmentCount   int
	LastTileEntryCount int
	LastFlattenUsedGPU bool
	LastCoarseUsedGPU  bool
	LastFineUsedGPU    bool
}

HybridPipelineStats contains statistics about pipeline execution.

type ImageCopyBuffer added in v0.20.0

type ImageCopyBuffer struct {
	// Buffer is the buffer to copy to/from.
	Buffer *core.Buffer

	// Layout describes how the data is laid out in the buffer.
	Layout types.TextureDataLayout
}

ImageCopyBuffer describes a buffer for texture copy operations.

type ImageCopyTexture added in v0.20.0

type ImageCopyTexture struct {
	// Texture is the texture to copy to/from.
	Texture *GPUTexture

	// MipLevel is the mip level to copy.
	MipLevel uint32

	// Origin is the origin of the copy in the texture.
	Origin types.Origin3D

	// Aspect is the aspect of the texture to copy.
	Aspect types.TextureAspect
}

ImageCopyTexture describes a texture for copy operations.

type IndexFormat

type IndexFormat uint32

IndexFormat specifies the format of index buffer elements.

const (
	// IndexFormatUint16 uses 16-bit unsigned integers.
	IndexFormatUint16 IndexFormat = 0

	// IndexFormatUint32 uses 32-bit unsigned integers.
	IndexFormatUint32 IndexFormat = 1
)

type LayerDescriptor

type LayerDescriptor struct {
	TextureIdx uint32  // Index into layer textures
	BlendMode  uint32  // Blend mode for this layer
	Alpha      float32 // Layer opacity
	Padding    float32 // Alignment padding
}

LayerDescriptor represents a single layer for compositing. This matches the Layer struct in composite.wgsl.

type LineEdge added in v0.20.2

type LineEdge struct {
	// Linked list pointers (indices into edge array).
	// Using Option<u32> pattern from Rust as nullable int32.
	Prev int32
	Next int32

	// X is the current X position in FDot16 (16.16 fixed-point).
	X FDot16

	// DX is the slope: change in X per scanline (in FDot16).
	DX FDot16

	// FirstY is the first scanline this edge covers.
	FirstY int32

	// LastY is the last scanline this edge covers (inclusive).
	LastY int32

	// Winding indicates direction: +1 for downward, -1 for upward.
	Winding int8
}

LineEdge represents a single line segment in the Active Edge Table. This is the base type that QuadraticEdge and CubicEdge use internally. Derived from tiny-skia's LineEdge.

func NewLineEdge added in v0.20.2

func NewLineEdge(p0, p1 CurvePoint, shift int) *LineEdge

NewLineEdge creates a new line edge from two points. Returns nil if the edge is horizontal (no Y extent).

Parameters:

  • p0, p1: endpoints in pixel coordinates
  • shift: AA shift (0 for no AA, 2 for 4x AA quality)

func (*LineEdge) IsVertical added in v0.20.2

func (e *LineEdge) IsVertical() bool

IsVertical returns true if the edge has zero slope.

type LineSegment

type LineSegment struct {
	// Start point (X0, Y0) and end point (X1, Y1).
	// For monotonic segments, Y0 <= Y1 (always going down).
	X0, Y0, X1, Y1 float32

	// Winding direction: +1 for left-to-right, -1 for right-to-left.
	// Determined by original path direction before monotonic split.
	Winding int8

	// TileY0, TileY1 are the tile row range this segment spans.
	// Precomputed for efficient coarse rasterization.
	TileY0, TileY1 int32
}

LineSegment represents a monotonic line segment for tile processing. A monotonic segment has consistent Y direction (always going down or up). This simplifies tile intersection calculations.

func NewLineSegment

func NewLineSegment(x0, y0, x1, y1 float32, winding int8) LineSegment

NewLineSegment creates a new line segment, ensuring Y0 <= Y1. The winding is adjusted if the segment is flipped.

func (*LineSegment) Bounds

func (s *LineSegment) Bounds() (minX, minY, maxX, maxY float32)

Bounds returns the bounding box of the segment.

func (*LineSegment) CrossesTileRow

func (s *LineSegment) CrossesTileRow(tileY int32) bool

CrossesTileRow returns true if the segment crosses the given tile row.

func (*LineSegment) DeltaX

func (s *LineSegment) DeltaX() float32

DeltaX returns the X distance of the segment.

func (*LineSegment) DeltaY

func (s *LineSegment) DeltaY() float32

DeltaY returns the Y distance of the segment.

func (*LineSegment) InverseSlope

func (s *LineSegment) InverseSlope() float32

InverseSlope returns dy/dx. Returns a large value for vertical segments.

func (*LineSegment) IsHorizontal

func (s *LineSegment) IsHorizontal() bool

IsHorizontal returns true if the segment is approximately horizontal.

func (*LineSegment) IsVertical

func (s *LineSegment) IsVertical() bool

IsVertical returns true if the segment is approximately vertical.

func (*LineSegment) Slope

func (s *LineSegment) Slope() float32

Slope returns the slope (dx/dy) of the segment. Returns 0 for horizontal segments.

func (*LineSegment) TileXRange

func (s *LineSegment) TileXRange(tileY int32) (minTileX, maxTileX int32)

TileXRange returns the range of tile columns this segment touches at a given tile row.

func (*LineSegment) XAtY

func (s *LineSegment) XAtY(y float32) float32

XAtY returns the X coordinate at a given Y. Assumes Y is within the segment's Y range.

func (*LineSegment) YAtX

func (s *LineSegment) YAtX(x float32) float32

YAtX returns the Y coordinate at a given X. Assumes X is within the segment's X range.

type MemoryManager

type MemoryManager struct {
	// contains filtered or unexported fields
}

MemoryManager tracks GPU memory allocations and enforces budget limits. It provides LRU eviction when the memory budget is exceeded.

MemoryManager is safe for concurrent use.

func NewMemoryManager

func NewMemoryManager(backend *NativeBackend, config MemoryManagerConfig) *MemoryManager

NewMemoryManager creates a new memory manager for GPU memory tracking. The backend parameter is used for texture creation operations.

func (*MemoryManager) AllocTexture

func (m *MemoryManager) AllocTexture(config TextureConfig) (*GPUTexture, error)

AllocTexture allocates a new texture with the given configuration. If the allocation would exceed the memory budget, LRU eviction is triggered. Returns an error if the allocation cannot be satisfied even after eviction.

func (*MemoryManager) Close

func (m *MemoryManager) Close()

Close releases all managed textures and closes the memory manager. The manager should not be used after Close is called.

func (*MemoryManager) Contains

func (m *MemoryManager) Contains(tex *GPUTexture) bool

Contains returns true if the texture is managed by this manager.

func (*MemoryManager) FreeTexture

func (m *MemoryManager) FreeTexture(tex *GPUTexture) error

FreeTexture releases a texture and returns its memory to the pool. The texture is closed and should not be used after this call.

func (*MemoryManager) SetBudget

func (m *MemoryManager) SetBudget(megabytes int) error

SetBudget updates the memory budget. If the new budget is lower than current usage, eviction may be triggered.

func (*MemoryManager) Stats

func (m *MemoryManager) Stats() MemoryStats

Stats returns current memory usage statistics.

func (*MemoryManager) Textures

func (m *MemoryManager) Textures() []*GPUTexture

Textures returns a slice of all managed textures. The returned slice is a copy and can be safely modified.

func (*MemoryManager) TouchTexture

func (m *MemoryManager) TouchTexture(tex *GPUTexture)

TouchTexture updates the last-used time of a texture, moving it to the front of the LRU list. Call this when a texture is used for rendering.

type MemoryManagerConfig

type MemoryManagerConfig struct {
	// MaxMemoryMB is the maximum memory budget in megabytes.
	// Defaults to DefaultMaxMemoryMB if <= 0.
	MaxMemoryMB int

	// EvictionThreshold is the usage fraction at which eviction starts.
	// Defaults to DefaultEvictionThreshold if <= 0.
	EvictionThreshold float64
}

MemoryManagerConfig holds configuration for creating a MemoryManager.

type MemoryStats

type MemoryStats struct {
	// TotalBytes is the total memory budget in bytes.
	TotalBytes uint64

	// UsedBytes is the currently allocated memory in bytes.
	UsedBytes uint64

	// AvailableBytes is the remaining memory budget.
	AvailableBytes uint64

	// TextureCount is the number of allocated textures.
	TextureCount int

	// EvictionCount is the total number of textures evicted.
	EvictionCount uint64

	// Utilization is the percentage of budget used (0.0 to 1.0).
	Utilization float64
}

MemoryStats contains GPU memory usage statistics.

func (MemoryStats) String

func (s MemoryStats) String() string

String returns a human-readable string of memory stats.

type NativeBackend

type NativeBackend struct {
	// contains filtered or unexported fields
}

NativeBackend is a GPU-accelerated rendering backend using gogpu/wgpu. It implements the backend.RenderBackend interface.

The backend manages GPU resources including instance, adapter, device, and queue. It supports both immediate mode rendering (via NewRenderer) and retained mode rendering (via RenderScene).

func NewNativeBackend

func NewNativeBackend() *NativeBackend

NewNativeBackend creates a new Pure Go GPU rendering backend. The backend must be initialized with Init() before use.

func (*NativeBackend) Close

func (b *NativeBackend) Close()

Close releases all backend resources. The backend should not be used after Close is called.

func (*NativeBackend) Device

func (b *NativeBackend) Device() core.DeviceID

Device returns the GPU device ID. Returns a zero ID if the backend is not initialized.

func (*NativeBackend) GPUInfo

func (b *NativeBackend) GPUInfo() *GPUInfo

GPUInfo returns information about the selected GPU. Returns nil if the backend is not initialized.

func (*NativeBackend) Init

func (b *NativeBackend) Init() error

Init initializes the backend by creating GPU resources. This includes creating an instance, requesting an adapter, creating a device, and getting the command queue.

Returns an error if GPU initialization fails.

func (*NativeBackend) IsInitialized

func (b *NativeBackend) IsInitialized() bool

IsInitialized returns true if the backend has been initialized.

func (*NativeBackend) Name

func (b *NativeBackend) Name() string

Name returns the backend identifier.

func (*NativeBackend) NewRenderer

func (b *NativeBackend) NewRenderer(width, height int) gg.Renderer

NewRenderer creates a renderer for immediate mode rendering. The renderer is sized for the given dimensions.

Note: This is a stub implementation that returns a GPURenderer. The actual GPU rendering will be implemented in TASK-110.

func (*NativeBackend) Queue

func (b *NativeBackend) Queue() core.QueueID

Queue returns the GPU queue ID. Returns a zero ID if the backend is not initialized.

func (*NativeBackend) RenderScene

func (b *NativeBackend) RenderScene(target *gg.Pixmap, s *scene.Scene) error

RenderScene renders a scene to the target pixmap using retained mode. This method is optimized for complex scenes with many draw operations.

The implementation uses GPUSceneRenderer for tessellation, strip rasterization, and layer compositing on the GPU. When wgpu texture readback is fully implemented, results will be downloaded to the target pixmap. Currently, data flows through the GPU pipeline as stubs.

type PipelineCache

type PipelineCache struct {
	// contains filtered or unexported fields
}

PipelineCache caches compiled GPU pipelines for rendering operations. It manages bind group layouts and pipelines for blit, blend, strip rasterization, and compositing operations.

PipelineCache is safe for concurrent read access. Pipeline creation is synchronized internally.

func NewPipelineCache

func NewPipelineCache(device core.DeviceID, shaders *ShaderModules) (*PipelineCache, error)

NewPipelineCache creates a new pipeline cache for the given device. It initializes all base pipelines using the provided shader modules.

Returns an error if pipeline creation fails.

func (*PipelineCache) BlendPipelineCount

func (pc *PipelineCache) BlendPipelineCount() int

BlendPipelineCount returns the number of cached blend pipelines. Useful for debugging and monitoring.

func (*PipelineCache) Close

func (pc *PipelineCache) Close()

Close releases all pipeline resources.

func (*PipelineCache) CreateBlendBindGroup

func (pc *PipelineCache) CreateBlendBindGroup(tex *GPUTexture, params *BlendParams) StubBindGroupID

CreateBlendBindGroup creates a bind group for blend operations.

func (*PipelineCache) CreateBlitBindGroup

func (pc *PipelineCache) CreateBlitBindGroup(tex *GPUTexture) StubBindGroupID

CreateBlitBindGroup creates a bind group for blit operations.

func (*PipelineCache) CreateStripBindGroup

func (pc *PipelineCache) CreateStripBindGroup(
	headerBuffer StubBufferID,
	coverageBuffer StubBufferID,
	outputTex *GPUTexture,
	params *StripParams,
) StubBindGroupID

CreateStripBindGroup creates a bind group for strip compute operations.

func (*PipelineCache) GetBlendLayout

func (pc *PipelineCache) GetBlendLayout() StubBindGroupLayoutID

GetBlendLayout returns the bind group layout for blend operations.

func (*PipelineCache) GetBlendPipeline

func (pc *PipelineCache) GetBlendPipeline(mode scene.BlendMode) StubPipelineID

GetBlendPipeline returns the pipeline for the specified blend mode. Pipelines are created on demand and cached.

func (*PipelineCache) GetBlitLayout

func (pc *PipelineCache) GetBlitLayout() StubBindGroupLayoutID

GetBlitLayout returns the bind group layout for blit operations.

func (*PipelineCache) GetBlitPipeline

func (pc *PipelineCache) GetBlitPipeline() StubPipelineID

GetBlitPipeline returns the blit pipeline.

func (*PipelineCache) GetCompositePipeline

func (pc *PipelineCache) GetCompositePipeline() StubPipelineID

GetCompositePipeline returns the compositing pipeline.

func (*PipelineCache) GetStripLayout

func (pc *PipelineCache) GetStripLayout() StubBindGroupLayoutID

GetStripLayout returns the bind group layout for strip compute.

func (*PipelineCache) GetStripPipeline

func (pc *PipelineCache) GetStripPipeline() StubComputePipelineID

GetStripPipeline returns the strip rasterization compute pipeline.

func (*PipelineCache) IsInitialized

func (pc *PipelineCache) IsInitialized() bool

IsInitialized returns true if the cache has been initialized.

func (*PipelineCache) WarmupBlendPipelines

func (pc *PipelineCache) WarmupBlendPipelines()

WarmupBlendPipelines pre-creates pipelines for commonly used blend modes. This avoids pipeline compilation stutter during first use.

type PipelineCacheCore added in v0.20.0

type PipelineCacheCore struct {
	// contains filtered or unexported fields
}

PipelineCacheCore caches compiled render and compute pipelines.

Pipeline creation is expensive because it involves shader compilation and validation. This cache stores pipelines indexed by descriptor hash to avoid redundant creation.

Thread Safety: PipelineCacheCore is safe for concurrent use. It uses RWMutex with double-check locking for efficient reads and safe writes.

Usage:

cache := NewPipelineCacheCore()
pipeline, err := cache.GetOrCreateRenderPipeline(device, desc)
if err != nil {
    // handle error
}
// Use pipeline for rendering

The cache tracks hit/miss statistics for performance monitoring.

func NewPipelineCacheCore added in v0.20.0

func NewPipelineCacheCore() *PipelineCacheCore

NewPipelineCacheCore creates a new pipeline cache.

The cache starts empty and pipelines are created on demand.

func (*PipelineCacheCore) Clear added in v0.20.0

func (c *PipelineCacheCore) Clear()

Clear removes all cached pipelines and resets statistics.

This does NOT destroy the underlying resources. Call Destroy() on individual pipelines if resource cleanup is needed.

func (*PipelineCacheCore) ComputePipelineCount added in v0.20.0

func (c *PipelineCacheCore) ComputePipelineCount() int

ComputePipelineCount returns the number of cached compute pipelines.

func (*PipelineCacheCore) DestroyAll added in v0.20.0

func (c *PipelineCacheCore) DestroyAll()

DestroyAll destroys all cached pipelines and clears the cache.

This releases underlying resources. After calling DestroyAll(), the cache is empty and ready for reuse.

func (*PipelineCacheCore) GetOrCreateComputePipeline added in v0.20.0

func (c *PipelineCacheCore) GetOrCreateComputePipeline(
	device hal.Device,
	desc *ComputePipelineDescriptor,
) (*ComputePipeline, error)

GetOrCreateComputePipeline returns a cached pipeline or creates a new one.

This method implements the "get or create" pattern with double-check locking.

Parameters:

  • device: The device to create the pipeline on (used for creation only).
  • desc: The compute pipeline descriptor.

Returns the pipeline and nil on success. Returns nil and an error if:

  • The device is nil
  • The descriptor is nil
  • Pipeline creation fails

func (*PipelineCacheCore) GetOrCreateRenderPipeline added in v0.20.0

func (c *PipelineCacheCore) GetOrCreateRenderPipeline(
	device hal.Device,
	desc *RenderPipelineDescriptor,
) (*RenderPipeline, error)

GetOrCreateRenderPipeline returns a cached pipeline or creates a new one.

This method implements the "get or create" pattern with double-check locking:

  1. Fast path: RLock, check cache, return if found
  2. Slow path: Lock, double-check, create if needed

Parameters:

  • device: The device to create the pipeline on (used for creation only).
  • desc: The render pipeline descriptor.

Returns the pipeline and nil on success. Returns nil and an error if:

  • The device is nil
  • The descriptor is nil
  • Pipeline creation fails

func (*PipelineCacheCore) HitRate added in v0.20.0

func (c *PipelineCacheCore) HitRate() float64

HitRate returns the cache hit rate as a percentage (0.0 to 1.0).

Returns 0.0 if no requests have been made.

func (*PipelineCacheCore) RenderPipelineCount added in v0.20.0

func (c *PipelineCacheCore) RenderPipelineCount() int

RenderPipelineCount returns the number of cached render pipelines.

func (*PipelineCacheCore) Size added in v0.20.0

func (c *PipelineCacheCore) Size() int

Size returns the total number of cached pipelines.

func (*PipelineCacheCore) Stats added in v0.20.0

func (c *PipelineCacheCore) Stats() (hits, misses uint64)

Stats returns cache statistics.

Returns the number of cache hits and misses. These values are read atomically and may not be perfectly synchronized.

type PipelineStage

type PipelineStage uint8

PipelineStage represents which stage of the pipeline is being executed.

const (
	// StageFlatten is the path flattening stage (path -> segments).
	StageFlatten PipelineStage = iota
	// StageCoarse is the coarse rasterization stage (segments -> tile bins).
	StageCoarse
	// StageFine is the fine rasterization stage (tile bins -> coverage).
	StageFine
)

func (PipelineStage) String

func (s PipelineStage) String() string

String returns a human-readable name for the pipeline stage.

type QuadraticEdge added in v0.20.2

type QuadraticEdge struct {
	// TopY is the curve's overall top scanline (for AET insertion timing).
	// This is set once at creation and never changes, unlike line.FirstY
	// which changes as we step through curve segments.
	TopY int32

	// BottomY is the curve's overall bottom scanline.
	BottomY int32
	// contains filtered or unexported fields
}

QuadraticEdge represents a quadratic Bezier curve for scanline conversion. Uses forward differencing for O(1) per-step evaluation.

A quadratic Bezier is defined by:

p(t) = (1-t)^2 * p0 + 2*t*(1-t) * p1 + t^2 * p2

Rewritten in polynomial form:

p(t) = A*t^2 + B*t + C
where A = p0 - 2*p1 + p2, B = 2*(p1 - p0), C = p0

func NewQuadraticEdge added in v0.20.2

func NewQuadraticEdge(p0, p1, p2 CurvePoint, shift int) *QuadraticEdge

NewQuadraticEdge creates a quadratic edge from control points. Returns nil if the curve has no vertical extent.

Parameters:

  • p0: start point
  • p1: control point
  • p2: end point
  • shift: AA shift (0 for no AA, 2 for 4x AA quality)

func (*QuadraticEdge) CurveCount added in v0.20.2

func (q *QuadraticEdge) CurveCount() int8

CurveCount returns the remaining number of segments.

func (*QuadraticEdge) Line added in v0.20.2

func (q *QuadraticEdge) Line() *LineEdge

Line returns the current line segment for AET processing.

func (*QuadraticEdge) Update added in v0.20.2

func (q *QuadraticEdge) Update() bool

Update advances the quadratic curve to the next line segment. Returns true if a valid segment was produced.

This is the core of the forward differencing algorithm:

newx = oldx + (dx >> shift)
dx += ddx  // Second derivative is constant!

func (*QuadraticEdge) Winding added in v0.20.2

func (q *QuadraticEdge) Winding() int8

Winding returns the winding direction.

type QueueSubmitter

type QueueSubmitter struct {
	// contains filtered or unexported fields
}

QueueSubmitter submits command buffers to a GPU queue.

func NewQueueSubmitter

func NewQueueSubmitter(queue core.QueueID) *QueueSubmitter

NewQueueSubmitter creates a new queue submitter.

func (*QueueSubmitter) Submit

func (s *QueueSubmitter) Submit(buffers ...*CommandBuffer)

Submit submits command buffers to the queue.

func (*QueueSubmitter) WriteBuffer

func (s *QueueSubmitter) WriteBuffer(buffer StubBufferID, offset uint64, data []byte)

WriteBuffer writes data to a GPU buffer.

func (*QueueSubmitter) WriteTexture

func (s *QueueSubmitter) WriteTexture(texture *GPUTexture, data []byte)

WriteTexture writes data to a GPU texture.

type RectAllocator

type RectAllocator struct {
	// contains filtered or unexported fields
}

RectAllocator implements a simple shelf-packing algorithm for allocating rectangular regions within a fixed-size area.

The shelf-packing algorithm works by dividing the atlas into horizontal "shelves". Each new rectangle is placed on the current shelf if it fits, or a new shelf is created below.

func NewRectAllocator

func NewRectAllocator(width, height, padding int) *RectAllocator

NewRectAllocator creates a new rectangular region allocator.

func (*RectAllocator) AllocCount

func (a *RectAllocator) AllocCount() int

AllocCount returns the number of successful allocations.

func (*RectAllocator) Allocate

func (a *RectAllocator) Allocate(width, height int) AtlasRegion

Allocate finds space for a rectangle of the given size. Returns an invalid region if the rectangle cannot be allocated.

func (*RectAllocator) Reset

func (a *RectAllocator) Reset()

Reset clears all allocations, making the entire area available again.

func (*RectAllocator) UsedArea

func (a *RectAllocator) UsedArea() int

UsedArea returns the total area of allocated rectangles.

func (*RectAllocator) Utilization

func (a *RectAllocator) Utilization() float64

Utilization returns the fraction of area used (0.0 to 1.0).

type RenderCommandBuilder

type RenderCommandBuilder struct {
	// contains filtered or unexported fields
}

RenderCommandBuilder provides a fluent API for building render commands.

func NewRenderCommandBuilder

func NewRenderCommandBuilder(device core.DeviceID, target *GPUTexture, clearTarget bool) *RenderCommandBuilder

NewRenderCommandBuilder creates a new render command builder.

func (*RenderCommandBuilder) Draw

func (b *RenderCommandBuilder) Draw(vertexCount, instanceCount uint32) *RenderCommandBuilder

Draw issues a draw call.

func (*RenderCommandBuilder) DrawFullScreen

func (b *RenderCommandBuilder) DrawFullScreen() *RenderCommandBuilder

DrawFullScreen draws a full-screen triangle.

func (*RenderCommandBuilder) Finish

Finish ends the pass and returns the command buffer.

func (*RenderCommandBuilder) SetBindGroup

func (b *RenderCommandBuilder) SetBindGroup(index uint32, bindGroup StubBindGroupID) *RenderCommandBuilder

SetBindGroup sets a bind group.

func (*RenderCommandBuilder) SetPipeline

func (b *RenderCommandBuilder) SetPipeline(pipeline StubPipelineID) *RenderCommandBuilder

SetPipeline sets the render pipeline.

type RenderPass

type RenderPass struct {
	// contains filtered or unexported fields
}

RenderPass represents an active render pass for draw commands. Draw commands can only be issued while a render pass is active.

func (*RenderPass) Draw

func (p *RenderPass) Draw(vertexCount, instanceCount, firstVertex, firstInstance uint32)

Draw issues a non-indexed draw call. vertexCount: number of vertices to draw instanceCount: number of instances to draw firstVertex: offset into the vertex buffer firstInstance: instance ID offset

func (*RenderPass) DrawFullScreenTriangle

func (p *RenderPass) DrawFullScreenTriangle()

DrawFullScreenTriangle is a convenience method for drawing a full-screen triangle. This is commonly used for post-processing effects and texture blits. Uses 3 vertices with no instance or offset.

func (*RenderPass) DrawIndexed

func (p *RenderPass) DrawIndexed(indexCount, instanceCount, firstIndex uint32, baseVertex int32, firstInstance uint32)

DrawIndexed issues an indexed draw call.

func (*RenderPass) End

func (p *RenderPass) End()

End finishes the render pass. No more draw calls can be issued after this.

func (*RenderPass) SetBindGroup

func (p *RenderPass) SetBindGroup(index uint32, bindGroup StubBindGroupID)

SetBindGroup sets a bind group at the specified index.

func (*RenderPass) SetIndexBuffer

func (p *RenderPass) SetIndexBuffer(buffer StubBufferID, format IndexFormat)

SetIndexBuffer sets the index buffer for indexed drawing.

func (*RenderPass) SetPipeline

func (p *RenderPass) SetPipeline(pipeline StubPipelineID)

SetPipeline sets the render pipeline for subsequent draw calls.

func (*RenderPass) SetVertexBuffer

func (p *RenderPass) SetVertexBuffer(slot uint32, buffer StubBufferID)

SetVertexBuffer sets a vertex buffer at the specified slot.

func (*RenderPass) Target

func (p *RenderPass) Target() *GPUTexture

Target returns the render target texture.

type RenderPassColorAttachment added in v0.20.0

type RenderPassColorAttachment struct {
	// View is the texture view to render to.
	View *TextureView

	// ResolveTarget is the MSAA resolve target (optional).
	ResolveTarget *TextureView

	// LoadOp specifies what to do at pass start.
	LoadOp types.LoadOp

	// StoreOp specifies what to do at pass end.
	StoreOp types.StoreOp

	// ClearValue is the clear color (used if LoadOp is Clear).
	ClearValue types.Color
}

RenderPassColorAttachment describes a color attachment.

type RenderPassDepthStencilAttachment added in v0.20.0

type RenderPassDepthStencilAttachment struct {
	// View is the texture view to use.
	View *TextureView

	// DepthLoadOp specifies what to do with depth at pass start.
	DepthLoadOp types.LoadOp

	// DepthStoreOp specifies what to do with depth at pass end.
	DepthStoreOp types.StoreOp

	// DepthClearValue is the depth clear value.
	DepthClearValue float32

	// DepthReadOnly makes the depth aspect read-only.
	DepthReadOnly bool

	// StencilLoadOp specifies what to do with stencil at pass start.
	StencilLoadOp types.LoadOp

	// StencilStoreOp specifies what to do with stencil at pass end.
	StencilStoreOp types.StoreOp

	// StencilClearValue is the stencil clear value.
	StencilClearValue uint32

	// StencilReadOnly makes the stencil aspect read-only.
	StencilReadOnly bool
}

RenderPassDepthStencilAttachment describes a depth/stencil attachment.

type RenderPassDescriptor added in v0.20.0

type RenderPassDescriptor struct {
	// Label is an optional debug name.
	Label string

	// ColorAttachments are the color render targets.
	ColorAttachments []RenderPassColorAttachment

	// DepthStencilAttachment is the depth/stencil target (optional).
	DepthStencilAttachment *RenderPassDepthStencilAttachment
}

RenderPassDescriptor describes a render pass.

type RenderPassEncoder added in v0.20.0

type RenderPassEncoder struct {
	// contains filtered or unexported fields
}

RenderPassEncoder records render commands within a render pass.

RenderPassEncoder wraps core.CoreRenderPassEncoder and provides Go-idiomatic access with immediate error returns. Commands recorded include:

  • SetPipeline: Set the render pipeline for subsequent draw calls
  • SetBindGroup: Bind resource groups (textures, buffers, samplers)
  • SetVertexBuffer: Bind vertex buffers to slots
  • SetIndexBuffer: Bind the index buffer for indexed draws
  • SetViewport: Set the viewport transformation
  • SetScissorRect: Set the scissor rectangle for clipping
  • SetBlendConstant: Set the blend constant color
  • SetStencilReference: Set the stencil reference value
  • Draw: Draw primitives
  • DrawIndexed: Draw indexed primitives
  • DrawIndirect: Draw with GPU-generated parameters
  • DrawIndexedIndirect: Draw indexed with GPU-generated parameters

Thread Safety: RenderPassEncoder is NOT safe for concurrent use. All commands must be recorded from a single goroutine. The pass must be ended with End() before the parent command encoder can continue recording.

Lifecycle:

  1. Created by CoreCommandEncoder.BeginRenderPass()
  2. Record commands (SetPipeline, SetVertexBuffer, Draw, etc.)
  3. Call End() to complete the pass

State Machine:

Recording -> End() -> Ended

func (*RenderPassEncoder) Draw added in v0.20.0

func (p *RenderPassEncoder) Draw(vertexCount, instanceCount, firstVertex, firstInstance uint32) error

Draw issues a non-indexed draw call.

This draws primitives using vertices sequentially from bound vertex buffers. A pipeline must be bound before calling Draw.

Parameters:

  • vertexCount: The number of vertices to draw.
  • instanceCount: The number of instances to draw.
  • firstVertex: The first vertex index.
  • firstInstance: The first instance index.

Returns nil on success. Returns an error if the pass has ended.

func (*RenderPassEncoder) DrawIndexed added in v0.20.0

func (p *RenderPassEncoder) DrawIndexed(indexCount, instanceCount, firstIndex uint32, baseVertex int32, firstInstance uint32) error

DrawIndexed issues an indexed draw call.

This draws primitives using indices from the bound index buffer. Both a pipeline and index buffer must be bound before calling DrawIndexed.

Parameters:

  • indexCount: The number of indices to draw.
  • instanceCount: The number of instances to draw.
  • firstIndex: The first index in the index buffer.
  • baseVertex: Value added to each index before vertex lookup.
  • firstInstance: The first instance index.

Returns nil on success. Returns an error if the pass has ended.

func (*RenderPassEncoder) DrawIndexedIndirect added in v0.20.0

func (p *RenderPassEncoder) DrawIndexedIndirect(indirectBuffer *Buffer, indirectOffset uint64) error

DrawIndexedIndirect issues an indexed draw call with GPU-generated parameters.

The draw parameters are read from the indirect buffer at the specified offset. The buffer must contain a DrawIndexedIndirectArgs structure:

struct DrawIndexedIndirectArgs {
    indexCount: u32,
    instanceCount: u32,
    firstIndex: u32,
    baseVertex: i32,
    firstInstance: u32,
}

Parameters:

  • indirectBuffer: Buffer containing DrawIndexedIndirectArgs.
  • indirectOffset: Byte offset into the buffer (must be 4-byte aligned).

Returns nil on success. Returns an error if:

  • The pass has ended
  • The buffer is nil
  • The offset is not 4-byte aligned

func (*RenderPassEncoder) DrawIndirect added in v0.20.0

func (p *RenderPassEncoder) DrawIndirect(indirectBuffer *Buffer, indirectOffset uint64) error

DrawIndirect issues a draw call with GPU-generated parameters.

The draw parameters are read from the indirect buffer at the specified offset. The buffer must contain a DrawIndirectArgs structure:

struct DrawIndirectArgs {
    vertexCount: u32,
    instanceCount: u32,
    firstVertex: u32,
    firstInstance: u32,
}

Parameters:

  • indirectBuffer: Buffer containing DrawIndirectArgs.
  • indirectOffset: Byte offset into the buffer (must be 4-byte aligned).

Returns nil on success. Returns an error if:

  • The pass has ended
  • The buffer is nil
  • The offset is not 4-byte aligned

func (*RenderPassEncoder) End added in v0.20.0

func (p *RenderPassEncoder) End() error

End completes the render pass.

After calling End(), the render pass encoder cannot be used for further recording. The parent command encoder returns to the Recording state.

Returns nil on success. Returns an error if the pass has already ended.

func (*RenderPassEncoder) IsEnded added in v0.20.0

func (p *RenderPassEncoder) IsEnded() bool

IsEnded returns true if the pass has been ended.

func (*RenderPassEncoder) SetBindGroup added in v0.20.0

func (p *RenderPassEncoder) SetBindGroup(index uint32, bindGroup *BindGroup, dynamicOffsets []uint32) error

SetBindGroup binds a bind group for the given index.

Bind groups provide resources (buffers, textures, samplers) to shaders. WebGPU supports up to 4 bind groups (indices 0-3).

Parameters:

  • index: The bind group index (0, 1, 2, or 3).
  • bindGroup: The bind group to bind.
  • dynamicOffsets: Dynamic offsets for dynamic uniform/storage buffers (optional).

Returns nil on success. Returns an error if:

  • The pass has ended
  • The index exceeds maximum (3)
  • The bind group is nil

func (*RenderPassEncoder) SetBlendConstant added in v0.20.0

func (p *RenderPassEncoder) SetBlendConstant(color types.Color) error

SetBlendConstant sets the blend constant color.

The blend constant is used in blend operations when the blend factor is set to Constant or OneMinusConstant.

Parameters:

  • color: The blend constant color.

Returns nil on success. Returns an error if the pass has ended.

func (*RenderPassEncoder) SetIndexBuffer added in v0.20.0

func (p *RenderPassEncoder) SetIndexBuffer(buffer *Buffer, format IndexFormat, offset, size uint64) error

SetIndexBuffer binds the index buffer for indexed draw calls.

The index buffer provides vertex indices for indexed drawing. Only one index buffer can be bound at a time.

Parameters:

  • buffer: The buffer containing indices.
  • format: The index format (Uint16 or Uint32).
  • offset: Byte offset into the buffer.
  • size: Size of the index data in bytes. Use 0 to bind the remaining buffer.

Returns nil on success. Returns an error if:

  • The pass has ended
  • The buffer is nil

func (*RenderPassEncoder) SetPipeline added in v0.20.0

func (p *RenderPassEncoder) SetPipeline(pipeline *RenderPipeline) error

SetPipeline binds a render pipeline for subsequent draw calls.

The pipeline defines:

  • Vertex and fragment shaders
  • Primitive topology (triangles, lines, points)
  • Rasterization state (culling, depth bias)
  • Depth/stencil state
  • Blend state for color attachments

Parameters:

  • pipeline: The render pipeline to bind.

Returns nil on success. Returns an error if:

  • The pass has ended
  • The pipeline is nil

func (*RenderPassEncoder) SetScissorRect added in v0.20.0

func (p *RenderPassEncoder) SetScissorRect(x, y, width, height uint32) error

SetScissorRect sets the scissor rectangle for clipping.

Fragments outside the scissor rectangle are discarded. By default, the scissor rectangle matches the framebuffer size.

Parameters:

  • x, y: The scissor origin (pixels).
  • width, height: The scissor size (pixels).

Returns nil on success. Returns an error if the pass has ended.

func (*RenderPassEncoder) SetStencilReference added in v0.20.0

func (p *RenderPassEncoder) SetStencilReference(reference uint32) error

SetStencilReference sets the stencil reference value.

The stencil reference is used in stencil comparison and update operations.

Parameters:

  • reference: The stencil reference value.

Returns nil on success. Returns an error if the pass has ended.

func (*RenderPassEncoder) SetVertexBuffer added in v0.20.0

func (p *RenderPassEncoder) SetVertexBuffer(slot uint32, buffer *Buffer, offset, size uint64) error

SetVertexBuffer binds a vertex buffer to a slot.

Vertex buffers provide per-vertex data to vertex shaders. Multiple vertex buffers can be bound to different slots for interleaved or separate vertex attributes.

Parameters:

  • slot: The vertex buffer slot (0 to maxVertexBuffers-1).
  • buffer: The buffer to bind.
  • offset: Byte offset into the buffer.
  • size: Size of the vertex data in bytes. Use 0 to bind the remaining buffer.

Returns nil on success. Returns an error if:

  • The pass has ended
  • The buffer is nil

func (*RenderPassEncoder) SetViewport added in v0.20.0

func (p *RenderPassEncoder) SetViewport(x, y, width, height, minDepth, maxDepth float32) error

SetViewport sets the viewport transformation.

The viewport defines how normalized device coordinates (-1 to 1) are transformed to framebuffer coordinates. The depth range is clamped to [0, 1].

Parameters:

  • x, y: The viewport origin (pixels).
  • width, height: The viewport size (pixels).
  • minDepth, maxDepth: The depth range [0, 1].

Returns nil on success. Returns an error if the pass has ended.

func (*RenderPassEncoder) State added in v0.20.0

State returns the current pass state.

type RenderPassState added in v0.20.0

type RenderPassState int

RenderPassState represents the state of a render pass encoder.

const (
	// RenderPassStateRecording means the pass is actively recording commands.
	RenderPassStateRecording RenderPassState = iota

	// RenderPassStateEnded means the pass has been ended.
	RenderPassStateEnded
)

func (RenderPassState) String added in v0.20.0

func (s RenderPassState) String() string

String returns the string representation of RenderPassState.

type RenderPipeline added in v0.20.0

type RenderPipeline struct {
	// contains filtered or unexported fields
}

RenderPipeline represents a GPU render pipeline.

Render pipelines define the complete rendering state including:

  • Vertex and fragment shaders
  • Primitive topology
  • Rasterization state
  • Depth/stencil state
  • Blend state

RenderPipeline is a placeholder type that will be expanded when pipeline creation is implemented.

func (*RenderPipeline) Destroy added in v0.20.0

func (p *RenderPipeline) Destroy()

Destroy releases the pipeline resources.

func (*RenderPipeline) ID added in v0.20.0

func (p *RenderPipeline) ID() uint64

ID returns the pipeline's unique identifier.

func (*RenderPipeline) IsDestroyed added in v0.20.0

func (p *RenderPipeline) IsDestroyed() bool

IsDestroyed returns true if the pipeline has been destroyed.

func (*RenderPipeline) Label added in v0.20.0

func (p *RenderPipeline) Label() string

Label returns the pipeline's debug label.

type RenderPipelineDescriptor added in v0.20.0

type RenderPipelineDescriptor struct {
	// Label is an optional debug name.
	Label string

	// VertexShader is the vertex shader module.
	VertexShader *ShaderModule

	// VertexEntryPoint is the vertex shader entry point function name.
	// Defaults to "vs_main" if empty.
	VertexEntryPoint string

	// FragmentShader is the fragment shader module.
	FragmentShader *ShaderModule

	// FragmentEntryPoint is the fragment shader entry point function name.
	// Defaults to "fs_main" if empty.
	FragmentEntryPoint string

	// VertexBufferLayouts describes the vertex buffer layouts.
	VertexBufferLayouts []VertexBufferLayout

	// PrimitiveTopology is the primitive type (triangles, lines, points).
	PrimitiveTopology types.PrimitiveTopology

	// FrontFace defines which face is considered front-facing.
	FrontFace types.FrontFace

	// CullMode defines which faces to cull.
	CullMode types.CullMode

	// ColorFormat is the format of the color attachment.
	ColorFormat types.TextureFormat

	// DepthFormat is the format of the depth attachment (optional).
	// Use TextureFormatUndefined for no depth attachment.
	DepthFormat types.TextureFormat

	// DepthWriteEnabled enables depth buffer writes.
	DepthWriteEnabled bool

	// DepthCompare is the depth comparison function.
	DepthCompare types.CompareFunction

	// BlendState is the color blending configuration (optional).
	// Nil means no blending (source replaces destination).
	BlendState *BlendState

	// SampleCount is the number of samples per pixel (1 for non-MSAA).
	SampleCount uint32
}

RenderPipelineDescriptor describes a render pipeline to create.

This is a minimal descriptor focused on the fields needed for hashing. It captures the essential pipeline state that affects rendering behavior.

type SegmentList

type SegmentList struct {
	// contains filtered or unexported fields
}

SegmentList is a collection of line segments.

func FlattenPath

func FlattenPath(path *scene.Path, transform scene.Affine, tolerance float32) *SegmentList

FlattenPath flattens a path to monotonic line segments. It converts Bezier curves to line segments and ensures all segments are monotonic in Y (Y0 <= Y1).

Parameters:

  • path: The input path to flatten
  • transform: Affine transformation to apply to all points
  • tolerance: Flattening tolerance (use FlattenTolerance for default)

Returns a SegmentList containing all flattened line segments.

func NewSegmentList

func NewSegmentList() *SegmentList

NewSegmentList creates a new empty segment list.

func (*SegmentList) Add

func (sl *SegmentList) Add(seg LineSegment)

Add adds a segment to the list.

func (*SegmentList) AddLine

func (sl *SegmentList) AddLine(x0, y0, x1, y1 float32, winding int8)

AddLine adds a line segment from (x0,y0) to (x1,y1).

func (*SegmentList) Bounds

func (sl *SegmentList) Bounds() (minX, minY, maxX, maxY float32)

Bounds returns the bounding box of all segments.

func (*SegmentList) Len

func (sl *SegmentList) Len() int

Len returns the number of segments.

func (*SegmentList) Reset

func (sl *SegmentList) Reset()

Reset clears the list for reuse.

func (*SegmentList) Segments

func (sl *SegmentList) Segments() []LineSegment

Segments returns the slice of segments.

func (*SegmentList) SegmentsInTileRow

func (sl *SegmentList) SegmentsInTileRow(tileY int32) []LineSegment

SegmentsInTileRow returns segments that cross a given tile row. The list should be sorted by TileY0 for efficient access.

func (*SegmentList) SortByTileY

func (sl *SegmentList) SortByTileY()

SortByTileY sorts segments by their starting tile Y coordinate. This enables efficient row-by-row processing.

func (*SegmentList) TileYRange

func (sl *SegmentList) TileYRange() (minTileY, maxTileY int32)

TileYRange returns the range of tile rows that segments span.

type ShaderModule added in v0.20.0

type ShaderModule struct {
	// contains filtered or unexported fields
}

ShaderModule represents a compiled shader module.

Shader modules contain SPIR-V bytecode and are used to create pipelines. The hash is computed from the SPIR-V code for cache lookup.

func NewShaderModule added in v0.20.0

func NewShaderModule(id uint64, label string, code []byte, halModule hal.ShaderModule) *ShaderModule

NewShaderModule creates a new shader module wrapper.

Parameters:

  • id: Unique identifier for this module.
  • label: Debug label.
  • code: SPIR-V bytecode.
  • halModule: The underlying module (may be nil for testing).

func (*ShaderModule) CodeHash added in v0.20.0

func (m *ShaderModule) CodeHash() uint64

CodeHash returns the hash of the shader bytecode.

func (*ShaderModule) Destroy added in v0.20.0

func (m *ShaderModule) Destroy()

Destroy marks the shader module as destroyed.

func (*ShaderModule) ID added in v0.20.0

func (m *ShaderModule) ID() uint64

ID returns the shader module's unique identifier.

func (*ShaderModule) IsDestroyed added in v0.20.0

func (m *ShaderModule) IsDestroyed() bool

IsDestroyed returns true if the module has been destroyed.

func (*ShaderModule) Label added in v0.20.0

func (m *ShaderModule) Label() string

Label returns the shader module's debug label.

func (*ShaderModule) Raw added in v0.20.0

func (m *ShaderModule) Raw() hal.ShaderModule

Raw returns the underlying shader module.

type ShaderModuleID

type ShaderModuleID uint64

ShaderModuleID represents a compiled shader module handle. This is a placeholder type that will be replaced with the actual wgpu core.ShaderModuleID once shader compilation is implemented.

const InvalidShaderModule ShaderModuleID = 0

InvalidShaderModule represents an invalid/uninitialized shader module.

type ShaderModules

type ShaderModules struct {
	// Blit is the simple texture copy shader
	Blit ShaderModuleID

	// Blend is the 29-mode blend shader
	Blend ShaderModuleID

	// Strip is the strip rasterization compute shader
	Strip ShaderModuleID

	// Composite is the final layer compositing shader
	Composite ShaderModuleID
}

ShaderModules holds compiled shader modules for all rendering operations.

func CompileShaders

func CompileShaders(deviceID uint64) (*ShaderModules, error)

CompileShaders compiles all WGSL shaders and returns the shader modules. This function currently returns stub module IDs since gogpu/wgpu shader compilation is not yet fully implemented. The WGSL sources are validated for correct syntax.

Parameters:

  • deviceID: The GPU device ID to use for compilation (currently unused)

Returns:

  • *ShaderModules: Compiled shader module handles
  • error: Compilation error if shader sources are invalid

func (*ShaderModules) IsValid

func (s *ShaderModules) IsValid() bool

IsValid returns true if all shader modules are initialized.

type SparseStrip

type SparseStrip struct {
	X        uint16 // X coordinate in pixels
	Y        uint16 // Y coordinate in pixels
	AlphaIdx uint32 // Index into alpha buffer
	FillGap  bool   // Whether to fill gap before this strip
}

SparseStrip represents a sparse strip for efficient rendering. A strip is a horizontal run of tiles with the same Y coordinate. This is different from the legacy Strip type in strips.go.

type SparseStripsConfig

type SparseStripsConfig struct {
	Width     uint16
	Height    uint16
	FillRule  scene.FillStyle
	Tolerance float32 // Flattening tolerance (0 uses default)
}

SparseStripsConfig configures the sparse strips rasterizer.

func DefaultConfig

func DefaultConfig(width, height uint16) SparseStripsConfig

DefaultConfig returns a default configuration.

type SparseStripsPool

type SparseStripsPool struct {
	// contains filtered or unexported fields
}

SparseStripsPool manages pooled rasterizers for reuse.

func NewSparseStripsPool

func NewSparseStripsPool() *SparseStripsPool

NewSparseStripsPool creates a new pool.

func (*SparseStripsPool) Get

Get retrieves a rasterizer from the pool or creates a new one.

func (*SparseStripsPool) Put

Put returns a rasterizer to the pool.

type SparseStripsRasterizer

type SparseStripsRasterizer struct {
	// contains filtered or unexported fields
}

SparseStripsRasterizer is the main entry point for vello-style sparse strips rendering. It orchestrates the complete pipeline: flatten -> coarse -> fine -> render.

The sparse strips algorithm works by: 1. Flattening Bezier curves to monotonic line segments 2. Coarse rasterization: binning segments into tiles they intersect 3. Fine rasterization: calculating analytic anti-aliased coverage per pixel 4. Rendering: outputting coverage as strips for efficient GPU rendering

func NewSparseStripsRasterizer

func NewSparseStripsRasterizer(config SparseStripsConfig) *SparseStripsRasterizer

NewSparseStripsRasterizer creates a new sparse strips rasterizer.

func (*SparseStripsRasterizer) FillRule

func (ssr *SparseStripsRasterizer) FillRule() scene.FillStyle

FillRule returns the current fill rule.

func (*SparseStripsRasterizer) GetStats

func (ssr *SparseStripsRasterizer) GetStats() Stats

GetStats returns statistics about the current rasterization state.

func (*SparseStripsRasterizer) Grid

func (ssr *SparseStripsRasterizer) Grid() *TileGrid

Grid returns the tile grid with computed coverage.

func (*SparseStripsRasterizer) Height

func (ssr *SparseStripsRasterizer) Height() uint16

Height returns the viewport height.

func (*SparseStripsRasterizer) RasterizePath

func (ssr *SparseStripsRasterizer) RasterizePath(
	path *scene.Path,
	transform scene.Affine,
	tolerance float32,
)

RasterizePath rasterizes a single path to the tile grid.

func (*SparseStripsRasterizer) RasterizeToStrips

func (ssr *SparseStripsRasterizer) RasterizeToStrips(
	path *scene.Path,
	transform scene.Affine,
	tolerance float32,
)

RasterizeToStrips rasterizes a path and generates sparse strips.

func (*SparseStripsRasterizer) RenderStripsToBuffer

func (ssr *SparseStripsRasterizer) RenderStripsToBuffer(
	buffer []uint8,
	stride int,
	color [4]uint8,
)

RenderStripsToBuffer renders strips to a pixel buffer.

func (*SparseStripsRasterizer) RenderToBuffer

func (ssr *SparseStripsRasterizer) RenderToBuffer(
	buffer []uint8,
	stride int,
	color [4]uint8,
)

RenderToBuffer renders the rasterized coverage to a pixel buffer.

func (*SparseStripsRasterizer) Reset

func (ssr *SparseStripsRasterizer) Reset()

Reset clears the rasterizer state for reuse with new geometry.

func (*SparseStripsRasterizer) Segments

func (ssr *SparseStripsRasterizer) Segments() *SegmentList

Segments returns the flattened segments.

func (*SparseStripsRasterizer) SetFillRule

func (ssr *SparseStripsRasterizer) SetFillRule(rule scene.FillStyle)

SetFillRule sets the fill rule for rendering.

func (*SparseStripsRasterizer) SetSize

func (ssr *SparseStripsRasterizer) SetSize(width, height uint16)

SetSize changes the rasterizer viewport dimensions.

func (*SparseStripsRasterizer) Strips

func (ssr *SparseStripsRasterizer) Strips() *StripRenderer

Strips returns the strip renderer with generated strips.

func (*SparseStripsRasterizer) Width

func (ssr *SparseStripsRasterizer) Width() uint16

Width returns the viewport width.

type Stats

type Stats struct {
	SegmentCount    int
	TileEntryCount  int
	ActiveTileCount int
	StripCount      int
	AlphaByteCount  int
}

Stats contains statistics about the rasterization process.

type StripParams

type StripParams struct {
	Color        [4]float32 // Fill color (premultiplied RGBA)
	TargetWidth  int32      // Output texture width
	TargetHeight int32      // Output texture height
	StripCount   int32      // Number of strips to process
	Padding      int32      // Alignment padding
}

StripParams represents the uniform buffer structure for strip shaders. This matches the StripParams struct in strip.wgsl.

type StripRenderer

type StripRenderer struct {
	// contains filtered or unexported fields
}

StripRenderer renders tiles as sparse strips.

func NewStripRenderer

func NewStripRenderer() *StripRenderer

NewStripRenderer creates a new strip renderer.

func (*StripRenderer) Alphas

func (sr *StripRenderer) Alphas() []uint8

Alphas returns the alpha buffer.

func (*StripRenderer) RenderTiles

func (sr *StripRenderer) RenderTiles(
	coarse *CoarseRasterizer,
	segments *SegmentList,
	backdrop []int32,
)

RenderTiles converts tiles to strips for efficient rendering.

func (*StripRenderer) Reset

func (sr *StripRenderer) Reset()

Reset clears the renderer state for reuse.

func (*StripRenderer) SetAliasMode

func (sr *StripRenderer) SetAliasMode(enabled bool)

SetAliasMode enables or disables aliased (non-anti-aliased) rendering.

func (*StripRenderer) SetFillRule

func (sr *StripRenderer) SetFillRule(rule scene.FillStyle)

SetFillRule sets the fill rule.

func (*StripRenderer) Strips

func (sr *StripRenderer) Strips() []SparseStrip

Strips returns the strips.

type StubBindGroupID

type StubBindGroupID uint64

StubBindGroupID is a placeholder for actual wgpu BindGroupID.

type StubBindGroupLayoutID

type StubBindGroupLayoutID uint64

StubBindGroupLayoutID is a placeholder for actual wgpu BindGroupLayoutID.

type StubBufferID

type StubBufferID uint64

StubBufferID is a placeholder for actual wgpu BufferID.

type StubCommandBufferID

type StubCommandBufferID uint64

StubCommandBufferID is a placeholder for actual wgpu CommandBufferID.

type StubCommandEncoderID

type StubCommandEncoderID uint64

StubCommandEncoderID is a placeholder for actual wgpu CommandEncoderID.

type StubComputePassID

type StubComputePassID uint64

StubComputePassID is a placeholder for actual wgpu ComputePassID.

type StubComputePipelineID

type StubComputePipelineID uint64

StubComputePipelineID is a placeholder for actual wgpu ComputePipelineID.

type StubPipelineID

type StubPipelineID uint64

StubPipelineID is a placeholder for actual wgpu RenderPipelineID. This will be replaced with core.RenderPipelineID when wgpu support is complete.

const InvalidPipelineID StubPipelineID = 0

InvalidPipelineID represents an invalid/uninitialized pipeline.

type StubRenderPassID

type StubRenderPassID uint64

StubRenderPassID is a placeholder for actual wgpu RenderPassID.

type StubSamplerID

type StubSamplerID uint64

StubSamplerID is a placeholder for actual wgpu SamplerID.

type TextBatch

type TextBatch struct {
	Quads     []TextQuad
	Color     gg.RGBA
	Transform gg.Matrix
}

TextBatch represents a batch of text quads with shared rendering parameters.

type TextPipeline

type TextPipeline struct {
	// contains filtered or unexported fields
}

TextPipeline handles GPU-accelerated MSDF text rendering. It manages the render pipeline, bind groups, and vertex buffers for rendering text using multi-channel signed distance fields.

TextPipeline is safe for concurrent use after initialization.

func NewTextPipeline

func NewTextPipeline(device core.DeviceID, config TextPipelineConfig) (*TextPipeline, error)

NewTextPipeline creates a new text rendering pipeline. The pipeline must be initialized before use.

func NewTextPipelineDefault

func NewTextPipelineDefault(device core.DeviceID) (*TextPipeline, error)

NewTextPipelineDefault creates a text pipeline with default configuration.

func (*TextPipeline) Close

func (p *TextPipeline) Close()

Close releases all pipeline resources.

func (*TextPipeline) Config

func (p *TextPipeline) Config() TextPipelineConfig

Config returns the pipeline configuration.

func (*TextPipeline) GetOrCreateAtlasBindGroup

func (p *TextPipeline) GetOrCreateAtlasBindGroup(atlasIndex int, atlasTexture *GPUTexture) (StubBindGroupID, error)

GetOrCreateAtlasBindGroup gets or creates a bind group for an atlas texture.

func (*TextPipeline) Init

func (p *TextPipeline) Init() error

Init initializes the text pipeline, compiling shaders and creating GPU resources.

func (*TextPipeline) InvalidateAllAtlasBindGroups

func (p *TextPipeline) InvalidateAllAtlasBindGroups()

InvalidateAllAtlasBindGroups removes all cached bind groups.

func (*TextPipeline) InvalidateAtlasBindGroup

func (p *TextPipeline) InvalidateAtlasBindGroup(atlasIndex int)

InvalidateAtlasBindGroup removes a cached bind group for an atlas. Call this when an atlas texture is updated.

func (*TextPipeline) IsInitialized

func (p *TextPipeline) IsInitialized() bool

IsInitialized returns true if the pipeline has been initialized.

func (*TextPipeline) RenderText

func (p *TextPipeline) RenderText(
	pass *RenderPass,
	quads []TextQuad,
	atlasIndex int,
	color gg.RGBA,
	transform gg.Matrix,
) error

RenderText renders text quads using the specified atlas. All quads are rendered in a single draw call for efficiency.

Parameters:

  • pass: The render pass to record commands into
  • quads: Text quads to render (position and UV for each glyph)
  • atlasIndex: Index of the MSDF atlas texture to use
  • color: Text color (RGBA, will be premultiplied)
  • transform: 2D affine transform matrix (gg.Matrix)

Note: This is a stub implementation that validates inputs and prepares vertex data. Actual GPU rendering will be implemented when wgpu is ready.

func (*TextPipeline) RenderTextBatch

func (p *TextPipeline) RenderTextBatch(
	pass *RenderPass,
	batches []TextBatch,
	atlasIndex int,
) error

RenderTextBatch renders multiple text batches efficiently. Each batch can have different color and transform but shares the same atlas.

type TextPipelineConfig

type TextPipelineConfig struct {
	// InitialQuadCapacity is the initial vertex buffer capacity in quads.
	// Default: 256
	InitialQuadCapacity int

	// MaxQuadCapacity is the maximum number of quads per draw call.
	// Default: 16384
	MaxQuadCapacity int

	// DefaultPxRange is the default MSDF pixel range.
	// Default: 4.0
	DefaultPxRange float32
}

TextPipelineConfig holds configuration for the text pipeline.

func DefaultTextPipelineConfig

func DefaultTextPipelineConfig() TextPipelineConfig

DefaultTextPipelineConfig returns default configuration.

type TextQuad

type TextQuad struct {
	// Position of quad corners in screen/clip space
	X0, Y0, X1, Y1 float32

	// UV coordinates in MSDF atlas [0, 1]
	U0, V0, U1, V1 float32
}

TextQuad represents a single glyph quad for rendering. Each glyph is rendered as a textured quad with position and UV coordinates.

type TextRenderer

type TextRenderer struct {
	// contains filtered or unexported fields
}

TextRenderer provides a higher-level API for rendering text. It combines TextPipeline with AtlasManager for convenient text rendering.

func NewTextRenderer

func NewTextRenderer(backend *NativeBackend, config TextRendererConfig) (*TextRenderer, error)

NewTextRenderer creates a new text renderer.

func (*TextRenderer) AtlasManager

func (r *TextRenderer) AtlasManager() *msdf.AtlasManager

AtlasManager returns the underlying atlas manager.

func (*TextRenderer) Close

func (r *TextRenderer) Close()

Close releases all renderer resources.

func (*TextRenderer) Init

func (r *TextRenderer) Init() error

Init initializes the text renderer.

func (*TextRenderer) Pipeline

func (r *TextRenderer) Pipeline() *TextPipeline

Pipeline returns the underlying text pipeline.

func (*TextRenderer) SyncAtlases

func (r *TextRenderer) SyncAtlases() error

SyncAtlases uploads dirty atlases to GPU.

type TextRendererConfig

type TextRendererConfig struct {
	// PipelineConfig for the underlying text pipeline.
	PipelineConfig TextPipelineConfig

	// AtlasConfig for the MSDF atlas manager.
	AtlasConfig msdf.AtlasConfig
}

TextRendererConfig holds configuration for TextRenderer.

func DefaultTextRendererConfig

func DefaultTextRendererConfig() TextRendererConfig

DefaultTextRendererConfig returns default configuration.

type TextUniforms

type TextUniforms struct {
	// Transform matrix (4x4 for alignment, row-major)
	// Maps local coordinates to clip space [-1, 1]
	Transform [16]float32

	// Text color (RGBA, premultiplied alpha)
	Color [4]float32

	// MSDF parameters:
	// [0]: px_range (distance range in pixels)
	// [1]: atlas_size (texture size)
	// [2]: outline_width (for outline effect)
	// [3]: reserved
	MSDFParams [4]float32
}

TextUniforms represents the uniform buffer for text shaders. Matches the TextUniforms struct in msdf_text.wgsl.

type TextVertex

type TextVertex struct {
	// Position in local/screen space
	X, Y float32

	// UV coordinates in atlas
	U, V float32
}

TextVertex represents a single vertex for text rendering. Matches the VertexInput struct in msdf_text.wgsl.

type Texture added in v0.20.0

type Texture struct {
	// contains filtered or unexported fields
}

Texture represents a GPU texture resource.

Texture wraps a hal.Texture and provides Go-idiomatic access with lazy default view creation using sync.Once. This follows the wgpu pattern where textures have a default view that is created on-demand.

Thread Safety: Texture is safe for concurrent read access. The default view is lazily created using sync.Once, making GetDefaultView() thread-safe. Destroy() should only be called once, typically when the texture is no longer needed.

Lifecycle:

  1. Create via Device.CreateTexture() or CreateTexture()
  2. Use GetDefaultView() for simple render targets
  3. Use CreateView() for custom views (mip levels, array layers, etc.)
  4. Call Destroy() when done

func CreateCoreTexture added in v0.20.0

func CreateCoreTexture(device hal.Device, desc *TextureDescriptor) (*Texture, error)

CreateCoreTexture creates a new texture from a device.

This is a helper function for creating textures using the HAL API directly. It handles validation and wraps the texture in a Texture.

Parameters:

  • device: The device to create the texture on.
  • desc: The texture descriptor.

Returns the new Texture and nil on success. Returns nil and an error if:

  • The device is nil
  • The descriptor is nil
  • Texture dimensions are invalid
  • Texture creation fails

func CreateCoreTextureSimple added in v0.20.0

func CreateCoreTextureSimple(
	device hal.Device,
	width, height uint32,
	format types.TextureFormat,
	usage types.TextureUsage,
	label string,
) (*Texture, error)

CreateCoreTextureSimple creates a 2D texture with common defaults.

This is a convenience function for creating simple 2D textures with:

  • Dimension: 2D
  • MipLevelCount: 1
  • SampleCount: 1
  • DepthOrArrayLayers: 1

Parameters:

  • device: The device to create the texture on.
  • width: Texture width in pixels.
  • height: Texture height in pixels.
  • format: Texture pixel format.
  • usage: Texture usage flags.
  • label: Optional debug label.

Returns the new Texture and nil on success. Returns nil and an error if creation fails.

func NewTexture added in v0.20.0

func NewTexture(halTexture hal.Texture, device hal.Device, desc *TextureDescriptor) *Texture

NewTexture creates a new Texture from a texture handle.

This is typically called by Device.CreateTexture() after successfully creating the underlying texture.

Parameters:

  • halTexture: The underlying texture (ownership transferred)
  • device: The parent device (retained for view creation)
  • desc: The texture descriptor (copied)

Returns the new Texture.

func (*Texture) CreateView added in v0.20.0

func (t *Texture) CreateView(desc *TextureViewDescriptor) (*TextureView, error)

CreateView creates a texture view with explicit parameters.

Use this method when you need a custom view that differs from the default, such as:

  • A specific mip level for mipmap generation
  • A subset of array layers for layered rendering
  • A different format for format reinterpretation
  • A different aspect (depth or stencil only)

Parameters:

  • desc: View descriptor specifying the view configuration

Returns the texture view and nil on success. Returns nil and an error if:

  • The texture has been destroyed
  • The descriptor is nil
  • View creation failed

func (*Texture) DepthOrArrayLayers added in v0.20.0

func (t *Texture) DepthOrArrayLayers() uint32

DepthOrArrayLayers returns the texture depth or array layer count.

func (*Texture) Descriptor added in v0.20.0

func (t *Texture) Descriptor() TextureDescriptor

Descriptor returns a copy of the texture descriptor.

func (*Texture) Destroy added in v0.20.0

func (t *Texture) Destroy()

Destroy releases the texture and any associated resources.

After calling Destroy(), the texture and any views created from it should not be used.

This method is idempotent - calling it multiple times is safe.

func (*Texture) Dimension added in v0.20.0

func (t *Texture) Dimension() types.TextureDimension

Dimension returns the texture dimension (1D, 2D, 3D).

func (*Texture) Format added in v0.20.0

func (t *Texture) Format() types.TextureFormat

Format returns the texture pixel format.

func (*Texture) GetDefaultView added in v0.20.0

func (t *Texture) GetDefaultView() (*TextureView, error)

GetDefaultView returns the default texture view, creating it lazily on first call.

The default view covers all mip levels and array layers with the texture's native format. This is the most common use case for render targets and texture bindings.

Thread Safety: This method is thread-safe. Multiple goroutines can call GetDefaultView() concurrently, and the view will be created exactly once.

Returns the default view and nil on success. Returns nil and an error if:

  • The texture has been destroyed
  • View creation failed

func (*Texture) Height added in v0.20.0

func (t *Texture) Height() uint32

Height returns the texture height in pixels.

func (*Texture) IsDestroyed added in v0.20.0

func (t *Texture) IsDestroyed() bool

IsDestroyed returns true if the texture has been destroyed.

func (*Texture) Label added in v0.20.0

func (t *Texture) Label() string

Label returns the texture's debug label.

func (*Texture) MipLevelCount added in v0.20.0

func (t *Texture) MipLevelCount() uint32

MipLevelCount returns the number of mip levels.

func (*Texture) Raw added in v0.20.0

func (t *Texture) Raw() hal.Texture

Raw returns the underlying texture handle.

Returns nil if the texture has been destroyed. Use with caution - the caller should ensure the texture is not destroyed while the handle is in use.

func (*Texture) SampleCount added in v0.20.0

func (t *Texture) SampleCount() uint32

SampleCount returns the number of samples per pixel.

func (*Texture) Size added in v0.20.0

func (t *Texture) Size() types.Extent3D

Size returns the texture dimensions.

func (*Texture) Usage added in v0.20.0

func (t *Texture) Usage() types.TextureUsage

Usage returns the texture usage flags.

func (*Texture) Width added in v0.20.0

func (t *Texture) Width() uint32

Width returns the texture width in pixels.

type TextureAtlas

type TextureAtlas struct {
	// contains filtered or unexported fields
}

TextureAtlas manages a texture atlas for efficient batching of small images. It combines multiple small textures into a single large GPU texture to reduce draw calls and texture binding changes.

TextureAtlas is safe for concurrent use.

func NewTextureAtlas

func NewTextureAtlas(backend *NativeBackend, config TextureAtlasConfig) (*TextureAtlas, error)

NewTextureAtlas creates a new texture atlas with the given configuration.

func (*TextureAtlas) AllocCount

func (a *TextureAtlas) AllocCount() int

AllocCount returns the number of allocated regions.

func (*TextureAtlas) Allocate

func (a *TextureAtlas) Allocate(width, height int) (AtlasRegion, error)

Allocate finds space for a rectangle of the given size. Returns an invalid region (Width/Height == 0) if the atlas is full.

func (*TextureAtlas) AllocateAndUpload

func (a *TextureAtlas) AllocateAndUpload(pixmap *gg.Pixmap) (AtlasRegion, error)

AllocateAndUpload combines Allocate and Upload into a single operation. This is a convenience method for adding new images to the atlas.

func (*TextureAtlas) Close

func (a *TextureAtlas) Close()

Close releases the atlas resources. The atlas should not be used after Close is called.

func (*TextureAtlas) Height

func (a *TextureAtlas) Height() int

Height returns the atlas height in pixels.

func (*TextureAtlas) IsClosed

func (a *TextureAtlas) IsClosed() bool

IsClosed returns true if the atlas has been closed.

func (*TextureAtlas) Reset

func (a *TextureAtlas) Reset()

Reset clears all allocations, making the entire atlas available again. Note: This does not clear the texture data, just the allocation tracking.

func (*TextureAtlas) Texture

func (a *TextureAtlas) Texture() *GPUTexture

Texture returns the underlying GPU texture.

func (*TextureAtlas) Upload

func (a *TextureAtlas) Upload(region AtlasRegion, pixmap *gg.Pixmap) error

Upload copies pixel data from a pixmap to a region of the atlas. The pixmap dimensions must match the region dimensions.

func (*TextureAtlas) Utilization

func (a *TextureAtlas) Utilization() float64

Utilization returns the fraction of atlas area used (0.0 to 1.0).

func (*TextureAtlas) Width

func (a *TextureAtlas) Width() int

Width returns the atlas width in pixels.

type TextureAtlasConfig

type TextureAtlasConfig struct {
	// Width is the atlas width in pixels. Defaults to DefaultAtlasSize.
	Width int

	// Height is the atlas height in pixels. Defaults to DefaultAtlasSize.
	Height int

	// Padding is the spacing between regions. Defaults to DefaultShelfPadding.
	Padding int

	// Label is an optional debug label.
	Label string
}

TextureAtlasConfig holds configuration for creating a TextureAtlas.

type TextureConfig

type TextureConfig struct {
	// Width is the texture width in pixels.
	Width int

	// Height is the texture height in pixels.
	Height int

	// Format is the pixel format.
	Format TextureFormat

	// Label is an optional debug label.
	Label string

	// Usage flags (default: CopySrc | CopyDst | TextureBinding)
	Usage types.TextureUsage
}

TextureConfig holds configuration for creating a new texture.

type TextureDescriptor added in v0.20.0

type TextureDescriptor struct {
	// Label is an optional debug name.
	Label string

	// Size is the texture dimensions.
	Size types.Extent3D

	// MipLevelCount is the number of mip levels (1+ required).
	MipLevelCount uint32

	// SampleCount is the number of samples per pixel (1 for non-MSAA).
	SampleCount uint32

	// Dimension is the texture dimension (1D, 2D, 3D).
	Dimension types.TextureDimension

	// Format is the texture pixel format.
	Format types.TextureFormat

	// Usage specifies how the texture will be used.
	Usage types.TextureUsage

	// ViewFormats are additional formats for texture views.
	ViewFormats []types.TextureFormat
}

TextureDescriptor describes a texture to create.

type TextureFormat

type TextureFormat uint8

TextureFormat represents the pixel format of a GPU texture.

const (
	// TextureFormatRGBA8 is the standard RGBA format with 8 bits per channel.
	TextureFormatRGBA8 TextureFormat = iota

	// TextureFormatBGRA8 is BGRA format, often used for surface presentation.
	TextureFormatBGRA8

	// TextureFormatR8 is single-channel 8-bit format, used for masks.
	TextureFormatR8
)

func (TextureFormat) BytesPerPixel

func (f TextureFormat) BytesPerPixel() int

BytesPerPixel returns the number of bytes per pixel for the format.

func (TextureFormat) String

func (f TextureFormat) String() string

String returns a human-readable name for the format.

func (TextureFormat) ToWGPUFormat

func (f TextureFormat) ToWGPUFormat() types.TextureFormat

ToWGPUFormat converts to wgpu types.TextureFormat. This will be used when actual GPU texture creation is implemented.

type TextureView added in v0.20.0

type TextureView struct {
	// contains filtered or unexported fields
}

TextureView represents a view into a GPU texture.

Texture views provide different ways to access texture data, such as:

  • Different mip levels
  • Different array layers
  • Different formats (for format reinterpretation)
  • Different aspects (depth, stencil, color)

Thread Safety: TextureView is safe for concurrent read access. Destroy() should only be called once, and only for non-default views.

func (*TextureView) ArrayLayerCount added in v0.20.0

func (v *TextureView) ArrayLayerCount() uint32

ArrayLayerCount returns the number of array layers in the view.

func (*TextureView) Aspect added in v0.20.0

func (v *TextureView) Aspect() types.TextureAspect

Aspect returns the view's aspect.

func (*TextureView) BaseArrayLayer added in v0.20.0

func (v *TextureView) BaseArrayLayer() uint32

BaseArrayLayer returns the first array layer in the view.

func (*TextureView) BaseMipLevel added in v0.20.0

func (v *TextureView) BaseMipLevel() uint32

BaseMipLevel returns the first mip level in the view.

func (*TextureView) Descriptor added in v0.20.0

func (v *TextureView) Descriptor() TextureViewDescriptor

Descriptor returns a copy of the view descriptor.

func (*TextureView) Destroy added in v0.20.0

func (v *TextureView) Destroy()

Destroy releases the texture view.

Note: Default views should not be manually destroyed - they are automatically destroyed when the parent texture is destroyed. Calling Destroy() on a default view has no effect.

This method is idempotent - calling it multiple times is safe.

func (*TextureView) Dimension added in v0.20.0

func (v *TextureView) Dimension() types.TextureViewDimension

Dimension returns the view's dimension.

func (*TextureView) Format added in v0.20.0

func (v *TextureView) Format() types.TextureFormat

Format returns the view's format. Returns TextureFormatUndefined if the view inherits from the texture.

func (*TextureView) IsDefault added in v0.20.0

func (v *TextureView) IsDefault() bool

IsDefault returns true if this is the texture's default view.

func (*TextureView) IsDestroyed added in v0.20.0

func (v *TextureView) IsDestroyed() bool

IsDestroyed returns true if the view has been destroyed.

func (*TextureView) Label added in v0.20.0

func (v *TextureView) Label() string

Label returns the view's debug label.

func (*TextureView) MipLevelCount added in v0.20.0

func (v *TextureView) MipLevelCount() uint32

MipLevelCount returns the number of mip levels in the view.

func (*TextureView) Raw added in v0.20.0

func (v *TextureView) Raw() hal.TextureView

Raw returns the underlying texture view handle.

Returns nil if the view has been destroyed. Use with caution - the caller should ensure the view is not destroyed while the handle is in use.

func (*TextureView) Texture added in v0.20.0

func (v *TextureView) Texture() *Texture

Texture returns the parent texture.

type TextureViewDescriptor added in v0.20.0

type TextureViewDescriptor struct {
	// Label is an optional debug name.
	Label string

	// Format is the view format (use TextureFormatUndefined to inherit from texture).
	Format types.TextureFormat

	// Dimension is the view dimension (use TextureViewDimensionUndefined to inherit).
	Dimension types.TextureViewDimension

	// Aspect specifies which aspect to view (color, depth, stencil).
	Aspect types.TextureAspect

	// BaseMipLevel is the first mip level in the view.
	BaseMipLevel uint32

	// MipLevelCount is the number of mip levels (0 means all remaining levels).
	MipLevelCount uint32

	// BaseArrayLayer is the first array layer in the view.
	BaseArrayLayer uint32

	// ArrayLayerCount is the number of array layers (0 means all remaining layers).
	ArrayLayerCount uint32
}

TextureViewDescriptor describes a texture view to create.

type Tile

type Tile struct {
	// X, Y are tile coordinates (not pixel coordinates).
	// Pixel coordinates are (X * TileSize, Y * TileSize).
	X, Y int32

	// Coverage holds 4×4 = 16 anti-aliased coverage values (0-255).
	// Index = row * TileSize + col
	Coverage [TileSize * TileSize]uint8

	// Backdrop is the winding number entering this tile from the left.
	// Used for propagating fill state across tile boundaries.
	Backdrop int16

	// SegmentCount tracks how many segments cross this tile.
	// Used for optimization: tiles with 0 segments use backdrop only.
	SegmentCount int16
}

Tile represents a 4×4 pixel tile with coverage data. This is the core unit of the sparse strips algorithm.

The coverage array stores anti-aliased alpha values for each pixel in row-major order: [row0: 0-3, row1: 4-7, row2: 8-11, row3: 12-15]

func (*Tile) FillSolid

func (t *Tile) FillSolid(value uint8)

FillSolid fills the entire tile with a single coverage value.

func (*Tile) GetCoverage

func (t *Tile) GetCoverage(px, py int) uint8

GetCoverage returns the coverage value for a pixel within the tile.

func (*Tile) IsEmpty

func (t *Tile) IsEmpty() bool

IsEmpty returns true if all coverage values are zero.

func (*Tile) IsSolid

func (t *Tile) IsSolid() bool

IsSolid returns true if all coverage values are 255 (fully opaque).

func (*Tile) PixelX

func (t *Tile) PixelX() int32

PixelX returns the pixel X coordinate of the tile's top-left corner.

func (*Tile) PixelY

func (t *Tile) PixelY() int32

PixelY returns the pixel Y coordinate of the tile's top-left corner.

func (*Tile) Reset

func (t *Tile) Reset()

Reset clears the tile for reuse.

func (*Tile) SetCoverage

func (t *Tile) SetCoverage(px, py int, value uint8)

SetCoverage sets the coverage value for a pixel within the tile. px, py are pixel offsets within the tile (0-3).

type TileCoord

type TileCoord struct {
	X, Y int32
}

TileCoord represents tile coordinates for hashing.

func (TileCoord) Key

func (tc TileCoord) Key() uint64

Key returns a unique key for the tile coordinate.

type TileCoverage16

type TileCoverage16 [16]uint8

TileCoverage16 holds coverage values for a 4×4 tile.

func ProcessMultipleSegmentsSIMD

func ProcessMultipleSegmentsSIMD(
	lines []LineSegment,
	lineIndices []uint32,
	tileX, tileY uint16,
	backdrop float32,
	fillRule scene.FillStyle,
) TileCoverage16

ProcessMultipleSegmentsSIMD processes multiple segments for a single tile. This batches segment processing to maximize SIMD utilization.

type TileGrid

type TileGrid struct {
	// contains filtered or unexported fields
}

TileGrid is a sparse collection of non-empty tiles. It uses a hashmap for O(1) tile lookup by coordinates.

func NewTileGrid

func NewTileGrid() *TileGrid

NewTileGrid creates a new empty tile grid.

func RasterizePath

func RasterizePath(
	path *scene.Path,
	transform scene.Affine,
	width, height uint16,
	fillRule scene.FillStyle,
) *TileGrid

RasterizePath is a convenience function that rasterizes a path using a pooled rasterizer.

func (*TileGrid) Bounds

func (g *TileGrid) Bounds() (minX, minY, maxX, maxY int32)

Bounds returns the bounding rectangle in tile coordinates.

func (*TileGrid) FillRule

func (g *TileGrid) FillRule() scene.FillStyle

FillRule returns the current fill rule.

func (*TileGrid) ForEach

func (g *TileGrid) ForEach(fn func(*Tile))

ForEach iterates over all tiles in unspecified order.

func (*TileGrid) ForEachInRow

func (g *TileGrid) ForEachInRow(y int32, fn func(*Tile))

ForEachInRow iterates over tiles in a specific row, sorted by X.

func (*TileGrid) ForEachSorted

func (g *TileGrid) ForEachSorted(fn func(*Tile))

ForEachSorted iterates over tiles sorted by Y, then X. This is important for correct backdrop propagation.

func (*TileGrid) Get

func (g *TileGrid) Get(x, y int32) *Tile

Get returns the tile at coordinates, or nil if not present.

func (*TileGrid) GetOrCreate

func (g *TileGrid) GetOrCreate(x, y int32) *Tile

GetOrCreate returns the tile at the given coordinates, creating if needed.

func (*TileGrid) Has

func (g *TileGrid) Has(x, y int32) bool

Has returns true if a tile exists at the coordinates.

func (*TileGrid) PixelBounds

func (g *TileGrid) PixelBounds() scene.Rect

PixelBounds returns the bounding rectangle in pixel coordinates.

func (*TileGrid) Reset

func (g *TileGrid) Reset()

Reset clears the grid for reuse.

func (*TileGrid) SetFillRule

func (g *TileGrid) SetFillRule(rule scene.FillStyle)

SetFillRule sets the fill rule for coverage calculation.

func (*TileGrid) TileCount

func (g *TileGrid) TileCount() int

TileCount returns the number of non-empty tiles.

type TilePool

type TilePool struct {
	// contains filtered or unexported fields
}

TilePool manages a pool of reusable tiles.

func NewTilePool

func NewTilePool() *TilePool

NewTilePool creates a new tile pool.

func (*TilePool) Get

func (p *TilePool) Get() *Tile

Get retrieves a tile from the pool or creates a new one.

func (*TilePool) Put

func (p *TilePool) Put(tile *Tile)

Put returns a tile to the pool.

type TileWinding16

type TileWinding16 [16]float32

TileWinding16 holds winding values for a 4×4 tile in SIMD-friendly layout. All 16 pixels stored contiguously for vectorized operations.

type VertexAttribute added in v0.20.0

type VertexAttribute struct {
	// ShaderLocation is the attribute location in the shader.
	ShaderLocation uint32

	// Format is the attribute data format.
	Format types.VertexFormat

	// Offset is the byte offset from the start of the vertex.
	Offset uint64
}

VertexAttribute describes a vertex attribute.

type VertexBufferLayout added in v0.20.0

type VertexBufferLayout struct {
	// ArrayStride is the byte stride between consecutive vertices.
	ArrayStride uint64

	// StepMode is the input rate (per vertex or per instance).
	StepMode types.VertexStepMode

	// Attributes describes the vertex attributes in this buffer.
	Attributes []VertexAttribute
}

VertexBufferLayout describes a vertex buffer layout.

Jump to

Keyboard shortcuts

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