render

package
v0.1.18 Latest Latest
Warning

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

Go to latest
Published: May 1, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package render provides the internal rendering implementation for gogpu/ui.

This package is INTERNAL and not intended for public use. It implements the widget.Canvas interface using gogpu/gg as the 2D drawing backend.

Architecture

The render package provides:

  • Canvas: Implementation of widget.Canvas that wraps gg.Context
  • Renderer: Orchestrates render cycles (frame begin/end, surface management)
  • Color conversion utilities for widget.Color to gg.RGBA

Canvas Implementation

Canvas wraps a gg.Context and implements all drawing operations required by the widget system. It manages:

  • Clip stack: PushClip/PopClip for hierarchical clipping regions
  • Transform stack: PushTransform/PopTransform for coordinate translation
  • Drawing primitives: Rectangles, rounded rectangles, circles, lines

Thread Safety

Canvas is NOT thread-safe. All drawing operations must occur on the main/UI thread during the Draw phase. This matches the widget.Canvas contract.

Usage

This package is used internally by the UI framework. Application code should use the widget.Canvas interface instead of directly using this package.

// Internal framework usage
canvas := render.NewCanvas(ggContext, width, height)
widget.Draw(ctx, canvas)

Index

Constants

View Source
const (
	// DefaultImageCacheMaxSizeMB is the default maximum cache size in megabytes.
	DefaultImageCacheMaxSizeMB = 64
)

Default cache configuration constants.

Variables

This section is empty.

Functions

func Clamp01Float32

func Clamp01Float32(v float32) float32

Clamp01Float32 clamps a float32 value to the range [0, 1].

func Clamp01Float64

func Clamp01Float64(v float64) float64

Clamp01Float64 clamps a float64 value to the range [0, 1].

func FromGGColor

func FromGGColor(c gg.RGBA) widget.Color

FromGGColor converts a gg.RGBA to widget.Color.

This is the inverse of ToGGColor.

func LerpColor

func LerpColor(a, b gg.RGBA, t float64) gg.RGBA

LerpColor linearly interpolates between two colors.

t=0 returns a, t=1 returns b, values in between interpolate. This is a convenience function that operates on gg.RGBA directly.

func ToGGColor

func ToGGColor(c widget.Color) gg.RGBA

ToGGColor converts a widget.Color to gg.RGBA.

Both types use float components in the range [0, 1], but widget.Color uses float32 while gg.RGBA uses float64. This function performs the conversion.

func ToGGColorPremultiplied

func ToGGColorPremultiplied(c widget.Color) gg.RGBA

ToGGColorPremultiplied converts a widget.Color to premultiplied gg.RGBA.

Premultiplied alpha is more efficient for blending operations. The RGB components are multiplied by alpha.

func ToRGBA added in v0.1.14

func ToRGBA(img image.Image) *image.RGBA

ToRGBA converts any image.Image to *image.RGBA. If the source is already *image.RGBA, it is returned as-is without copying.

Types

type Canvas

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

Canvas implements widget.Canvas using gogpu/gg as the 2D drawing backend.

Canvas wraps a gg.Context and provides all drawing operations required by the widget system. It manages clip and transform stacks internally.

Canvas is NOT thread-safe. All drawing operations must occur on the main/UI thread during the Draw phase.

func NewCanvas

func NewCanvas(dc *gg.Context, width, height int) *Canvas

NewCanvas creates a new Canvas wrapping the given gg.Context.

The width and height specify the canvas dimensions in logical pixels. The gg.Context should already be created with matching dimensions.

func (*Canvas) Clear

func (c *Canvas) Clear(color widget.Color)

Clear fills the entire canvas with the given color.

func (*Canvas) ClipBounds

func (c *Canvas) ClipBounds() geometry.Rect

ClipBounds returns the current clip bounds.

This is useful for widgets that want to optimize drawing by skipping elements outside the visible area.

func (*Canvas) ClipDepth

func (c *Canvas) ClipDepth() int

ClipDepth returns the current depth of the clip stack.

func (*Canvas) Context

func (c *Canvas) Context() *gg.Context

Context returns the underlying gg.Context.

This is provided for advanced use cases where direct access to gg functionality is needed. Use with caution as it bypasses Canvas state.

