Enterprise API Audit — gpucontext Public API Cleanup
Tracking issue for gpucontext improvements. Sources: @lkmavi audit (Flutter embedding scenario), independent senior-go-architect audit, cross-repo consistency check.
Architecture Context: Why gpucontext exists
gogpu is a shared resource ecosystem — multiple libraries (gg, ui, Born ML, g3d) share a single GPU device/queue created by the app framework. This is fundamentally different from monolithic engines (Flutter, Unity) where the engine owns all GPU resources internally.
Our architectural pattern matches:
- wgpu-rs ecosystem: wgpu creates device → vello/bevy consume it via shared references
- Vulkan ecosystem:
VkDevice shared across libraries via handle passing
- Go
database/sql: shared sql.DB (concrete) + driver.Driver (SPI interface)
gpucontext is the shared interface contract between producer (gogpu) and consumers (gg, ui, Born ML). It defines what a GPU host must provide (DeviceProvider, WindowProvider, EventSource) without coupling consumers to a specific implementation (wgpu Native Go vs Rust FFI vs Browser).
The original audit used Flutter embedding as the test scenario. Flutter manages its own GPU device internally (host only provides platform hooks) — a different architecture. The audit findings were validated independently of the Flutter scenario, on their own enterprise merits.
✅ Remove Dead Code (verified: zero consumers across ecosystem)
✅ Documentation
💬 Needs Discussion: Button Ordering Mismatch
Button (pointer.go) uses W3C ordering: Left=0, Middle=1, Right=2
MouseButton (events.go) uses: Left=0, Right=1, Middle=2
Middle and Right are swapped between the two types. buttonToMouseButton in gogpu/event_source.go:362 converts, but this is a bug vector.
Options:
- Deprecate
MouseButton entirely in favor of W3C Button (breaking change)
- Keep both but add prominent doc warnings
- Align
MouseButton to W3C ordering (breaking change)
@lkmavi thoughts?
💬 Needs Discussion: Duplicate Types with ui/event
gpucontext defines Key (83 values), Modifiers (6 flags), MouseButton (5 values).
ui/event defines identical event.Key, event.Modifiers, event.Button.
ui/app/event_bridge.go is 250 lines of pure 1:1 translation.
Naming differs: ModControl (gpucontext) vs ModCtrl (ui).
Options:
- ui imports gpucontext types directly (eliminate translation layer)
- gpucontext exports canonical types, ui re-exports (type alias)
- Keep separate but add compile-time sync assertions
💬 Needs Discussion: Dual AdapterInfo
gputypes.AdapterInfo — full (VendorID, DeviceID, Driver info, 8 fields)
gpucontext.AdapterInfo — simplified (Name + Type, 2 fields)
Both serve different purposes (gputypes for HAL, gpucontext for abstract provider). Document canonical source or add conversion helper.
💬 Needs Discussion: EventSource Size (ISP)
EventSource has 12 methods (keyboard 3, mouse 4, window 2, IME 3). Every implementor must implement all 12. Consider splitting for v1.0:
KeyEventSource (3 methods)
MouseEventSource (4 methods)
WindowEventSource (2 methods)
IMEEventSource (3 methods)
winit has no split (monolithic handler). GTK4/Qt6 do split. What's right for gogpu?
✅ Low Priority (v1.0 planning)
💬 Counter-arguments (open for discussion)
1. EventSource unsubscribe — @lkmavi suggested adding unsubscribe for dynamic widget trees. Our research: Flutter uses push model (no subscribe/unsubscribe at embedder boundary), winit has no unsubscribe. GTK4/Qt6 do (they're widget toolkits). Our position: widget-level event routing belongs in ui, not in gpucontext windowing layer. @lkmavi, do you see a concrete use case where gogpu-level unsubscribe is needed that ui can't handle internally?
2. SetTabbingMode in PlatformProvider — @lkmavi flagged as ISP violation. Checking code: SetTabbingMode is in gogpu.Config, not in gpucontext.PlatformProvider. PlatformProvider has only cross-platform methods (clipboard, cursor, accessibility). @lkmavi, was this based on a different method or earlier code version?
This is a living tracking issue. Feedback welcome from everyone — especially on the 💬 discussion items. If you use gpucontext as a consumer or have experience with similar shared-interface patterns, your perspective is valuable.
References
- Independent audit: full interface + consumer analysis across ecosystem
- Breaking change risk matrix: DeviceProvider=CRITICAL, EventSource=HIGH, IMEController=NONE
- Zero-value safety: all types verified safe
Enterprise API Audit — gpucontext Public API Cleanup
Tracking issue for gpucontext improvements. Sources: @lkmavi audit (Flutter embedding scenario), independent senior-go-architect audit, cross-repo consistency check.
Architecture Context: Why gpucontext exists
gogpu is a shared resource ecosystem — multiple libraries (gg, ui, Born ML, g3d) share a single GPU device/queue created by the app framework. This is fundamentally different from monolithic engines (Flutter, Unity) where the engine owns all GPU resources internally.
Our architectural pattern matches:
VkDeviceshared across libraries via handle passingdatabase/sql: sharedsql.DB(concrete) +driver.Driver(SPI interface)gpucontextis the shared interface contract between producer (gogpu) and consumers (gg, ui, Born ML). It defines what a GPU host must provide (DeviceProvider,WindowProvider,EventSource) without coupling consumers to a specific implementation (wgpu Native Go vs Rust FFI vs Browser).The original audit used Flutter embedding as the test scenario. Flutter manages its own GPU device internally (host only provides platform hooks) — a different architecture. The audit findings were validated independently of the Flutter scenario, on their own enterprise merits.
✅ Remove Dead Code (verified: zero consumers across ecosystem)
Instanceinterface (webgpu_types.go:70) — zero references in gogpu, gg, ui, g3dSurfaceinterface (webgpu_types.go:62) — zero references anywhereOpenDevicestruct (webgpu_types.go:74) — zero references anywhereIMEControllerinterface (events.go:109-120) — zero consumers, zero implementors. Remove until actual needRegistry[T](registry.go, 160 LOC) — zero consumers. gogpu uses different backend selection mechanism. Remove or move to internal✅ Documentation
doc.goconsumer list stale — missing ui (major EventSource consumer) and g3ddoc.gointerface list incomplete — omits GestureEventSource, IMEController, AdapterInfo, etc.NullPlatformProviderdoc missingSubpixelLayout: SubpixelNoneString()methods toKey,MouseButton,Modifiers— all other enums have them, these three don't💬 Needs Discussion: Button Ordering Mismatch
Button(pointer.go) uses W3C ordering: Left=0, Middle=1, Right=2MouseButton(events.go) uses: Left=0, Right=1, Middle=2Middle and Right are swapped between the two types.
buttonToMouseButtoningogpu/event_source.go:362converts, but this is a bug vector.Options:
MouseButtonentirely in favor of W3CButton(breaking change)MouseButtonto W3C ordering (breaking change)@lkmavi thoughts?
💬 Needs Discussion: Duplicate Types with ui/event
gpucontext defines
Key(83 values),Modifiers(6 flags),MouseButton(5 values).ui/event defines identical
event.Key,event.Modifiers,event.Button.ui/app/event_bridge.gois 250 lines of pure 1:1 translation.Naming differs:
ModControl(gpucontext) vsModCtrl(ui).Options:
💬 Needs Discussion: Dual AdapterInfo
gputypes.AdapterInfo— full (VendorID, DeviceID, Driver info, 8 fields)gpucontext.AdapterInfo— simplified (Name + Type, 2 fields)Both serve different purposes (gputypes for HAL, gpucontext for abstract provider). Document canonical source or add conversion helper.
💬 Needs Discussion: EventSource Size (ISP)
EventSource has 12 methods (keyboard 3, mouse 4, window 2, IME 3). Every implementor must implement all 12. Consider splitting for v1.0:
KeyEventSource(3 methods)MouseEventSource(4 methods)WindowEventSource(2 methods)IMEEventSource(3 methods)winit has no split (monolithic handler). GTK4/Qt6 do split. What's right for gogpu?
✅ Low Priority (v1.0 planning)
Device interface{}etc.) — add sentinel methods for compile-time safety💬 Counter-arguments (open for discussion)
1. EventSource unsubscribe — @lkmavi suggested adding unsubscribe for dynamic widget trees. Our research: Flutter uses push model (no subscribe/unsubscribe at embedder boundary), winit has no unsubscribe. GTK4/Qt6 do (they're widget toolkits). Our position: widget-level event routing belongs in ui, not in gpucontext windowing layer. @lkmavi, do you see a concrete use case where gogpu-level unsubscribe is needed that ui can't handle internally?
2. SetTabbingMode in PlatformProvider — @lkmavi flagged as ISP violation. Checking code:
SetTabbingModeis ingogpu.Config, not ingpucontext.PlatformProvider. PlatformProvider has only cross-platform methods (clipboard, cursor, accessibility). @lkmavi, was this based on a different method or earlier code version?This is a living tracking issue. Feedback welcome from everyone — especially on the 💬 discussion items. If you use gpucontext as a consumer or have experience with similar shared-interface patterns, your perspective is valuable.
References