gpucontext

package module
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Apr 25, 2026 License: MIT Imports: 4 Imported by: 9

README

gpucontext

Shared GPU infrastructure for the gogpu ecosystem.

Overview

gpucontext provides interfaces and utilities for sharing GPU resources across multiple packages without circular dependencies.

Relationship to gputypes

Package Purpose Dependencies
gputypes WebGPU types (enums, structs, constants) ZERO
gpucontext Interfaces (DeviceProvider, EventSource, WindowChrome, Texture) imports gputypes

gpucontext imports gputypes to use shared types in interface signatures, ensuring type compatibility across the ecosystem.

Installation

go get github.com/gogpu/gpucontext

Requires: Go 1.25+

Features

  • DeviceProvider — Interface for injecting GPU device and queue (typed, zero any)
  • WindowProvider — Window geometry, DPI scale factor, and redraw requests
  • PlatformProvider — Clipboard, cursor, dark mode, and accessibility preferences
  • CursorShape — 12 standard cursor shapes (arrow, pointer, text, resize, etc.)
  • EventSource — Interface for input events (keyboard, mouse, window, IME)
  • PointerEventSource — W3C Pointer Events Level 3 (unified mouse/touch/pen)
  • ScrollEventSource — Scroll/wheel events with pixel/line/page modes
  • Texture — Minimal interface for GPU textures with TextureUpdater/TextureRegionUpdater/TextureDrawer/TextureCreator
  • IME Support — Input Method Editor for CJK languages (Chinese, Japanese, Korean)
  • WindowChrome — Custom window chrome for frameless windows (hit testing, minimize/maximize/close)
  • Registry[T] — Generic registry with priority-based backend selection
  • WebGPU Interfaces — Device, Queue, Adapter, Surface interfaces
  • WebGPU Types — Re-exports from gputypes (TextureFormat, etc.)

Usage

DeviceProvider Pattern

The DeviceProvider interface enables dependency injection of GPU capabilities:

// In gogpu/gogpu - implements DeviceProvider
type App struct {
    device gpucontext.Device
    queue  gpucontext.Queue
}

func (app *App) Device() gpucontext.Device       { return app.device }
func (app *App) Queue() gpucontext.Queue         { return app.queue }
func (app *App) SurfaceFormat() gpucontext.TextureFormat { return app.format }
func (app *App) Adapter() gpucontext.Adapter     { return app.adapter }

// In gogpu/gg - uses DeviceProvider
func NewGPUCanvas(provider gpucontext.DeviceProvider) *Canvas {
    return &Canvas{
        device: provider.Device(),
        queue:  provider.Queue(),
    }
}
Device Sharing (typed, zero any)