func (*Canvas) DrawCircle

func (c *Canvas) DrawCircle(center geometry.Point, radius float32, color widget.Color)

DrawCircle fills a circle with the given color.

func (*Canvas) DrawGPUTexture added in v0.1.14

func (c *Canvas) DrawGPUTexture(view gpucontext.TextureView, x, y float64, width, height int)

DrawGPUTexture composites a pre-existing GPU texture view as a textured quad at the given position. The texture is drawn with dimensions width x height.

This is the GPU layer compositing path used by RepaintBoundary — zero CPU readback, zero pixel upload. The view must originate from the same GPU device (typically obtained via gg.Context.CreateOffscreenTexture).

The position is adjusted by the current transform offset and snapped to the pixel grid, consistent with DrawImage behavior.

func (*Canvas) DrawImage

func (c *Canvas) DrawImage(img image.Image, at geometry.Point)

DrawImage draws an image at the specified position.

The image is composited using source-over blending via gg.DrawImage. The position is adjusted by the current transform offset and snapped to the pixel grid.

func (*Canvas) DrawLine

func (c *Canvas) DrawLine(from, to geometry.Point, color widget.Color, strokeWidth float32)

DrawLine draws a line between two points.

func (*Canvas) DrawRect

func (c *Canvas) DrawRect(r geometry.Rect, color widget.Color)

DrawRect fills a rectangle with the given color.

func (*Canvas) DrawRoundRect

func (c *Canvas) DrawRoundRect(r geometry.Rect, color widget.Color, radius float32)

DrawRoundRect fills a rounded rectangle with the given color.

func (*Canvas) DrawText

func (c *Canvas) DrawText(s string, bounds geometry.Rect, fontSize float32, color widget.Color, bold bool, align widget.TextAlign)

DrawText draws text within the given bounding rectangle.

func (*Canvas) FillRectDirect added in v0.1.14

func (c *Canvas) FillRectDirect(r geometry.Rect, color widget.Color)

FillRectDirect fills a rectangle directly on the CPU pixmap, bypassing the GPU shape accelerator. This prevents SDF shapes from being queued on the compositor canvas, enabling the non-MSAA blit-only fast path (ADR-016).

func (*Canvas) FillSVGPath added in v0.1.4

func (c *Canvas) FillSVGPath(svgData string, viewBox float32, bounds geometry.Rect, color widget.Color)

FillSVGPath fills an SVG path within the given bounds.

func (*Canvas) Height

func (c *Canvas) Height() int

Height returns the canvas height in logical pixels.

func (*Canvas) MeasureText

func (c *Canvas) MeasureText(s string, fontSize float32, bold bool) float32

MeasureText returns the width in pixels of the given text string when rendered at the specified font size and weight.

func (*Canvas) PopClip

func (c *Canvas) PopClip()

PopClip removes the most recently pushed clipping region.

Must be called for each PushClip or PushClipRoundRect call.

func (*Canvas) PopTransform

func (c *Canvas) PopTransform()

PopTransform removes the most recently pushed transform.

Must be called for each PushTransform call.

func (*Canvas) PushClip

func (c *Canvas) PushClip(r geometry.Rect)

PushClip pushes a clipping rectangle onto the clip stack.

All subsequent drawing operations will be clipped to this rectangle intersected with any parent clip rectangles.

func (*Canvas) PushClipRoundRect

func (c *Canvas) PushClipRoundRect(r geometry.Rect, radius float32)

PushClipRoundRect pushes a rounded rectangle clipping region.

Uses gg.ClipRoundRect which activates GPU SDF-based clipping for rounded rectangles. All subsequent draw operations will be clipped to the rounded rect shape.

func (*Canvas) PushTransform

func (c *Canvas) PushTransform(offset geometry.Point)

PushTransform pushes a translation transform onto the transform stack.

All subsequent drawing operations will be offset by the given point.

func (*Canvas) RenderSVG added in v0.1.4

func (c *Canvas) RenderSVG(svgXML []byte, bounds geometry.Rect, color widget.Color)

RenderSVG renders full SVG XML within the given bounds with color override. Uses gg/svg.Document.RenderToWithColor to draw directly into the gg.Context.

