@motionscript/browser 0.0.0-stage → 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/LICENSE +201 -0
- package/README.md +68 -3
- package/dist/asset-bytes.d.ts +50 -0
- package/dist/asset-bytes.d.ts.map +1 -0
- package/dist/asset-bytes.js +60 -0
- package/dist/asset-bytes.js.map +1 -0
- package/dist/audio/bus-graph.d.ts +43 -0
- package/dist/audio/bus-graph.d.ts.map +1 -0
- package/dist/audio/bus-graph.js +104 -0
- package/dist/audio/bus-graph.js.map +1 -0
- package/dist/audio/filter-graph.d.ts +58 -0
- package/dist/audio/filter-graph.d.ts.map +1 -0
- package/dist/audio/filter-graph.js +235 -0
- package/dist/audio/filter-graph.js.map +1 -0
- package/dist/audio/index.d.ts +5 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/index.js +12 -0
- package/dist/audio/index.js.map +1 -0
- package/dist/audio/mixer.d.ts +59 -0
- package/dist/audio/mixer.d.ts.map +1 -0
- package/dist/audio/mixer.js +193 -0
- package/dist/audio/mixer.js.map +1 -0
- package/dist/audio/player.d.ts +49 -0
- package/dist/audio/player.d.ts.map +1 -0
- package/dist/audio/player.js +226 -0
- package/dist/audio/player.js.map +1 -0
- package/dist/browser/audio.js +2 -0
- package/dist/browser/audio.js.map +7 -0
- package/dist/browser/chunks/GLTFLoader-PGXD4V5B.js +2 -0
- package/dist/browser/chunks/GLTFLoader-PGXD4V5B.js.map +7 -0
- package/dist/browser/chunks/SkeletonUtils-XYDMTGTM.js +2 -0
- package/dist/browser/chunks/SkeletonUtils-XYDMTGTM.js.map +7 -0
- package/dist/browser/chunks/chunk-CTLBXZSU.js +4119 -0
- package/dist/browser/chunks/chunk-CTLBXZSU.js.map +7 -0
- package/dist/browser/chunks/chunk-FQ32PDIU.js +2 -0
- package/dist/browser/chunks/chunk-FQ32PDIU.js.map +7 -0
- package/dist/browser/chunks/chunk-FY3BTKY4.js +2 -0
- package/dist/browser/chunks/chunk-FY3BTKY4.js.map +7 -0
- package/dist/browser/chunks/chunk-NSFLRI4P.js +2 -0
- package/dist/browser/chunks/chunk-NSFLRI4P.js.map +7 -0
- package/dist/browser/chunks/three.module-Z4EOVUWF.js +2 -0
- package/dist/browser/chunks/three.module-Z4EOVUWF.js.map +7 -0
- package/dist/browser/esbuild.wasm +0 -0
- package/dist/browser/index.js +2172 -0
- package/dist/browser/index.js.map +7 -0
- package/dist/browser/manifest.json +15 -0
- package/dist/concat.d.ts +95 -0
- package/dist/concat.d.ts.map +1 -0
- package/dist/concat.js +174 -0
- package/dist/concat.js.map +1 -0
- package/dist/decode/image-levels.d.ts +137 -0
- package/dist/decode/image-levels.d.ts.map +1 -0
- package/dist/decode/image-levels.js +477 -0
- package/dist/decode/image-levels.js.map +1 -0
- package/dist/decode/levels.d.ts +37 -0
- package/dist/decode/levels.d.ts.map +1 -0
- package/dist/decode/levels.js +68 -0
- package/dist/decode/levels.js.map +1 -0
- package/dist/decode/video-levels.d.ts +37 -0
- package/dist/decode/video-levels.d.ts.map +1 -0
- package/dist/decode/video-levels.js +95 -0
- package/dist/decode/video-levels.js.map +1 -0
- package/dist/dynamic-nodes.d.ts +9 -0
- package/dist/dynamic-nodes.d.ts.map +1 -0
- package/dist/dynamic-nodes.js +56 -0
- package/dist/dynamic-nodes.js.map +1 -0
- package/dist/engine.d.ts +59 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +171 -0
- package/dist/engine.js.map +1 -0
- package/dist/exporter.d.ts +163 -0
- package/dist/exporter.d.ts.map +1 -0
- package/dist/exporter.js +263 -0
- package/dist/exporter.js.map +1 -0
- package/dist/getter.d.ts +10 -0
- package/dist/getter.d.ts.map +1 -0
- package/dist/getter.js +38 -0
- package/dist/getter.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/measure-context.d.ts +12 -0
- package/dist/measure-context.d.ts.map +1 -0
- package/dist/measure-context.js +12 -0
- package/dist/measure-context.js.map +1 -0
- package/dist/mix-timeline-audio.d.ts +42 -0
- package/dist/mix-timeline-audio.d.ts.map +1 -0
- package/dist/mix-timeline-audio.js +63 -0
- package/dist/mix-timeline-audio.js.map +1 -0
- package/dist/output.d.ts +7 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +6 -0
- package/dist/output.js.map +1 -0
- package/dist/render-context.d.ts +30 -0
- package/dist/render-context.d.ts.map +1 -0
- package/dist/render-context.js +55 -0
- package/dist/render-context.js.map +1 -0
- package/dist/screenshot.d.ts +45 -0
- package/dist/screenshot.d.ts.map +1 -0
- package/dist/screenshot.js +32 -0
- package/dist/screenshot.js.map +1 -0
- package/dist/still.d.ts +151 -0
- package/dist/still.d.ts.map +1 -0
- package/dist/still.js +222 -0
- package/dist/still.js.map +1 -0
- package/dist/storage-adapter.d.ts +367 -0
- package/dist/storage-adapter.d.ts.map +1 -0
- package/dist/storage-adapter.js +1278 -0
- package/dist/storage-adapter.js.map +1 -0
- package/dist/three/renderer.d.ts +48 -0
- package/dist/three/renderer.d.ts.map +1 -0
- package/dist/three/renderer.js +177 -0
- package/dist/three/renderer.js.map +1 -0
- package/dist/ticker.d.ts +42 -0
- package/dist/ticker.d.ts.map +1 -0
- package/dist/ticker.js +143 -0
- package/dist/ticker.js.map +1 -0
- package/package.json +74 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-adapter.js","sourceRoot":"","sources":["../src/storage-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CanvasKit, Image as CKImage, Surface, TypefaceFontProvider } from \"@motionscript/canvaskit\";\nimport { AssetCatalog, StorageAdapter, type Size2D } from \"@motionscript/core\";\nimport { ALL_FORMATS, BlobSource, Input, UrlSource, VideoSampleSink, type InputVideoTrack, type VideoSample } from \"mediabunny\";\nimport { ParagraphShapeCache } from \"@motionscript/skia-render/shapes/paragraph-cache\";\nimport type { SkiaAssets, SkiaTextureSource } from \"@motionscript/skia-render/assets\";\n// Type-only three usage keeps this a real lazy boundary — see three/bridge.ts.\nimport { hasPendingCanvas3D, warmPendingCanvas3D } from \"@motionscript/skia-render/three/bridge\";\nimport { localAssetBytes } from \"./asset-bytes\";\nimport { ImageLevelCache, type DecodePolicy, type DecodedImage } from \"./decode/image-levels\";\nimport { levelCap, levelSize, MAX_IMAGE_DECODE_EDGE, type PixelSize } from \"./decode/levels\";\nimport { VideoLevel, videoWindowFrames } from \"./decode/video-levels\";\n\n/** A live mediabunny decode session for one video src, opened once by loadVideo. */\ninterface VideoSession {\n input: Input;\n sink: VideoSampleSink;\n /** Source duration in seconds, from the container. */\n durationSec: number;\n /** Per-frame step in source seconds, learned from the first decoded sample's duration. */\n frameStep: number;\n /** Size frames are currently snapshotted at. */\n width: number;\n height: number;\n /** Display size of the track — the space a video fill is placed in. */\n intrinsic: PixelSize;\n levels: VideoLevel;\n /** Pooled snapshot target, resized when the level moves. */\n canvas: OffscreenCanvas | null;\n /**\n * One persistent GPU texture-backed image, reused across frames via\n * Surface.updateTextureFromSource — so advancing the playhead is a single\n * in-place texture blit, with no CPU readback or per-frame image allocation.\n */\n textureImage: CKImage | null;\n /** Quantized timestamp currently uploaded into {@link textureImage}, or null. */\n uploadedTs: number | null;\n uploadedBitmap?: ImageBitmap | null;\n textureWidth?: number;\n textureHeight?: number;\n /** A sequential decode pass is currently running for this src. */\n decoding: boolean;\n}\n\n/**\n * A texture-backed image plus what is uploaded into it — the session's own\n * pairing, factored out so the extra playhead slots\n * ({@link WebStorageAdapter.claimVideoFrame}) reuse their textures the same way.\n */\ninterface VideoTextureSlot {\n image: CKImage | null;\n uploadedTs: number | null;\n bitmap?: ImageBitmap | null;\n width?: number;\n height?: number;\n}\n\n/** A decoded video frame, snapshotted to an immutable {@link ImageBitmap} at the clip's level. */\ninterface DecodedVideoFrame {\n /** Start timestamp of this sample, in source seconds. */\n timestamp: number;\n bitmap: ImageBitmap;\n /** The level it was snapshotted at; a frame from before a level change still paints, as a fallback. */\n level?: number;\n}\n\n/** What an upgrade decodes from without refetching. */\ninterface ImageSource {\n blob?: Blob;\n svg?: HTMLImageElement;\n natural?: PixelSize;\n bytes: number;\n}\n\n/** A view over a readback's own buffer — a copy of a level's pixels is a second full-size allocation. */\nfunction pixelsOf(image: ImageData): Uint8Array {\n const { data } = image;\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n}\n\n/** Whether a src points at an SVG (by extension, ignoring any query/hash). */\nfunction isSvgSrc(src: string): boolean {\n return /\\.svg(?:[?#]|$)/i.test(src);\n}\n\n/** The buckets {@link WebStorageAdapter.assetUrl} reads a source's address from, in order. */\nconst ASSET_URL_LOOKUPS = {\n image: [(c: AssetCatalog, src: string) => c.getImageMeta(src)],\n video: [(c: AssetCatalog, src: string) => c.getVideoMeta(src)],\n media: [\n (c: AssetCatalog, src: string) => c.getAudioMeta(src),\n (c: AssetCatalog, src: string) => c.getVideoMeta(src),\n ],\n} satisfies Record<string, ((c: AssetCatalog, src: string) => { src: string })[]>;\n\n/**\n * Browser implementation of {@link StorageAdapter} — owns all async asset\n * decoding (images, video, audio, fonts) so the render loop can stay\n * synchronous.\n *\n * Images and video are held at **levels** chosen from the footprints the\n * renderer's getters report, not from declared layout boxes: a 4K photo drawn\n * as a thumbnail holds a thumbnail's pixels, and the same photo zoomed to fill\n * the screen is re-decoded to match. See `decode/image-levels.ts`.\n */\nexport class WebStorageAdapter extends StorageAdapter implements SkiaAssets {\n private canvasKit: CanvasKit;\n private fontMgr: TypefaceFontProvider;\n private disposed: boolean = false;\n\n /**\n * GPU surface the render context draws into; needed to upload decoded video\n * frames straight to texture (Surface.makeImageFromTextureSource /\n * updateTextureFromSource). Set by the render context on mount.\n */\n private surface: Surface | null = null;\n\n /** Open decode session per video src (opened once by loadVideo, deduped). */\n private videoSessions = new Map<string, VideoSession>();\n /** Decoded frame bitmaps per src, keyed by quantized source timestamp; bounded to the forward/back window. */\n private videoFrames = new Map<string, Map<number, DecodedVideoFrame>>();\n /**\n * Decoded past frames the Echo filter needs, kept in a SEPARATE cache so the\n * forward/back window eviction (which is centered on the current playhead)\n * never drops them — echo taps reach intentionally outside that window.\n * Bounded by trimming to the most-recently requested {@link ECHO_CACHE_LIMIT}\n * per src.\n */\n private videoEchoFrames = new Map<string, Map<number, DecodedVideoFrame>>();\n /** Last timestamp each src's playhead was asked to show, used to drive sequential decoding forward. */\n private videoPlayhead = new Map<string, number>();\n /**\n * Exact `(src, timestamp)` pairs a render asked for but couldn't satisfy from\n * the warm window. A blocking caller drains these via\n * {@link warmPendingDecodes} and re-renders.\n */\n private pendingVideoFrames = new Map<string, number>();\n /** Like {@link pendingVideoFrames}, for the several past frames an echo or a second playhead needs at once. */\n private pendingEchoFrames = new Map<string, Set<number>>();\n /** In-flight echo/extra-playhead decodes, keyed `src#quantizedTs`, so callers join one seek. */\n private echoDecodes = new Map<string, Promise<void>>();\n /**\n * Quantized timestamps claimed per src during the current render pass, in claim\n * order (see {@link claimVideoFrame}): index 0 holds the session's own texture,\n * index *n* holds {@link videoAltSlots} slot *n−1*. Cleared by\n * {@link beginRenderPass}.\n */\n private videoFrameClaims = new Map<string, number[]>();\n /**\n * Extra textures per src — one per *simultaneously visible* time of that clip\n * beyond the first. Persistent and updated in place exactly like a session's\n * own texture, so a second playhead costs a blit per frame, not an allocation.\n */\n private videoAltSlots = new Map<string, VideoTextureSlot[]>();\n /** The last footprint each clip was drawn at, for sizing a session opened later. */\n private videoDemand = new Map<string, number>();\n /**\n * Whether playback is live. When false the adapter does no look-ahead\n * prefetch, so a paused clip never drains a backlog of stale decodes.\n */\n private playing = false;\n\n private decodePolicy: DecodePolicy = \"interactive\";\n private readonly images: ImageLevelCache<CKImage>;\n private readonly imageSources = new Map<string, ImageSource>();\n private readonly reportedImageErrors = new Set<string>();\n\n private audioBuffers = new Map<string, AudioBuffer>();\n private audioCtx: AudioContext | null = null;\n private fps: number;\n\n /** Families already registered with the font provider (registered once, all weights at once). */\n private registeredFontFamilies = new Set<string>();\n\n /**\n * Families the catalog could not describe, so the warning is emitted once\n * rather than on every `loadAt`. Cleared by {@link setCatalog}: a new\n * manifest is exactly the event that can turn one of these into a real face.\n */\n private unknownFontFamilies = new Set<string>();\n\n /** Cache of shaped straight-text runs; owns the cached Fonts. See {@link ParagraphShapeCache}. */\n private paragraphCache = new ParagraphShapeCache();\n /** Bumped whenever a new font family registers, invalidating runs shaped against a fallback. */\n private fontEpoch = 0;\n\n /** Past frames the Echo cache holds per src; caps the renderer's MAX_ECHOES (32) with slack. */\n private static readonly ECHO_CACHE_LIMIT = 48;\n /**\n * Max extra textures per src (see {@link videoAltSlots}) — how many different\n * times of one clip can be on screen together. Past it the last slot is reused.\n */\n private static readonly ALT_SLOT_LIMIT = 16;\n\n constructor(canvasKit: CanvasKit, catalog: AssetCatalog, viewport: Size2D, fps: number) {\n super(catalog, viewport);\n this.canvasKit = canvasKit;\n this.fps = fps;\n this.fontMgr = canvasKit.TypefaceFontProvider.Make();\n this.images = new ImageLevelCache<CKImage>({\n now: () => performance.now(),\n decode: (src, chooseEdge) => this.decodeImage(src, chooseEdge),\n released: (_src, level) => {\n level.gpu?.delete();\n level.gpu = null;\n },\n sourceBytes: (src) => this.imageSources.get(src)?.bytes ?? 0,\n dropSource: (src) => this.imageSources.delete(src),\n surfaceEdge: () => this.surfaceEdge(),\n onError: (src, error) => {\n if (this.disposed || this.reportedImageErrors.has(src)) return;\n this.reportedImageErrors.add(src);\n console.error(`[WebStorageAdapter] image decode failed for ${src}:`, error);\n },\n });\n }\n\n getCanvasKit(): CanvasKit {\n return this.canvasKit;\n }\n\n /**\n * Adopt a new manifest, and forget which families it previously could not\n * describe — installing a typeface folds it into the live manifest without\n * rebuilding this adapter, and that family deserves a fresh attempt.\n */\n override setCatalog(catalog: AssetCatalog): void {\n super.setCatalog(catalog);\n this.unknownFontFamilies.clear();\n }\n\n // ─── Decode policy ───────────────────────────────────────────────────────\n\n override setDecodePolicy(policy: DecodePolicy): void {\n this.decodePolicy = policy;\n this.images.setPolicy(policy);\n }\n\n override getDecodePolicy(): DecodePolicy {\n return this.decodePolicy;\n }\n\n override hasPendingDecodes(): boolean {\n return this.pendingVideoFrames.size > 0\n || this.pendingEchoFrames.size > 0\n || this.echoDecodes.size > 0\n || hasPendingCanvas3D()\n || this.images.hasPending();\n }\n\n /**\n * Settle what the last render could not draw acceptably: video frames, echo\n * taps, the 3D runtime, and images — every exact level under `\"exact\"`, only\n * a source drawn with nothing resident under `\"interactive\"`, whose upgrades\n * are {@link warmPendingUpgrades}. Returns whether there was any, so a\n * blocking caller re-renders only when something changed.\n */\n override async warmPendingDecodes(): Promise<boolean> {\n const [video, images] = await Promise.all([this.warmVideo(), this.images.warm()]);\n return video || images;\n }\n\n override hasPendingUpgrades(): boolean {\n return this.images.hasUpgrades();\n }\n\n override warmPendingUpgrades(): Promise<boolean> {\n return this.images.warmUpgrades();\n }\n\n /** @deprecated Use {@link warmPendingDecodes}. */\n override warmPendingVideo(): Promise<boolean> {\n return this.warmPendingDecodes();\n }\n\n /** Resident decode memory, for tests and the e2e memory script. */\n _decodeStats(): {\n images: ReturnType<ImageLevelCache[\"stats\"]>;\n video: { sessions: number; windowFrames: number; echoFrames: number; frameBytes: number };\n } {\n let windowFrames = 0;\n let echoFrames = 0;\n let frameBytes = 0;\n const counted = new Set<ImageBitmap>();\n const count = (frames: Map<number, DecodedVideoFrame>) => {\n for (const { bitmap } of frames.values()) {\n if (counted.has(bitmap)) continue;\n counted.add(bitmap);\n frameBytes += (bitmap.width ?? 0) * (bitmap.height ?? 0) * 4;\n }\n };\n for (const frames of this.videoFrames.values()) { windowFrames += frames.size; count(frames); }\n for (const frames of this.videoEchoFrames.values()) { echoFrames += frames.size; count(frames); }\n return {\n images: this.images.stats(),\n video: { sessions: this.videoSessions.size, windowFrames, echoFrames, frameBytes },\n };\n }\n\n // ─── Image ───────────────────────────────────────────────────────────────\n\n /**\n * Make `src` drawable: decode its first level. Which level that is follows the\n * policy — see `ImageLevelCache.load`. Every later level follows the\n * footprints the draws report.\n */\n async loadImage(src: string): Promise<void> {\n await this.images.load(src);\n }\n\n /** GPU-resident image for `src` at the level this draw needs, or null until it has loaded. */\n getCKImage(src: string, footprint?: number): CKImage | null {\n const level = this.images.select(src, footprint);\n if (!level) return null;\n level.gpu ??= this.makeCKImageFromPixels(level.pixels, level.width, level.height);\n return level.gpu;\n }\n\n /**\n * Decoded RGBA8888 pixels for `src` at the level this draw needs, or null\n * until it has loaded. The same object comes back for as long as that level\n * is resident, which is what the 3D texture cache keys its uploads on.\n */\n getImagePixels(src: string, footprint?: number): { pixels: Uint8Array; width: number; height: number } | null {\n return this.images.select(src, footprint);\n }\n\n getImageSize(src: string): PixelSize | null {\n return this.images.intrinsicSize(src) ?? this.catalogImageSize(src);\n }\n\n private catalogImageSize(src: string): PixelSize | null {\n try {\n const meta = this.catalog.getImageMeta(src);\n return meta.width > 0 && meta.height > 0 ? { width: meta.width, height: meta.height } : null;\n } catch {\n return null;\n }\n }\n\n /**\n * Decode one level of `src`.\n *\n * A raster decodes from its kept compressed bytes, resized by the browser's\n * own high-quality scaler; with no manifest size it is decoded once at\n * natural size to learn it. An SVG is rasterized from its kept `<img>` at\n * any level, since it has no resolution of its own to cap at.\n */\n private async decodeImage(\n src: string,\n chooseEdge: (intrinsic: PixelSize, vector: boolean) => number,\n ): Promise<DecodedImage & { edge: number }> {\n const url = this.assetUrl(src, \"image\");\n if (isSvgSrc(url)) {\n const svg = await this.svgSource(src, url);\n const intrinsic = svg.natural!;\n const edge = chooseEdge(intrinsic, true);\n const size = levelSize(edge, intrinsic);\n const canvas = new OffscreenCanvas(size.width, size.height);\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) throw new Error(`loadImage(${src}): could not get 2d context`);\n ctx.drawImage(svg.svg!, 0, 0, size.width, size.height);\n return { pixels: pixelsOf(ctx.getImageData(0, 0, size.width, size.height)), ...size, intrinsic, vector: true, edge };\n }\n\n const blob = await this.rasterSource(src, url);\n let intrinsic = this.catalogImageSize(src);\n let full: ImageBitmap | null = null;\n if (!intrinsic) {\n full = await createImageBitmap(blob);\n intrinsic = { width: full.width, height: full.height };\n }\n const edge = chooseEdge(intrinsic, false);\n const natural = edge >= levelCap(intrinsic, false)\n && Math.max(intrinsic.width, intrinsic.height) <= MAX_IMAGE_DECODE_EDGE;\n\n let bitmap: ImageBitmap;\n if (natural) {\n bitmap = full ?? await createImageBitmap(blob);\n } else {\n const size = levelSize(edge, intrinsic);\n try {\n bitmap = await createImageBitmap(full ?? blob, {\n resizeWidth: size.width,\n resizeHeight: size.height,\n resizeQuality: \"high\",\n });\n } finally {\n full?.close();\n }\n }\n\n try {\n const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) throw new Error(`loadImage(${src}): could not get 2d context`);\n ctx.drawImage(bitmap, 0, 0);\n return {\n pixels: pixelsOf(ctx.getImageData(0, 0, bitmap.width, bitmap.height)),\n width: bitmap.width,\n height: bitmap.height,\n intrinsic,\n vector: false,\n edge,\n };\n } finally {\n bitmap.close();\n }\n }\n\n private async rasterSource(src: string, url: string): Promise<Blob> {\n const kept = this.imageSources.get(src);\n if (kept?.blob) return kept.blob;\n const blob = await this.fetchBlob(url);\n this.imageSources.set(src, { blob, bytes: blob.size });\n return blob;\n }\n\n /**\n * Decodes an SVG through an `HTMLImageElement`, which every browser\n * supports — `createImageBitmap` can't decode SVG reliably (Chrome throws on\n * an SVG Blob). From a data URL rather than an object URL so a missing xmlns\n * or external ref can't taint the image and fail the readback.\n */\n private async svgSource(src: string, url: string): Promise<ImageSource> {\n const kept = this.imageSources.get(src);\n if (kept?.svg && kept.natural) return kept;\n const text = await (await this.fetchBlob(url)).text();\n const img = new Image();\n img.decoding = \"sync\";\n await new Promise<void>((resolve, reject) => {\n img.onload = () => resolve();\n img.onerror = () => reject(new Error(`loadImage(${src}): failed to decode SVG`));\n img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(text)}`;\n });\n // 300 is the CSS default replaced-element size, which is what a browser\n // itself gives an SVG with no intrinsic dimensions.\n const natural = {\n width: img.naturalWidth > 0 ? img.naturalWidth : 300,\n height: img.naturalHeight > 0 ? img.naturalHeight : 300,\n };\n const source: ImageSource = { svg: img, natural, bytes: text.length };\n this.imageSources.set(src, source);\n return source;\n }\n\n /** Long edge of the draw surface in device px, or the viewport before one is attached. */\n private surfaceEdge(): number {\n const surface = this.surface as { width?: () => number; height?: () => number } | null;\n if (surface && typeof surface.width === \"function\" && typeof surface.height === \"function\") {\n return Math.max(surface.width(), surface.height());\n }\n return Math.max(this.viewport.width, this.viewport.height);\n }\n\n /**\n * The compressed bytes for `src`, from the host's local store if it has\n * them and from the network otherwise. Every byte-reading path goes through\n * this, so a source is local for all of images, video, audio and fonts or\n * for none of them.\n */\n private async fetchBlob(src: string): Promise<Blob> {\n const local = await localAssetBytes(src);\n if (local) return local;\n return (await fetch(src)).blob();\n }\n\n /**\n * The address `src` is fetched from.\n *\n * A manifest key and the URL its bytes live at are the same string only\n * while the host keys its manifest by URL; `meta.src` is the address. An\n * undescribed source falls back to itself. `media` is audio-then-video\n * because a video's own soundtrack is requested under the video's key.\n */\n private assetUrl(src: string, kind: \"image\" | \"video\" | \"media\"): string {\n const lookup = ASSET_URL_LOOKUPS[kind];\n for (const read of lookup) {\n try {\n const found = read(this.catalog, src).src;\n if (found) return found;\n } catch {\n // Undescribed in this bucket; try the next, then `src` itself.\n }\n }\n return src;\n }\n\n // ─── 3D compositing ──────────────────────────────────────────────────────\n\n /** Persistent CanvasKit texture per 3D slot, so a 60 fps 3D scene doesn't allocate a texture a frame. */\n private canvas3DTextures = new Map<string, CKImage>();\n\n /**\n * Upload a 3D renderer's canvas into a GPU-resident CanvasKit image, creating\n * the texture on first use and updating it in place afterwards.\n *\n * **The source arrives unpremultiplied, even though the canvas is not.**\n * Uploading a canvas *as a texture source* goes through the browser's unpack\n * pipeline, where `UNPACK_PREMULTIPLY_ALPHA_WEBGL` is false by default, so\n * what reaches Skia is straight colour. Declaring it `Premul` made Skia\n * composite additively — invisible at full alpha, and read as `opacity`\n * being ignored on a translucent surface. `packages/e2e` has a probe in a\n * colour that separates the two.\n *\n * The returned image is owned by this adapter (keyed by slot): it must NOT\n * be deleted after the draw, or the next frame loses its texture.\n */\n upload3DFrame(\n key: string,\n // In this backend always an HTMLCanvasElement | OffscreenCanvas | ImageBitmap;\n // widened to the seam's opaque handle so skia-render never names a DOM type.\n source: SkiaTextureSource,\n width: number,\n height: number,\n ): CKImage | null {\n const surface = this.surface;\n if (!surface) return null;\n\n const info = {\n width,\n height,\n alphaType: this.canvasKit.AlphaType.Unpremul,\n colorType: this.canvasKit.ColorType.RGBA_8888,\n colorSpace: this.canvasKit.ColorSpace.SRGB,\n };\n\n let image = this.canvas3DTextures.get(key);\n\n // The buffer can grow (see the renderer's size quantisation); a texture is\n // fixed-size, so a size change needs a fresh one.\n if (image && (image.width() !== width || image.height() !== height)) {\n image.delete();\n this.canvas3DTextures.delete(key);\n image = undefined;\n }\n\n if (!image) {\n // CanvasKit's TextureSource type omits canvas elements, though the\n // underlying texImage2D upload accepts them.\n const made = surface.makeImageFromTextureSource(source as never, info, false);\n if (!made) return null;\n this.canvas3DTextures.set(key, made);\n return made;\n }\n\n surface.updateTextureFromSource(image, source as never, false);\n return image;\n }\n\n /** Release a 3D node's texture — called when its node is swept. */\n release3DTexture(key: string): void {\n this.canvas3DTextures.get(key)?.delete();\n this.canvas3DTextures.delete(key);\n }\n\n // ─── Render pass ─────────────────────────────────────────────────────────\n\n /**\n * Receive the GPU surface so decoded video frames can upload straight to\n * texture. A texture-backed image is only valid for the surface that made it,\n * so swapping surfaces drops every one; they are recreated on the next frame.\n * Image levels are raster images and survive.\n */\n setSurface(surface: Surface | null): void {\n if (surface === this.surface) return;\n for (const session of this.videoSessions.values()) {\n session.textureImage?.delete();\n session.textureImage = null;\n session.uploadedTs = null;\n session.uploadedBitmap = null;\n }\n this.clearVideoAltSlots();\n for (const image of this.canvas3DTextures.values()) image.delete();\n this.canvas3DTextures.clear();\n\n this.surface = surface;\n }\n\n /**\n * Toggle live-playback mode. While playing, the adapter prefetches a window\n * ahead; when paused it decodes only the exact frame the render needs, so\n * pausing immediately quiesces.\n */\n setPlaying(playing: boolean): void {\n this.playing = playing;\n }\n\n /** Start a render pass: forget which timestamp each clip's texture was claimed for. */\n beginRenderPass(): void {\n this.videoFrameClaims.clear();\n this.images.beginPass();\n }\n\n /**\n * End a render pass: every draw has reported its footprint, so decide level\n * changes now rather than chasing each draw.\n */\n endRenderPass(): void {\n this.images.endPass();\n const now = performance.now();\n for (const [src, session] of this.videoSessions) {\n const moved = session.levels?.endPass(this.decodePolicy, this.playing, now) ?? false;\n if (!moved) continue;\n this.videoDemand.set(src, session.levels.level);\n const size = levelSize(session.levels.level, session.intrinsic);\n session.width = size.width;\n session.height = size.height;\n // What this pass drew is now at the wrong level: queue the exact\n // frames again so a settling caller lands them at the new one.\n const claims = this.videoFrameClaims.get(src) ?? [];\n claims.forEach((key, index) => {\n const ts = key * session.frameStep;\n if (index === 0) {\n // A miss already queued the time it asked for; the claim\n // only records the fallback frame that was painted.\n if (!this.pendingVideoFrames.has(src)) this.pendingVideoFrames.set(src, ts);\n } else {\n let set = this.pendingEchoFrames.get(src);\n if (!set) { set = new Set(); this.pendingEchoFrames.set(src, set); }\n set.add(ts);\n }\n });\n if (this.playing) this.driveSequentialDecode(src, this.videoPlayhead.get(src) ?? 0);\n }\n }\n\n // ─── Video ───────────────────────────────────────────────────────────────\n\n /**\n * Open a streaming decode session for `src` (deduped — runs once per clip)\n * and warm the first frame around `trimStart` so the first synchronous render\n * hits cache. The rest streams in as the playhead advances; the level\n * follows the footprints claims report.\n */\n async loadVideo(\n src: string,\n _startFrame: number,\n _endFrame: number,\n trimStart: number = 0,\n _trimEnd?: number,\n ): Promise<void> {\n if (this.videoSessions.has(src)) return;\n\n // A local blob is handed to mediabunny as a `BlobSource` rather than\n // downloaded first: both are random-access, so the streaming decode and\n // the frame window behave identically.\n const url = this.assetUrl(src, \"video\");\n const local = await localAssetBytes(url);\n const input = new Input({\n formats: ALL_FORMATS,\n source: local ? new BlobSource(local) : new UrlSource(url),\n });\n const track = await input.getPrimaryVideoTrack();\n if (!track) {\n input.dispose();\n throw new Error(`loadVideo(${src}): no video track found`);\n }\n\n const sink = new VideoSampleSink(track);\n const durationSec = await input.computeDuration();\n const probe = await this.probeFirstFrame(sink);\n const intrinsic = this.catalogVideoSize(src) ?? await this.trackDisplaySize(track, probe);\n const levels = new VideoLevel(intrinsic, this.decodePolicy, this.videoDemand.get(src), this.surfaceEdge());\n const size = levelSize(levels.level, intrinsic);\n\n this.videoSessions.set(src, {\n input, sink, durationSec, frameStep: probe.frameStep,\n width: size.width, height: size.height, intrinsic, levels, canvas: null,\n textureImage: null, uploadedTs: null, decoding: false,\n });\n this.videoFrames.set(src, new Map());\n\n // Warm the entry frame so the first render after load is never empty.\n await this.decodeAt(src, trimStart);\n }\n\n getVideoSize(src: string): PixelSize | null {\n return this.videoSessions.get(src)?.intrinsic ?? this.catalogVideoSize(src);\n }\n\n private catalogVideoSize(src: string): PixelSize | null {\n try {\n const meta = this.catalog.getVideoMeta(src);\n return meta.width > 0 && meta.height > 0 ? { width: meta.width, height: meta.height } : null;\n } catch {\n return null;\n }\n }\n\n private async trackDisplaySize(track: InputVideoTrack, probe: { width: number; height: number }): Promise<PixelSize> {\n try {\n const width = await track.getDisplayWidth();\n const height = await track.getDisplayHeight();\n if (width > 0 && height > 0) return { width, height };\n } catch {\n // fall through to the probed sample\n }\n return { width: Math.max(1, probe.width), height: Math.max(1, probe.height) };\n }\n\n /**\n * Synchronously return the GPU image for the frame at `timestamp` (source\n * seconds), uploaded in place into the session's one texture. On a miss it\n * records the exact frame for a blocking re-render and, while playing, primes\n * the sequential decoder; it returns the nearest decoded frame so the picture\n * never goes blank mid-stream.\n *\n * A *drawing* caller should go through {@link claimVideoFrame}, which owns\n * the rule for one frame needing two different times of the same clip.\n */\n getVideoFrame(src: string, timestamp: number): CKImage | null {\n const session = this.videoSessions.get(src);\n const frames = this.videoFrames.get(src);\n if (!session || !frames || !this.surface) return null;\n if (!Number.isFinite(timestamp)) timestamp = 0;\n this.videoPlayhead.set(src, timestamp);\n\n const frame = this.nearestDecoded(frames, timestamp, session.frameStep);\n const exactKey = this.quantizeTs(timestamp, session.frameStep);\n const haveExact = !!frame\n && this.quantizeTs(frame.timestamp, session.frameStep) === exactKey\n && this.accepts(session, frame);\n\n if (!haveExact) {\n this.pendingVideoFrames.set(src, timestamp);\n if (this.playing) this.driveSequentialDecode(src, timestamp);\n } else if (this.playing) {\n this.driveSequentialDecode(src, timestamp);\n }\n\n if (!frame) return null;\n return this.uploadFrame(src, session, frame);\n }\n\n /**\n * The image to paint `src` at `timestamp` with, for one draw in the current\n * render pass. **This, not {@link getVideoFrame}, is what a fill should call.**\n *\n * A session's texture is updated in place and Skia doesn't resolve a draw\n * until the surface flushes, so two draws of the same clip at different times\n * would both sample whatever was uploaded last. Each distinct timestamp a\n * pass asks for therefore gets its own texture: the first claim takes the\n * session's, the rest take {@link videoAltSlots} by claim order. Every\n * returned image is adapter-owned.\n */\n claimVideoFrame(src: string, timestamp: number, footprint?: number): CKImage | null {\n const session = this.videoSessions.get(src);\n if (!session || !this.surface) return null;\n if (!Number.isFinite(timestamp)) timestamp = 0;\n session.levels?.note(footprint);\n\n const key = this.quantizeTs(timestamp, session.frameStep);\n let claims = this.videoFrameClaims.get(src);\n if (!claims) { claims = []; this.videoFrameClaims.set(src, claims); }\n\n const claimed = claims.indexOf(key);\n if (claimed === 0) return session.textureImage;\n if (claimed > 0) return this.videoAltSlots.get(src)?.[claimed - 1]?.image ?? null;\n\n if (claims.length === 0) {\n const image = this.getVideoFrame(src, timestamp);\n // Record what the texture actually holds, not what was asked for: a\n // miss paints the nearest decoded frame, and a later draw wanting\n // *that* frame can then share it.\n if (image) claims.push(session.uploadedTs ?? key);\n return image;\n }\n\n const slot = Math.min(claims.length - 1, WebStorageAdapter.ALT_SLOT_LIMIT - 1);\n const image = this.uploadAltFrame(src, session, timestamp, slot);\n if (image) claims.push(key);\n return image;\n }\n\n /** Free every alt-slot texture (surface swap, teardown). */\n private clearVideoAltSlots(): void {\n for (const slots of this.videoAltSlots.values()) {\n for (const slot of slots) slot.image?.delete();\n }\n this.videoAltSlots.clear();\n }\n\n /** Upload the frame for a non-primary timestamp into its slot — see {@link claimVideoFrame}. */\n private uploadAltFrame(\n src: string,\n session: VideoSession,\n timestamp: number,\n slotIndex: number,\n ): CKImage | null {\n const surface = this.surface;\n if (!surface) return null;\n const frame = this.decodedFrameFor(src, session, timestamp);\n if (!frame) return null;\n\n let slots = this.videoAltSlots.get(src);\n if (!slots) { slots = []; this.videoAltSlots.set(src, slots); }\n let slot = slots[slotIndex];\n if (!slot) { slot = { image: null, uploadedTs: null }; slots[slotIndex] = slot; }\n\n const key = this.quantizeTs(frame.timestamp, session.frameStep);\n if (slot.image && slot.uploadedTs === key && (slot.bitmap === undefined || slot.bitmap === frame.bitmap)) {\n return slot.image;\n }\n this.uploadInto(slot, frame, session);\n slot.uploadedTs = slot.image ? key : null;\n return slot.image;\n }\n\n /**\n * Upload `frame` into `slot`'s texture — in place when the size held, fresh\n * when a level change resized the frames, since a texture is fixed-size.\n */\n private uploadInto(slot: VideoTextureSlot, frame: DecodedVideoFrame, session: VideoSession): void {\n const surface = this.surface!;\n const width = frame.bitmap.width || session.width;\n const height = frame.bitmap.height || session.height;\n if (slot.image && (slot.width !== width || slot.height !== height)) {\n slot.image.delete();\n slot.image = null;\n }\n if (!slot.image) {\n slot.image = surface.makeImageFromTextureSource(frame.bitmap, {\n width,\n height,\n alphaType: this.canvasKit.AlphaType.Unpremul,\n colorType: this.canvasKit.ColorType.RGBA_8888,\n colorSpace: this.canvasKit.ColorSpace.SRGB,\n });\n } else {\n surface.updateTextureFromSource(slot.image, frame.bitmap);\n }\n slot.width = width;\n slot.height = height;\n slot.bitmap = slot.image ? frame.bitmap : null;\n }\n\n /**\n * The decoded frame to show a non-primary playhead at `timestamp`: the exact\n * one when it's warm at the clip's level, otherwise the nearest decoded, with\n * the exact one queued. Null only when nothing at all is decoded yet.\n */\n private decodedFrameFor(\n src: string,\n session: VideoSession,\n timestamp: number,\n ): DecodedVideoFrame | null {\n const step = session.frameStep;\n const clamped = Math.max(0, Math.min(timestamp, session.durationSec));\n const accept = (f: DecodedVideoFrame) => this.accepts(session, f);\n // The echo cache first — its entries survive the playhead window's\n // eviction, which is centred on the *primary* head.\n const echo = this.videoEchoFrames.get(src);\n const window = this.videoFrames.get(src);\n const exact =\n this.nearestWithin(echo, clamped, step, accept) ??\n this.nearestWithin(window, clamped, step, accept);\n if (exact) return exact;\n\n let set = this.pendingEchoFrames.get(src);\n if (!set) { set = new Set(); this.pendingEchoFrames.set(src, set); }\n set.add(clamped);\n // While playing there is no blocking caller to drain that set, and the\n // sequential prefetch only runs ahead of the primary head.\n if (this.playing) void this.decodeEchoFrameAt(src, clamped);\n\n const nearEcho = echo ? this.nearestDecoded(echo, clamped, step) : null;\n const nearWindow = window ? this.nearestDecoded(window, clamped, step) : null;\n if (!nearEcho) return nearWindow;\n if (!nearWindow) return nearEcho;\n return Math.abs(nearEcho.timestamp - clamped) <= Math.abs(nearWindow.timestamp - clamped)\n ? nearEcho\n : nearWindow;\n }\n\n /**\n * The decoded length of `src` in seconds, or `0` when its session hasn't\n * opened yet. The *container's* duration rather than the manifest's, so\n * looping still works for a source whose manifest probe couldn't read one.\n */\n getVideoDuration(src: string): number {\n return this.videoSessions.get(src)?.durationSec ?? 0;\n }\n\n /**\n * An INDEPENDENT, caller-owned image for a past `timestamp` — the Echo\n * filter needs several frames resident at once, which the shared session\n * texture can't give. The caller must push it to `transientImages`.\n *\n * On a miss it records the timestamp for {@link warmPendingDecodes} and\n * returns null, so the tap is skipped this pass and a blocking caller lands it.\n */\n getVideoFrameImage(src: string, timestamp: number, footprint?: number): CKImage | null {\n const session = this.videoSessions.get(src);\n if (!session || !this.surface || !Number.isFinite(timestamp)) return null;\n session.levels?.note(footprint);\n\n const clamped = Math.max(0, Math.min(timestamp, session.durationSec));\n const step = session.frameStep;\n const accept = (f: DecodedVideoFrame) => this.accepts(session, f);\n const frame =\n this.nearestWithin(this.videoEchoFrames.get(src), clamped, step, accept) ??\n this.nearestWithin(this.videoFrames.get(src), clamped, step, accept);\n if (!frame) {\n let set = this.pendingEchoFrames.get(src);\n if (!set) { set = new Set(); this.pendingEchoFrames.set(src, set); }\n set.add(clamped);\n return null;\n }\n\n return this.surface.makeImageFromTextureSource(frame.bitmap, {\n width: frame.bitmap.width || session.width,\n height: frame.bitmap.height || session.height,\n alphaType: this.canvasKit.AlphaType.Unpremul,\n colorType: this.canvasKit.ColorType.RGBA_8888,\n colorSpace: this.canvasKit.ColorSpace.SRGB,\n });\n }\n\n /**\n * Upload `frame`'s bitmap into the session's persistent texture and return it.\n * No upload when that bitmap is already resident, so a parked playhead costs\n * nothing per render.\n */\n private uploadFrame(src: string, session: VideoSession, frame: DecodedVideoFrame): CKImage | null {\n if (!this.surface) return null;\n const key = this.quantizeTs(frame.timestamp, session.frameStep);\n if (session.textureImage && session.uploadedTs === key\n && (session.uploadedBitmap == null || session.uploadedBitmap === frame.bitmap)) {\n return session.textureImage;\n }\n\n const slot: VideoTextureSlot = {\n image: session.textureImage,\n uploadedTs: session.uploadedTs,\n width: session.textureWidth,\n height: session.textureHeight,\n };\n this.uploadInto(slot, frame, session);\n session.textureImage = slot.image;\n session.textureWidth = slot.width;\n session.textureHeight = slot.height;\n session.uploadedBitmap = slot.bitmap;\n session.uploadedTs = session.textureImage ? key : null;\n return session.textureImage;\n }\n\n /** Whether `frame` counts as the frame at the clip's current level. */\n private accepts(session: VideoSession, frame: DecodedVideoFrame): boolean {\n return session.levels ? session.levels.accepts(frame.level, this.decodePolicy) : true;\n }\n\n /** Decode every exact video frame and echo tap a prior render asked for, plus the 3D runtime. */\n private async warmVideo(): Promise<boolean> {\n const pending = [...this.pendingVideoFrames];\n this.pendingVideoFrames.clear();\n\n const echo = [...this.pendingEchoFrames].flatMap(\n ([src, set]) => [...set].map((ts) => [src, ts] as [string, number]),\n );\n this.pendingEchoFrames.clear();\n\n // Drained before the early return below so a 3D-only scene, which queues\n // no video work at all, still gets its runtime loaded.\n const warmed3D = await warmPendingCanvas3D();\n\n const inFlight = [...this.echoDecodes.values()];\n if (pending.length === 0 && echo.length === 0 && inFlight.length === 0) return warmed3D;\n await Promise.all([\n ...pending.map(([src, ts]) => this.decodeAt(src, ts)),\n ...echo.map(([src, ts]) => this.decodeEchoFrameAt(src, ts)),\n ...inFlight,\n ]);\n return true;\n }\n\n /**\n * Sequentially decode forward from `timestamp` to fill the window ahead, using\n * mediabunny's monotonic pipeline — far cheaper than a random seek per frame.\n * At most one pass runs per src; it stops as soon as playback pauses or the\n * playhead jumps away. Each sample is sized as it is snapshotted, so a level\n * change mid-pass applies to the next frame without restarting the stream.\n */\n private driveSequentialDecode(src: string, timestamp: number): void {\n const session = this.videoSessions.get(src);\n if (!session || session.decoding || !session.sink) return;\n if (!this.videoFrames.get(src)) return;\n\n const step = session.frameStep;\n const { forward } = this.windowFrames(session);\n const end = Math.min(session.durationSec, timestamp + forward * step);\n if (timestamp >= end) return;\n\n session.decoding = true;\n void (async () => {\n try {\n for await (const sample of session.sink.samples(timestamp, end + step)) {\n const store = this.videoFrames.get(src);\n if (this.disposed || !store) { sample.close(); break; }\n const key = this.quantizeTs(sample.timestamp, step);\n const existing = store.get(key);\n if (existing && this.accepts(session, existing)) {\n sample.close();\n } else {\n this.storeFrame(src, store, key, await this.snapshot(session, sample));\n }\n const head = this.videoPlayhead.get(src) ?? timestamp;\n if (!this.playing || head < timestamp - step || head > end) break;\n }\n this.evictVideoWindow(src, this.videoPlayhead.get(src) ?? timestamp, step);\n } catch (err) {\n if (!this.disposed) console.error(`[WebStorageAdapter] sequential decode failed for ${src}:`, err);\n } finally {\n session.decoding = false;\n }\n })();\n }\n\n /**\n * Decode the single frame containing `timestampSec` (random access) and cache\n * its bitmap — for cold warms, where streaming isn't appropriate. Idempotent\n * per quantized ts at the clip's current level.\n */\n private async decodeAt(src: string, timestampSec: number): Promise<void> {\n const session = this.videoSessions.get(src);\n if (!session || !Number.isFinite(timestampSec)) return;\n const clamped = Math.max(0, Math.min(timestampSec, session.durationSec));\n const key = this.quantizeTs(clamped, session.frameStep);\n const store = this.videoFrames.get(src);\n const existing = store?.get(key);\n if (!store || (existing && this.accepts(session, existing))) return;\n\n try {\n const sample = await session.sink.getSample(clamped);\n if (!sample) return;\n if (this.disposed) { sample.close(); return; }\n const frame = await this.snapshot(session, sample);\n const dst = this.videoFrames.get(src);\n if (!dst) { frame.bitmap.close(); return; }\n this.storeFrame(src, dst, this.quantizeTs(frame.timestamp, session.frameStep), frame);\n this.evictVideoWindow(src, clamped, session.frameStep);\n } catch (err) {\n if (!this.disposed) console.error(`[WebStorageAdapter] video decode failed for ${src}@${clamped}:`, err);\n }\n }\n\n /** Put `frame` in the window, closing what it replaces unless the echo cache shares it. */\n private storeFrame(src: string, store: Map<number, DecodedVideoFrame>, key: number, frame: DecodedVideoFrame): void {\n const session = this.videoSessions.get(src);\n const existing = store.get(key);\n if (existing && session && this.accepts(session, existing) && !this.accepts(session, frame)) {\n frame.bitmap.close();\n return;\n }\n if (existing && existing !== frame && this.videoEchoFrames.get(src)?.get(key) !== existing) {\n existing.bitmap.close();\n }\n store.set(key, frame);\n }\n\n /**\n * Decode a single past frame into the dedicated {@link videoEchoFrames} cache.\n * Like {@link decodeAt} but it does NOT window-evict — echo taps reach outside\n * that window on purpose. Concurrent calls for the same frame join one decode.\n */\n private decodeEchoFrameAt(src: string, timestampSec: number): Promise<void> {\n const session = this.videoSessions.get(src);\n if (!session || !Number.isFinite(timestampSec)) return Promise.resolve();\n const clamped = Math.max(0, Math.min(timestampSec, session.durationSec));\n const key = this.quantizeTs(clamped, session.frameStep);\n const cached = this.videoEchoFrames.get(src)?.get(key);\n if (cached && this.accepts(session, cached)) return Promise.resolve();\n\n const id = `${src}#${key}`;\n const inFlight = this.echoDecodes.get(id);\n if (inFlight) return inFlight;\n const decode = this.decodeEchoFrameNow(src, session, clamped, key)\n .finally(() => this.echoDecodes.delete(id));\n this.echoDecodes.set(id, decode);\n return decode;\n }\n\n /** {@link decodeEchoFrameAt}'s body, past the dedup gate. */\n private async decodeEchoFrameNow(\n src: string,\n session: VideoSession,\n clamped: number,\n key: number,\n ): Promise<void> {\n let store = this.videoEchoFrames.get(src);\n const windowed = this.videoFrames.get(src)?.get(key);\n\n try {\n if (!store) { store = new Map(); this.videoEchoFrames.set(src, store); }\n if (windowed && this.accepts(session, windowed)) {\n this.replaceEcho(src, store, key, windowed);\n } else {\n const sample = await session.sink.getSample(clamped);\n if (!sample) return;\n if (this.disposed) { sample.close(); return; }\n const frame = await this.snapshot(session, sample);\n store = this.videoEchoFrames.get(src);\n if (!store) { frame.bitmap.close(); return; }\n this.replaceEcho(src, store, this.quantizeTs(frame.timestamp, session.frameStep), frame);\n }\n this.trimEchoCache(src);\n } catch (err) {\n if (!this.disposed) console.error(`[WebStorageAdapter] echo decode failed for ${src}@${clamped}:`, err);\n }\n }\n\n private replaceEcho(src: string, store: Map<number, DecodedVideoFrame>, key: number, frame: DecodedVideoFrame): void {\n const existing = store.get(key);\n if (existing && existing !== frame && this.videoFrames.get(src)?.get(key) !== existing) {\n existing.bitmap.close();\n }\n store.set(key, frame);\n }\n\n /** Bound the echo cache to ECHO_CACHE_LIMIT frames per src, dropping oldest-inserted first. */\n private trimEchoCache(src: string): void {\n const store = this.videoEchoFrames.get(src);\n if (!store) return;\n while (store.size > WebStorageAdapter.ECHO_CACHE_LIMIT) {\n const oldest = store.keys().next().value as number | undefined;\n if (oldest === undefined) break;\n const frame = store.get(oldest);\n // Only close the bitmap if it isn't shared with the live playback window.\n if (frame && this.videoFrames.get(src)?.get(oldest) !== frame) frame.bitmap.close();\n store.delete(oldest);\n }\n }\n\n /**\n * Resize `sample` to the clip's level and snapshot it to an immutable bitmap,\n * closing the sample. Drawn and snapshotted in one synchronous step, so the\n * pooled canvas can be shared by concurrent decodes of the same clip.\n */\n private snapshot(session: VideoSession, sample: VideoSample): Promise<DecodedVideoFrame> {\n const level = session.levels.level;\n const { width, height } = levelSize(level, session.intrinsic);\n try {\n let canvas = session.canvas;\n if (!canvas || canvas.width !== width || canvas.height !== height) {\n canvas = new OffscreenCanvas(width, height);\n session.canvas = canvas;\n }\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"video snapshot: could not get 2d context\");\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = \"high\";\n ctx.clearRect(0, 0, width, height);\n sample.drawWithFit(ctx, { fit: \"fill\" });\n const bitmap = createImageBitmap(canvas);\n const timestamp = sample.timestamp;\n return bitmap.then((b) => ({ timestamp, bitmap: b, level }));\n } finally {\n sample.close();\n }\n }\n\n private windowFrames(session: VideoSession | undefined): { forward: number; back: number } {\n return videoWindowFrames(session ? { width: session.width, height: session.height } : null);\n }\n\n /** Drop decoded frames (closing their bitmaps) outside the window around `timestamp` (source seconds). */\n private evictVideoWindow(src: string, timestamp: number, step: number): void {\n const frames = this.videoFrames.get(src);\n if (!frames) return;\n const { forward, back } = this.windowFrames(this.videoSessions.get(src));\n const lo = timestamp - back * step;\n const hi = timestamp + forward * step;\n const echo = this.videoEchoFrames.get(src);\n for (const [key, frame] of frames) {\n if (frame.timestamp < lo || frame.timestamp > hi) {\n if (echo?.get(key) !== frame) frame.bitmap.close();\n frames.delete(key);\n }\n }\n }\n\n /**\n * Closest decoded frame to `timestamp`, or null if none are decoded yet — at\n * any distance, so a not-yet-warm playhead paints the closest frame.\n */\n private nearestDecoded(\n frames: Map<number, DecodedVideoFrame>,\n timestamp: number,\n step: number,\n ): DecodedVideoFrame | null {\n const exact = frames.get(this.quantizeTs(timestamp, step));\n if (exact) return exact;\n let best: DecodedVideoFrame | null = null;\n let bestDist = Infinity;\n for (const frame of frames.values()) {\n const dist = Math.abs(frame.timestamp - timestamp);\n if (dist < bestDist) { bestDist = dist; best = frame; }\n }\n return best;\n }\n\n /** Quantize a source timestamp to a stable integer ring key. */\n private quantizeTs(timestamp: number, step: number): number {\n return Math.round(timestamp / step);\n }\n\n /**\n * The frame in `store` closest to `timestamp`, but only within one frame step\n * (so a request matches the sample whose grid-aligned timestamp quantized to\n * an adjacent key, without returning a clearly wrong frame).\n */\n private nearestWithin(\n store: Map<number, DecodedVideoFrame> | undefined,\n timestamp: number,\n step: number,\n accept?: (frame: DecodedVideoFrame) => boolean,\n ): DecodedVideoFrame | null {\n if (!store || store.size === 0) return null;\n let best: DecodedVideoFrame | null = null;\n let bestDist = Infinity;\n for (const frame of store.values()) {\n if (accept && !accept(frame)) continue;\n const dist = Math.abs(frame.timestamp - timestamp);\n if (dist < bestDist) { bestDist = dist; best = frame; }\n }\n return best && bestDist <= step ? best : null;\n }\n\n /** The first sample's duration and size; ~30fps when the track won't say. */\n private async probeFirstFrame(sink: VideoSampleSink): Promise<{ frameStep: number; width: number; height: number }> {\n try {\n let first = await sink.getSample(0);\n if (!first) {\n for await (const sample of sink.samples()) { first = sample; break; }\n }\n if (first) {\n const probe = {\n frameStep: first.duration > 0 ? first.duration : 1 / 30,\n width: first.displayWidth,\n height: first.displayHeight,\n };\n first.close();\n return probe;\n }\n } catch {\n // fall through to defaults\n }\n return { frameStep: 1 / 30, width: 1, height: 1 };\n }\n\n private makeCKImageFromPixels(pixels: Uint8Array, width: number, height: number): CKImage | null {\n return this.canvasKit.MakeImage(\n {\n width,\n height,\n alphaType: this.canvasKit.AlphaType.Unpremul,\n colorType: this.canvasKit.ColorType.RGBA_8888,\n colorSpace: this.canvasKit.ColorSpace.SRGB,\n },\n pixels,\n 4 * width,\n );\n }\n\n // ─── Audio ───────────────────────────────────────────────────────────────\n\n /** Fetches and decodes `src` into a Web Audio `AudioBuffer`, cached for {@link getAudioBuffer}. No-op if already cached. */\n async loadAudio(\n src: string,\n _startFrame: number,\n _endFrame: number,\n _trimStart: number = 0,\n _trimEnd?: number,\n ): Promise<void> {\n if (this.audioBuffers.has(src)) return;\n if (!this.audioCtx) this.audioCtx = new AudioContext();\n\n const arrayBuffer = await (await this.fetchBlob(this.assetUrl(src, \"media\"))).arrayBuffer();\n const audioBuffer = await this.audioCtx.decodeAudioData(arrayBuffer);\n this.audioBuffers.set(src, audioBuffer);\n }\n\n async fetchAudioData(src: string): Promise<ArrayBuffer> {\n return (await this.fetchBlob(this.assetUrl(src, \"media\"))).arrayBuffer();\n }\n\n getAudioBuffer(src: string): AudioBuffer | null {\n return this.audioBuffers.get(src) ?? null;\n }\n\n // ─── Font ────────────────────────────────────────────────────────────────\n\n /**\n * Registers every weight/slant file for `fontFamily` under the bare family\n * name, once per family, so CanvasKit's matcher can pick the closest file for\n * any requested weight — which is what makes weights tweenable.\n */\n async loadFont(key: string, fontFamily: string, _fontWeight: number): Promise<boolean> {\n if (this.registeredFontFamilies.has(fontFamily)) return true;\n\n const metas = this.catalog.getFontFamilyMetas(fontFamily);\n if (metas.length === 0) {\n // Not an error: an undescribed family shapes against the platform\n // fallback. Warned once per family per catalog, since the caller\n // retries on every `loadAt`.\n if (!this.unknownFontFamilies.has(fontFamily)) {\n this.unknownFontFamilies.add(fontFamily);\n console.warn(`[WebStorageAdapter] No font manifest entry for \"${key}\"; shaping against the fallback face. Add it to the manifest font record.`);\n }\n return false;\n }\n\n // Dedupe by src in case the same file is registered under multiple keys.\n const sources = [...new Set(metas.map(m => m.src))];\n await Promise.all(sources.map(async src => {\n const bytes = await (await this.fetchBlob(src)).arrayBuffer();\n this.fontMgr.registerFont(new Uint8Array(bytes), fontFamily);\n }));\n\n this.registeredFontFamilies.add(fontFamily);\n this.unknownFontFamilies.delete(fontFamily);\n this.fontEpoch++;\n return true;\n }\n\n getFontMgr(): TypefaceFontProvider {\n return this.fontMgr;\n }\n\n /** The shared shaped-text cache (see {@link paragraphCache}). */\n getParagraphCache(): ParagraphShapeCache {\n return this.paragraphCache;\n }\n\n /** Current font-registration epoch, folded into paragraph cache keys. */\n getFontEpoch(): number {\n return this.fontEpoch;\n }\n\n // ─── Lifecycle ───────────────────────────────────────────────────────────\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n\n this.paragraphCache.dispose();\n\n this.images.dispose();\n this.imageSources.clear();\n\n for (const image of this.canvas3DTextures.values()) image.delete();\n this.canvas3DTextures.clear();\n\n // Close window bitmaps, tracking them so shared echo entries aren't\n // double-closed below.\n const closed = new Set<ImageBitmap>();\n for (const frames of this.videoFrames.values()) {\n for (const { bitmap } of frames.values()) { bitmap.close(); closed.add(bitmap); }\n }\n this.videoFrames.clear();\n for (const frames of this.videoEchoFrames.values()) {\n for (const { bitmap } of frames.values()) if (!closed.has(bitmap)) bitmap.close();\n }\n this.videoEchoFrames.clear();\n for (const session of this.videoSessions.values()) {\n session.textureImage?.delete();\n session.input.dispose();\n }\n this.videoSessions.clear();\n this.clearVideoAltSlots();\n this.videoPlayhead.clear();\n this.videoFrameClaims.clear();\n this.pendingVideoFrames.clear();\n this.pendingEchoFrames.clear();\n this.echoDecodes.clear();\n this.surface = null;\n\n this.audioBuffers.clear();\n if (this.audioCtx && this.audioCtx.state !== \"closed\") {\n this.audioCtx.close();\n }\n this.audioCtx = null;\n\n super.dispose();\n }\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type * as THREE from "three";
|
|
2
|
+
import type { RenderedCanvas3D, ThreeModule, Canvas3DRendererHost, Canvas3DRendererSettings } from "@motionscript/skia-render";
|
|
3
|
+
/**
|
|
4
|
+
* Render `scene` through `camera` at the given device-pixel size and return the
|
|
5
|
+
* renderer's canvas for upload.
|
|
6
|
+
*
|
|
7
|
+
* The canvas is shared and reused, so the caller must consume it (upload to a
|
|
8
|
+
* texture) before rendering another node — which the compositor does, since both
|
|
9
|
+
* happen inside one synchronous draw call.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderCanvas3D(three: ThreeModule, key: string, scene: THREE.Scene, camera: THREE.Camera, width: number, height: number, options?: {
|
|
12
|
+
antialias?: boolean;
|
|
13
|
+
}): RenderedCanvas3D;
|
|
14
|
+
/** Apply renderer-level scene settings that live on the renderer, not the scene. */
|
|
15
|
+
export declare function applyRendererSettings(three: ThreeModule, settings: Canvas3DRendererSettings): void;
|
|
16
|
+
/** The live renderer, or null before first use. For environment/PMREM helpers. */
|
|
17
|
+
export declare function activeRenderer(): THREE.WebGLRenderer | null;
|
|
18
|
+
/**
|
|
19
|
+
* Release the shared renderer and its GL context.
|
|
20
|
+
*
|
|
21
|
+
* Called on render-context unmount/dispose. Unlike CanvasKit's context (which is
|
|
22
|
+
* deliberately kept alive because the canvas element outlives an HMR remount),
|
|
23
|
+
* this one owns its own canvas and is safe to drop — it is recreated on the next
|
|
24
|
+
* 3D frame.
|
|
25
|
+
*/
|
|
26
|
+
export declare function disposeSharedRenderer(): void;
|
|
27
|
+
/** Forget a node's buffer size, so a removed node stops pinning a large buffer. */
|
|
28
|
+
export declare function forgetCanvas3DBuffer(key: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* This package's implementation of the renderer seam
|
|
31
|
+
* `@motionscript/skia-render` declares.
|
|
32
|
+
*
|
|
33
|
+
* The reconciler and the 3D backend live in skia-render, which cannot import this
|
|
34
|
+
* module — that would be an upward package dependency. So the renderer is handed
|
|
35
|
+
* over instead, and everything above stays exactly as it was: module-level
|
|
36
|
+
* singletons behind free functions, with this object as the adapter.
|
|
37
|
+
*
|
|
38
|
+
* **Registered from `../index.ts`, deliberately not here.** After the extraction
|
|
39
|
+
* nothing in this package statically imports this module, and the package declares
|
|
40
|
+
* `sideEffects: false` — so a module-scope registration here could legitimately be
|
|
41
|
+
* tree-shaken away, and 3D would silently render nothing at all (`canvas3DBackend()`
|
|
42
|
+
* returns null forever, the warm loop gives up after its three passes, and frames
|
|
43
|
+
* ship with their 2D parts only and no error). It has to be in the barrel every
|
|
44
|
+
* consumer imports, which is the same argument the comment on
|
|
45
|
+
* `registerCanvas3DBackend()` already makes.
|
|
46
|
+
*/
|
|
47
|
+
export declare const webCanvas3DRendererHost: Canvas3DRendererHost;
|
|
48
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/three/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EACR,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EAC3B,MAAM,2BAA2B,CAAC;AAoGnC;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,gBAAgB,CAgBlB;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CACjC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,wBAAwB,GACnC,IAAI,CAeN;AAED,kFAAkF;AAClF,wBAAgB,cAAc,IAAI,KAAK,CAAC,aAAa,GAAG,IAAI,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,uBAAuB,EAAE,oBAMrC,CAAC"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single shared `WebGLRenderer` for every 3D node in the document.
|
|
3
|
+
*
|
|
4
|
+
* One renderer is a requirement, not an optimisation: browsers cap concurrent
|
|
5
|
+
* WebGL contexts at roughly 16 and CanvasKit already owns one, so a renderer per
|
|
6
|
+
* node would start losing contexts on any scene with a handful of 3D nodes. Each
|
|
7
|
+
* node instead renders serially into this one, sized to its own destination, and
|
|
8
|
+
* the result is uploaded before the next node draws.
|
|
9
|
+
*
|
|
10
|
+
* Created lazily on first render so merely importing this module never touches
|
|
11
|
+
* WebGL (safe for SSR and unit tests).
|
|
12
|
+
*/
|
|
13
|
+
let renderer = null;
|
|
14
|
+
let rendererAntialias = true;
|
|
15
|
+
/**
|
|
16
|
+
* Device-pixel buffer size actually in use, per node.
|
|
17
|
+
*
|
|
18
|
+
* `setSize` reallocates the drawing buffer, which is expensive. A node under a
|
|
19
|
+
* `scale` tween changes its derived device size every single frame, so without
|
|
20
|
+
* quantisation it would reallocate 60 times a second and stutter. Sizes are
|
|
21
|
+
* rounded up to {@link SIZE_QUANTUM} and never shrink within a session, letting
|
|
22
|
+
* Skia scale a slightly-oversized image into the destination rect instead.
|
|
23
|
+
*/
|
|
24
|
+
const bufferSizes = new Map();
|
|
25
|
+
const SIZE_QUANTUM = 64;
|
|
26
|
+
/** Conservative cap; the real limit is read from the GL context on first use. */
|
|
27
|
+
let maxTextureSize = 4096;
|
|
28
|
+
function createRenderer(three, antialias) {
|
|
29
|
+
const created = new three.WebGLRenderer({
|
|
30
|
+
antialias,
|
|
31
|
+
// Transparent so the 3D composites over whatever the 2D scene drew below.
|
|
32
|
+
alpha: true,
|
|
33
|
+
// three's default, and what the compositor's `srcIsPremul: true` assumes.
|
|
34
|
+
premultipliedAlpha: true,
|
|
35
|
+
// Keep the buffer readable for the texture upload. The upload happens in
|
|
36
|
+
// the same synchronous task as the render, so this is belt-and-braces
|
|
37
|
+
// rather than strictly required — see the note in the compositor.
|
|
38
|
+
preserveDrawingBuffer: true,
|
|
39
|
+
});
|
|
40
|
+
created.setClearColor(0x000000, 0);
|
|
41
|
+
created.setPixelRatio(1); // sizes are already in device pixels
|
|
42
|
+
maxTextureSize = created.capabilities.maxTextureSize ?? maxTextureSize;
|
|
43
|
+
return created;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The shared renderer, creating it on first call.
|
|
47
|
+
*
|
|
48
|
+
* `antialias` is fixed at context creation, so a later change needs a new
|
|
49
|
+
* context — the renderer is rebuilt when it flips, which is rare (it's a
|
|
50
|
+
* per-node authoring choice, not something to animate).
|
|
51
|
+
*/
|
|
52
|
+
function getRenderer(three, antialias) {
|
|
53
|
+
if (renderer && rendererAntialias !== antialias) {
|
|
54
|
+
renderer.dispose();
|
|
55
|
+
renderer.forceContextLoss();
|
|
56
|
+
renderer = null;
|
|
57
|
+
}
|
|
58
|
+
if (!renderer) {
|
|
59
|
+
renderer = createRenderer(three, antialias);
|
|
60
|
+
rendererAntialias = antialias;
|
|
61
|
+
bufferSizes.clear();
|
|
62
|
+
}
|
|
63
|
+
return renderer;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Round a requested device size up to a stable, GPU-friendly buffer size that
|
|
67
|
+
* never shrinks for this node. See {@link bufferSizes}.
|
|
68
|
+
*/
|
|
69
|
+
function quantizeBuffer(key, width, height) {
|
|
70
|
+
const wanted = {
|
|
71
|
+
width: Math.min(maxTextureSize, Math.max(1, Math.ceil(width / SIZE_QUANTUM) * SIZE_QUANTUM)),
|
|
72
|
+
height: Math.min(maxTextureSize, Math.max(1, Math.ceil(height / SIZE_QUANTUM) * SIZE_QUANTUM)),
|
|
73
|
+
};
|
|
74
|
+
const current = bufferSizes.get(key);
|
|
75
|
+
if (!current) {
|
|
76
|
+
bufferSizes.set(key, wanted);
|
|
77
|
+
return wanted;
|
|
78
|
+
}
|
|
79
|
+
// Grow only. A node that shrinks keeps its larger buffer, so a scale tween
|
|
80
|
+
// reallocates at most once per size step rather than every frame.
|
|
81
|
+
const grown = {
|
|
82
|
+
width: Math.max(current.width, wanted.width),
|
|
83
|
+
height: Math.max(current.height, wanted.height),
|
|
84
|
+
};
|
|
85
|
+
if (grown.width !== current.width || grown.height !== current.height) {
|
|
86
|
+
bufferSizes.set(key, grown);
|
|
87
|
+
}
|
|
88
|
+
return grown;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Render `scene` through `camera` at the given device-pixel size and return the
|
|
92
|
+
* renderer's canvas for upload.
|
|
93
|
+
*
|
|
94
|
+
* The canvas is shared and reused, so the caller must consume it (upload to a
|
|
95
|
+
* texture) before rendering another node — which the compositor does, since both
|
|
96
|
+
* happen inside one synchronous draw call.
|
|
97
|
+
*/
|
|
98
|
+
export function renderCanvas3D(three, key, scene, camera, width, height, options = {}) {
|
|
99
|
+
const active = getRenderer(three, options.antialias !== false);
|
|
100
|
+
const size = quantizeBuffer(key, width, height);
|
|
101
|
+
const current = active.getSize(new three.Vector2());
|
|
102
|
+
if (current.x !== size.width || current.y !== size.height) {
|
|
103
|
+
active.setSize(size.width, size.height, false);
|
|
104
|
+
}
|
|
105
|
+
active.render(scene, camera);
|
|
106
|
+
return {
|
|
107
|
+
source: active.domElement,
|
|
108
|
+
width: size.width,
|
|
109
|
+
height: size.height,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** Apply renderer-level scene settings that live on the renderer, not the scene. */
|
|
113
|
+
export function applyRendererSettings(three, settings) {
|
|
114
|
+
if (!renderer)
|
|
115
|
+
return;
|
|
116
|
+
// Toggling shadow mapping recompiles every affected material, so only write
|
|
117
|
+
// when it actually changes.
|
|
118
|
+
if (renderer.shadowMap.enabled !== settings.shadowsEnabled) {
|
|
119
|
+
renderer.shadowMap.enabled = settings.shadowsEnabled;
|
|
120
|
+
renderer.shadowMap.needsUpdate = true;
|
|
121
|
+
}
|
|
122
|
+
if (renderer.shadowMap.type !== settings.shadowType) {
|
|
123
|
+
renderer.shadowMap.type = settings.shadowType;
|
|
124
|
+
renderer.shadowMap.needsUpdate = true;
|
|
125
|
+
}
|
|
126
|
+
renderer.toneMapping = settings.toneMapping;
|
|
127
|
+
renderer.toneMappingExposure = settings.toneMappingExposure;
|
|
128
|
+
void three;
|
|
129
|
+
}
|
|
130
|
+
/** The live renderer, or null before first use. For environment/PMREM helpers. */
|
|
131
|
+
export function activeRenderer() {
|
|
132
|
+
return renderer;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Release the shared renderer and its GL context.
|
|
136
|
+
*
|
|
137
|
+
* Called on render-context unmount/dispose. Unlike CanvasKit's context (which is
|
|
138
|
+
* deliberately kept alive because the canvas element outlives an HMR remount),
|
|
139
|
+
* this one owns its own canvas and is safe to drop — it is recreated on the next
|
|
140
|
+
* 3D frame.
|
|
141
|
+
*/
|
|
142
|
+
export function disposeSharedRenderer() {
|
|
143
|
+
renderer?.dispose();
|
|
144
|
+
renderer?.forceContextLoss();
|
|
145
|
+
renderer = null;
|
|
146
|
+
bufferSizes.clear();
|
|
147
|
+
}
|
|
148
|
+
/** Forget a node's buffer size, so a removed node stops pinning a large buffer. */
|
|
149
|
+
export function forgetCanvas3DBuffer(key) {
|
|
150
|
+
bufferSizes.delete(key);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* This package's implementation of the renderer seam
|
|
154
|
+
* `@motionscript/skia-render` declares.
|
|
155
|
+
*
|
|
156
|
+
* The reconciler and the 3D backend live in skia-render, which cannot import this
|
|
157
|
+
* module — that would be an upward package dependency. So the renderer is handed
|
|
158
|
+
* over instead, and everything above stays exactly as it was: module-level
|
|
159
|
+
* singletons behind free functions, with this object as the adapter.
|
|
160
|
+
*
|
|
161
|
+
* **Registered from `../index.ts`, deliberately not here.** After the extraction
|
|
162
|
+
* nothing in this package statically imports this module, and the package declares
|
|
163
|
+
* `sideEffects: false` — so a module-scope registration here could legitimately be
|
|
164
|
+
* tree-shaken away, and 3D would silently render nothing at all (`canvas3DBackend()`
|
|
165
|
+
* returns null forever, the warm loop gives up after its three passes, and frames
|
|
166
|
+
* ship with their 2D parts only and no error). It has to be in the barrel every
|
|
167
|
+
* consumer imports, which is the same argument the comment on
|
|
168
|
+
* `registerCanvas3DBackend()` already makes.
|
|
169
|
+
*/
|
|
170
|
+
export const webCanvas3DRendererHost = {
|
|
171
|
+
render: renderCanvas3D,
|
|
172
|
+
applySettings: applyRendererSettings,
|
|
173
|
+
active: activeRenderer,
|
|
174
|
+
forgetBuffer: forgetCanvas3DBuffer,
|
|
175
|
+
dispose: disposeSharedRenderer,
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/three/renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as THREE from \"three\";\nimport type {\n RenderedCanvas3D,\n ThreeModule,\n Canvas3DRendererHost,\n Canvas3DRendererSettings,\n} from \"@motionscript/skia-render\";\n\n/**\n * The single shared `WebGLRenderer` for every 3D node in the document.\n *\n * One renderer is a requirement, not an optimisation: browsers cap concurrent\n * WebGL contexts at roughly 16 and CanvasKit already owns one, so a renderer per\n * node would start losing contexts on any scene with a handful of 3D nodes. Each\n * node instead renders serially into this one, sized to its own destination, and\n * the result is uploaded before the next node draws.\n *\n * Created lazily on first render so merely importing this module never touches\n * WebGL (safe for SSR and unit tests).\n */\nlet renderer: THREE.WebGLRenderer | null = null;\nlet rendererAntialias = true;\n\n/**\n * Device-pixel buffer size actually in use, per node.\n *\n * `setSize` reallocates the drawing buffer, which is expensive. A node under a\n * `scale` tween changes its derived device size every single frame, so without\n * quantisation it would reallocate 60 times a second and stutter. Sizes are\n * rounded up to {@link SIZE_QUANTUM} and never shrink within a session, letting\n * Skia scale a slightly-oversized image into the destination rect instead.\n */\nconst bufferSizes = new Map<string, { width: number; height: number }>();\n\nconst SIZE_QUANTUM = 64;\n\n/** Conservative cap; the real limit is read from the GL context on first use. */\nlet maxTextureSize = 4096;\n\nfunction createRenderer(three: ThreeModule, antialias: boolean): THREE.WebGLRenderer {\n const created = new three.WebGLRenderer({\n antialias,\n // Transparent so the 3D composites over whatever the 2D scene drew below.\n alpha: true,\n // three's default, and what the compositor's `srcIsPremul: true` assumes.\n premultipliedAlpha: true,\n // Keep the buffer readable for the texture upload. The upload happens in\n // the same synchronous task as the render, so this is belt-and-braces\n // rather than strictly required — see the note in the compositor.\n preserveDrawingBuffer: true,\n });\n created.setClearColor(0x000000, 0);\n created.setPixelRatio(1); // sizes are already in device pixels\n maxTextureSize = created.capabilities.maxTextureSize ?? maxTextureSize;\n return created;\n}\n\n/**\n * The shared renderer, creating it on first call.\n *\n * `antialias` is fixed at context creation, so a later change needs a new\n * context — the renderer is rebuilt when it flips, which is rare (it's a\n * per-node authoring choice, not something to animate).\n */\nfunction getRenderer(three: ThreeModule, antialias: boolean): THREE.WebGLRenderer {\n if (renderer && rendererAntialias !== antialias) {\n renderer.dispose();\n renderer.forceContextLoss();\n renderer = null;\n }\n if (!renderer) {\n renderer = createRenderer(three, antialias);\n rendererAntialias = antialias;\n bufferSizes.clear();\n }\n return renderer;\n}\n\n/**\n * Round a requested device size up to a stable, GPU-friendly buffer size that\n * never shrinks for this node. See {@link bufferSizes}.\n */\nfunction quantizeBuffer(key: string, width: number, height: number): { width: number; height: number } {\n const wanted = {\n width: Math.min(maxTextureSize, Math.max(1, Math.ceil(width / SIZE_QUANTUM) * SIZE_QUANTUM)),\n height: Math.min(maxTextureSize, Math.max(1, Math.ceil(height / SIZE_QUANTUM) * SIZE_QUANTUM)),\n };\n\n const current = bufferSizes.get(key);\n if (!current) {\n bufferSizes.set(key, wanted);\n return wanted;\n }\n\n // Grow only. A node that shrinks keeps its larger buffer, so a scale tween\n // reallocates at most once per size step rather than every frame.\n const grown = {\n width: Math.max(current.width, wanted.width),\n height: Math.max(current.height, wanted.height),\n };\n if (grown.width !== current.width || grown.height !== current.height) {\n bufferSizes.set(key, grown);\n }\n return grown;\n}\n\n/**\n * Render `scene` through `camera` at the given device-pixel size and return the\n * renderer's canvas for upload.\n *\n * The canvas is shared and reused, so the caller must consume it (upload to a\n * texture) before rendering another node — which the compositor does, since both\n * happen inside one synchronous draw call.\n */\nexport function renderCanvas3D(\n three: ThreeModule,\n key: string,\n scene: THREE.Scene,\n camera: THREE.Camera,\n width: number,\n height: number,\n options: { antialias?: boolean } = {},\n): RenderedCanvas3D {\n const active = getRenderer(three, options.antialias !== false);\n const size = quantizeBuffer(key, width, height);\n\n const current = active.getSize(new three.Vector2());\n if (current.x !== size.width || current.y !== size.height) {\n active.setSize(size.width, size.height, false);\n }\n\n active.render(scene, camera);\n\n return {\n source: active.domElement,\n width: size.width,\n height: size.height,\n };\n}\n\n/** Apply renderer-level scene settings that live on the renderer, not the scene. */\nexport function applyRendererSettings(\n three: ThreeModule,\n settings: Canvas3DRendererSettings,\n): void {\n if (!renderer) return;\n // Toggling shadow mapping recompiles every affected material, so only write\n // when it actually changes.\n if (renderer.shadowMap.enabled !== settings.shadowsEnabled) {\n renderer.shadowMap.enabled = settings.shadowsEnabled;\n renderer.shadowMap.needsUpdate = true;\n }\n if (renderer.shadowMap.type !== settings.shadowType) {\n renderer.shadowMap.type = settings.shadowType;\n renderer.shadowMap.needsUpdate = true;\n }\n renderer.toneMapping = settings.toneMapping;\n renderer.toneMappingExposure = settings.toneMappingExposure;\n void three;\n}\n\n/** The live renderer, or null before first use. For environment/PMREM helpers. */\nexport function activeRenderer(): THREE.WebGLRenderer | null {\n return renderer;\n}\n\n/**\n * Release the shared renderer and its GL context.\n *\n * Called on render-context unmount/dispose. Unlike CanvasKit's context (which is\n * deliberately kept alive because the canvas element outlives an HMR remount),\n * this one owns its own canvas and is safe to drop — it is recreated on the next\n * 3D frame.\n */\nexport function disposeSharedRenderer(): void {\n renderer?.dispose();\n renderer?.forceContextLoss();\n renderer = null;\n bufferSizes.clear();\n}\n\n/** Forget a node's buffer size, so a removed node stops pinning a large buffer. */\nexport function forgetCanvas3DBuffer(key: string): void {\n bufferSizes.delete(key);\n}\n\n/**\n * This package's implementation of the renderer seam\n * `@motionscript/skia-render` declares.\n *\n * The reconciler and the 3D backend live in skia-render, which cannot import this\n * module — that would be an upward package dependency. So the renderer is handed\n * over instead, and everything above stays exactly as it was: module-level\n * singletons behind free functions, with this object as the adapter.\n *\n * **Registered from `../index.ts`, deliberately not here.** After the extraction\n * nothing in this package statically imports this module, and the package declares\n * `sideEffects: false` — so a module-scope registration here could legitimately be\n * tree-shaken away, and 3D would silently render nothing at all (`canvas3DBackend()`\n * returns null forever, the warm loop gives up after its three passes, and frames\n * ship with their 2D parts only and no error). It has to be in the barrel every\n * consumer imports, which is the same argument the comment on\n * `registerCanvas3DBackend()` already makes.\n */\nexport const webCanvas3DRendererHost: Canvas3DRendererHost = {\n render: renderCanvas3D,\n applySettings: applyRendererSettings,\n active: activeRenderer,\n forgetBuffer: forgetCanvas3DBuffer,\n dispose: disposeSharedRenderer,\n};\n"]}
|
package/dist/ticker.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Ticker } from "@motionscript/core";
|
|
2
|
+
/**
|
|
3
|
+
* Ticker backed by a Web Audio AudioContext. Scene time advances in
|
|
4
|
+
* lock-step with `audioContext.currentTime`, so any AudioBufferSourceNodes
|
|
5
|
+
* scheduled on the same context play perfectly in sync.
|
|
6
|
+
*
|
|
7
|
+
* When paused we suspend the context (audio stops, currentTime freezes);
|
|
8
|
+
* when playing we resume and a rAF loop publishes ticks at the target fps.
|
|
9
|
+
*
|
|
10
|
+
* A single silent buffer covering the full timeline is started on play(),
|
|
11
|
+
* which keeps the context active and gives the browser a stable audio
|
|
12
|
+
* graph to schedule against even on scenes that contain no audio nodes.
|
|
13
|
+
*/
|
|
14
|
+
export declare class WebTicker extends Ticker {
|
|
15
|
+
private context;
|
|
16
|
+
private ownsContext;
|
|
17
|
+
private fps;
|
|
18
|
+
private playStartCtxTime;
|
|
19
|
+
private seekOffset;
|
|
20
|
+
private speed;
|
|
21
|
+
private reverse;
|
|
22
|
+
private rafId;
|
|
23
|
+
private silentSource;
|
|
24
|
+
constructor(opts: {
|
|
25
|
+
context?: AudioContext;
|
|
26
|
+
fps: number;
|
|
27
|
+
});
|
|
28
|
+
getContext(): AudioContext;
|
|
29
|
+
seek(t: number): void;
|
|
30
|
+
/** Resumes the (possibly suspended) context, anchors elapsed-time tracking to the current `context.currentTime`, and starts the silent ticker + rAF tick loop. */
|
|
31
|
+
play(speed?: number, reverse?: boolean): Promise<void>;
|
|
32
|
+
/** Stops the tick loop and silent ticker, then suspends the context — freezing `currentTime` so elapsed-time math stays correct across the pause. */
|
|
33
|
+
pause(): void;
|
|
34
|
+
/** (Re)starts the silent buffer source covering the remaining timeline — keeps the AudioContext active and gives a stable graph for other AudioBufferSourceNodes to schedule against, per the class-level note. */
|
|
35
|
+
private startSilentTicker;
|
|
36
|
+
private stopSilentTicker;
|
|
37
|
+
/** Drives ticks off `requestAnimationFrame`, deriving scene time from elapsed `context.currentTime` (so it stays sample-accurate) and only firing `tick()` when a full frame interval has elapsed. */
|
|
38
|
+
private startLoop;
|
|
39
|
+
private stopLoop;
|
|
40
|
+
dispose(): void;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=ticker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticker.d.ts","sourceRoot":"","sources":["../src/ticker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,qBAAa,SAAU,SAAQ,MAAM;IACjC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAkB;IAEjC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,YAAY,CAAsC;gBAE9C,IAAI,EAAE;QAAE,OAAO,CAAC,EAAE,YAAY,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAOzD,UAAU,IAAI,YAAY;IAI1B,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAOrB,kKAAkK;IAC5J,IAAI,CAAC,KAAK,GAAE,MAAU,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAetE,qJAAqJ;IACrJ,KAAK,IAAI,IAAI;IAUb,mNAAmN;IACnN,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,gBAAgB;IAaxB,sMAAsM;IACtM,OAAO,CAAC,SAAS;IA2CjB,OAAO,CAAC,QAAQ;IAOhB,OAAO,IAAI,IAAI;CAQlB"}
|