GPU accelerators (like gg's SDF pipeline) share the host device via typed interfaces:

// Consumer gets typed device from provider
func (a *SDFAccelerator) SetDeviceProvider(dp gpucontext.DeviceProvider) {
    dev := dp.Device()                    // gpucontext.Device (minimal interface)
    wgpuDev, ok := dev.(*wgpu.Device)     // type assert for full wgpu API
    if ok {
        a.initWithSharedDevice(wgpuDev)
    }
}

The pattern follows Go's "accept interfaces, return structs":

  • gpucontext.Device — minimal interface (type token)
  • *wgpu.Device — concrete type, satisfies gpucontext.Device implicitly
  • Consumer type-asserts when it needs the full API
WindowProvider (for UI frameworks and rendering libraries)

The WindowProvider interface enables UI frameworks and rendering libraries to query window dimensions (logical points) and DPI scale factor:

// In gogpu/ui - uses WindowProvider for layout
func (ui *UI) Layout(wp gpucontext.WindowProvider) {
    w, h := wp.Size()           // logical points (DIP)
    scale := wp.ScaleFactor()   // 2.0 on Retina
    ui.root.Layout(w, h, scale)
}

// In gg/ggcanvas - auto-detects HiDPI from provider
func New(provider gpucontext.DeviceProvider, w, h int) (*Canvas, error) {
    scale := 1.0
    if wp, ok := provider.(gpucontext.WindowProvider); ok {
        scale = wp.ScaleFactor()
    }
    // allocate pixmap at physical resolution: w*scale x h*scale
}
PlatformProvider (optional OS integration)

PlatformProvider exposes clipboard, cursor, and system preferences. Not all hosts support it — use type assertion to check:

// In gogpu/ui - cursor management
func (ui *UI) UpdateCursor(provider gpucontext.WindowProvider) {
    if pp, ok := provider.(gpucontext.PlatformProvider); ok {
        pp.SetCursor(gpucontext.CursorPointer) // hand cursor
    }
}

// In gogpu/ui - clipboard
func (ui *UI) Paste(provider gpucontext.WindowProvider) {
    if pp, ok := provider.(gpucontext.PlatformProvider); ok {
        text, err := pp.ClipboardRead()
        if err == nil {
            ui.focused.InsertText(text)
        }
    }
}

// In gogpu/ui - theme detection
func (ui *UI) DetectTheme(provider gpucontext.WindowProvider) {
    if pp, ok := provider.(gpucontext.PlatformProvider); ok {
        if pp.DarkMode() {
            ui.SetTheme(DarkTheme)
        }
    }
}
EventSource (for UI frameworks)

EventSource enables UI frameworks to receive input events from host applications:

// In gogpu/ui - uses EventSource
func (ui *UI) AttachEvents(source gpucontext.EventSource) {
    source.OnKeyPress(func(key gpucontext.Key, mods gpucontext.Modifiers) {
        ui.focused.HandleKeyDown(key, mods)
    })

    source.OnMousePress(func(button gpucontext.MouseButton, x, y float64) {
        widget := ui.hitTest(x, y)
        widget.HandleMouseDown(button, x, y)
    })
}

// In gogpu/gogpu - implements EventSource
type App struct {
    keyHandlers []func(gpucontext.Key, gpucontext.Modifiers)
}

func (app *App) OnKeyPress(fn func(gpucontext.Key, gpucontext.Modifiers)) {
    app.keyHandlers = append(app.keyHandlers, fn)
}
IME Support (CJK Input)

IMEState and related interfaces enable Input Method Editor support for Chinese, Japanese, and Korean input:

// In gogpu/ui - handle IME composition
func (input *TextInput) AttachIME(source gpucontext.EventSource) {
    source.OnIMECompositionStart(func() {
        input.showCompositionWindow()
    })

    source.OnIMECompositionUpdate(func(state gpucontext.IMEState) {
        // Show composition text with cursor
        input.setCompositionText(state.CompositionText, state.CursorPos)
    })

    source.OnIMECompositionEnd(func(committed string) {
        // Insert final text
        input.insertText(committed)
        input.hideCompositionWindow()
    })
}

// Control IME position (for composition window placement)
func (input *TextInput) Focus(controller gpucontext.IMEController) {
    controller.SetIMEEnabled(true)
    controller.SetIMEPosition(input.cursorX, input.cursorY)
}
Texture Interface

Texture provides a minimal interface for GPU textures, enabling sharing between packages:

// Texture is a minimal interface for GPU textures
type Texture interface {
    Width() int
    Height() int
}

// TextureDrawer can draw textures (implemented by renderers)
type TextureDrawer interface {
    DrawTexture(tex Texture, x, y float32) error
    DrawTextureEx(tex Texture, opts TextureDrawOptions) error
}

// TextureCreator can create textures from pixel data
type TextureCreator interface {
    CreateTexture(width, height int, pixels []byte) (Texture, error)
}
TextureUpdater (Dynamic Content)

TextureUpdater enables efficient texture updates without recreating textures:

// TextureUpdater updates existing texture pixel data (full upload)
type TextureUpdater interface {
    UpdateData(data []byte) error
}

// TextureRegionUpdater uploads only a sub-rectangle (partial upload)
type TextureRegionUpdater interface {
    UpdateRegion(x, y, w, h int, data []byte) error
}

TextureRegionUpdater enables incremental rendering — only dirty regions are uploaded to GPU instead of the full texture. For a 1080p@2x window, this reduces upload from ~33MB to a few KB per frame when only a small widget changes.

Usage in integration packages:

// In gg/integration/ggcanvas - creates textures from CPU canvas
func (c *Canvas) Flush() (gpucontext.Texture, error) {
    pixels := c.pixmap.Pix()
    return c.creator.CreateTexture(c.width, c.height, pixels)
}

// In gogpu - implements TextureDrawer
func (ctx *Context) DrawTexture(tex gpucontext.Texture, x, y float32) error {
    return ctx.renderer.DrawTexture(tex, x, y)
}
WindowChrome (frameless windows)

WindowChrome enables custom window chrome for frameless windows with custom title bars:

// In gogpu/ui - custom title bar with hit testing
func (ui *UI) SetupFramelessWindow(provider gpucontext.WindowProvider) {
    if wc, ok := provider.(gpucontext.WindowChrome); ok {
        wc.SetFrameless(true)
        wc.SetHitTestCallback(func(x, y float64) gpucontext.HitTestResult {
            if y < 40 { // title bar height
                return gpucontext.HitTestCaption // enables window dragging
            }
            return gpucontext.HitTestClient
        })
    }
}

// Window controls
wc.Minimize()
wc.Maximize()       // toggles maximized/restored
wc.IsMaximized()    // for button icon state
wc.Close()
Backend Registry

The Registry[T] provides thread-safe registration with priority-based selection:

import "github.com/gogpu/gpucontext"

// Create registry with priority order
var backends = gpucontext.NewRegistry[Backend](
    gpucontext.WithPriority("vulkan", "dx12", "metal", "gles", "software"),
)

// Register backends (typically in init())
func init() {
    backends.Register("vulkan", NewVulkanBackend)
    backends.Register("software", NewSoftwareBackend)
}

// Get best available backend
backend := backends.Best()

// Or get specific backend
vulkan := backends.Get("vulkan")

// Check availability
if backends.Has("vulkan") {
    // Vulkan is available
}

// List all available
names := backends.Available() // ["vulkan", "software"]

Dependency Graph

                   gputypes (ZERO deps)
                 All WebGPU types (100+)
                          │
                          ▼
                   gpucontext
                  (imports gputypes)
          DeviceProvider, WindowChrome,
          WindowProvider, PlatformProvider,
          EventSource, Texture, Registry
                          │
          ┌───────────────┼───────────────┐
          │               │               │
          ▼               ▼               ▼
        gogpu            gg              ui
     (implements)      (uses)         (uses)
          │
          ▼
       wgpu/hal

Ecosystem

Package Description
gogpu/gogpu Graphics framework, implements DeviceProvider
gogpu/gg 2D graphics, uses DeviceProvider
gogpu/wgpu Pure Go WebGPU implementation
born-ml/born ML framework, implements & uses

License

MIT License — see LICENSE for details.

Documentation

Overview

Package gpucontext provides shared GPU infrastructure for the gogpu ecosystem.

This package defines interfaces and utilities used across multiple gogpu projects to enable GPU resource sharing without circular dependencies:

  • DeviceProvider: Interface for providing GPU device and queue
  • EventSource: Interface for window/input events (keyboard, mouse)
  • PointerEventSource: Interface for unified pointer events (W3C Level 3, mouse+touch+pen)
  • WindowProvider: Interface for window geometry, DPI, and redraw requests
  • PlatformProvider: Interface for clipboard, cursor, dark mode, accessibility
  • ScrollEventSource: Interface for detailed scroll events
  • WindowChrome: Interface for custom window chrome (frameless windows)
  • Texture: Minimal interface for GPU textures
  • TextureDrawer: Interface for drawing textures (2D rendering)
  • TextureCreator: Interface for creating textures from pixel data

Consumers

  • gogpu/gogpu: Implements DeviceProvider via App/Renderer
  • gogpu/gg: Uses DeviceProvider for GPU-accelerated 2D rendering
  • born-ml/born: Implements and uses for GPU compute

Design Principles

This package follows the wgpu ecosystem pattern where shared types are separated from implementation (cf. wgpu-types in Rust).

The key insight is that GPU context (device + queue + related state) is a universal concept across Vulkan, CUDA, OpenGL, and WebGPU. By defining a minimal interface here, different packages can share GPU resources without depending on each other.

Example Usage

// In gogpu/gogpu - implements DeviceProvider
func (app *App) Device() gpucontext.Device { return app.renderer.device }
func (app *App) Queue() gpucontext.Queue { return app.renderer.queue }

// In gogpu/gg - uses DeviceProvider
func NewGPUCanvas(provider gpucontext.DeviceProvider) *Canvas {
    return &Canvas{
        device: provider.Device(),
        queue:  provider.Queue(),
    }
}

Reference: https://github.com/gogpu/gpucontext

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Adapter

type Adapter interface{}

Adapter is a type token for a physical GPU adapter. Consumers that need the full adapter API should type-assert to the concrete type (e.g., *wgpu.Adapter).

type Button added in v0.5.0

type Button int8

Button identifies which button triggered a pointer event. This follows the W3C Pointer Events specification button values.

const (
	// ButtonNone indicates no button or no change in button state.
	// Used for move events where no button triggered the event.
	ButtonNone Button = -1

	// ButtonLeft is the primary button (usually left mouse button).
	ButtonLeft Button = 0

	// ButtonMiddle is the auxiliary button (usually middle mouse button or wheel click).
	ButtonMiddle Button = 1

	// ButtonRight is the secondary button (usually right mouse button).
	ButtonRight Button = 2

	// ButtonX1 is the first extra button (usually "back" button).
	ButtonX1 Button = 3

	// ButtonX2 is the second extra button (usually "forward" button).
	ButtonX2 Button = 4

	// ButtonEraser is the eraser button on a pen (if available).
	ButtonEraser Button = 5
)

func (Button) String added in v0.5.0

func (b Button) String() string

String returns the button name for debugging.

type Buttons added in v0.5.0

type Buttons uint8

Buttons is a bitmask representing currently pressed buttons. This allows tracking multiple button states simultaneously.

const (
	// ButtonsNone indicates no buttons are pressed.
	ButtonsNone Buttons = 0

	// ButtonsLeft indicates the left button is pressed.
	ButtonsLeft Buttons = 1 << 0

	// ButtonsRight indicates the right button is pressed.
	ButtonsRight Buttons = 1 << 1

	// ButtonsMiddle indicates the middle button is pressed.
	ButtonsMiddle Buttons = 1 << 2

	// ButtonsX1 indicates the X1 (back) button is pressed.
	ButtonsX1 Buttons = 1 << 3

	// ButtonsX2 indicates the X2 (forward) button is pressed.
	ButtonsX2 Buttons = 1 << 4

	// ButtonsEraser indicates the eraser button is pressed.
	ButtonsEraser Buttons = 1 << 5
)

func (Buttons) Count added in v0.5.0

func (b Buttons) Count() int

Count returns the number of pressed buttons.

func (Buttons) HasEraser added in v0.5.0

func (b Buttons) HasEraser() bool

HasEraser returns true if the eraser button is pressed.

func (Buttons) HasLeft added in v0.5.0

func (b Buttons) HasLeft() bool

HasLeft returns true if the left button is pressed.

func (Buttons) HasMiddle added in v0.5.0

func (b Buttons) HasMiddle() bool

HasMiddle returns true if the middle button is pressed.

func (Buttons) HasRight added in v0.5.0

func (b Buttons) HasRight() bool

HasRight returns true if the right button is pressed.

func (Buttons) HasX1 added in v0.5.0

func (b Buttons) HasX1() bool

HasX1 returns true if the X1 (back) button is pressed.

func (Buttons) HasX2 added in v0.5.0

func (b Buttons) HasX2() bool

HasX2 returns true if the X2 (forward) button is pressed.

type CommandEncoder added in v0.15.0

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

CommandEncoder is a type-safe opaque handle to a GPU command encoder.

Same pattern as TextureView. Used for the shared encoder pipeline (ADR-017). 8 bytes, value type, zero allocations.

func NewCommandEncoder added in v0.15.0

func NewCommandEncoder(ptr unsafe.Pointer) CommandEncoder

NewCommandEncoder creates a CommandEncoder from an unsafe.Pointer to a concrete GPU command encoder (e.g., *wgpu.CommandEncoder).

func (CommandEncoder) IsNil added in v0.15.0

func (ce CommandEncoder) IsNil() bool

IsNil reports whether the handle holds no resource (zero value).

func (CommandEncoder) Pointer added in v0.15.0

func (ce CommandEncoder) Pointer() unsafe.Pointer

Pointer returns the underlying unsafe.Pointer. Consumers type-convert to the concrete type: (*wgpu.CommandEncoder)(ce.Pointer()).

type CursorMode added in v0.12.0

type CursorMode int

CursorMode controls how the mouse cursor behaves within the window.

This follows the pattern established by SDL_SetRelativeMouseMode and SDL_SetWindowMouseGrab, providing three modes that cover the common use cases for games and interactive applications.

const (
	// CursorModeNormal is the default mode: cursor is visible and moves freely.
	CursorModeNormal CursorMode = iota

	// CursorModeLocked hides the cursor and confines it to the window.
	// Mouse movement is reported as relative deltas (DeltaX/DeltaY on PointerEvent).
	// The cursor is warped to the window center on each frame.
	// Equivalent to SDL_SetRelativeMouseMode(SDL_TRUE).
	CursorModeLocked

	// CursorModeConfined keeps the cursor visible but confines it to the window bounds.
	// Equivalent to SDL_SetWindowMouseGrab(SDL_TRUE).
	CursorModeConfined
)

func (CursorMode) String added in v0.12.0

func (m CursorMode) String() string

String returns the cursor mode name for debugging.

type CursorShape added in v0.8.0

type CursorShape int

CursorShape represents the mouse cursor shape.

These values cover the most common cursor shapes across platforms (Windows, macOS, Linux). They map directly to platform-specific cursor constants.

For applications that need cursor changes:

if pp, ok := provider.(gpucontext.PlatformProvider); ok {
    pp.SetCursor(gpucontext.CursorText) // I-beam for text input
}
const (
	// CursorDefault is the standard arrow cursor.
	CursorDefault CursorShape = iota

	// CursorPointer is the hand cursor for clickable elements.
	CursorPointer

	// CursorText is the I-beam cursor for text input areas.
	CursorText

	// CursorCrosshair is the crosshair cursor for precise selection.
	CursorCrosshair

	// CursorMove is the four-arrow cursor for movable elements.
	CursorMove

	// CursorResizeNS is the north-south resize cursor.
	CursorResizeNS

	// CursorResizeEW is the east-west resize cursor.
	CursorResizeEW

	// CursorResizeNWSE is the NW-SE diagonal resize cursor.
	CursorResizeNWSE

	// CursorResizeNESW is the NE-SW diagonal resize cursor.
	CursorResizeNESW

	// CursorNotAllowed is the circle-with-line cursor for forbidden actions.
	CursorNotAllowed

	// CursorWait is the busy/wait cursor.
	CursorWait

	// CursorNone hides the cursor.
	CursorNone
)

func (CursorShape) String added in v0.8.0

func (c CursorShape) String() string

String returns the cursor shape name for debugging.

type Device

type Device interface{}

Device is a type token for a logical GPU device.

Concrete implementations (e.g., *wgpu.Device) satisfy this interface implicitly. Consumers that need the full device API should type-assert to the concrete type:

dev := provider.Device()
wgpuDev, ok := dev.(*wgpu.Device)
if ok {
    halDevice := wgpuDev.HalDevice()
}

The interface is intentionally minimal to avoid coupling gpucontext to any specific GPU implementation.

type DeviceProvider

type DeviceProvider interface {
	// Device returns the WebGPU device handle.
	// The device is used for creating GPU resources (buffers, textures, pipelines).
	Device() Device

	// Queue returns the WebGPU command queue.
	// The queue is used for submitting command buffers to the GPU.
	Queue() Queue

	// SurfaceFormat returns the preferred texture format for the surface.
	// May return gputypes.TextureFormatUndefined if no surface is attached (headless mode).
	// This is useful for creating render targets that match the surface format.
	SurfaceFormat() gputypes.TextureFormat

	// Adapter returns the WebGPU adapter (optional, may be nil).
	// The adapter provides information about the GPU capabilities.
	// Some implementations may not expose the adapter.
	Adapter() Adapter
}

DeviceProvider provides access to GPU device, queue, and related resources. This interface enables dependency injection of GPU capabilities between packages without circular dependencies.

Implementations:

  • gogpu.App implements DeviceProvider via renderer
  • born.Session implements DeviceProvider for ML compute

Example usage in gg:

import (
    "github.com/gogpu/gpucontext"
    "github.com/gogpu/gputypes"
)

func NewGPUCanvas(provider gpucontext.DeviceProvider) *Canvas {
    format := provider.SurfaceFormat() // returns gputypes.TextureFormat
    return &Canvas{
        device: provider.Device(),
        queue:  provider.Queue(),
        format: format,
    }
}

type EventSource

type EventSource interface {

	// OnKeyPress registers a callback for key press events.
	OnKeyPress(func(key Key, mods Modifiers))

	// OnKeyRelease registers a callback for key release events.
	OnKeyRelease(func(key Key, mods Modifiers))

	// OnTextInput registers a callback for text input events.
	// Text input is the result of key presses after applying keyboard layouts
	// and input methods. This is the preferred way to handle text entry.
	OnTextInput(func(text string))

	// OnMouseMove registers a callback for mouse movement.
	OnMouseMove(func(x, y float64))

	// OnMousePress registers a callback for mouse button press.
	OnMousePress(func(button MouseButton, x, y float64))

	// OnMouseRelease registers a callback for mouse button release.
	OnMouseRelease(func(button MouseButton, x, y float64))

	// OnScroll registers a callback for scroll wheel events.
	// dx and dy are the scroll deltas (positive = right/down).
	OnScroll(func(dx, dy float64))

	// OnResize registers a callback for window resize.
	OnResize(func(width, height int))

	// OnFocus registers a callback for focus change.
	OnFocus(func(focused bool))

	// OnIMECompositionStart registers a callback for when IME composition begins.
	// This is called when the user starts typing in an IME (e.g., for CJK input).
	OnIMECompositionStart(fn func())

	// OnIMECompositionUpdate registers a callback for IME composition updates.
	// Called during composition with the current state (preview text, cursor).
	OnIMECompositionUpdate(fn func(state IMEState))

	// OnIMECompositionEnd registers a callback for when IME composition ends.
	// The committed parameter contains the final text that should be inserted.
	OnIMECompositionEnd(fn func(committed string))
}

EventSource provides input events from the host application to UI frameworks.

This interface enables UI frameworks (like gogpu/ui) to receive user input events from the host window system. The host application (e.g., gogpu.App) implements EventSource and passes it to the UI layer.

Event callbacks are invoked on the main thread during the event loop. Callback functions should be fast and non-blocking.

Example usage in a UI framework:

func (ui *UI) AttachEvents(source gpucontext.EventSource) {
    source.OnMousePress(func(button MouseButton, x, y float64) {
        widget := ui.hitTest(x, y)
        if widget != nil {
            widget.HandleMouseDown(button, x, y)
        }
    })

    source.OnKeyPress(func(key Key, mods Modifiers) {
        ui.focused.HandleKeyDown(key, mods)
    })
}

Note: This interface is designed for gogpu ↔ ui integration. The rendering library (gg) does NOT use this interface.

type GestureEvent added in v0.6.0

type GestureEvent struct {
	// NumPointers is the number of active touch points.
	// Gestures require at least 2 pointers.
	NumPointers int

	// ZoomDelta is the proportional zoom factor for this frame.
	// 1.0 = no change, >1.0 = zoom in, <1.0 = zoom out.
	// Computed from change in average distance from centroid.
	ZoomDelta float64

	// ZoomDelta2D provides non-proportional zoom (stretch) deltas.
	// This allows independent X and Y scaling for non-uniform zoom.
	// For most use cases, use ZoomDelta instead.
	ZoomDelta2D Point

	// RotationDelta is the rotation change in radians for this frame.
	// Positive = counter-clockwise, negative = clockwise.
	// Computed from angle change of first pointer relative to centroid.
	RotationDelta float64

	// TranslationDelta is the pan movement in logical pixels for this frame.
	// Computed from change in centroid position.
	TranslationDelta Point

	// PinchType classifies the pinch gesture based on finger geometry.
	// Useful for constraining zoom to one axis (e.g., timeline scrubbing).
	PinchType PinchType

	// Center is the centroid of all active touch points.
	// Use this as the zoom/rotation pivot point.
	Center Point

	// Timestamp is the event time as duration since an arbitrary reference.
	// Useful for velocity calculations or animation timing.
	// Zero if timestamps are not available.
	Timestamp time.Duration
}

GestureEvent contains computed gesture deltas per frame.

This event follows the Vello multi-touch pattern where gesture deltas are computed once per frame from the set of active pointers. This approach avoids jitter from individual pointer moves and provides smooth, predictable gesture values.

The event is designed for multi-touch gestures (pinch-to-zoom, rotation, pan) but degrades gracefully with fewer pointers:

  • 0-1 pointers: Empty event (no gesture possible)
  • 2+ pointers: Full gesture with zoom, rotation, and translation

Example usage:

source.OnGesture(func(ev gpucontext.GestureEvent) {
    if ev.NumPointers >= 2 {
        camera.Zoom(ev.ZoomDelta)
        camera.Rotate(ev.RotationDelta)
        camera.Pan(ev.TranslationDelta)
    }
})

type GestureEventSource added in v0.6.0

type GestureEventSource interface {
	// OnGesture registers a callback for gesture events.
	// The callback receives a GestureEvent containing computed deltas.
	//
	// Callback threading: Called on the main/UI thread at end of frame.
	// Callbacks should be fast and non-blocking.
	//
	// Gesture events are delivered once per frame when 2+ pointers are active.
	OnGesture(fn func(GestureEvent))
}

GestureEventSource provides gesture event callbacks.

This interface extends EventSource with high-level gesture recognition. The gesture recognizer computes deltas once per frame from pointer events, following the Vello pattern for smooth, predictable gestures.

Type assertion pattern:

if ges, ok := eventSource.(gpucontext.GestureEventSource); ok {
    ges.OnGesture(handleGestureEvent)
}

For applications that need gesture support:

ges.OnGesture(func(ev gpucontext.GestureEvent) {
    if ev.NumPointers >= 2 {
        handlePinchZoom(ev.ZoomDelta, ev.Center)
    }
})

type HitTestCallback added in v0.11.0

type HitTestCallback func(x, y float64) HitTestResult

HitTestCallback is called by the platform layer to determine what region of the window the cursor is in. The coordinates (x, y) are in logical points (DIP) relative to the window's top-left corner.

The callback is invoked during mouse move events when the window is frameless. It must return quickly to avoid input lag.

type HitTestResult added in v0.11.0

type HitTestResult int

HitTestResult represents what region of the window the cursor is over.

When a window is frameless (no OS title bar), the application must tell the OS what part of the window the cursor is in, so the OS can handle dragging, resizing, and window button interactions.

These values map directly to platform-specific hit test constants:

  • Windows: WM_NCHITTEST return values (HTCLIENT, HTCAPTION, etc.)
  • macOS: NSWindow regions
  • Linux: xdg-toplevel resize edges
const (
	// HitTestClient indicates the cursor is over the client (content) area.
	// The application handles all input normally.
	HitTestClient HitTestResult = iota

	// HitTestCaption indicates the cursor is over the title bar / drag area.
	// The OS handles window dragging on mouse down.
	HitTestCaption

	// HitTestClose indicates the cursor is over the close button region.
	HitTestClose

	// HitTestMaximize indicates the cursor is over the maximize button region.
	HitTestMaximize

	// HitTestMinimize indicates the cursor is over the minimize button region.
	HitTestMinimize

	// HitTestResizeN indicates the cursor is over the top resize edge.
	HitTestResizeN

	// HitTestResizeS indicates the cursor is over the bottom resize edge.
	HitTestResizeS

	// HitTestResizeW indicates the cursor is over the left resize edge.
	HitTestResizeW

	// HitTestResizeE indicates the cursor is over the right resize edge.
	HitTestResizeE

	// HitTestResizeNW indicates the cursor is over the top-left resize corner.
	HitTestResizeNW

	// HitTestResizeNE indicates the cursor is over the top-right resize corner.
	HitTestResizeNE

	// HitTestResizeSW indicates the cursor is over the bottom-left resize corner.
	HitTestResizeSW

	// HitTestResizeSE indicates the cursor is over the bottom-right resize corner.
	HitTestResizeSE
)

func (HitTestResult) String added in v0.11.0

func (h HitTestResult) String() string

String returns the hit test result name for debugging.

type IMEController added in v0.2.0

type IMEController interface {
	// SetIMEPosition tells the platform where to show the IME candidate window.
	// The coordinates are in screen pixels relative to the window.
	SetIMEPosition(x, y int)

	// SetIMEEnabled enables or disables IME for the current input context.
	// When disabled, key presses are delivered directly without IME processing.
	// This is useful for password fields or non-text inputs.
	SetIMEEnabled(enabled bool)
}

IMEController allows widgets to control IME behavior. This interface is typically implemented by the host window system.

type IMEState added in v0.2.0

type IMEState struct {
	// Composing indicates whether IME is currently in composition mode.
	Composing bool

	// CompositionText is the text currently being composed (e.g., pinyin for Chinese).
	// This should be displayed inline at the cursor position with special styling.
	CompositionText string

	// CursorPos is the cursor position within the composition text.
	CursorPos int

	// SelectionStart is the start of the selection within the composition text.
	// This is used for candidate selection in some IME systems.
	SelectionStart int

	// SelectionEnd is the end of the selection within the composition text.
	SelectionEnd int
}

IMEState represents the current state of the Input Method Editor. This is used for CJK (Chinese, Japanese, Korean) and other complex text input.

During IME composition, the user types phonetic characters that are converted to ideographic characters. The IMEState contains the current preview text and cursor information for rendering the composition inline.

type Instance

type Instance interface{}

Instance is a type token for the GPU instance entry point. Consumers that need the full instance API should type-assert to the concrete type (e.g., *wgpu.Instance).

type Key

type Key uint16

Key represents a keyboard key. Values follow a platform-independent virtual key code scheme.

const (
	KeyUnknown Key = iota

	// Letters
	KeyA
	KeyB
	KeyC
	KeyD
	KeyE
	KeyF
	KeyG
	KeyH
	KeyI
	KeyJ
	KeyK
	KeyL
	KeyM
	KeyN
	KeyO
	KeyP
	KeyQ
	KeyR
	KeyS
	KeyT
	KeyU
	KeyV
	KeyW
	KeyX
	KeyY
	KeyZ

	// Numbers
	Key0
	Key1
	Key2
	Key3
	Key4
	Key5
	Key6
	Key7
	Key8
	Key9

	// Function keys
	KeyF1
	KeyF2
	KeyF3
	KeyF4
	KeyF5
	KeyF6
	KeyF7
	KeyF8
	KeyF9
	KeyF10
	KeyF11
	KeyF12

	// Navigation
	KeyEscape
	KeyTab
	KeyBackspace
	KeyEnter
	KeySpace
	KeyInsert
	KeyDelete
	KeyHome
	KeyEnd
	KeyPageUp
	KeyPageDown
	KeyLeft
	KeyRight
	KeyUp
	KeyDown

	// Modifiers (as keys, not modifiers)
	KeyLeftShift
	KeyRightShift
	KeyLeftControl
	KeyRightControl
	KeyLeftAlt
	KeyRightAlt
	KeyLeftSuper
	KeyRightSuper

	// Punctuation
	KeyMinus
	KeyEqual
	KeyLeftBracket
	KeyRightBracket
	KeyBackslash
	KeySemicolon
	KeyApostrophe
	KeyGrave
	KeyComma
	KeyPeriod
	KeySlash

	// Numpad
	KeyNumpad0
	KeyNumpad1
	KeyNumpad2
	KeyNumpad3
	KeyNumpad4
	KeyNumpad5
	KeyNumpad6
	KeyNumpad7
	KeyNumpad8
	KeyNumpad9
	KeyNumpadDecimal
	KeyNumpadDivide
	KeyNumpadMultiply
	KeyNumpadSubtract
	KeyNumpadAdd
	KeyNumpadEnter

	// Other
	KeyCapsLock
	KeyScrollLock
	KeyNumLock
	KeyPrintScreen
	KeyPause
)

Common key codes. These match typical USB HID usage codes for cross-platform compatibility.

type Modifiers

type Modifiers uint8

Modifiers represents keyboard modifier keys.

const (
	// ModShift indicates the Shift key is pressed.
	ModShift Modifiers = 1 << iota

	// ModControl indicates the Control key is pressed.
	ModControl

	// ModAlt indicates the Alt key is pressed (Option on macOS).
	ModAlt

	// ModSuper indicates the Super key is pressed (Windows/Command).
	ModSuper

	// ModCapsLock indicates Caps Lock is active.
	ModCapsLock

	// ModNumLock indicates Num Lock is active.
	ModNumLock
)

func (Modifiers) HasAlt

func (m Modifiers) HasAlt() bool

HasAlt returns true if the Alt modifier is set.

func (Modifiers) HasControl

func (m Modifiers) HasControl() bool

HasControl returns true if the Control modifier is set.

func (Modifiers) HasShift

func (m Modifiers) HasShift() bool

HasShift returns true if the Shift modifier is set.

func (Modifiers) HasSuper

func (m Modifiers) HasSuper() bool

HasSuper returns true if the Super modifier is set.

type MouseButton

type MouseButton uint8

MouseButton represents a mouse button.

const (
	// MouseButtonLeft is the primary mouse button.
	MouseButtonLeft MouseButton = iota

	// MouseButtonRight is the secondary mouse button.
	MouseButtonRight

	// MouseButtonMiddle is the middle mouse button (scroll wheel click).
	MouseButtonMiddle

	// MouseButton4 is an extra mouse button.
	MouseButton4

	// MouseButton5 is an extra mouse button.
	MouseButton5
)

type NullEventSource

type NullEventSource struct{}

NullEventSource is an EventSource that ignores all event registrations. Used when events are not needed.

func (NullEventSource) OnFocus

func (NullEventSource) OnFocus(func(bool))

OnFocus does nothing.

func (NullEventSource) OnIMECompositionEnd added in v0.2.0

func (NullEventSource) OnIMECompositionEnd(func(string))

OnIMECompositionEnd does nothing.

func (NullEventSource) OnIMECompositionStart added in v0.2.0

func (NullEventSource) OnIMECompositionStart(func())

OnIMECompositionStart does nothing.

func (NullEventSource) OnIMECompositionUpdate added in v0.2.0

func (NullEventSource) OnIMECompositionUpdate(func(IMEState))

OnIMECompositionUpdate does nothing.

func (NullEventSource) OnKeyPress

func (NullEventSource) OnKeyPress(func(Key, Modifiers))

OnKeyPress does nothing.

func (NullEventSource) OnKeyRelease

func (NullEventSource) OnKeyRelease(func(Key, Modifiers))

OnKeyRelease does nothing.

func (NullEventSource) OnMouseMove

func (NullEventSource) OnMouseMove(func(float64, float64))

OnMouseMove does nothing.

func (NullEventSource) OnMousePress

func (NullEventSource) OnMousePress(func(MouseButton, float64, float64))

OnMousePress does nothing.

func (NullEventSource) OnMouseRelease

func (NullEventSource) OnMouseRelease(func(MouseButton, float64, float64))

OnMouseRelease does nothing.

func (NullEventSource) OnResize

func (NullEventSource) OnResize(func(int, int))

OnResize does nothing.

func (NullEventSource) OnScroll

func (NullEventSource) OnScroll(func(float64, float64))

OnScroll does nothing.

func (NullEventSource) OnTextInput

func (NullEventSource) OnTextInput(func(string))

OnTextInput does nothing.

type NullGestureEventSource added in v0.6.0

type NullGestureEventSource struct{}

NullGestureEventSource implements GestureEventSource by ignoring all registrations. Useful for platforms or configurations where gesture input is not available.

func (NullGestureEventSource) OnGesture added in v0.6.0

func (NullGestureEventSource) OnGesture(func(GestureEvent))

OnGesture does nothing.

type NullPlatformProvider added in v0.8.0

type NullPlatformProvider struct{}

NullPlatformProvider implements PlatformProvider with no-op behavior. Used for testing and platforms without OS integration.

Default return values:

  • ClipboardRead: "", nil
  • ClipboardWrite: nil
  • SetCursor: no-op
  • DarkMode: false
  • ReduceMotion: false
  • HighContrast: false
  • FontScale: 1.0

func (NullPlatformProvider) ClipboardRead added in v0.8.0

func (NullPlatformProvider) ClipboardRead() (string, error)

ClipboardRead returns empty string and nil error.

func (NullPlatformProvider) ClipboardWrite added in v0.8.0

func (NullPlatformProvider) ClipboardWrite(string) error

ClipboardWrite does nothing and returns nil.

func (NullPlatformProvider) DarkMode added in v0.8.0

func (NullPlatformProvider) DarkMode() bool

DarkMode returns false.

func (NullPlatformProvider) FontScale added in v0.8.0

func (NullPlatformProvider) FontScale() float32

FontScale returns 1.0.

func (NullPlatformProvider) HighContrast added in v0.8.0

func (NullPlatformProvider) HighContrast() bool

HighContrast returns false.

func (NullPlatformProvider) ReduceMotion added in v0.8.0

func (NullPlatformProvider) ReduceMotion() bool

ReduceMotion returns false.

func (NullPlatformProvider) SetCursor added in v0.8.0

func (NullPlatformProvider) SetCursor(CursorShape)

SetCursor does nothing.

type NullPointerEventSource added in v0.5.0

type NullPointerEventSource struct{}

NullPointerEventSource implements PointerEventSource by ignoring all registrations. Useful for platforms or configurations where pointer input is not available.

func (NullPointerEventSource) OnPointer added in v0.5.0

func (NullPointerEventSource) OnPointer(func(PointerEvent))

OnPointer does nothing.

type NullScrollEventSource added in v0.5.0

type NullScrollEventSource struct{}

NullScrollEventSource implements ScrollEventSource by ignoring all registrations. Useful for platforms or configurations where scroll input is not available.

func (NullScrollEventSource) OnScrollEvent added in v0.5.0

func (NullScrollEventSource) OnScrollEvent(func(ScrollEvent))

OnScrollEvent does nothing.

type NullWindowChrome added in v0.11.0

type NullWindowChrome struct{}

NullWindowChrome implements WindowChrome with no-op behavior. Used for testing and platforms without window chrome support.

Default return values:

  • IsFrameless: false
  • IsMaximized: false
  • All actions: no-op

func (NullWindowChrome) Close added in v0.11.0

func (NullWindowChrome) Close()

Close does nothing.

func (NullWindowChrome) IsFrameless added in v0.11.0

func (NullWindowChrome) IsFrameless() bool

IsFrameless returns false.

func (NullWindowChrome) IsMaximized added in v0.11.0

func (NullWindowChrome) IsMaximized() bool

IsMaximized returns false.

func (NullWindowChrome) Maximize added in v0.11.0

func (NullWindowChrome) Maximize()

Maximize does nothing.

func (NullWindowChrome) Minimize added in v0.11.0

func (NullWindowChrome) Minimize()

Minimize does nothing.

func (NullWindowChrome) SetFrameless added in v0.11.0

func (NullWindowChrome) SetFrameless(bool)

SetFrameless does nothing.

func (NullWindowChrome) SetHitTestCallback added in v0.11.0

func (NullWindowChrome) SetHitTestCallback(HitTestCallback)

SetHitTestCallback does nothing.

type NullWindowProvider added in v0.8.0

type NullWindowProvider struct {
	// W is the window width in logical points (DIP).
	W int

	// H is the window height in logical points (DIP).
	H int

	// SF is the DPI scale factor. When zero, ScaleFactor returns 1.0.
	SF float64
}

NullWindowProvider implements WindowProvider with configurable defaults. Used for testing and headless operation.

When SF is zero (the default), ScaleFactor returns 1.0.

Example:

wp := gpucontext.NullWindowProvider{W: 800, H: 600, SF: 2.0}
w, h := wp.Size()       // 800, 600 (logical points)
scale := wp.ScaleFactor() // 2.0

func (NullWindowProvider) RequestRedraw added in v0.8.0

func (n NullWindowProvider) RequestRedraw()

RequestRedraw does nothing.

func (NullWindowProvider) ScaleFactor added in v0.8.0

func (n NullWindowProvider) ScaleFactor() float64

ScaleFactor returns the configured scale factor, defaulting to 1.0 when zero.

func (NullWindowProvider) Size added in v0.8.0

func (n NullWindowProvider) Size() (int, int)

Size returns the configured window dimensions.

type OpenDevice

type OpenDevice struct {
	Device Device
	Queue  Queue
}

OpenDevice bundles a device and queue together. This is a convenience type for initialization.

type PinchType added in v0.6.0

type PinchType uint8

PinchType classifies a two-finger pinch gesture based on finger geometry.

const (
	// PinchNone indicates no pinch gesture (fewer than 2 pointers).
	PinchNone PinchType = iota

	// PinchHorizontal indicates horizontal separation exceeds vertical by 3x.
	// The fingers are spread horizontally, suggesting horizontal zoom/scrub.
	PinchHorizontal

	// PinchVertical indicates vertical separation exceeds horizontal by 3x.
	// The fingers are spread vertically, suggesting vertical zoom.
	PinchVertical

	// PinchProportional indicates uniform pinch (default).
	// Neither axis dominates, suggesting proportional zoom.
	PinchProportional
)

func (PinchType) String added in v0.6.0

func (p PinchType) String() string

String returns the pinch type name for debugging.

type PlatformProvider added in v0.8.0

type PlatformProvider interface {
	// ClipboardRead reads text content from the system clipboard.
	// Returns empty string and nil error if clipboard is empty or not text.
	ClipboardRead() (string, error)

	// ClipboardWrite writes text content to the system clipboard.
	ClipboardWrite(text string) error

	// SetCursor changes the mouse cursor shape.
	// The cursor is typically reset to CursorDefault at the start of each frame.
	SetCursor(cursor CursorShape)

	// DarkMode returns true if the system dark mode is active.
	// Used for automatic theme switching.
	DarkMode() bool

	// ReduceMotion returns true if the user prefers reduced animation.
	// Used to disable or simplify animations for accessibility.
	ReduceMotion() bool

	// HighContrast returns true if the user needs high contrast mode.
	// Used to adjust colors and borders for accessibility.
	HighContrast() bool

	// FontScale returns the user's font size preference multiplier.
	// 1.0 = default system font size. Used to scale Sp (scale-independent pixels).
	FontScale() float32
}

PlatformProvider provides OS integration features.

This interface enables UI frameworks (like gogpu/ui) to access platform capabilities such as clipboard, cursor management, and system accessibility preferences.

Implementations:

  • gogpu.App implements PlatformProvider via platform-specific code
  • NullPlatformProvider provides no-op defaults for testing

PlatformProvider is optional. Not all WindowProviders support platform integration (e.g., headless or embedded systems). Use type assertion to check availability:

if pp, ok := provider.(gpucontext.PlatformProvider); ok {
    pp.SetCursor(gpucontext.CursorPointer)
}

Note: This interface is designed for gogpu <-> ui integration. The rendering library (gg) does NOT use this interface.

type Point added in v0.6.0

type Point struct {
	X, Y float64
}

Point represents a 2D coordinate in logical pixels.

func (Point) Add added in v0.6.0

func (p Point) Add(other Point) Point

Add returns the sum of two points.

func (Point) Scale added in v0.6.0

func (p Point) Scale(factor float64) Point

Scale returns the point scaled by a factor.

func (Point) Sub added in v0.6.0

func (p Point) Sub(other Point) Point

Sub returns the difference of two points.

type PointerEvent added in v0.5.0

type PointerEvent struct {
	// Type indicates the type of pointer event (down, up, move, etc.).
	Type PointerEventType

	// PointerID uniquely identifies the pointer causing this event.
	// For mouse, this is typically 1. For touch/pen, each contact has a unique ID.
	// The ID remains constant from PointerDown through PointerUp/PointerCancel.
	PointerID int

	// X is the horizontal position relative to the window content area.
	// Uses logical pixels (CSS pixels equivalent).
	X float64

	// Y is the vertical position relative to the window content area.
	// Uses logical pixels (CSS pixels equivalent).
	Y float64

	// Pressure indicates the normalized pressure of the pointer input.
	// Range: 0.0 (no pressure) to 1.0 (maximum pressure).
	// For devices without pressure support (e.g., mouse), this is:
	//   - 0.5 when buttons are pressed
	//   - 0.0 when no buttons are pressed
	Pressure float32

	// TiltX is the plane angle between the Y-Z plane and the plane containing
	// the pointer axis and the Y axis, in degrees.
	// Range: -90 to 90 degrees.
	// Positive values tilt toward the right.
	// 0 when the pointer is perpendicular to the surface or not supported.
	TiltX float32

	// TiltY is the plane angle between the X-Z plane and the plane containing
	// the pointer axis and the X axis, in degrees.
	// Range: -90 to 90 degrees.
	// Positive values tilt toward the user.
	// 0 when the pointer is perpendicular to the surface or not supported.
	TiltY float32

	// Twist is the clockwise rotation of the pointer around its major axis,
	// in degrees.
	// Range: 0 to 359 degrees.
	// 0 when not supported.
	Twist float32

	// Width is the width of the contact geometry in logical pixels.
	// For devices that don't support contact geometry, this is 1.
	Width float32

	// Height is the height of the contact geometry in logical pixels.
	// For devices that don't support contact geometry, this is 1.
	Height float32

	// PointerType indicates the type of pointing device.
	PointerType PointerType

	// IsPrimary indicates if this is the primary pointer of its type.
	// For single-pointer devices (mouse), this is always true.
	// For multi-touch, the first finger down is primary.
	IsPrimary bool

	// Button indicates which button triggered this event.
	// Only meaningful for PointerDown and PointerUp events.
	// For PointerMove, this is ButtonNone.
	Button Button

	// Buttons is a bitmask of all currently pressed buttons.
	// This allows tracking multiple button states during movement.
	Buttons Buttons

	// Modifiers contains the keyboard modifier state at event time.
	Modifiers Modifiers

	// DeltaX is the relative horizontal movement in logical pixels.
	// Non-zero only when CursorModeLocked is active; zero otherwise.
	// Use for first-person camera, drag, and other relative-motion input.
	DeltaX float64

	// DeltaY is the relative vertical movement in logical pixels.
	// Non-zero only when CursorModeLocked is active; zero otherwise.
	DeltaY float64

	// Timestamp is the event time as duration since an arbitrary reference.
	// Useful for calculating velocities and detecting double-clicks.
	// Zero if timestamps are not available on the platform.
	Timestamp time.Duration
}

PointerEvent represents a unified pointer event following W3C Pointer Events Level 3.

This event unifies mouse, touch, and pen input into a single abstraction, enabling applications to handle all pointing devices uniformly.

W3C Pointer Events Level 3 Specification: https://www.w3.org/TR/pointerevents3/

Key concepts:

  • PointerID: Unique identifier for each active pointer
  • PointerType: Distinguishes mouse, touch, and pen
  • IsPrimary: Identifies the "main" pointer in multi-pointer scenarios
  • Pressure/Tilt: Extended properties for pen/touch input

Example usage:

source.OnPointer(func(ev gpucontext.PointerEvent) {
    switch ev.Type {
    case gpucontext.PointerDown:
        startDrag(ev.PointerID, ev.X, ev.Y)
    case gpucontext.PointerMove:
        if ev.Pressure > 0 {
            updateDrag(ev.PointerID, ev.X, ev.Y, ev.Pressure)
        }
    case gpucontext.PointerUp:
        endDrag(ev.PointerID)
    }
})

type PointerEventSource added in v0.5.0

type PointerEventSource interface {
	// OnPointer registers a callback for pointer events.
	// The callback receives a PointerEvent containing all pointer information.
	//
	// Callback threading: Called on the main/UI thread.
	// Callbacks should be fast and non-blocking.
	//
	// Pointer events are delivered in order:
	//   PointerEnter -> PointerDown -> PointerMove* -> PointerUp/PointerCancel -> PointerLeave
	OnPointer(fn func(PointerEvent))
}

PointerEventSource extends EventSource with unified pointer event capabilities.

This interface provides W3C Pointer Events Level 3 compliant pointer input, unifying mouse, touch, and pen input into a single event stream.

Implementation note: Rather than adding to EventSource directly, we use a separate interface to maintain backward compatibility and allow type assertion:

if pes, ok := eventSource.(gpucontext.PointerEventSource); ok {
    pes.OnPointer(handlePointerEvent)
}

For applications that need only unified pointer events:

pes.OnPointer(func(ev gpucontext.PointerEvent) {
    // Handle all pointer types uniformly
})

type PointerEventType added in v0.5.0

type PointerEventType uint8

PointerEventType indicates the type of pointer event.

const (
	// PointerDown is fired when a pointer becomes active.
	// For mouse: button press.
	// For touch: contact starts.
	// For pen: contact with or hover above the digitizer.
	PointerDown PointerEventType = iota

	// PointerUp is fired when a pointer is no longer active.
	// For mouse: button release.
	// For touch: contact ends.
	// For pen: leaves the digitizer detection range.
	PointerUp

	// PointerMove is fired when a pointer changes coordinates.
	// Also fired when pressure, tilt, or other properties change.
	PointerMove

	// PointerEnter is fired when a pointer enters the window bounds.
	// Does not bubble in W3C spec, but we deliver it directly.
	PointerEnter

	// PointerLeave is fired when a pointer leaves the window bounds.
	// Does not bubble in W3C spec, but we deliver it directly.
	PointerLeave

	// PointerCancel is fired when the system cancels the pointer.
	// This happens when:
	//   - The browser decides the pointer is unlikely to produce more events
	//   - A device orientation change occurs
	//   - The application loses focus during an active pointer
	// Always handle cancellation to reset state properly.
	PointerCancel
)

func (PointerEventType) String added in v0.5.0

func (t PointerEventType) String() string

String returns the event type name for debugging.

type PointerType added in v0.5.0

type PointerType uint8

PointerType indicates the type of pointing device.

const (
	// PointerTypeMouse indicates a mouse or similar device.
	// Includes trackpads when they emulate mouse behavior.
	PointerTypeMouse PointerType = iota

	// PointerTypeTouch indicates direct touch input.
	// Includes touchscreens and touch-enabled trackpads.
	PointerTypeTouch

	// PointerTypePen indicates a stylus or pen input.
	// Includes graphics tablets and pen-enabled displays.
	PointerTypePen
)

func (PointerType) String added in v0.5.0

func (t PointerType) String() string

String returns the pointer type name for debugging.

type Queue

type Queue interface{}

Queue is a type token for a GPU command queue.

Concrete implementations (e.g., *wgpu.Queue) satisfy this interface implicitly. Consumers that need the full queue API should type-assert to the concrete type:

q := provider.Queue()
wgpuQueue, ok := q.(*wgpu.Queue)

type Registry

type Registry[T any] struct {
	// contains filtered or unexported fields
}

Registry provides thread-safe registration and lookup of named factories. It supports priority-based selection when multiple implementations exist.

Type parameter T is the type returned by factories.

Example:

var backends = gpucontext.NewRegistry[Backend](
    gpucontext.WithPriority("vulkan", "dx12", "metal", "gles", "software"),
)

backends.Register("vulkan", func() Backend { return NewVulkanBackend() })
backends.Register("software", func() Backend { return NewSoftwareBackend() })

best := backends.Best() // Returns vulkan if available, otherwise software

func NewRegistry

func NewRegistry[T any](opts ...RegistryOption) *Registry[T]

NewRegistry creates a new Registry with optional configuration.

func (*Registry[T]) Available

func (r *Registry[T]) Available() []string

Available returns all registered names. Thread-safe.

func (*Registry[T]) Best

func (r *Registry[T]) Best() T

Best returns the highest-priority registered implementation. Returns the zero value of T if no implementations are registered. Thread-safe.

func (*Registry[T]) BestName

func (r *Registry[T]) BestName() string

BestName returns the name of the highest-priority registered implementation. Returns empty string if no implementations are registered. Thread-safe.

func (*Registry[T]) Count

func (r *Registry[T]) Count() int

Count returns the number of registered factories. Thread-safe.

func (*Registry[T]) Get

func (r *Registry[T]) Get(name string) T

Get returns the factory output for the given name. Returns the zero value of T if not found. Thread-safe.

func (*Registry[T]) Has

func (r *Registry[T]) Has(name string) bool

Has returns true if a factory with the given name is registered. Thread-safe.

func (*Registry[T]) Register

func (r *Registry[T]) Register(name string, factory func() T)

Register adds a factory for the given name. If a factory with the same name already exists, it is replaced. Thread-safe.

func (*Registry[T]) Unregister

func (r *Registry[T]) Unregister(name string)

Unregister removes the factory with the given name. Thread-safe.

type RegistryOption

type RegistryOption func(*registryConfig)

RegistryOption configures a Registry.

func WithPriority

func WithPriority(names ...string) RegistryOption

WithPriority sets the priority order for backend selection. Backends listed first are preferred over backends listed later. Backends not in the list have lowest priority (in registration order).

type ScrollDeltaMode added in v0.5.0

type ScrollDeltaMode uint8

ScrollDeltaMode indicates the unit of scroll delta values.

const (
	// ScrollDeltaPixel indicates delta values are in logical pixels.
	// This is typical for touchpad scrolling.
	ScrollDeltaPixel ScrollDeltaMode = iota

	// ScrollDeltaLine indicates delta values are in lines.
	// This is typical for traditional mouse wheel scrolling.
	// Applications should convert to pixels using their line height.
	ScrollDeltaLine

	// ScrollDeltaPage indicates delta values are in pages.
	// This is rare but may occur for Page Up/Down emulation.
	// Applications should convert to pixels using their viewport height.
	ScrollDeltaPage
)

func (ScrollDeltaMode) String added in v0.5.0

func (m ScrollDeltaMode) String() string

String returns the delta mode name for debugging.

type ScrollEvent added in v0.5.0

type ScrollEvent struct {
	// X is the pointer horizontal position at the time of scrolling.
	// Uses logical pixels relative to the window content area.
	X float64

	// Y is the pointer vertical position at the time of scrolling.
	// Uses logical pixels relative to the window content area.
	Y float64

	// DeltaX is the horizontal scroll amount.
	// Positive values scroll content to the right (or indicate rightward intent).
	// The unit depends on DeltaMode.
	DeltaX float64

	// DeltaY is the vertical scroll amount.
	// Positive values scroll content down (or indicate downward intent).
	// The unit depends on DeltaMode.
	DeltaY float64

	// DeltaMode indicates the unit of the delta values.
	DeltaMode ScrollDeltaMode

	// Modifiers contains the keyboard modifier state at event time.
	// Commonly used for Ctrl+scroll zoom behavior.
	Modifiers Modifiers

	// Timestamp is the event time as duration since an arbitrary reference.
	// Useful for smooth scrolling animations.
	// Zero if timestamps are not available on the platform.
	Timestamp time.Duration
}

ScrollEvent represents a scroll wheel or touchpad scroll event.

This event is separate from PointerEvent because scroll events have different semantics:

  • They don't have a persistent pointer ID
  • They provide delta values rather than absolute positions
  • They may have different units (lines, pages, pixels)

For touchpad gestures, consider using GestureEvent (if available) for pinch-to-zoom and other multi-finger gestures.

Example usage:

source.OnScroll(func(ev gpucontext.ScrollEvent) {
    scrollY += ev.DeltaY * scrollSpeed
    if ev.Modifiers.HasControl() {
        // Ctrl+scroll for zoom
        zoom *= 1.0 + ev.DeltaY * 0.1
    }
})

type ScrollEventSource added in v0.5.0

type ScrollEventSource interface {
	// OnScrollEvent registers a callback for detailed scroll events.
	// The callback receives a ScrollEvent containing all scroll information.
	//
	// Callback threading: Called on the main/UI thread.
	// Callbacks should be fast and non-blocking.
	OnScrollEvent(fn func(ScrollEvent))
}

ScrollEventSource extends EventSource with scroll event capabilities.

This interface provides detailed scroll events with position, delta mode, and timing information beyond what the basic EventSource.OnScroll provides.

For basic scroll handling, EventSource.OnScroll(dx, dy) is sufficient. Use ScrollEventSource when you need:

  • Pointer position at scroll time
  • Delta mode (pixels vs lines vs pages)
  • Timestamps for smooth scrolling

Type assertion pattern:

if ses, ok := eventSource.(gpucontext.ScrollEventSource); ok {
    ses.OnScrollEvent(handleScrollEvent)
} else {
    // Fall back to basic scroll handler
    eventSource.OnScroll(handleBasicScroll)
}

type Surface

type Surface interface{}

Surface is a type token for a rendering surface (window). Consumers that need the full surface API should type-assert to the concrete type (e.g., *wgpu.Surface).

type Texture added in v0.4.0

type Texture interface {
	// Width returns the texture width in pixels.
	Width() int

	// Height returns the texture height in pixels.
	Height() int
}

Texture is the minimal interface for GPU textures. This interface enables type-safe cross-package texture handling without circular dependencies.

Implementations:

  • gogpu.Texture implements Texture

Design note: This interface intentionally contains only read-only methods that are universally needed for texture operations. Implementation-specific methods (like UpdateData) remain on concrete types.

type TextureCreator added in v0.4.0

type TextureCreator interface {
	// NewTextureFromRGBA creates a texture from RGBA pixel data.
	// The data must be width * height * 4 bytes (RGBA, 8 bits per channel).
	//
	// The returned Texture can be drawn using TextureDrawer.DrawTexture.
	//
	// Returns error if:
	//   - Data size doesn't match width * height * 4
	//   - GPU texture creation fails
	NewTextureFromRGBA(width, height int, data []byte) (Texture, error)
}

TextureCreator provides texture creation from raw pixel data. This interface enables packages to create GPU textures without depending directly on specific GPU implementations.

Implementations:

  • gogpu.Renderer implements TextureCreator (via adapter)

Example usage:

creator := drawer.TextureCreator()
tex, err := creator.NewTextureFromRGBA(800, 600, pixelData)
if err != nil {
    return err
}
drawer.DrawTexture(tex, 0, 0)

type TextureDrawer added in v0.4.0

type TextureDrawer interface {
	// DrawTexture draws a texture at the specified position.
	//
	// Coordinate system:
	//   - (0, 0) is the top-left corner
	//   - Positive X goes right
	//   - Positive Y goes down
	//   - Coordinates are in pixels
	//
	// The texture must have been created by TextureCreator from this drawer.
	DrawTexture(tex Texture, x, y float32) error

	// TextureCreator returns the texture creator associated with this drawer.
	// Use this to create textures that can be drawn by this drawer.
	TextureCreator() TextureCreator
}

TextureDrawer provides texture drawing capabilities for 2D rendering. This interface enables packages like ggcanvas to draw textures without depending directly on gogpu, following the Dependency Inversion Principle.

Implementations:

  • gogpu.Context implements TextureDrawer (via adapter)

Example usage in ggcanvas:

func (c *Canvas) RenderTo(drawer gpucontext.TextureDrawer) error {
    tex, _ := c.Flush()
    return drawer.DrawTexture(tex, 0, 0)
}

type TextureRegionUpdater added in v0.13.0

type TextureRegionUpdater interface {
	// UpdateRegion uploads a sub-rectangle of pixel data to the texture.
	// x, y is the top-left corner of the region in the texture.
	// w, h is the size of the region.
	// data must be exactly w * h * bytesPerPixel bytes (densely packed RGBA rows).
	//
	// Returns error if the region exceeds texture bounds, data size is invalid,
	// or the texture has been destroyed.
	UpdateRegion(x, y, w, h int, data []byte) error
}

TextureRegionUpdater uploads a sub-rectangle of pixel data to the texture. Use for incremental rendering where only a small portion of the texture changes per frame (e.g., dirty region upload).

Implementations:

  • gogpu.Texture implements TextureRegionUpdater

type TextureUpdater added in v0.7.0

type TextureUpdater interface {
	// UpdateData uploads new pixel data to the texture.
	// Data must be exactly width * height * bytesPerPixel bytes (typically RGBA).
	//
	// Returns error if the texture has been destroyed or data size is invalid.
	UpdateData(data []byte) error
}

TextureUpdater updates existing texture pixel data. Use for dynamic content such as canvas rendering and video frames.

Implementations:

  • gogpu.Texture implements TextureUpdater

type TextureView added in v0.14.0

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

TextureView is a type-safe opaque handle to a GPU texture view.

Provides compile-time type safety: TextureView cannot be confused with CommandEncoder or other GPU resource types (unlike the previous interface{} token approach). Following the Vulkan/Ebitengine/Go Protobuf Opaque pattern.

The ptr field is unexported, preventing construction outside this package. Use NewTextureView to create, Pointer to extract, IsNil to check. 8 bytes, value type, zero allocations.

GC safety: unsafe.Pointer keeps the underlying object alive (Go spec §Safety).

func NewTextureView added in v0.15.0

func NewTextureView(ptr unsafe.Pointer) TextureView

NewTextureView creates a TextureView from an unsafe.Pointer to a concrete GPU texture view (e.g., *wgpu.TextureView). The caller must ensure the pointer remains valid for the lifetime of the returned handle.

func (TextureView) IsNil added in v0.15.0

func (tv TextureView) IsNil() bool

IsNil reports whether the handle holds no resource (zero value).

func (TextureView) Pointer added in v0.15.0

func (tv TextureView) Pointer() unsafe.Pointer

Pointer returns the underlying unsafe.Pointer. Consumers type-convert to the concrete type: (*wgpu.TextureView)(tv.Pointer()).

type WindowChrome added in v0.11.0

type WindowChrome interface {
	// SetFrameless enables or disables frameless (borderless) window mode.
	// When true, the OS title bar and borders are removed.
	// The application must provide its own title bar via SetHitTestCallback.
	SetFrameless(frameless bool)

	// IsFrameless returns true if the window is in frameless mode.
	IsFrameless() bool

	// SetHitTestCallback sets the callback that determines what region
	// of the window the cursor is over. This is used by the platform layer
	// to route mouse events to the OS for dragging, resizing, etc.
	//
	// Pass nil to clear the callback (all areas become HitTestClient).
	SetHitTestCallback(callback HitTestCallback)

	// Minimize minimizes the window to the taskbar/dock.
	Minimize()

	// Maximize toggles between maximized and restored window state.
	// If the window is currently maximized, it is restored to its previous size.
	Maximize()

	// IsMaximized returns true if the window is currently maximized.
	IsMaximized() bool

	// Close requests the window to close.
	// This triggers the normal close flow (close events, cleanup).
	Close()
}

WindowChrome provides control over window chrome (title bar, borders).

This interface enables replacing the OS window chrome with a custom GPU-rendered title bar. When frameless mode is enabled, the OS removes the title bar and borders, and the application takes responsibility for:

  • Rendering its own title bar
  • Providing hit-test regions (drag area, buttons, resize edges)
  • Handling minimize/maximize/close actions

Implementations:

  • gogpu.App implements WindowChrome via platform-specific code
  • NullWindowChrome provides no-op defaults for testing

WindowChrome is optional. Use type assertion to check availability:

if wc, ok := provider.(gpucontext.WindowChrome); ok {
    wc.SetFrameless(true)
    wc.SetHitTestCallback(myHitTest)
}

type WindowProvider added in v0.8.0

type WindowProvider interface {
	// Size returns the current window client area dimensions in logical points (DIP).
	// On HiDPI displays, multiply by ScaleFactor() to get physical pixel dimensions.
	Size() (width, height int)

	// ScaleFactor returns the DPI scale factor.
	// 1.0 = standard (96 DPI on Windows, 72 on macOS), 2.0 = Retina/HiDPI.
	ScaleFactor() float64

	// RequestRedraw requests the host to render a new frame.
	// In on-demand rendering mode, this triggers a single frame render.
	// In continuous mode, this is a no-op.
	RequestRedraw()
}

WindowProvider provides window geometry and DPI information.

This interface enables UI frameworks (like gogpu/ui) and rendering libraries (like gg/ggcanvas) to query window dimensions and scale factor for HiDPI-aware layout and rendering.

Size() returns logical points (DIP — density-independent pixels). To get physical pixel dimensions, multiply by ScaleFactor():

physW := int(float64(w) * scale)

Implementations:

  • gogpu.App implements WindowProvider via platform window
  • gogpu.gpuContextAdapter implements WindowProvider (returned by GPUContextProvider)
  • NullWindowProvider provides configurable defaults for testing

Example usage:

func (ui *UI) Layout(wp gpucontext.WindowProvider) {
    w, h := wp.Size()           // logical points
    scale := wp.ScaleFactor()   // 2.0 on Retina
    ui.root.Layout(w, h, scale)
}

Jump to

Keyboard shortcuts

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