func (*Canvas) ReplayScene added in v0.1.14

func (c *Canvas) ReplayScene(s *scene.Scene)

ReplayScene renders a previously recorded scene.Scene display list into this canvas. The scene commands are decoded and routed through gg.Context's GPU accelerator, which auto-selects GPU or CPU rendering per shape.

This is the retained-mode replay path (ADR-007): RepaintBoundary caches child drawing as a scene.Scene and replays it on cache hit instead of re-executing child.Draw().

func (*Canvas) Reset

func (c *Canvas) Reset()

Reset clears the clip and transform stacks, restoring initial state.

func (*Canvas) StrokeArc added in v0.1.14

func (c *Canvas) StrokeArc(center geometry.Point, radius float32,
	startAngle, sweepAngle float64, color widget.Color, strokeWidth float32)

StrokeArc draws a circular arc outline from startAngle with the given sweep. Angles are in radians. startAngle=0 is 3 o'clock, positive is counterclockwise. Uses gg.DrawArc which approximates arcs with cubic Bézier curves.

func (*Canvas) StrokeArcStyled added in v0.1.14

func (c *Canvas) StrokeArcStyled(center geometry.Point, radius float32,
	startAngle, sweepAngle float64, color widget.Color, strokeWidth float32, lineCap widget.LineCap)

StrokeArcStyled draws a circular arc with the specified line cap style.

func (*Canvas) StrokeCircle

func (c *Canvas) StrokeCircle(center geometry.Point, radius float32, color widget.Color, strokeWidth float32)

StrokeCircle draws the outline of a circle.

func (*Canvas) StrokeRect

func (c *Canvas) StrokeRect(r geometry.Rect, color widget.Color, strokeWidth float32)

StrokeRect draws the outline of a rectangle.

func (*Canvas) StrokeRoundRect

func (c *Canvas) StrokeRoundRect(r geometry.Rect, color widget.Color, radius float32, strokeWidth float32)

StrokeRoundRect draws the outline of a rounded rectangle.

func (*Canvas) TransformDepth

func (c *Canvas) TransformDepth() int

TransformDepth returns the current depth of the transform stack.

func (*Canvas) TransformOffset

func (c *Canvas) TransformOffset() geometry.Point

TransformOffset returns the current cumulative transform offset.

This is useful for converting between local and global coordinates.

func (*Canvas) Width

func (c *Canvas) Width() int

Width returns the canvas width in logical pixels.

type ImageCache added in v0.1.14

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

ImageCache provides a centralized LRU cache for RepaintBoundary pixel buffers (*image.RGBA). It is the ui-side equivalent of gg's scene.LayerCache, but stores image.RGBA instead of gg.Pixmap.

The cache evicts least recently used entries when the memory limit is exceeded. Entries are keyed by a monotonic uint64 ID assigned to each RepaintBoundary at creation time.

Thread Safety: All methods are safe for concurrent access. The cache uses a sync.RWMutex for read/write separation and atomic counters for statistics.

func DefaultImageCache added in v0.1.14

func DefaultImageCache() *ImageCache

DefaultImageCache creates a new image cache with the default 64MB limit.

func NewImageCache added in v0.1.14

func NewImageCache(maxSizeMB int) *ImageCache

NewImageCache creates a new image cache with the specified maximum size. The maxSizeMB parameter sets the memory budget in megabytes. If maxSizeMB is zero or negative, DefaultImageCacheMaxSizeMB (64MB) is used.

func (*ImageCache) Contains added in v0.1.14

func (c *ImageCache) Contains(key uint64) bool

Contains checks if an entry with the given key exists in the cache. This does not update the LRU order.

func (*ImageCache) EntryCount added in v0.1.14

func (c *ImageCache) EntryCount() int

EntryCount returns the number of entries in the cache.

func (*ImageCache) Get added in v0.1.14

func (c *ImageCache) Get(key uint64) (*image.RGBA, bool)

Get retrieves a cached image by its key. Returns the image and true if found, nil and false otherwise. On cache hit, the entry is moved to the front of the LRU list.

func (*ImageCache) GetVersion added in v0.1.14

func (c *ImageCache) GetVersion(key uint64) (uint64, bool)

