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
TypeScript
/**
* 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>;