UNPKG

ranui

Version:

A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.

42 lines (41 loc) 2.46 kB
/** * WebGPU backend for `<r-glass rim>` — the exact same shape-only SDF rim + * chromatic fringe as the WebGL backend in `rim.ts`, reimplemented in WGSL. * See the module doc in `rim.ts` for what this draws and why it never * samples the backdrop; this file is purely an alternate rendering backend * for the identical effect, not a different one. * * WHY THIS EXISTS, GIVEN THE WEBGL PATH ALREADY WORKS EVERYWHERE: * It doesn't make this draw any faster. A single draw call, reissued only on * resize/radius change, has no per-frame or many-draw-call overhead for * WebGPU's command-buffer model to amortize, and the GPU-side shader work (a * handful of distance-field evaluations over a thin band of pixels) is * microseconds either way — the bottleneck for this workload was never the * choice of API. This backend exists because it was explicitly requested, * not because it measurably helps this effect; if `rim` ever grows into a * heavier multi-pass effect (real per-frame refraction, multiple blur * passes), that's the scenario where WebGPU's model would actually start to * matter. * * WHY IT'S A SEPARATE, OPTIONAL UPGRADE INSTEAD OF REPLACING WEBGL: * `GPUAdapter`/`GPUDevice` negotiation (`requestAdapter`/`requestDevice`) is * asynchronous — unlike `canvas.getContext('webgl')`, which returns * synchronously. Blocking the rim's first appearance on that Promise would * make an optional decorative layer show up later than the WebGL path does * today, for a visually identical result — a real regression for zero gain. * So `createRimRenderer` in `rim.ts` always shows the WebGL canvas first and * only swaps to this backend if/when the negotiation here resolves. */ export interface RimBackend { /** Draws once at the given backing-store size (already dpr-scaled) plus CSS-px radius and dpr. */ draw(width: number, height: number, radius: number, dpr: number): void; /** Frees the GPU device — browsers cap how many WebGPU/WebGL contexts can be live at once. */ destroy(): void; } /** * Negotiates a WebGPU device and configures `canvas` for it. Resolves to * `null` — never rejects — if WebGPU isn't present, adapter/device * negotiation fails, or the canvas context can't be configured. Every one of * those cases means the same thing to the caller: keep showing the WebGL rim. */ export declare function createWebGpuRim(canvas: HTMLCanvasElement): Promise<RimBackend | null>;