GetVersion returns the version of a cached entry if it exists. Returns 0 and false if the entry is not found. This does not update the LRU order.

func (*ImageCache) Invalidate added in v0.1.14

func (c *ImageCache) Invalidate(key uint64)

Invalidate removes a specific entry from the cache by key.

func (*ImageCache) InvalidateAll added in v0.1.14

func (c *ImageCache) InvalidateAll()

InvalidateAll clears the entire cache.

func (*ImageCache) MaxSize added in v0.1.14

func (c *ImageCache) MaxSize() int64

MaxSize returns the memory budget in bytes.

func (*ImageCache) Put added in v0.1.14

func (c *ImageCache) Put(key uint64, img *image.RGBA, version uint64)

Put stores an image in the cache with the given key and version. If the cache exceeds its memory budget, least recently used entries are evicted. If an entry with the same key exists, it is replaced.

Put is a no-op if img is nil or the image exceeds the entire cache budget.

func (*ImageCache) ResetStats added in v0.1.14

func (c *ImageCache) ResetStats()

ResetStats resets the hit, miss, and eviction counters to zero.

func (*ImageCache) Size added in v0.1.14

func (c *ImageCache) Size() int64

Size returns the current memory usage in bytes.

func (*ImageCache) Stats added in v0.1.14

func (c *ImageCache) Stats() ImageCacheStats

Stats returns current cache statistics.

type ImageCacheStats added in v0.1.14

type ImageCacheStats struct {
	// Size is the current memory usage in bytes.
	Size int64
	// MaxSize is the memory budget in bytes.
	MaxSize int64
	// Entries is the number of cached entries.
	Entries int
	// Hits is the number of cache hits.
	Hits uint64
	// Misses is the number of cache misses.
	Misses uint64
	// HitRate is the cache hit rate (0.0 to 1.0).
	HitRate float64
	// Evictions is the number of entries evicted.
	Evictions uint64
}

ImageCacheStats contains cache statistics for monitoring.

type RenderConfig

type RenderConfig struct {
	// BackgroundColor is the color used to clear the canvas at frame start.
	BackgroundColor widget.Color

	// Scale is the display scale factor (1.0 for standard, 2.0 for HiDPI).
	Scale float32
}

RenderConfig contains configuration options for rendering.

func DefaultRenderConfig

func DefaultRenderConfig() RenderConfig

DefaultRenderConfig returns the default render configuration.

type RenderTarget

type RenderTarget interface {
	// Width returns the target width in pixels.
	Width() int

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

	// Bounds returns the target bounds as a geometry.Rect.
	Bounds() geometry.Rect
}

RenderTarget represents an abstract render target.

This interface allows the renderer to work with different output targets (software buffer, GPU texture, etc.).

type Renderer

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

Renderer orchestrates the render cycle for the UI framework.

Renderer manages:

  • Frame begin/end lifecycle
  • Canvas creation and management
  • Surface abstraction for different backends

Renderer is NOT thread-safe. All operations must occur on the main/UI thread.

func NewRenderer

func NewRenderer(width, height int) *Renderer

NewRenderer creates a new Renderer with the given dimensions.

The dimensions specify the render target size in logical pixels.

func (*Renderer) BeginFrame

func (r *Renderer) BeginFrame(background widget.Color) *Canvas

BeginFrame starts a new render frame.

This must be called before any drawing operations. It clears the canvas with the given background color and resets the canvas state.

Returns the Canvas to use for drawing.

func (*Renderer) Canvas

func (r *Renderer) Canvas() *Canvas

Canvas returns the current Canvas.

This is a convenience method for cases where the Canvas is needed outside of the BeginFrame/EndFrame cycle.

func (*Renderer) Close

func (r *Renderer) Close() error

Close releases resources associated with the Renderer.

After Close, the Renderer should not be used.

func (*Renderer) Context

func (r *Renderer) Context() *gg.Context

Context returns the underlying gg.Context.

This is provided for advanced use cases where direct access is needed.

func (*Renderer) EndFrame

func (r *Renderer) EndFrame() *gg.Context

EndFrame finishes the current render frame.

This should be called after all drawing operations are complete. It returns the gg.Context which can be used to extract the rendered image.

func (*Renderer) Height

