@taole/giftstage 0.2.2 → 0.3.1
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/README.md +15 -3
- package/dist/core/gift-stage.d.ts +2 -1
- package/dist/core/render-manager.d.ts +5 -2
- package/dist/gift-stage.cjs +180 -47
- package/dist/gift-stage.es.js +2614 -1969
- package/dist/gpu/webgl2-backend.d.ts +2 -0
- package/dist/gpu/webgpu-backend.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/plugin/playback-scope.d.ts +3 -1
- package/dist/plugin/types.d.ts +74 -2
- package/dist/renderers/particle-batch-renderer.d.ts +46 -3
- package/dist/shaders/index.d.ts +5 -0
- package/dist/types/index.d.ts +4 -2
- package/package.json +1 -1
|
@@ -144,6 +144,7 @@ export declare class WebGL2Backend implements GPUBackend {
|
|
|
144
144
|
private recordSubmittedDraw;
|
|
145
145
|
private rejectSVGAFastPathDraw;
|
|
146
146
|
private initPrograms;
|
|
147
|
+
private ensureParticleSpriteProgram;
|
|
147
148
|
private makeProgramEntry;
|
|
148
149
|
/**
|
|
149
150
|
* `u_transform` on `svga-batch-premul` defaults to identity; shape draws overwrite it and
|
|
@@ -238,6 +239,7 @@ export declare class WebGL2Backend implements GPUBackend {
|
|
|
238
239
|
/** Shape/clip meshes fetch their child transform from the same resident frame table. */
|
|
239
240
|
private drawSVGAFrameTableMeshGL;
|
|
240
241
|
private drawInstancedParticlesGL;
|
|
242
|
+
private drawInstancedParticleSpritesGL;
|
|
241
243
|
private drawInstancedSvgaGL;
|
|
242
244
|
private ensureInstancedClipMaskBuffer;
|
|
243
245
|
private drawInstancedClipMaskGL;
|
|
@@ -214,6 +214,7 @@ export declare class WebGPUBackend implements GPUBackend {
|
|
|
214
214
|
private ensureSVGAFrameTableMeshPipeline;
|
|
215
215
|
private ensureMotionSvgaPipeline;
|
|
216
216
|
private ensureParticlePipeline;
|
|
217
|
+
private ensureParticleSpritePipeline;
|
|
217
218
|
private createInstancedSvgaPipeline;
|
|
218
219
|
private createInstancedClipMaskPipeline;
|
|
219
220
|
private createVapInstancedPipeline;
|
package/dist/index.d.ts
CHANGED
|
@@ -33,4 +33,4 @@ export { initWasm, isWasmReady } from './wasm/wasm-bridge.js';
|
|
|
33
33
|
export { WebCodecsMp4Playback } from './video/webcodecs-mp4-playback.js';
|
|
34
34
|
export type { WebCodecsMp4CreateOptions } from './video/webcodecs-mp4-playback.js';
|
|
35
35
|
export type { WebCodecsPlaybackHandle, GPUBackend, BackendOperationFailureReason, BackendOperationResult, GPUBufferHandle, GPUTextureHandle, TextureOpts, BufferUsage, DrawCommand, ShaderType, BackendType, ParentMotionMode, SVGADrawBatchMode, SVGAFrameEvaluation, SVGAFrameEvaluationStrategy, SVGAFrameTableBinding, SVGAFrameTableBindingBase, SVGAFrameTableCreateOptions, SVGAFrameTableState, SVGAFrameTimelineFallbackReason, SVGAFrameTimelinePath, SVGAFrameTimelineRenderInfo, SVGAFrameTimelineStrategy, SVGAFrameTimelineTransport, SVGARenderFallbackReason, SVGARenderInfo, SVGARenderPath, SVGARenderPathState, SVGARenderPathChangeInfo, GiftStageRuntimeDiagnosticType, GiftStageRuntimeDiagnosticEvent, GiftStageRuntimeDiagnostics, SVGAHybridCommandTable, SVGAHybridOperation, SVGAHybridOperationType, SVGATimelineDrawRun, WebGL2FrameTableBinding, WebGPUFrameTableBinding, GiftStageOptions, AddGiftOptions, GiftHandle, GiftSlot, GiftType, GiftObjectFit, GiftCoordinate, GiftState, GiftAnimationStep, GiftAnimationChain, SVGAMovieEntity, SVGAParams, SVGASpriteTable, SVGAAudio, SVGATransform, SVGAShape, VideoEntity, UVRect, FrameJobData, FlyAnimation, VAPConfig, VAPSrcItem, VAPFrameItem, VAPFrameObj, } from './types/index.js';
|
|
36
|
-
export type { GiftAssetLease, GiftAssetMetadata, GiftStageCapabilities, SVGAFrameTimelineCapabilities, GiftStagePlugin, GiftStagePluginHost, MountedGiftStagePlugin, MotionBindingOptions, MotionTrackDescriptor, MotionTrackLease, ParticleBatchDescriptor, ParticleBatchHandle, PlaybackFrame, PlaybackScope, PlaybackScopeStartOptions, PlaybackScopeState, ReadonlyTableDescriptor, ReadonlyTableLease, } from './plugin/types.js';
|
|
36
|
+
export type { GiftAssetLease, GiftAssetMetadata, GiftStageCapabilities, SVGAFrameTimelineCapabilities, GiftStagePlugin, GiftStagePluginHost, MountedGiftStagePlugin, MotionBindingOptions, MotionTrackDescriptor, MotionTrackLease, BallisticV1ParticleBatchDescriptor, ParticleAtlasDescriptor, ParticleAtlasHandle, ParticleBatchDescriptor, ParticleBatchEnvelope, ParticleBatchGroupHandle, ParticleBatchHandle, ParticleEnvelopeSegment, SpriteV2ParticleBatchDescriptor, PlaybackFrame, PlaybackScope, PlaybackScopeStartOptions, PlaybackScopeState, ReadonlyTableDescriptor, ReadonlyTableLease, } from './plugin/types.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AddGiftOptions, GiftHandle } from '../types/index.js';
|
|
2
|
-
import type { MotionBindingOptions, MotionTrackDescriptor, MotionTrackLease, ParticleBatchDescriptor, ParticleBatchHandle, PlaybackFrame, PlaybackFrameController, PlaybackScope, PlaybackScopeHost, PlaybackScopeStartOptions, PlaybackScopeState } from './types.js';
|
|
2
|
+
import type { MotionBindingOptions, MotionTrackDescriptor, MotionTrackLease, ParticleBatchDescriptor, ParticleBatchGroupHandle, ParticleBatchHandle, PlaybackFrame, PlaybackFrameController, PlaybackScope, PlaybackScopeHost, PlaybackScopeStartOptions, PlaybackScopeState } from './types.js';
|
|
3
3
|
export declare class PlaybackScopeImpl implements PlaybackScope, PlaybackFrameController {
|
|
4
4
|
readonly id: string;
|
|
5
5
|
private readonly host;
|
|
@@ -8,6 +8,7 @@ export declare class PlaybackScopeImpl implements PlaybackScope, PlaybackFrameCo
|
|
|
8
8
|
private readonly tracks;
|
|
9
9
|
private readonly bindings;
|
|
10
10
|
private readonly particleBatches;
|
|
11
|
+
private readonly particleBatchGroups;
|
|
11
12
|
private readonly frameListeners;
|
|
12
13
|
private readonly finishListeners;
|
|
13
14
|
private unregisterController;
|
|
@@ -23,6 +24,7 @@ export declare class PlaybackScopeImpl implements PlaybackScope, PlaybackFrameCo
|
|
|
23
24
|
addGift(options: AddGiftOptions): Promise<GiftHandle>;
|
|
24
25
|
createMotionTrack(descriptor: MotionTrackDescriptor): MotionTrackLease;
|
|
25
26
|
createParticleBatch(descriptor: ParticleBatchDescriptor): ParticleBatchHandle;
|
|
27
|
+
createParticleBatchGroup(descriptors: readonly ParticleBatchDescriptor[]): ParticleBatchGroupHandle;
|
|
26
28
|
bindMotion(gift: GiftHandle, track: MotionTrackLease, trackIndex: number, options?: MotionBindingOptions): () => void;
|
|
27
29
|
onFrame(listener: (frame: PlaybackFrame) => void): () => void;
|
|
28
30
|
onFinish(listener: () => void): () => void;
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -51,6 +51,16 @@ export interface GiftStageCapabilities {
|
|
|
51
51
|
particles: {
|
|
52
52
|
backend: 'webgpu' | 'webgl2' | 'unavailable';
|
|
53
53
|
canvas2D: false;
|
|
54
|
+
/** Optional feature negotiation. Absent on pre-sprite-v2 hosts. */
|
|
55
|
+
formats?: Array<'ballistic-v1' | 'sprite-v2'>;
|
|
56
|
+
spriteAtlas?: {
|
|
57
|
+
source: 'rgba8-premultiplied';
|
|
58
|
+
maxSize: number;
|
|
59
|
+
};
|
|
60
|
+
compositeLayers?: Array<'behind-media' | 'above-media'>;
|
|
61
|
+
batchEnvelope?: boolean;
|
|
62
|
+
atomicBatchGroup?: boolean;
|
|
63
|
+
maxInstancesPerBatch?: number;
|
|
54
64
|
};
|
|
55
65
|
/** Public SVGA frame-table path support exposed to playback plugins. */
|
|
56
66
|
svgaFrameTimeline?: SVGAFrameTimelineCapabilities;
|
|
@@ -107,16 +117,65 @@ export interface PlaybackFrame {
|
|
|
107
117
|
* Particle instance layout (16 floats): birth, lifetime, x, y, vx, vy, ax, ay,
|
|
108
118
|
* scale, scaleSpeed, rotation, spin, r, g, b, a. Times are seconds; positions are CSS pixels.
|
|
109
119
|
*/
|
|
110
|
-
export interface
|
|
120
|
+
export interface BallisticV1ParticleBatchDescriptor {
|
|
121
|
+
/** Omitted for backward compatibility. */
|
|
122
|
+
format?: 'ballistic-v1';
|
|
111
123
|
count: number;
|
|
112
124
|
instances: Float32Array;
|
|
113
125
|
particleSize?: number;
|
|
114
126
|
opacity?: number;
|
|
115
|
-
/** Sorts particle batches
|
|
127
|
+
/** Sorts particle batches inside their composite phase only. */
|
|
116
128
|
zIndex?: number;
|
|
117
129
|
blend?: 'normal' | 'additive';
|
|
130
|
+
/** v1 remains above media unless explicitly requested otherwise. */
|
|
131
|
+
compositeLayer?: 'behind-media' | 'above-media';
|
|
118
132
|
label?: string;
|
|
119
133
|
}
|
|
134
|
+
export interface ParticleAtlasDescriptor {
|
|
135
|
+
width: number;
|
|
136
|
+
height: number;
|
|
137
|
+
pixels: Uint8Array;
|
|
138
|
+
colorSpace: 'srgb';
|
|
139
|
+
alphaMode: 'premultiplied';
|
|
140
|
+
filter?: 'linear';
|
|
141
|
+
label?: string;
|
|
142
|
+
}
|
|
143
|
+
export interface ParticleAtlasHandle {
|
|
144
|
+
readonly width: number;
|
|
145
|
+
readonly height: number;
|
|
146
|
+
/** The caller lease was released. Existing groups may retain the GPU resource. */
|
|
147
|
+
readonly destroyed: boolean;
|
|
148
|
+
/** The owning backend generation was lost. Lost handles cannot be reused. */
|
|
149
|
+
readonly lost: boolean;
|
|
150
|
+
destroy(): void;
|
|
151
|
+
}
|
|
152
|
+
export interface ParticleEnvelopeSegment {
|
|
153
|
+
/** Absolute playback milliseconds. Segments use the half-open interval [startMs, endMs). */
|
|
154
|
+
startMs: number;
|
|
155
|
+
endMs: number;
|
|
156
|
+
from: number;
|
|
157
|
+
to: number;
|
|
158
|
+
interpolation?: 'linear' | 'hold';
|
|
159
|
+
}
|
|
160
|
+
export interface ParticleBatchEnvelope {
|
|
161
|
+
opacity?: readonly ParticleEnvelopeSegment[];
|
|
162
|
+
size?: readonly ParticleEnvelopeSegment[];
|
|
163
|
+
}
|
|
164
|
+
export interface SpriteV2ParticleBatchDescriptor {
|
|
165
|
+
format: 'sprite-v2';
|
|
166
|
+
atlas: ParticleAtlasHandle;
|
|
167
|
+
count: number;
|
|
168
|
+
/** 24 floats per instance; the first 16 preserve ballistic-v1 semantics. */
|
|
169
|
+
instances: Float32Array;
|
|
170
|
+
opacity?: number;
|
|
171
|
+
fadeMode?: 'none' | 'lifetime';
|
|
172
|
+
envelope?: ParticleBatchEnvelope;
|
|
173
|
+
compositeLayer?: 'behind-media' | 'above-media';
|
|
174
|
+
zIndex?: number;
|
|
175
|
+
blend?: 'normal' | 'additive';
|
|
176
|
+
label?: string;
|
|
177
|
+
}
|
|
178
|
+
export type ParticleBatchDescriptor = BallisticV1ParticleBatchDescriptor | SpriteV2ParticleBatchDescriptor;
|
|
120
179
|
export interface ParticleBatchHandle {
|
|
121
180
|
readonly count: number;
|
|
122
181
|
readonly destroyed: boolean;
|
|
@@ -124,6 +183,14 @@ export interface ParticleBatchHandle {
|
|
|
124
183
|
setOpacity(opacity: number): void;
|
|
125
184
|
destroy(): void;
|
|
126
185
|
}
|
|
186
|
+
export interface ParticleBatchGroupHandle {
|
|
187
|
+
readonly count: number;
|
|
188
|
+
readonly destroyed: boolean;
|
|
189
|
+
readonly faulted: boolean;
|
|
190
|
+
setTime(timeMs: number): void;
|
|
191
|
+
setOpacity(opacity: number): void;
|
|
192
|
+
destroy(): void;
|
|
193
|
+
}
|
|
127
194
|
export interface PlaybackScope {
|
|
128
195
|
readonly id: string;
|
|
129
196
|
readonly signal: AbortSignal;
|
|
@@ -132,6 +199,8 @@ export interface PlaybackScope {
|
|
|
132
199
|
addGift(options: AddGiftOptions): Promise<GiftHandle>;
|
|
133
200
|
createMotionTrack(descriptor: MotionTrackDescriptor): MotionTrackLease;
|
|
134
201
|
createParticleBatch(descriptor: ParticleBatchDescriptor): ParticleBatchHandle;
|
|
202
|
+
/** Optional in API v1; feature-detect through `capabilities.particles.atomicBatchGroup`. */
|
|
203
|
+
createParticleBatchGroup?(descriptors: readonly ParticleBatchDescriptor[]): ParticleBatchGroupHandle;
|
|
135
204
|
bindMotion(gift: GiftHandle, track: MotionTrackLease, trackIndex: number, options?: MotionBindingOptions): () => void;
|
|
136
205
|
onFrame(listener: (frame: PlaybackFrame) => void): () => void;
|
|
137
206
|
onFinish(listener: () => void): () => void;
|
|
@@ -150,6 +219,8 @@ export interface GiftStagePluginHost {
|
|
|
150
219
|
height: number;
|
|
151
220
|
};
|
|
152
221
|
preload(type: 'svga' | 'image', source: string | ArrayBuffer, signal?: AbortSignal): Promise<GiftAssetLease>;
|
|
222
|
+
/** Optional in API v1; uploads one immutable premultiplied RGBA8 atlas. */
|
|
223
|
+
createParticleAtlas?(descriptor: ParticleAtlasDescriptor): Promise<ParticleAtlasHandle>;
|
|
153
224
|
createPlaybackScope(id?: string): PlaybackScope;
|
|
154
225
|
}
|
|
155
226
|
export interface GiftStagePlugin<TApi = unknown> {
|
|
@@ -176,6 +247,7 @@ export interface PlaybackScopeHost {
|
|
|
176
247
|
invalidate(resetClock?: boolean): void;
|
|
177
248
|
registerFrameController(controller: PlaybackFrameController): () => void;
|
|
178
249
|
createParticleBatch(descriptor: ParticleBatchDescriptor): ParticleBatchHandle;
|
|
250
|
+
createParticleBatchGroup?(descriptors: readonly ParticleBatchDescriptor[]): ParticleBatchGroupHandle;
|
|
179
251
|
}
|
|
180
252
|
export interface PlaybackFrameController {
|
|
181
253
|
readonly active: boolean;
|
|
@@ -1,19 +1,62 @@
|
|
|
1
1
|
import type { GPUBackend } from '../types/index.js';
|
|
2
|
-
import type { ParticleBatchDescriptor, ParticleBatchHandle } from '../plugin/types.js';
|
|
2
|
+
import type { ParticleAtlasDescriptor, ParticleAtlasHandle, ParticleBatchDescriptor, ParticleBatchGroupHandle, ParticleBatchHandle } from '../plugin/types.js';
|
|
3
|
+
type ParticleCompositeLayer = 'behind-media' | 'above-media';
|
|
4
|
+
export declare class ParticleBatchGroupDrawError extends Error {
|
|
5
|
+
readonly group: ParticleBatchGroupHandle;
|
|
6
|
+
constructor(group: ParticleBatchGroupHandle, message: string);
|
|
7
|
+
}
|
|
3
8
|
export declare class ParticleBatchRenderer {
|
|
4
9
|
private readonly backend;
|
|
5
10
|
private readonly batches;
|
|
11
|
+
private readonly groups;
|
|
12
|
+
private readonly atlases;
|
|
13
|
+
private readonly onRuntimeDiagnostic?;
|
|
6
14
|
private quadVB;
|
|
7
15
|
private quadIB;
|
|
8
16
|
private nextOrder;
|
|
9
17
|
private projW;
|
|
10
18
|
private projH;
|
|
11
19
|
private projection;
|
|
20
|
+
private backendLost;
|
|
21
|
+
private destroyed;
|
|
22
|
+
private drawOrderDirty;
|
|
23
|
+
private readonly behindDrawOrder;
|
|
24
|
+
private readonly aboveDrawOrder;
|
|
25
|
+
private readonly cssScaleUniform;
|
|
12
26
|
private readonly uniforms;
|
|
13
27
|
private readonly command;
|
|
14
|
-
constructor(backend: GPUBackend
|
|
28
|
+
constructor(backend: GPUBackend, onRuntimeDiagnostic?: (event: {
|
|
29
|
+
type: 'particle-group-failure';
|
|
30
|
+
message?: string;
|
|
31
|
+
}) => void);
|
|
32
|
+
createAtlas(descriptor: ParticleAtlasDescriptor): Promise<ParticleAtlasHandle>;
|
|
15
33
|
createBatch(descriptor: ParticleBatchDescriptor): ParticleBatchHandle;
|
|
34
|
+
createBatchGroup(descriptors: readonly ParticleBatchDescriptor[]): ParticleBatchGroupHandle;
|
|
16
35
|
get activeCount(): number;
|
|
17
|
-
|
|
36
|
+
private rebuildDrawOrder;
|
|
37
|
+
draw(compositeLayer?: ParticleCompositeLayer): void;
|
|
38
|
+
/** Uploads complete dirty groups inside the active framebuffer transaction. */
|
|
39
|
+
prepareFrame(): void;
|
|
40
|
+
onBackendLoss(): void;
|
|
18
41
|
destroy(): void;
|
|
42
|
+
private assertAvailable;
|
|
43
|
+
private validateDescriptor;
|
|
44
|
+
private validateEnvelope;
|
|
45
|
+
private cloneEnvelope;
|
|
46
|
+
private createGroupRecord;
|
|
47
|
+
private stageRecord;
|
|
48
|
+
private setRecordTime;
|
|
49
|
+
private setRecordOpacity;
|
|
50
|
+
private updateRecordHeader;
|
|
51
|
+
private syncRecordCssScale;
|
|
52
|
+
private evaluateEnvelope;
|
|
53
|
+
private faultGroup;
|
|
54
|
+
private destroyGroup;
|
|
55
|
+
private destroyRecord;
|
|
56
|
+
private disposeStagedRecord;
|
|
57
|
+
private retainAtlas;
|
|
58
|
+
private releaseAtlasCaller;
|
|
59
|
+
private releaseAtlasRetain;
|
|
60
|
+
private releaseAtlasRef;
|
|
19
61
|
}
|
|
62
|
+
export {};
|
package/dist/shaders/index.d.ts
CHANGED
|
@@ -55,6 +55,10 @@ export declare const glsl: {
|
|
|
55
55
|
readonly vert: string;
|
|
56
56
|
readonly frag: string;
|
|
57
57
|
};
|
|
58
|
+
readonly particleSpriteInstanced: {
|
|
59
|
+
readonly vert: string;
|
|
60
|
+
readonly frag: string;
|
|
61
|
+
};
|
|
58
62
|
};
|
|
59
63
|
export declare const wgsl: {
|
|
60
64
|
readonly svgaBatchPremul: string;
|
|
@@ -68,6 +72,7 @@ export declare const wgsl: {
|
|
|
68
72
|
readonly clipMask: string;
|
|
69
73
|
readonly clipMaskInstanced: string;
|
|
70
74
|
readonly particleInstanced: string;
|
|
75
|
+
readonly particleSpriteInstanced: string;
|
|
71
76
|
readonly svgaMotionInstancedPremul: string;
|
|
72
77
|
readonly svgaFrameTableShape: string;
|
|
73
78
|
readonly svgaFrameTableClipMask: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type SVGADrawBatchMode = 'multi-slot' | 'per-slot' | 'hybrid-scheduled';
|
|
|
21
21
|
/** Why a slot did not use the direct SVGA GPU frame-table path. */
|
|
22
22
|
export type SVGARenderFallbackReason = 'device-capability' | 'table-too-large-or-budget' | 'table-preparing' | 'upload-failed' | 'slot-overrides' | 'plan-not-ready-or-unsupported' | 'validation-failed' | 'policy-disabled';
|
|
23
23
|
export type SVGAFrameTimelineFallbackReason = SVGARenderFallbackReason;
|
|
24
|
-
export type GiftStageRuntimeDiagnosticType = 'svga-frame-abort' | 'svga-frame-replay-failed' | 'svga-frame-retry' | 'svga-runtime-fallback' | 'gpu-uncaptured-error' | 'backend-lost' | 'observer-error' | 'clip-protocol-error' | 'clip-mesh-invalid' | 'stencil-transaction-failure' | 'backend-operation-rejected' | 'atlas-command-invalid' | 'backend-quarantined';
|
|
24
|
+
export type GiftStageRuntimeDiagnosticType = 'svga-frame-abort' | 'svga-frame-replay-failed' | 'svga-frame-retry' | 'svga-runtime-fallback' | 'gpu-uncaptured-error' | 'backend-lost' | 'observer-error' | 'clip-protocol-error' | 'clip-mesh-invalid' | 'stencil-transaction-failure' | 'backend-operation-rejected' | 'atlas-command-invalid' | 'backend-quarantined' | 'frame-controller-failure' | 'particle-group-failure';
|
|
25
25
|
/** One production-safe runtime event. GiftStage never uploads these events. */
|
|
26
26
|
export interface GiftStageRuntimeDiagnosticEvent {
|
|
27
27
|
type: GiftStageRuntimeDiagnosticType;
|
|
@@ -205,7 +205,9 @@ export type ShaderType = 'svga-batch-premul'
|
|
|
205
205
|
/** WebGPU / WebGL2: one local-space clip mesh transformed by per-instance affine data. */
|
|
206
206
|
| 'clip-mask-instanced'
|
|
207
207
|
/** WebGPU / WebGL2: immutable ballistic particle instances evaluated in the vertex shader. */
|
|
208
|
-
| 'particle-instanced'
|
|
208
|
+
| 'particle-instanced'
|
|
209
|
+
/** WebGPU / WebGL2: immutable textured sprite-v2 particles sampled from an explicit atlas. */
|
|
210
|
+
| 'particle-sprite-instanced';
|
|
209
211
|
export type StencilMode = 'none' | 'write' | 'test' | 'clear';
|
|
210
212
|
export interface DrawCommand {
|
|
211
213
|
shader: ShaderType;
|
package/package.json
CHANGED