All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- deps: gputypes v0.7.0 → v0.8.0 (Viewport, ScissorRect, DrawArgs, DrawIndexedArgs — ADR-072)
- docs: update README and ROADMAP for struct-based
UpdateRegionAPI (image.Rectangle+ImageDataLayout). v0.31.1 shipped with stale documentation showing old 6-parameter signature.
TextureRegionUpdater.UpdateRegion— struct API (#484) — replaced six positional int parameters withimage.Rectangle+ImageDataLayout(WebGPU / Go stdlib idiom). Fixes silent parameter-swap bugs. Zero-value layout = offset 0, tight packed rows, region height.
TextureRegionUpdater.UpdateRegion— strided upload (#484) — addedbytesPerRowparameter (pre-v1.0 signature change).0= tightly packed rows (w * bytesPerPixel), matching WebGPUImageDataLayout.bytesPerRow. Enables zero-copy dirty-band uploads from full-frame buffers (geckty, ggcanvas) withoutextractRegionmemcpy.
DeviceProvider.DownlevelCapabilities()— returnsgputypes.DownlevelCapabilitiesfor backend capability queries. Enables consumers (gg, g3d, Born ML) to check compute support, indirect execution, and other capabilities that may be absent on non-conformant backends (GLES 3.0, CPU software). Returns zero-value if implementation does not track downlevel capabilities (backward compatible). Matches Rust wgpuAdapter::get_downlevel_capabilities()pattern. Architecture: DeviceProvider interface method, not type-assert — follows Flutter Impeller "check capabilities, not backend type" principle. See ADR-071.
- deps: gputypes v0.6.0 → v0.7.0 (DownlevelCapabilities types)
DeviceProvider.Features()— returnsgputypes.Featuresbitfield of optional device capabilities. Enables consumers (g3d, gg) to query features likeFeatureRayQuerywithout importing wgpu directly. Returns 0 if implementation does not track features (backward compatible). Matches Rust wgpudevice.features()pattern.
- deps: gputypes v0.5.2 → v0.6.0 (ray tracing types)
MouseButton.String()— returns button name (Left, Right, Middle, X1, X2) for debugging and logging. Names match pointerButton.String().Modifiers.String()— returns deterministic modifier string (Ctrl+Alt+Shift+Super+CapsLock+NumLock). Order matchesgogpu/uievent convention. Unknown bits are silently ignored.
- deps: gputypes v0.5.1 → v0.5.2
- Shared string constants (
stringLeft,stringRight,stringMiddle) betweenKey.String(),Button.String(), andMouseButton.String()— eliminates duplication.
SurfaceCompositorinterface (ADR-067) — compositor-level bridge between gogpu and content renderers (gg, g3d). 4 methods:ShouldPreserveContent(),DamageRects(),MarkContentRendered(),CompositeMSAAOverlay(). Enables drawing library to delegate surface-level decisions (LoadOp, damage scissoring, MSAA overlay compositing) to the compositor without importing gogpu directly. Enterprise pattern validated by Chromium cc/Skia, GTK4 GSK, Flutter flow/ source code.
- Key enum redesign — flat
iota(94 keys) replaced with grouped explicit bases (138 keys). Each group has its ownconstblock with reserved gaps, following thenet/httpstatus code pattern. Adding keys within a group never shifts values in other groups — binary-stable for v1.0+.- New groups: Media (5 keys), Volume (3), Browser (5), System (4)
- Extended: Function keys F13-F24 (12 new), Punctuation +IntlBackslash/IntlYen, Numpad +NumpadEqual/NumpadComma
- New keys:
KeyContextMenu,KeyCancel,KeyLaunchApp1,KeyLaunchApp2,KeyMediaPlayPause,KeyMediaStop,KeyMediaTrackNext,KeyMediaTrackPrevious,KeyMediaRecord,KeyAudioVolumeUp,KeyAudioVolumeDown,KeyAudioVolumeMute,KeyBrowserBack,KeyBrowserForward,KeyBrowserRefresh,KeyBrowserHome,KeyBrowserSearch - Naming: W3C UIEvents KeyboardEvent.code convention adapted to Go PascalCase
- BREAKING: Key numeric values changed (pre-v1.0, no external consumers store numeric values)
KeyFromStringfunction — thread-safe reverse lookup from string name to Key value. Enables W3C KeyboardEvent.code compatibility for browser/WASM platforms. Usessync.Onceinitialization. Round-trips withKey.String().Key.String()method — covers all 138 keys with human-readable names
-
Damage tracking interfaces (ADR-065) — multi-renderer damage aggregation for shared surfaces. When multiple renderers (gg, g3d, video, compose) share a single GPU surface, each registers as a damage source and reports per-frame damage rectangles. The compositor unions all sources at present time.
DamageReporterinterface — 2-method frozen contract (ReportDamage,ReportDamageWithReason)DamageCategoryenum — 6 categories (Content,Layout,Animation,Resize,Full,External)DamageReasonstruct — typed category + human-readable detail stringDamageSourceSnapshotstruct — per-source frame snapshot (name, color, rects, reason)DamageOverlayRendererinterface — custom overlay rendering for libraries with text capabilityDamageOverlayInfostruct — structured per-source data passed to overlay renderer- Design follows Chromium
cc/DamageTrackerpattern — adapted for explicit registration model
-
Pluggable debug overlay system (ADR-066) — GTK4 Inspector-inspired overlay architecture. Multiple debug overlays register with the compositor and draw in registration order after content, before present.
DebugOverlayinterface — 2-method frozen contract (Name,Draw)DebugOverlayContextstruct — GPU resources and frame metadata for overlay rendering- Self-sustaining render loop:
Draw()returns true → compositor callsRequestRedraw() - Env var activation:
GOGPU_DEBUG_DAMAGE=overlay,GOGPU_DEBUG_FPS=overlay,GOGPU_DEBUG_DIRTY=overlay
ScaleChangedEvent(ADR-059, gogpu#409) — runtime DPI/scale factor change event. Emitted when window moves between monitors with different DPI or OS DPI settings change. CarriesScaleFactor,Width,Height. Event ordering:ScaleChangedEventbeforeResizeEvent(cause before effect, winit pattern). Enterprise research: winit, Qt6, SDL3, Flutter — all emit separate DPI event.
InputEventsealed interface (ADR-058) — unified event type for SDL-style event queue. Sealed via unexportedinputEventTag()marker — only gpucontext types implement it. Enables exhaustive type switch handling.KeyEventstruct — keyboard key state change (Key, Modifiers, Pressed)CharEventstruct — committed text input (Char rune)FocusEventstruct — window focus state change (Focused bool)ResizeEventstruct — window content area size change (Width, Height in logical DIP)PointerEventandScrollEventnow implementInputEventinterface- 8 test cases covering interface satisfaction, type switch, field access
FontSmoothingtype (gogpu#396, ADR-057) — three-state enum (None,Grayscale,Subpixel) for OS text anti-aliasing mode. Separate fromSubpixelLayout— answers "how is text AA'd?" vs "what is the display's pixel arrangement?".PlatformProvider.FontSmoothing()method added.NullPlatformProviderdefaults toFontSmoothingGrayscale.String()method for debugging.- Coordinate space documentation (gogpu#398) — explicit "logical DIP, do NOT divide by ScaleFactor" godoc on
PointerEvent.X/Y,ScrollEvent.X/Y, and allOnMouse*callbacks.
- deps: gputypes v0.5.0 → v0.5.1
-
GPU handles: interface → struct tokens (BREAKING) —
Device,Queue,Adapter,Surface,Instancechanged from interfaces to opaque struct tokens wrappingunsafe.Pointer. Same pattern asTextureViewandCommandEncoder(ADR-018).Why: v0.20.0 used unexported sentinel methods on interfaces, but Go spec prohibits cross-package satisfaction of interfaces with unexported methods.
*wgpu.Devicecould never implementgpucontext.Device— build broke in gogpu/gg/ui. Struct tokens solve this: 8 bytes, zero alloc, GC-safe (unsafe.Pointerin struct fields is traced —reflect.Valueprecedent), compile-time type distinct (Device ≠ Queue).Migration:
// Before (v0.19.0): dev := provider.Device() // gpucontext.Device (interface) wgpuDev := dev.(*wgpu.Device) // type assertion // After (v0.21.0): dev := provider.Device() // gpucontext.Device (struct) wgpuDev := (*wgpu.Device)(dev.Pointer()) // unsafe.Pointer extraction // Or via helper: wgpuDev := wgpu.DeviceFromHandle(dev) // Nil check: // Before: dev != nil // After: !dev.IsNil()
Constructors:
NewDevice(ptr),NewQueue(ptr),NewAdapter(ptr),NewSurface(ptr),NewInstance(ptr). Extraction:.Pointer(),.IsNil().
DO NOT USE — unexported sentinel methods on interfaces do not work
cross-package per Go spec. *wgpu.Device cannot implement gpucontext.Device.
Fixed in v0.21.0 with struct tokens.
- ScrollPhase + IsMomentum on ScrollEvent (FEAT-INPUT-021) —
ScrollPhaseenum (None,Began,Changed,Ended,Canceled) andIsMomentum boolfield onScrollEvent. Enables apps to distinguish active trackpad gestures from momentum/inertial scroll. On macOS: maps NSEvent.phase and NSEvent.momentumPhase. On Wayland: maps axis_stop. Zero value preserves backward compatibility (Phase=None, IsMomentum=false).
- SubpixelLayout on PlatformProvider (ADR-024) —
SubpixelLayout()method returns display subpixel arrangement (SubpixelNone,SubpixelRGB,SubpixelBGR,SubpixelVRGB,SubpixelVBGR). Enables LCD/ClearType font rendering in gg. Follows Qt6QPlatformScreen::SubpixelAntialiasingTypepattern — subpixel is a display/OS property, not GPU.NullPlatformProviderreturnsSubpixelNone(grayscale AA). Researched Qt6, GTK4/Wayland, FreeType, DRM/KMS — all treat subpixel as platform property.
- Lint: extracted
stringNonereuse for SubpixelLayout.String().
- AdapterInfo on DeviceProvider (ADR-020) —
AdapterInfo()method returnsAdapterInfo{Name, Type}withAdapterTypeenum (Discrete, Integrated, Software, Unknown). Enables gg render mode auto-selection: CPU rasterizer on software adapters (60 FPS) vs GPU accelerator on real hardware. Triggered by software backend 92x regression after SPIR-V interpreter (FEAT-SW-004).
- WindowChrome.SetFullscreen / IsFullscreen — runtime fullscreen toggle interface (ADR-018). Enables
App.SetFullscreen(bool)in gogpu for borderless fullscreen (Windows), nativetoggleFullScreen:(macOS),_NET_WM_STATE_FULLSCREEN(X11),xdg_toplevel.set_fullscreen(Wayland). NullWindowChrome provides no-op defaults. Triggered by ui#88 (@AgentNemo00).
- TextureView — replaced
interface{}token withstruct{ ptr unsafe.Pointer }opaque handle (ADR-018, Vulkan/Ebitengine/Go Protobuf Opaque pattern). Compile-time type safety: TextureView cannot be confused with CommandEncoder or other resource types. 8 bytes, value type, zero allocations. GC-safe (unsafe.Pointer keeps object alive per Go spec). Breaking: callers must useNewTextureView(unsafe.Pointer(ptr))andtv.Pointer()/tv.IsNil()instead of direct assignment.
- CommandEncoder opaque handle — same pattern as TextureView. Used for the shared encoder
pipeline (ADR-017).
NewCommandEncoder(),Pointer(),IsNil().
- TextureView type token interface — enables type-safe render target passing between packages without importing wgpu. Follows existing Device/Queue/Surface/Instance pattern. Used by gg
GPURenderTarget.Viewfor per-pass render target selection (WebGPU spec alignment).
- TextureRegionUpdater interface —
UpdateRegion(x, y, w, h int, data []byte) errorfor partial texture upload. Enables incremental rendering where only dirty regions are uploaded to GPU instead of full texture.
- Dependencies: gputypes v0.2.0 → v0.5.0 (PrimitiveState zero value = WebGPU spec default)
- CursorMode —
CursorNormal,CursorLocked,CursorConfinedconstants for mouse grab / pointer lock. Matches SDLSDL_SetRelativeMouseModeandSDL_SetWindowMouseGrabsemantics. (gogpu#173) - PointerEvent.DeltaX/DeltaY — relative mouse movement fields for locked cursor mode. Non-zero only when cursor is locked (FPS mouselook). Follows W3C Pointer Events pattern.
0.11.0 - 2026-03-20
-
WindowChrome interface for custom window chrome (frameless windows)
SetFrameless(bool)/IsFrameless() bool— enable/disable frameless modeSetHitTestCallback(HitTestCallback)— custom hit testing for drag, resize, buttonsMinimize()/Maximize()/IsMaximized() bool/Close()— window controls- Optional interface — use type assertion:
if wc, ok := provider.(gpucontext.WindowChrome); ok { ... }
-
HitTestResult enum (13 values) for custom window regions
HitTestClient— normal content areaHitTestCaption— title bar drag areaHitTestClose/HitTestMaximize/HitTestMinimize— window buttonsHitTestResizeN/S/W/E/NW/NE/SW/SE— 8 resize edges/cornersString()method for debugging
-
HitTestCallback type —
func(x, y float64) HitTestResult -
NullWindowChrome — no-op implementation for testing
0.10.0 - 2026-03-15
- HalProvider interface DELETED —
HalDevice() anyandHalQueue() anyremoved entirely. Replaced by typed pattern:provider.Device()returnsgpucontext.Device, consumers type-assert to*wgpu.Devicefor full API access. Zeroanyin the device provider chain. Go "accept interfaces, return structs" pattern.
-
Device, Queue, Adapter, Surface, Instance interfaces in webgpu_types.go converted to minimal type-token interfaces. Enables implicit Go interface satisfaction —
*wgpu.Deviceimplementsgpucontext.Devicewithout gpucontext importing wgpu. -
WindowProvider.Size() now documented as returning logical points (DIP) instead of physical pixels
- Aligns with gogpu RETINA refactor:
App.Size()returns logical coordinates - Physical pixel dimensions =
Size() * ScaleFactor() NullWindowProviderfields W/H updated to logical points- README examples updated for HiDPI-aware rendering pattern
- Aligns with gogpu RETINA refactor:
0.9.0 - 2026-02-10
- HalProvider interface for direct HAL device/queue access (gg#95)
HalDevice() any— returns underlying HAL device for direct GPU accessHalQueue() any— returns underlying HAL queue for direct GPU access- Optional interface — use type assertion on DeviceProvider:
if hp, ok := provider.(gpucontext.HalProvider); ok { ... } - Enables GPU accelerators (e.g., gg SDF pipeline) to share devices with host applications without creating their own wgpu instance
0.8.0 - 2026-02-06
-
WindowProvider interface for window geometry and DPI integration
Size() (width, height int)— window client area in logical points (DIP)ScaleFactor() float64— DPI scale factor (1.0 = standard, 2.0 = Retina/HiDPI)RequestRedraw()— request a new frame in on-demand rendering modeNullWindowProvider— configurable defaults for testing and headless operation
-
PlatformProvider interface for OS integration features (optional)
ClipboardRead() (string, error)— read text from system clipboardClipboardWrite(text string) error— write text to system clipboardSetCursor(cursor CursorShape)— change mouse cursor shapeDarkMode() bool— system dark mode detectionReduceMotion() bool— accessibility: reduced animation preferenceHighContrast() bool— accessibility: high contrast modeFontScale() float32— user's font size preference multiplierNullPlatformProvider— no-op defaults for testing
-
CursorShape enum with 12 standard cursor shapes
- Default, Pointer, Text, Crosshair, Move
- ResizeNS, ResizeEW, ResizeNWSE, ResizeNESW
- NotAllowed, Wait, None (hidden)
String()method for debugging
- TouchEventSource interface — replaced by PointerEventSource (W3C Pointer Events Level 3)
TouchID,TouchPhase,TouchPoint,TouchEventtypes removedTouchEventSourceinterface removedNullTouchEventSourceremoved- Touch input is fully covered by
PointerEventSourcewithPointerType: Touch - W3C recommends Pointer Events over Touch Events (Touch Events is legacy)
- PlatformProvider is optional — use type assertion on WindowProvider:
if pp, ok := provider.(gpucontext.PlatformProvider); ok { ... } - These interfaces enable UI frameworks to access host window and platform capabilities without direct dependency on gogpu
0.7.0 - 2026-02-05
- TextureUpdater interface for updating existing texture pixel data (gg#79)
UpdateData(data []byte) error— upload new pixel data to existing texture- Enables proper error handling for dynamic content (canvas rendering, video frames)
- Implemented by
gogpu.Texture
0.6.0 - 2026-01-31
- Gesture Events for multi-touch gesture recognition (#6)
GestureEvent— Vello-style per-frame gesture deltas (zoom, rotation, translation)GestureEventSource— interface for registering gesture callbacksNullGestureEventSource— no-op implementation
0.5.0 - 2026-01-31
-
W3C Pointer Events Level 3 for unified pointer input
PointerEvent— unified mouse, touch, pen input with full W3C compliancePointerEventType— Down, Up, Move, Enter, Leave, CancelPointerType— Mouse, Touch, PenButton— Left, Middle, Right, X1, X2, EraserButtons— bitmask for tracking multiple pressed buttonsPointerEventSource— interface for registering pointer callbacksNullPointerEventSource— no-op implementation
-
Scroll Events for mouse wheel and trackpad
ScrollEvent— horizontal/vertical scroll with delta modesScrollDeltaMode— Pixel, Line, Page modesScrollEventSource— interface for registering scroll callbacksNullScrollEventSource— no-op implementation
-
CI/CD Infrastructure
- GitHub Actions workflow (build, test, lint on Linux/macOS/Windows)
- golangci-lint v2 configuration
- TouchCancelled → TouchCanceled — US English spelling (misspell linter)
- Removed unused
DeviceHandlealias
0.4.0 - 2026-01-30
-
Texture interfaces for GPU texture sharing across packages
Texture— minimal interface with Width/HeightTextureDrawer— interface for drawing textures (DrawTexture, DrawTextureEx)TextureCreator— interface for creating textures from pixel dataTextureDrawOptions— options for advanced texture rendering (position, scale, alpha, flip)
-
Touch input support for mobile and tablet applications
TouchID— unique identifier for touch pointsTouchPhase— lifecycle stages (Began, Moved, Ended, Cancelled)TouchPoint— single touch contact with position, optional pressure/radiusTouchEvent— complete touch event with Changed/All points, modifiers, timestampTouchEventSource— interface for registering touch callbacksNullTouchEventSource— no-op implementation for non-touch platforms
- Touch interfaces follow platform conventions (iOS, Android, W3C Touch Events)
- Texture interfaces enable gg↔gogpu integration without circular dependencies
- Both are contracts only — implementations in host applications
0.3.1 - 2026-01-29
- Update gputypes to v0.2.0 for webgpu.h spec-compliant enum values
0.3.0 - 2026-01-29
- Import gputypes for unified WebGPU types
- DeviceProvider.SurfaceFormat() now returns
gputypes.TextureFormat - Removed local type re-exports in favor of gputypes
- Single source of truth for WebGPU types across ecosystem
- DeviceProvider.SurfaceFormat() now returns
- CODE_OF_CONDUCT.md
- SECURITY.md
0.2.0 - 2026-01-27
- IME Support for CJK input (Chinese, Japanese, Korean)
IMEStatestruct with composition state trackingIMEControllerinterface for positioning IME window- Extended
EventSourcewithOnIMECompositionStart,OnIMECompositionUpdate,OnIMECompositionEnd - Updated
NullEventSourcewith no-op IME implementations
- IME interfaces are contracts only — platform integration happens in host applications (gogpu)
- Required for enterprise UI frameworks supporting international users
0.1.1 - 2026-01-27
-
DeviceProvider interface for GPU device/queue injection
Device()returns WebGPU deviceQueue()returns command queueAdapter()returns GPU adapterSurfaceFormat()returns preferred texture format
-
EventSource interface for input events
- Keyboard:
OnKeyPress,OnKeyRelease,OnTextInput - Mouse:
OnMouseMove,OnMousePress,OnMouseRelease,OnScroll - Window:
OnResize,OnFocus Key,Modifiers,MouseButtontypesNullEventSourceno-op implementation
- Keyboard:
-
Registry[T] generic backend registry
- Thread-safe registration with
sync.RWMutex - Priority-based selection via
Best() Register,Unregister,Get,Has,Available,Count
- Thread-safe registration with
-
WebGPU Types (zero dependencies)
Device,Queue,Adapter,Surface,InstanceinterfacesTextureFormatenum with common formatsOpenDeviceconvenience struct
- This package has zero external dependencies by design
- All interfaces are minimal to allow diverse implementations
- Part of the gogpu ecosystem