func (r *Renderer) Height() int

Height returns the renderer height in logical pixels.

func (*Renderer) InFrame

func (r *Renderer) InFrame() bool

InFrame returns true if currently between BeginFrame and EndFrame.

func (*Renderer) Resize

func (r *Renderer) Resize(width, height int)

Resize changes the renderer dimensions.

This recreates the underlying context and canvas. Any in-progress frame is implicitly ended.

func (*Renderer) Width

func (r *Renderer) Width() int

Width returns the renderer width in logical pixels.

type SceneCanvas

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

SceneCanvas implements widget.Canvas by recording drawing commands into a scene.Scene. This is used inside RepaintBoundary for tile-parallel rendering of widget subtrees.

Shape drawing (rect, round rect, circle, line) is recorded directly into the scene's encoding as scene shapes. Text rendering uses scene.DrawText which converts glyph outlines to vector Fill paths — scalable and resolution-independent. No bitmap capture needed.

SceneCanvas is NOT thread-safe. All drawing operations must occur on the main/UI thread during the Draw phase.

func NewSceneCanvas

func NewSceneCanvas(sc *scene.Scene, width, height int) *SceneCanvas

NewSceneCanvas creates a new SceneCanvas that records drawing commands into the given scene. The width and height specify the canvas dimensions in logical pixels.

func (*SceneCanvas) Clear

func (c *SceneCanvas) Clear(color widget.Color)

Clear fills the entire canvas with the given color.

func (*SceneCanvas) ClipBounds added in v0.1.14

func (c *SceneCanvas) ClipBounds() geometry.Rect

ClipBounds returns the current clip rectangle.

func (*SceneCanvas) Close

func (c *SceneCanvas) Close()

Close releases resources held by the SceneCanvas. Currently a no-op since vector text rendering does not hold persistent resources, but retained for lifecycle symmetry with NewSceneCanvas.

func (*SceneCanvas) DrawCircle

func (c *SceneCanvas) DrawCircle(center geometry.Point, radius float32, color widget.Color)

DrawCircle fills a circle with the given color.

func (*SceneCanvas) DrawImage

func (c *SceneCanvas) DrawImage(img image.Image, at geometry.Point)

DrawImage draws an image at the specified position.

func (*SceneCanvas) DrawLine

func (c *SceneCanvas) DrawLine(from, to geometry.Point, color widget.Color, strokeWidth float32)

DrawLine draws a line between two points.

func (*SceneCanvas) DrawRect

func (c *SceneCanvas) DrawRect(r geometry.Rect, color widget.Color)

DrawRect fills a rectangle with the given color.

func (*SceneCanvas) DrawRoundRect

func (c *SceneCanvas) DrawRoundRect(r geometry.Rect, color widget.Color, radius float32)

DrawRoundRect fills a rounded rectangle with the given color.

func (*SceneCanvas) DrawText

func (c *SceneCanvas) DrawText(s string, bounds geometry.Rect, fontSize float32, color widget.Color, bold bool, align widget.TextAlign)

DrawText draws text within the given bounding rectangle using vector paths.

Text is rendered via scene.DrawText which converts glyph outlines to vector Fill paths in the scene — scalable, resolution-independent, and enterprise- quality. No bitmap capture or temporary gg.Context needed.

Alignment is handled by measuring the text advance and computing the x offset before calling scene.DrawText with the final position.

func (*SceneCanvas) FillRectDirect added in v0.1.14

func (c *SceneCanvas) FillRectDirect(r geometry.Rect, color widget.Color)

FillRectDirect fills a rectangle via the scene graph. SceneCanvas does not use the GPU SDF accelerator, so this is equivalent to DrawRect.

func (*SceneCanvas) FillSVGPath added in v0.1.4

func (c *SceneCanvas) FillSVGPath(svgData string, viewBox float32, bounds geometry.Rect, color widget.Color)

FillSVGPath fills an SVG path within the given bounds using a temporary gg.Context.

func (*SceneCanvas) MeasureText

func (c *SceneCanvas) MeasureText(s string, fontSize float32, bold bool) float32

MeasureText returns the width in pixels of the given text string when rendered at the specified font size and weight.

Uses text.Measure from the gg text package for accurate, standalone measurement — no gg.Context required.

