import type { Result, RhiDevice, RhiError, Texture, TextureView } from '@forgeax/engine-rhi'; import type { Handle } from '@forgeax/engine-types'; /** * The host-owned external image the engine copies an image from * (HTMLVideoElement / VideoFrame / ImageBitmap / canvas). Mirrors the `source` * member of the WebGPU `GPUCopyExternalImageSourceInfo` the RHI * `copyExternalImageToTexture` consumes; aliased here so the store does not pull * the whole webgpu descriptor type into its surface. */ export type CopyExternalImageSource = GPUCopyExternalImageSourceInfo['source']; /** rgba8unorm-srgb: Canvas and decoded video color are sRGB; sampling returns linear. */ declare const DYNAMIC_TEXTURE_FORMAT: "rgba8unorm-srgb"; /** * The minimal RHI device surface DynamicTextureStore needs. Declared structurally * (not the full RhiDevice) so unit tests drive it with a small mock and the store * stays decoupled from the rest of the device surface (Pipeline Isolation). */ export interface DynamicTextureDevice { createTexture(desc: { readonly size: { readonly width: number; readonly height: number; readonly depthOrArrayLayers: number; }; readonly format: typeof DYNAMIC_TEXTURE_FORMAT; readonly usage: number; readonly label?: string; }): Result; createTextureView(texture: Texture, desc: Record): Result; destroyTexture(texture: Texture): Result; readonly queue: { copyExternalImageToTexture(source: { readonly source: CopyExternalImageSource; readonly flipY?: boolean; }, destination: { readonly texture: Texture; }, copySize: { readonly width: number; readonly height: number; readonly depthOrArrayLayers: number; }): Result; }; } /** Adapt the opaque RHI device to the store's intentionally small upload seam. */ export declare function adaptDynamicTextureDevice(device: RhiDevice): DynamicTextureDevice; type DynamicTextureKey = Handle<'VideoAsset', 'shared'> | object; /** * Transient texture store for video frames and versioned Canvas sources. Independent of * GpuResourceStore: it neither imports nor reaches into the static residency * cache (AC-08 / D-3). */ export declare class DynamicTextureStore { private device; private readonly entries; /** * Wire the GPU device the store uploads through. Called once after the * renderer captures its device (mirrors GpuResourceStore.configureGpuDevice). * A replacement device invalidates every cached texture: the handles in the * map belong to the old device and cannot be reused after renderer recovery. */ configureGpuDevice(device: DynamicTextureDevice): void; /** * Upload an image for `key` from the caller-owned source image * (HTMLVideoElement / VideoFrame / ImageBitmap / Canvas), (re)allocating the transient * texture when its size changes, and return the current-frame view to bind. * * Returns `undefined` (not an error) when the device is not yet wired or the * source has no decodable dimensions yet (metadata pending) — the caller binds * the default view that frame. A structured RhiError surfaces only when a wired * device rejects the allocation or the copy (charter P3). */ uploadFrame(key: DynamicTextureKey, source: CopyExternalImageSource, width: number, height: number, options?: { readonly version?: number | undefined; readonly signal?: AbortSignal | undefined; readonly flipY?: boolean; }): Result | undefined; /** * The current-frame view for a clip, if one has been uploaded this session, * else undefined. The record stage reads this when assembling the bind group * (a frame that has not uploaded yet falls back to the default view). */ getView(key: DynamicTextureKey): TextureView | undefined; /** Release one source without disturbing other videos or canvases. */ release(key: DynamicTextureKey): void; /** Renderer teardown or device replacement invalidates all uploaded versions. */ destroyAll(): void; private createEntry; } export {}; //# sourceMappingURL=dynamic-texture-store.d.ts.map