import { TgpuRoot } from 'typegpu'; import { GpuFailureReason } from './support'; import { NodeHandles, FieldInit } from './uniformStore'; import { GpuShaderDefinition } from './contract'; import { SizeConversion } from '../utilities/dimensionalProps'; import { PerformanceStats } from '../performanceTracker'; import { NodeMetadata, ToneMappingMode } from '../types'; export { acquireRoot, configureCanvasContext, getRootForDevice, destroyDefaultGpuDevice } from './root'; export type { AcquireRootOptions, RootContext } from './root'; export { isWebGPUSupported, getWebGPUSupport, setShadersDebug, isShadersDebug, GpuUnavailableError, isGpuUnavailableError } from './support'; export type { GpuFailureReason, WebGPUSupportInfo } from './support'; /** * One prop's registration input. Carries the plain current `value` plus the CPU `transform` * and the compile-time flags. The uniform store applies the transform when seeding/patching the * packed struct field (see uniformStore.FieldHandle). The framework templates produce this * shape. */ export interface GpuUniformInput { /** Current value (raw, or dimensionally-resolved for shape props). The store transforms it. */ value: unknown; /** CPU transform (transformColor / transformPosition / transformAngle / …). */ transform?: (value: unknown) => unknown; /** Recompiles the composition when this prop changes (baked into the WGSL at build). */ compileTime?: boolean; /** Recompiles only when the predicate fires (e.g. blur crossing 0). */ compileTimeWhen?: (previousValue: unknown, newValue: unknown) => boolean; /** @internal last value a compileTimeWhen recompose was keyed to. */ _lastCompiledValue?: unknown; /** @internal raw (px / DimensionalValue) value for resize re-resolution of shape props. */ _rawDimensional?: unknown; /** String / JSON / origin / select props — CPU-only, never enter the packed struct. */ cpu?: boolean; /** @internal list props: the RAW items (drivers included) the renderer re-resolves per frame. */ _rawList?: unknown; /** @internal list props: the item spec (fields / maxItems) the renderer packs with. */ _listSpec?: import('../utilities/listProps').ListPropSpec; /** Explicit WGSL schema override (else inferred from the transformed value). */ schema?: import('typegpu/data').AnyWgslData; } /** A node's registration input, keyed by prop name. */ export type GpuUniformsMap = Record; export interface GpuInitializeOptions { canvas: HTMLCanvasElement; /** Element to observe for resize. Defaults to `canvas.parentElement`. */ resizeTarget?: HTMLElement; enablePerformanceTracking?: boolean; colorSpace?: 'p3-linear' | 'srgb'; toneMapping?: ToneMappingMode; /** Inject a shared device (Projects multi-tile) — one root per device. */ gpu?: { device: GPUDevice; adapter?: GPUAdapter; }; forceFullFrameRate?: boolean; /** When false, skips ResizeObserver + IntersectionObserver — use resize()/start()/stop(). */ observeElement?: boolean; /** Shared wall-clock time origin (performance.now ms) for synced multi-renderer animation. */ timeOrigin?: number; /** * REJECTED. This renderer is WebGPU-only and throws a descriptive error if a context is * passed. Present only to give a clear error, not for use. */ context?: unknown; } interface MouseDriverState { currentX: number; currentY: number; velocityX: number; velocityY: number; /** * Set once the state has seen a REAL pointer position. A state created before any pointer * event seeds from the off-screen park (-10) — on the first real event it must SNAP to the * cursor, not spring across the canvas (content visibly flying in from off-screen). */ pointerSnapped?: boolean; /** Live pre-flip box-local point for UI readback (mouse-position). */ liveX?: number; liveY?: number; /** Live resolved scalar for UI readback (mouse-map range). */ liveScalar?: number; } /** Resolved map/mouse remap bounds (plain numbers), refreshed on metadata + resize. */ interface MapValues { inputMin: number; inputMax: number; outputMin: number; outputMax: number; curve: number; } interface GpuNodeInfo { id: string; componentName: string; parentId: string | null; definition: GpuShaderDefinition; metadata: NodeMetadata; uniforms: GpuUniformsMap; domCanvas?: HTMLCanvasElement; requiresRTT: boolean; requiresChild: boolean; blendWithChildren: boolean; acceptsUVContext: boolean; providesUVContextViaCompute: boolean; usesPointer: boolean; hasUvRemap: boolean; boundingBoxDeclaration?: GpuShaderDefinition['boundingBoxDeclaration']; wantsBoundsParams: boolean; extraDimProps?: Map; mouseDriverState: Record; autoAnimateState: Record; mapValues: Record; /** Live per-field handles from the CURRENTLY BOUND composition's store (props + synthetic). */ _liveHandles: NodeHandles | null; } interface QueuedRegistration { id: string; definition: GpuShaderDefinition; parentId: string | null; metadata: NodeMetadata | null; uniforms: GpuUniformsMap; domCanvas?: HTMLCanvasElement; } /** * Construct a WebGPU renderer instance. */ export declare function shaderRendererGPU(): { initialize: (options: GpuInitializeOptions) => Promise; cleanup: () => void; registerNode: (id: string, fragmentNodeFunc: GpuShaderDefinition["fragment"] | null, parentId: string | null, metadata: NodeMetadata | null, uniforms?: GpuUniformsMap, componentDefinition?: GpuShaderDefinition, domCanvas?: HTMLCanvasElement) => void; removeNode: (id: string) => void; updateUniformValue: (nodeId: string, uniformName: string, value: unknown) => void; updateNodeMetadata: (nodeId: string, metadata: Partial) => void; isInitialized: () => boolean; resize: (width: number, height: number) => void; startAnimation: () => void; stopAnimation: () => void; renderAndWait: (options?: { waitForGpu?: boolean; }) => Promise; renderSyntheticFrame: (deltaSeconds: number, options?: { waitForGpu?: boolean; }) => Promise; getPerformanceStats: () => PerformanceStats; getLiveDriverValue: (nodeId: string, propName: string) => { x: number; y: number; } | null; getLiveScalarValue: (nodeId: string, propName: string) => number | null; getNodeRegistry: () => { nodes: ReadonlyMap; }; /** Always 'webgpu' (type kept wide for source-compat with callers expecting a union). */ getRendererType: () => "webgpu" | "webgl" | null; /** The renderer context object: `{ device, adapter?, root }`. */ getInternalRenderer: () => { device: GPUDevice; adapter?: GPUAdapter; root: TgpuRoot; } | null; setForceFullFrameRate: (enabled: boolean) => boolean; beginRecordingResolution: (targetWidth: number, targetHeight: number, ratio: number) => (() => void); setResolutionScale: (scale: number) => void; /** * Cap this renderer's ON-screen frame rate (`null`/0 restores the default * 60 FPS). The lever a multi-tile canvas pulls per tile: a frame that is * 80px on screen doesn't earn 60 renders a second. The RAF loop keeps * ticking; skipped frames cost one gate check and nothing else (no driver * update, no flush, no submit). Time stays correct across skips — delta * accumulates, and a shared time origin is wall-clock anyway. Caps are * clamped to 10 FPS minimum: below that the frame interval exceeds the * gate's 0.1s delta clamp and accumulated animation time would lose * elapsed wall-clock time on every rendered frame. */ setFrameRateCap: (fps: number | null) => void; setTimeOrigin: (origin: number | null) => void; setOnReady: (callback: (() => void) | null) => void; setOnDeviceLost: (callback: ((reason: string) => void) | null) => void; /** * Subscribe to "this renderer can never draw" — WebGPU missing, no adapter, device * refused/lost, or the GPU proving unusable at runtime. Fires at most once. A late * subscriber (registered after the failure) is still notified, so hosts can attach * this after `initialize()` has already resolved. * * By the time it fires every GPU resource has been released and the frame loop is * stopped. This is the hook for swapping in a static fallback. */ setOnUnavailable: (callback: ((reason: GpuFailureReason, error?: unknown) => void) | null) => void; /** Why this renderer gave up, or `null` while it is healthy. */ getFailureReason: () => GpuFailureReason | null; __testing: { needsTransformation: (transform: import('./kit/uvTransform').TransformConfig | undefined) => boolean; findChildNodes: (parentId: string) => GpuNodeInfo[]; /** The per-node FieldInit set the store registers (props + synthetic `_`-fields). */ buildFieldInits: (id: string) => FieldInit[] | null; /** Re-seed a node's persistent CPU driver state (the cache-hit rebind path). */ ensureDriverState: (id: string) => void; /** Advance the CPU mouse/auto drivers one step without a device (driver test). */ stepMouseDrivers: (deltaTime: number) => void; /** Advance + read a node's `_animTime` accumulator without a device (driver test). */ stepAnimatedTime: (deltaTime: number) => void; getAnimatedTimeValue: (id: string) => number | null; writeExtraField: (id: string, name: string, value: number | number[]) => void; readExtraField: (id: string, name: string) => unknown; getNodeRegistry: () => { nodes: Map; rootId: string | null; parentToChildren: Map>; }; getParentToChildren: () => Map>; getPendingRegistrations: () => QueuedRegistration[]; /** Passive read of the live frame-timing/pointer state (RAF-loop diagnosis). */ getFrameDiagnostics: () => { deltaTime: number; pointerX: number; pointerY: number; pointerActive: boolean; globalElapsedTime: number; lastRenderTime: number; isVisible: boolean; forceFullFrameRate: boolean; sharedTimeOrigin: number | null; animating: boolean; mouseListenersNeeded: boolean; }; computeStructuralHash: () => string | null; isStructuralDirty: () => boolean; clearStructuralDirty: () => void; /** Force the renderer "ready" WITHOUT a device, for registration/scheduling tests. */ setTestReady: (dims?: { width: number; height: number; }) => void; }; }; //# sourceMappingURL=index.d.ts.map