@taole/giftstage 0.1.34 → 0.1.36
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/dist/assets/webcodecs-mp4.worker-DeS4ARzq.js +398 -0
- package/dist/core/gift-stage.d.ts +9 -6
- package/dist/core/render-manager.d.ts +7 -0
- package/dist/gift-stage.cjs.js +780 -660
- package/dist/gift-stage.es.js +5248 -4568
- package/dist/gpu/webgl2-backend.d.ts +10 -0
- package/dist/gpu/webgpu-backend.d.ts +28 -5
- package/dist/parsers/svga-sprite-table.d.ts +7 -1
- package/dist/parsers/vap-config-parser.d.ts +11 -9
- package/dist/renderers/image-renderer.d.ts +3 -0
- package/dist/renderers/svga-batch-renderer.d.ts +46 -18
- package/dist/renderers/vap-renderer.d.ts +4 -0
- package/dist/shaders/index.d.ts +5 -0
- package/dist/types/index.d.ts +24 -4
- package/dist/video/webcodecs-mp4-core.d.ts +4 -0
- package/dist/video/webcodecs-mp4-playback.d.ts +10 -0
- package/package.json +1 -1
- package/dist/assets/webcodecs-mp4.worker-CDhalNDE.js +0 -379
|
@@ -22,8 +22,16 @@ export declare class WebGL2Backend implements GPUBackend {
|
|
|
22
22
|
private videoElementDirectUploadValidated;
|
|
23
23
|
/** DYNAMIC_DRAW upload target for `svga-instanced-premul` (`FrameJobData` per instance). */
|
|
24
24
|
private static readonly INST_SVGA_GL_MAX;
|
|
25
|
+
private static readonly INST_SVGA_GL_FLOATS;
|
|
26
|
+
private static readonly INST_SVGA_GL_STRIDE;
|
|
25
27
|
private static readonly INST_SVGA_GL_BYTES;
|
|
26
28
|
private instancedSvgaInstanceGLBuffer;
|
|
29
|
+
/** DYNAMIC_DRAW upload target for instanced clip-mask affine transforms. */
|
|
30
|
+
private static readonly INST_CLIP_MASK_GL_MAX;
|
|
31
|
+
private static readonly INST_CLIP_MASK_GL_FLOATS;
|
|
32
|
+
private static readonly INST_CLIP_MASK_GL_STRIDE;
|
|
33
|
+
private static readonly INST_CLIP_MASK_GL_BYTES;
|
|
34
|
+
private instancedClipMaskGLBuffer;
|
|
27
35
|
/** DYNAMIC_DRAW upload target for `alpha-video-instanced` (rect+atlasRemap+opacity per instance). */
|
|
28
36
|
private static readonly INST_ALPHA_GL_MAX;
|
|
29
37
|
private static readonly INST_ALPHA_GL_BYTES;
|
|
@@ -81,6 +89,8 @@ export declare class WebGL2Backend implements GPUBackend {
|
|
|
81
89
|
private deleteAllVertexArrays;
|
|
82
90
|
private ensureInstancedSvgaInstanceBuffer;
|
|
83
91
|
private drawInstancedSvgaGL;
|
|
92
|
+
private ensureInstancedClipMaskBuffer;
|
|
93
|
+
private drawInstancedClipMaskGL;
|
|
84
94
|
private ensureInstancedAlphaInstanceBuffer;
|
|
85
95
|
private drawInstancedAlphaGL;
|
|
86
96
|
private ensureInstancedVapInstanceBuffer;
|
|
@@ -85,18 +85,16 @@ export declare class WebGPUBackend implements GPUBackend {
|
|
|
85
85
|
private dualTexturedBindGroupCache;
|
|
86
86
|
/** All instanced pipelines also share one texture layout. */
|
|
87
87
|
private instancedTextureBindGroupCache;
|
|
88
|
-
/** Batched SVGA sprites (
|
|
88
|
+
/** Batched SVGA sprites (pre-scaled affine, UVs, and packed framebuffer clip rect). */
|
|
89
89
|
private static readonly SVGA_INSTANCED_MAX;
|
|
90
90
|
private static readonly SVGA_INSTANCED_STRIDE;
|
|
91
|
+
private static readonly CLIP_MASK_INSTANCED_MAX;
|
|
92
|
+
private static readonly CLIP_MASK_INSTANCED_STRIDE;
|
|
91
93
|
/** Batched alpha-video (storage instances + projection uniform). */
|
|
92
94
|
private static readonly ALPHA_INSTANCED_MAX;
|
|
93
95
|
private static readonly ALPHA_INSTANCED_STRIDE;
|
|
94
96
|
private static readonly VAP_INSTANCED_MAX;
|
|
95
97
|
private static readonly VAP_INSTANCED_STRIDE;
|
|
96
|
-
/** One draw may bind up to this many bytes of instance storage (max instances × stride). */
|
|
97
|
-
private static readonly INSTANCED_SVGA_CHUNK_BYTES;
|
|
98
|
-
private static readonly INSTANCED_ALPHA_CHUNK_BYTES;
|
|
99
|
-
private static readonly INSTANCED_VAP_CHUNK_BYTES;
|
|
100
98
|
/**
|
|
101
99
|
* Multiple `queue.writeBuffer(..., offset 0)` to the same storage buffer before one `submit` only keep the
|
|
102
100
|
* last write; one shared ring + dynamic offsets keeps all instanced paths non-overlapping until submit.
|
|
@@ -107,9 +105,19 @@ export declare class WebGPUBackend implements GPUBackend {
|
|
|
107
105
|
private storageBindOffsetAlign;
|
|
108
106
|
/** Reset in `beginFrame`; all instanced draw types reserve non-overlapping chunks. */
|
|
109
107
|
private instancedStorageRingOffset;
|
|
108
|
+
/** Grow-only CPU mirror; expands to the frame's actual storage high-water mark. */
|
|
109
|
+
private instancedStorageShadow;
|
|
110
|
+
private instancedStorageShadowDirtyMax;
|
|
110
111
|
private readonly instancedProjectionCache;
|
|
111
112
|
private instancedProjectionValid;
|
|
113
|
+
/** Storage range written by the latest instanced clip-mask write pass; reused by its clear. */
|
|
114
|
+
private lastClipMaskStorageBase;
|
|
115
|
+
private lastClipMaskStorageByteLength;
|
|
112
116
|
private lastInstancedTextureBindGroup;
|
|
117
|
+
private performanceBufferWrites;
|
|
118
|
+
private performanceBufferWriteBytes;
|
|
119
|
+
private performanceStorageBufferWrites;
|
|
120
|
+
private performanceStorageBufferWriteBytes;
|
|
113
121
|
constructor(canvas: HTMLCanvasElement, adapter: GPUAdapter, wantAntialias?: boolean);
|
|
114
122
|
init(): Promise<void>;
|
|
115
123
|
private configureCanvasContext;
|
|
@@ -118,10 +126,13 @@ export declare class WebGPUBackend implements GPUBackend {
|
|
|
118
126
|
private ensureStencilPipelines;
|
|
119
127
|
private ensureInstancedProjectionBuffer;
|
|
120
128
|
private ensureInstancedStorageBuffer;
|
|
129
|
+
private ensureInstancedDataBindGroup;
|
|
121
130
|
private ensureInstancedSvgaPipeline;
|
|
131
|
+
private ensureInstancedClipMaskPipeline;
|
|
122
132
|
private ensureInstancedAlphaPipeline;
|
|
123
133
|
private ensureInstancedVapPipeline;
|
|
124
134
|
private createInstancedSvgaPipeline;
|
|
135
|
+
private createInstancedClipMaskPipeline;
|
|
125
136
|
private createVapInstancedPipeline;
|
|
126
137
|
private createInstancedAlphaVideoPipeline;
|
|
127
138
|
private createTexturedPipeline;
|
|
@@ -130,8 +141,19 @@ export declare class WebGPUBackend implements GPUBackend {
|
|
|
130
141
|
stencil?: boolean;
|
|
131
142
|
}): void;
|
|
132
143
|
endFrame(): void;
|
|
144
|
+
getPerformanceSnapshot(): {
|
|
145
|
+
bufferWrites: number;
|
|
146
|
+
bufferWriteBytes: number;
|
|
147
|
+
storageBufferWrites: number;
|
|
148
|
+
storageBufferWriteBytes: number;
|
|
149
|
+
};
|
|
150
|
+
resetPerformanceSnapshot(): void;
|
|
151
|
+
private writeBuffer;
|
|
133
152
|
/** Uploads the touched range of `uniformShadow` in one call — must run before `queue.submit`. */
|
|
134
153
|
private flushUniformShadow;
|
|
154
|
+
/** Uploads every instanced draw's non-overlapping shadow range in one call before submit. */
|
|
155
|
+
private flushInstancedStorageShadow;
|
|
156
|
+
private writeInstancedStorageShadow;
|
|
135
157
|
/** Records a per-draw uniform write into the CPU shadow instead of touching the GPU buffer. */
|
|
136
158
|
private writeUniformShadow;
|
|
137
159
|
private ensureInstancedProjection;
|
|
@@ -167,6 +189,7 @@ export declare class WebGPUBackend implements GPUBackend {
|
|
|
167
189
|
draw(cmd: DrawCommand): void;
|
|
168
190
|
/** One `drawIndexed` with `instanceCount` for all SVGA sprites sharing the same atlas. */
|
|
169
191
|
private drawInstancedSvga;
|
|
192
|
+
private drawInstancedClipMask;
|
|
170
193
|
/** One `drawIndexed` with `instanceCount` for all gifts sharing the same video texture (e.g. atlas). */
|
|
171
194
|
private drawInstancedAlpha;
|
|
172
195
|
private drawInstancedVap;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* SVGA sprite SoA table: flat frame floats + deduped clip/shapes side tables.
|
|
3
3
|
* Replaces per-sprite `frames: SVGAFrame[]` object graphs on the hot path.
|
|
4
4
|
*/
|
|
5
|
-
import type { SVGAShape, SVGATransform } from '../types';
|
|
5
|
+
import type { SVGAParams, SVGAShape, SVGATransform } from '../types';
|
|
6
6
|
/** Floats per frame in `frameData`: layoutW, layoutH, a, b, c, d, tx, ty, alpha. */
|
|
7
7
|
export declare const SPRITE_FRAME_FLOATS = 9;
|
|
8
8
|
export interface SVGASpriteTable {
|
|
@@ -20,6 +20,7 @@ export interface SVGASpriteTable {
|
|
|
20
20
|
/** spriteCount × frameCount; -1 = none. */
|
|
21
21
|
shapesIndex: Int32Array;
|
|
22
22
|
hasAnyShapes: boolean;
|
|
23
|
+
allFramesInsideViewBox?: boolean;
|
|
23
24
|
}
|
|
24
25
|
/** Loose frame shape used when converting from AoS decode (JS proto / fixtures). */
|
|
25
26
|
export interface SVGAFrameLike {
|
|
@@ -55,5 +56,10 @@ export declare function getSpriteClipPath(table: SVGASpriteTable, spriteIndex: n
|
|
|
55
56
|
* Resolves shape `keep` chains to shared array references.
|
|
56
57
|
*/
|
|
57
58
|
export declare function spriteTableFromSprites(sprites: SVGASpriteLike[], frameCountHint?: number): SVGASpriteTable;
|
|
59
|
+
/**
|
|
60
|
+
* Compute the renderer's scissor-elision flag before the entity becomes renderable. Shapes are
|
|
61
|
+
* conservative because their geometry is not represented by the sprite layout rectangle.
|
|
62
|
+
*/
|
|
63
|
+
export declare function ensureAllFramesInsideViewBox(params: Pick<SVGAParams, 'viewBoxWidth' | 'viewBoxHeight'>, table: SVGASpriteTable): boolean;
|
|
58
64
|
/** Empty table used when there are no sprites. */
|
|
59
65
|
export declare function emptySpriteTable(frameCount?: number): SVGASpriteTable;
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import type { VAPConfig, VAPFrameItem } from '../types';
|
|
2
2
|
export declare function parseVAPConfig(config: string | object): Promise<VAPConfig>;
|
|
3
3
|
export declare function getVAPFrame(config: VAPConfig, frameIndex: number): VAPFrameItem | undefined;
|
|
4
|
-
|
|
5
|
-
* Logical content size for layout/aspect (matches visible RGB frame, not full mp4 frame).
|
|
6
|
-
* `videoW`/`videoH` often include separate alpha bands; use `w`/`h` or `rgbFrame` w×h.
|
|
7
|
-
*/
|
|
8
|
-
export declare function getVAPContentSize(info: VAPConfig['info']): {
|
|
4
|
+
export interface VAPContentSize {
|
|
9
5
|
w: number;
|
|
10
6
|
h: number;
|
|
11
|
-
}
|
|
7
|
+
}
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
9
|
+
* Logical content size for layout/aspect (matches visible RGB frame, not full mp4 frame).
|
|
10
|
+
* `videoW`/`videoH` often include separate alpha bands; use `w`/`h` or `rgbFrame` w×h.
|
|
14
11
|
*/
|
|
15
|
-
export declare function
|
|
12
|
+
export declare function getVAPContentSize(info: VAPConfig['info'], out?: VAPContentSize): VAPContentSize;
|
|
13
|
+
export interface VAPUVRect {
|
|
16
14
|
left: number;
|
|
17
15
|
right: number;
|
|
18
16
|
top: number;
|
|
19
17
|
bottom: number;
|
|
20
|
-
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Compute normalized UV coordinates for a frame region within the video texture.
|
|
21
|
+
*/
|
|
22
|
+
export declare function computeVAPUV(region: [number, number, number, number], videoW: number, videoH: number, out?: VAPUVRect): VAPUVRect;
|
|
@@ -8,6 +8,9 @@ export declare class ImageRenderer {
|
|
|
8
8
|
private projCacheW;
|
|
9
9
|
private projCacheH;
|
|
10
10
|
private projCache;
|
|
11
|
+
private readonly texturesScratch;
|
|
12
|
+
private readonly uniformsScratch;
|
|
13
|
+
private readonly drawCommand;
|
|
11
14
|
private static readonly QUAD_VERTS;
|
|
12
15
|
private static readonly QUAD_INDICES;
|
|
13
16
|
drawSlot(backend: GPUBackend, slot: GiftSlot): void;
|
|
@@ -12,6 +12,13 @@ export interface ClipMeshCache {
|
|
|
12
12
|
w: number;
|
|
13
13
|
h: number;
|
|
14
14
|
} | null;
|
|
15
|
+
/** Local-space bounds cached for conservative instanced stencil safety checks. */
|
|
16
|
+
bounds?: {
|
|
17
|
+
x0: number;
|
|
18
|
+
y0: number;
|
|
19
|
+
x1: number;
|
|
20
|
+
y1: number;
|
|
21
|
+
};
|
|
15
22
|
/** Lazily created static GPU buffers (local-space vertices, transformed via u_transform). */
|
|
16
23
|
vertexBuf?: GPUBufferHandle | null;
|
|
17
24
|
indexBuf?: GPUBufferHandle | null;
|
|
@@ -59,8 +66,10 @@ export declare class SVGABatchRenderer {
|
|
|
59
66
|
* back — each captured entry clones out of it immediately via `.slice()`. */
|
|
60
67
|
private staticBatchCacheRowScratch;
|
|
61
68
|
private instancedFrameDataScratch;
|
|
69
|
+
private instancedFrameDataWords;
|
|
62
70
|
private clipSpriteVertsScratch;
|
|
63
71
|
private clipSpriteIndicesScratch;
|
|
72
|
+
private clipMaskBatchTransformsScratch;
|
|
64
73
|
private instancedQuadVB;
|
|
65
74
|
private instancedQuadIB;
|
|
66
75
|
private whiteTexture;
|
|
@@ -73,10 +82,14 @@ export declare class SVGABatchRenderer {
|
|
|
73
82
|
private shapeTransformMat;
|
|
74
83
|
/** Scissor rect of the slot currently being drawn (canvas pixels), for clip intersection/restore. */
|
|
75
84
|
private slotScissor;
|
|
85
|
+
private slotClipX0;
|
|
86
|
+
private slotClipY0;
|
|
87
|
+
private slotClipX1;
|
|
88
|
+
private slotClipY1;
|
|
76
89
|
/**
|
|
77
90
|
* Whether `slotScissor` is currently the *active* GPU scissor rect (vs. the outer scissor
|
|
78
91
|
* having been intentionally skipped for a slot that cannot draw outside its own box — see
|
|
79
|
-
* `allFramesInsideViewBox`). Drives `restoreSlotScissor`'s fallback target.
|
|
92
|
+
* `spriteTable.allFramesInsideViewBox`). Drives `restoreSlotScissor`'s fallback target.
|
|
80
93
|
*/
|
|
81
94
|
private slotScissorActive;
|
|
82
95
|
/**
|
|
@@ -92,6 +105,10 @@ export declare class SVGABatchRenderer {
|
|
|
92
105
|
/** Reused scratch arrays (consumed synchronously). */
|
|
93
106
|
private batchSpritesScratch;
|
|
94
107
|
private drawGroupScratch;
|
|
108
|
+
private sharedSlotLayerWorkPool;
|
|
109
|
+
private sharedSlotLayerWorksScratch;
|
|
110
|
+
private clipLayerBatchPool;
|
|
111
|
+
private clipLayerBatchesScratch;
|
|
95
112
|
/** Per-entity result of the "any frame has shapes" scan (no-atlas render check). */
|
|
96
113
|
private entityHasShapesCache;
|
|
97
114
|
/** 0=no clip, 1=scissor-compatible clips only, 2=stencil required, 255=not analyzed. */
|
|
@@ -103,15 +120,6 @@ export declare class SVGABatchRenderer {
|
|
|
103
120
|
* resolution always goes through `getClipMesh`'s string cache, so array entries never go stale.
|
|
104
121
|
*/
|
|
105
122
|
private entityClipMeshArrayCache;
|
|
106
|
-
/**
|
|
107
|
-
* Per-entity result of scanning every sprite×frame layout AABB (in local viewBox space) to see
|
|
108
|
-
* whether it ever draws outside the entity's own viewBox. Entities with vector shapes are
|
|
109
|
-
* excluded (`false`) since shape geometry isn't covered by this scan. Used by `flushGroup` to
|
|
110
|
-
* skip the redundant outer scissor for contain/fill, non-rotated slots — such slots structurally
|
|
111
|
-
* cannot paint outside their own box, so consecutive same-atlas slots can share one scissor-free
|
|
112
|
-
* batch run instead of forcing a draw call per slot.
|
|
113
|
-
*/
|
|
114
|
-
private entityAllFramesInsideViewBoxCache;
|
|
115
123
|
private readonly affineScratch;
|
|
116
124
|
/**
|
|
117
125
|
* Reused DrawCommand/uniforms/textures per rendering branch (never allocated per draw).
|
|
@@ -142,6 +150,8 @@ export declare class SVGABatchRenderer {
|
|
|
142
150
|
private readonly clipMaskTexturesScratch;
|
|
143
151
|
private readonly clipMaskUniformsScratch;
|
|
144
152
|
private readonly clipMaskDrawCommand;
|
|
153
|
+
private readonly clipMaskInstancedUniformsScratch;
|
|
154
|
+
private readonly clipMaskInstancedDrawCommand;
|
|
145
155
|
/**
|
|
146
156
|
* `drawShapeFrame`'s fill/stroke draw (always the shared white texture). `u_transform`
|
|
147
157
|
* carries the per-frame sprite x slot transform so the static shape mesh stays on the GPU;
|
|
@@ -155,8 +165,17 @@ export declare class SVGABatchRenderer {
|
|
|
155
165
|
drawSlot(backend: GPUBackend, slot: GiftSlot): void;
|
|
156
166
|
drawSlots(backend: GPUBackend, slots: Iterable<GiftSlot>): void;
|
|
157
167
|
requiresStencil(slots: Iterable<GiftSlot>): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Returns the target frame only when every clip path referenced by its visible sprites has a
|
|
170
|
+
* resolved cache entry. A miss queues background triangulation and keeps the previous complete
|
|
171
|
+
* frame on screen, preventing a partially built frame from being drawn without clipping.
|
|
172
|
+
*/
|
|
173
|
+
private resolveRenderableFrame;
|
|
174
|
+
private isFrameClipReady;
|
|
158
175
|
private getFrameClipMode;
|
|
159
176
|
prewarmClipMeshes(entity: Pick<VideoEntity, 'spriteTable'>, options?: SVGAClipPrewarmOptions): Promise<number>;
|
|
177
|
+
prewarmClipMeshesForFrame(entity: Pick<VideoEntity, 'spriteTable'>, frame: number, options?: SVGAClipPrewarmOptions): Promise<number>;
|
|
178
|
+
private collectFrameClipPaths;
|
|
160
179
|
/** Builds every not-yet-cached path in `paths`, worker-first with a frame-budgeted fallback. */
|
|
161
180
|
private buildMissingClipMeshes;
|
|
162
181
|
/**
|
|
@@ -171,6 +190,17 @@ export declare class SVGABatchRenderer {
|
|
|
171
190
|
hydrateClipMeshes(meshes: SVGAClipMeshMap | null | undefined): void;
|
|
172
191
|
snapshotClipMeshes(entity: Pick<VideoEntity, 'spriteTable'>): SVGAClipMeshMap;
|
|
173
192
|
private flushGroup;
|
|
193
|
+
/**
|
|
194
|
+
* Transposes disjoint slots sharing one entity into sprite layers. Reordering across slots is
|
|
195
|
+
* safe because their outer clip bounds do not overlap; order within every slot remains sprite
|
|
196
|
+
* index order. Non-rect clips sharing one mesh become write -> instanced test -> clear.
|
|
197
|
+
*/
|
|
198
|
+
private tryFlushDisjointSharedEntityLayers;
|
|
199
|
+
private resetClipLayerBatches;
|
|
200
|
+
private acquireClipLayerBatch;
|
|
201
|
+
private resolveClipTransform;
|
|
202
|
+
private intersectWorkClipRect;
|
|
203
|
+
private drawBatchedClipLayer;
|
|
174
204
|
private acquireSpriteWork;
|
|
175
205
|
/**
|
|
176
206
|
* Like `acquireSpriteWork`, but for a P1-10 static batch cache replay entry: only `handle` and
|
|
@@ -178,6 +208,8 @@ export declare class SVGABatchRenderer {
|
|
|
178
208
|
* call only reads `work.handle`.
|
|
179
209
|
*/
|
|
180
210
|
private acquireCachedSpriteWork;
|
|
211
|
+
private updateSlotClipBounds;
|
|
212
|
+
private copyCurrentSlotClipToWork;
|
|
181
213
|
/** Drop object references so removed slots/entities are not retained by the pool. */
|
|
182
214
|
private releaseSpriteWorks;
|
|
183
215
|
/** Snapshot check for a P1-10 static batch cache: any mismatch means rebuild, never a stale hit. */
|
|
@@ -201,12 +233,16 @@ export declare class SVGABatchRenderer {
|
|
|
201
233
|
private applyClipRectScissor;
|
|
202
234
|
private restoreSlotScissor;
|
|
203
235
|
private getClipRect;
|
|
236
|
+
private getClipMeshBounds;
|
|
204
237
|
private ensureClipMeshBuffers;
|
|
205
238
|
private packClipTransform;
|
|
206
239
|
private drawSingleSprite;
|
|
207
240
|
private clearClipStencil;
|
|
208
241
|
private rotateTransform;
|
|
209
242
|
private packFrameData;
|
|
243
|
+
private packInstancedFrameData;
|
|
244
|
+
private packClipCoordinatePair;
|
|
245
|
+
private packFrameDataAt;
|
|
210
246
|
/** Resolve atlas/override texture into a pooled SpriteWork entry. Returns false when missing. */
|
|
211
247
|
private resolveSpriteTextureInto;
|
|
212
248
|
private drawShapeFrame;
|
|
@@ -219,14 +255,6 @@ export declare class SVGABatchRenderer {
|
|
|
219
255
|
private packShapeTransform;
|
|
220
256
|
private hasAtlasTexture;
|
|
221
257
|
private hasRenderableSVGA;
|
|
222
|
-
/**
|
|
223
|
-
* True when every sprite frame's transformed layout rect stays within the entity's own
|
|
224
|
-
* viewBox (with a small epsilon for float error). Computed once per entity and cached — the
|
|
225
|
-
* scan touches every sprite×frame combination, which is only affordable as a one-time cost.
|
|
226
|
-
* Entities with vector shapes always return `false`: shape geometry has its own coordinate
|
|
227
|
-
* system that this scan does not cover, so we conservatively keep per-slot scissoring for them.
|
|
228
|
-
*/
|
|
229
|
-
private allFramesInsideViewBox;
|
|
230
258
|
private getWhiteTexture;
|
|
231
259
|
private getShapeMesh;
|
|
232
260
|
private appendShape;
|
|
@@ -15,6 +15,10 @@ export declare class VAPRenderer {
|
|
|
15
15
|
private readonly scratchAtlasRemap;
|
|
16
16
|
private instancePackScratch;
|
|
17
17
|
private scratchTransform;
|
|
18
|
+
private readonly contentSizeScratch;
|
|
19
|
+
private readonly rgbUVScratch;
|
|
20
|
+
private readonly alphaUVScratch;
|
|
21
|
+
private readonly maskUVScratch;
|
|
18
22
|
private readonly processedHtmlGatesScratch;
|
|
19
23
|
private readonly vapVertexScratch;
|
|
20
24
|
private readonly layoutScratch;
|
package/dist/shaders/index.d.ts
CHANGED
|
@@ -35,6 +35,10 @@ export declare const glsl: {
|
|
|
35
35
|
readonly vert: string;
|
|
36
36
|
readonly frag: string;
|
|
37
37
|
};
|
|
38
|
+
readonly clipMaskInstanced: {
|
|
39
|
+
readonly vert: string;
|
|
40
|
+
readonly frag: string;
|
|
41
|
+
};
|
|
38
42
|
};
|
|
39
43
|
export declare const wgsl: {
|
|
40
44
|
readonly svgaBatchPremul: string;
|
|
@@ -46,4 +50,5 @@ export declare const wgsl: {
|
|
|
46
50
|
readonly alphaVideoInstanced: string;
|
|
47
51
|
readonly rgbaTextured: string;
|
|
48
52
|
readonly clipMask: string;
|
|
53
|
+
readonly clipMaskInstanced: string;
|
|
49
54
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -26,14 +26,16 @@ export interface TextureOpts {
|
|
|
26
26
|
sourcePremultiplied?: boolean;
|
|
27
27
|
}
|
|
28
28
|
export type ShaderType = 'svga-batch-premul'
|
|
29
|
-
/** WebGPU / WebGL2: SVGA premultiplied atlas sprites batched as instances
|
|
29
|
+
/** WebGPU / WebGL2: SVGA premultiplied atlas sprites batched as packed instances. */
|
|
30
30
|
| 'svga-instanced-premul' | 'vap'
|
|
31
31
|
/** Main-context VAP mixed resource draw: resource texture multiplied by raw-video mask. */
|
|
32
32
|
| 'vap-mix-overlay'
|
|
33
33
|
/** WebGPU / WebGL2: batched VAP sharing one texture; see `instanceCount` / `instanceData` (32 floats/instance). */
|
|
34
34
|
| 'vap-instanced' | 'alpha-video'
|
|
35
35
|
/** WebGPU: batched draws sharing one texture (e.g. atlas); see `instanceCount` / `instanceData`. */
|
|
36
|
-
| 'alpha-video-instanced' | 'rgba-textured' | 'clip-mask'
|
|
36
|
+
| 'alpha-video-instanced' | 'rgba-textured' | 'clip-mask'
|
|
37
|
+
/** WebGPU / WebGL2: one local-space clip mesh transformed by per-instance affine data. */
|
|
38
|
+
| 'clip-mask-instanced';
|
|
37
39
|
export type StencilMode = 'none' | 'write' | 'test' | 'clear';
|
|
38
40
|
export interface DrawCommand {
|
|
39
41
|
shader: ShaderType;
|
|
@@ -44,13 +46,15 @@ export interface DrawCommand {
|
|
|
44
46
|
uniforms: Record<string, Float32Array | number>;
|
|
45
47
|
stencil?: StencilMode;
|
|
46
48
|
/**
|
|
47
|
-
* `svga-instanced-premul`: the first `instanceCount * 13`
|
|
48
|
-
* (
|
|
49
|
+
* `svga-instanced-premul`: the first `instanceCount * 13` words are consumed
|
|
50
|
+
* (pre-scaled transform, alpha, UV rect, and two packed framebuffer clip pairs).
|
|
49
51
|
*
|
|
50
52
|
* `alpha-video-instanced`: the first `instanceCount * 12` floats are consumed
|
|
51
53
|
* (display rect + atlasRemap + opacity/source-alpha-mode vec4).
|
|
52
54
|
* `vap-instanced`: the first `instanceCount * 32` floats are consumed
|
|
53
55
|
* (mat4 + atlasRemap + rgb/alpha rects + opacity/source-alpha-mode vec4).
|
|
56
|
+
* `clip-mask-instanced`: the first `instanceCount * 6` floats are consumed
|
|
57
|
+
* (a, b, c, d, tx, ty affine transform).
|
|
54
58
|
* Renderers may pass a larger reused scratch array to avoid allocating a subarray view per draw.
|
|
55
59
|
*/
|
|
56
60
|
instanceCount?: number;
|
|
@@ -80,6 +84,15 @@ export interface GPUBackend {
|
|
|
80
84
|
clearStencil?(): void;
|
|
81
85
|
setScissor(x: number, y: number, w: number, h: number): void;
|
|
82
86
|
resetScissor(): void;
|
|
87
|
+
/** Internal performance-harness diagnostics; absent on backends without native buffer uploads. */
|
|
88
|
+
getPerformanceSnapshot?(): {
|
|
89
|
+
bufferWrites: number;
|
|
90
|
+
bufferWriteBytes: number;
|
|
91
|
+
storageBufferWrites: number;
|
|
92
|
+
storageBufferWriteBytes: number;
|
|
93
|
+
};
|
|
94
|
+
/** Resets the internal performance-harness diagnostics for a new sampling window. */
|
|
95
|
+
resetPerformanceSnapshot?(): void;
|
|
83
96
|
destroy(): void;
|
|
84
97
|
}
|
|
85
98
|
export interface SVGAParams {
|
|
@@ -148,6 +161,8 @@ export interface SVGASpriteTable {
|
|
|
148
161
|
shapesTable: SVGAShape[][];
|
|
149
162
|
shapesIndex: Int32Array;
|
|
150
163
|
hasAnyShapes: boolean;
|
|
164
|
+
/** Internal parser-derived fast-path flag; undefined only for legacy/incomplete data. */
|
|
165
|
+
allFramesInsideViewBox?: boolean;
|
|
151
166
|
}
|
|
152
167
|
export interface SVGAAudio {
|
|
153
168
|
audioKey: string;
|
|
@@ -607,6 +622,11 @@ export interface GiftSlot {
|
|
|
607
622
|
accumulatedTime: number;
|
|
608
623
|
lastTickTime: number;
|
|
609
624
|
loopCount: number;
|
|
625
|
+
/**
|
|
626
|
+
* SVGABatchRenderer internal: most recent frame whose complete set of referenced clip meshes
|
|
627
|
+
* is ready. A later frame with a mesh miss renders this frame until the missing meshes land.
|
|
628
|
+
*/
|
|
629
|
+
svgaClipReadyFrame?: number | null;
|
|
610
630
|
videoEntity: VideoEntity | null;
|
|
611
631
|
loadAbortController?: AbortController | null;
|
|
612
632
|
/** HTMLVideoElement finite-playback watchdog; cleared on normal completion or resource release. */
|
|
@@ -34,6 +34,8 @@ export declare function decodeH264ToFrames(codec: string, description: ArrayBuff
|
|
|
34
34
|
}>;
|
|
35
35
|
export interface IncrementalH264DecoderCallbacks {
|
|
36
36
|
onFrame: (index: number, frame: VideoFrame) => void;
|
|
37
|
+
onDecoded?: () => void;
|
|
38
|
+
onDropped?: () => void;
|
|
37
39
|
onEos?: () => void;
|
|
38
40
|
onError?: (error: unknown) => void;
|
|
39
41
|
}
|
|
@@ -61,11 +63,13 @@ export declare class IncrementalH264Decoder {
|
|
|
61
63
|
private lastPostedMax;
|
|
62
64
|
private minPosted;
|
|
63
65
|
private playbackNeedFloor;
|
|
66
|
+
/** Remaining output budget from the latest `ensure`; decremented only when a frame is posted. */
|
|
64
67
|
private freeSlots;
|
|
65
68
|
private eosClosed;
|
|
66
69
|
private pumpScheduled;
|
|
67
70
|
private pumping;
|
|
68
71
|
private destroyed;
|
|
72
|
+
private readonly onDecoderDequeue;
|
|
69
73
|
constructor(decodeOrder: Sample[], presTimes: Float64Array, timescale: number, codec: string, description: ArrayBuffer | undefined, duration: number, callbacks: IncrementalH264DecoderCallbacks, initialNeedIdx: number);
|
|
70
74
|
/** Raise the decode target and/or update main-thread ring headroom; resumes the pump if idle. */
|
|
71
75
|
ensure(needIdx: number, freeSlots: number): void;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
export interface WebCodecsPerformanceSnapshot {
|
|
2
|
+
decodedFrames: number;
|
|
3
|
+
postedFrames: number;
|
|
4
|
+
closedFrames: number;
|
|
5
|
+
residentPeak: number;
|
|
6
|
+
workerMessages: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function resetWebCodecsPerformanceSnapshot(): void;
|
|
9
|
+
export declare function getWebCodecsPerformanceSnapshot(): WebCodecsPerformanceSnapshot;
|
|
1
10
|
/**
|
|
2
11
|
* Presentation-index → VideoFrame with bounded size.
|
|
3
12
|
* Eviction follows the playhead (see {@link setPlaybackHint}) so we keep a window around the
|
|
@@ -11,6 +20,7 @@ export declare class VideoFrameRing {
|
|
|
11
20
|
private playbackHint;
|
|
12
21
|
constructor(maxSize: number);
|
|
13
22
|
setPlaybackHint(idx: number): void;
|
|
23
|
+
private evictConsumedFrames;
|
|
14
24
|
minKey(): number | undefined;
|
|
15
25
|
set(idx: number, frame: VideoFrame): void;
|
|
16
26
|
private evictDownToCapacity;
|
package/package.json
CHANGED