func (*SceneCanvas) PopClip

func (c *SceneCanvas) PopClip()

PopClip removes the most recently pushed clipping region.

func (*SceneCanvas) PopTransform

func (c *SceneCanvas) PopTransform()

PopTransform removes the most recently pushed transform.

func (*SceneCanvas) PushClip

func (c *SceneCanvas) PushClip(r geometry.Rect)

PushClip pushes a clipping rectangle onto the clip stack.

func (*SceneCanvas) PushClipRoundRect

func (c *SceneCanvas) PushClipRoundRect(r geometry.Rect, radius float32)

PushClipRoundRect pushes a rounded rectangle clipping region. SceneCanvas falls back to rectangular clip (scene.Scene does not yet support rounded clip shapes).

func (*SceneCanvas) PushTransform

func (c *SceneCanvas) PushTransform(offset geometry.Point)

PushTransform pushes a translation transform onto the transform stack.

func (*SceneCanvas) ReplayScene added in v0.1.14

func (c *SceneCanvas) ReplayScene(s *scene.Scene)

ReplayScene merges a child scene.Scene into this canvas's parent scene with translation offset. This is the scene-concatenation path (ADR-007) used when a RepaintBoundary replays its cached display list inside another SceneCanvas (nested boundaries).

The child scene was recorded in local coordinates (0,0 = boundary origin). AppendWithTranslation offsets all path coordinates by the current cumulative transform offset, following the Vello pattern (encoding.rs:162-169).

func (*SceneCanvas) Scene

func (c *SceneCanvas) Scene() *scene.Scene

Scene returns the underlying scene.Scene.

func (*SceneCanvas) StrokeArc added in v0.1.14

func (c *SceneCanvas) StrokeArc(center geometry.Point, radius float32,
	startAngle, sweepAngle float64, color widget.Color, strokeWidth float32)

StrokeArc draws a circular arc outline from startAngle with the given sweep. Uses scene.Path.Arc to record the arc as cubic Bézier curves into the scene.

func (*SceneCanvas) StrokeArcStyled added in v0.1.14

func (c *SceneCanvas) StrokeArcStyled(center geometry.Point, radius float32,
	startAngle, sweepAngle float64, color widget.Color, strokeWidth float32, lineCap widget.LineCap)

StrokeArcStyled draws a circular arc with the specified line cap style.

func (*SceneCanvas) StrokeCircle

func (c *SceneCanvas) StrokeCircle(center geometry.Point, radius float32, color widget.Color, strokeWidth float32)

StrokeCircle draws the outline of a circle.

func (*SceneCanvas) StrokeRect

func (c *SceneCanvas) StrokeRect(r geometry.Rect, color widget.Color, strokeWidth float32)

StrokeRect draws the outline of a rectangle.

func (*SceneCanvas) StrokeRoundRect

func (c *SceneCanvas) StrokeRoundRect(r geometry.Rect, color widget.Color, radius float32, strokeWidth float32)

StrokeRoundRect draws the outline of a rounded rectangle.

func (*SceneCanvas) TransformOffset

func (c *SceneCanvas) TransformOffset() geometry.Point

TransformOffset returns the current cumulative transform offset.

type SoftwareTarget

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

SoftwareTarget is a RenderTarget backed by a software buffer (gg.Context).

func NewSoftwareTarget

func NewSoftwareTarget(width, height int) *SoftwareTarget

NewSoftwareTarget creates a new software render target.

func (*SoftwareTarget) Bounds

func (t *SoftwareTarget) Bounds() geometry.Rect

Bounds returns the target bounds.

func (*SoftwareTarget) Close

func (t *SoftwareTarget) Close() error

Close releases resources.

func (*SoftwareTarget) Context

func (t *SoftwareTarget) Context() *gg.Context

Context returns the underlying gg.Context.

func (*SoftwareTarget) Height

func (t *SoftwareTarget) Height() int

Height returns the target height.

func (*SoftwareTarget) Width

func (t *SoftwareTarget) Width() int

Width returns the target width.

Directories

Path Synopsis
Package fonts embeds professional UI font files.
Package fonts embeds professional UI font files.

Jump to

Keyboard shortcuts

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