@taole/giftstage 0.3.4 → 0.3.5

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 CHANGED
@@ -218,11 +218,20 @@ envelope 使用绝对毫秒半开区间 `[startMs,endMs)`,支持 `linear` / `h
218
218
  SVGA 主线程加载任务的共享时间片上限,默认 `12ms`。图片 fallback、atlas、clip、音频、slot 纹理、二进制缓存和 Hybrid 命令表构建共用同一帧预算。
219
219
  Hybrid 的路径解析、裁剪检查、逐帧计划和命令打包会分片执行;同一资源的重复裁剪路径复用分类和矩形结果,避免视频与复杂 SVGA 同播时被同步准备工作阻塞。资源释放或后端丢失后会取消未完成的构建。
220
220
 
221
+ - `svgaCommandTableInWorker?: boolean`
222
+ 默认 `true`。后台 Worker 构建 GPU 命令表并打包帧数据;关闭时使用主线程共享帧预算分片。CPU 模式跳过 GPU 帧表准备。Worker 不可用、异常或结果校验失败时,每个资源最多回退一次,取消不触发回退。
223
+ 输入按不超过 64 KiB 的片段复制,只转移专用副本;CPU 回退持有的原始数组保持有效。GPU 资源仍在主线程创建,并在发布前检查资源生命周期。
224
+
225
+ - `onSVGAPreparationProfile?: (profile: SVGAPreparationProfile) => void`
226
+ 可选的 GPU 资源准备汇总回调;未配置时不进行详细采样。每个准备任务结束时回调一次,包括实际 `executor`、回退原因、完成/取消/失败状态和各阶段数据。
227
+ `mainThreadExecutionMs` 与 `workerExecutionMs` 是实际执行片段累计;`elapsedMs` 包含调度等待,不能当作 CPU 计算时间。各阶段可能重叠,不能相加作为总准备时长。
228
+ 阶段包括裁剪准备、Worker 排队、输入复制、命令构建、帧表打包、校验和 GPU 提交,另含最大连续片段、命中次数与字节数。GPU 提交时间是主线程调用耗时,并非 GPU 完成时间;网络/解析等待不属于此准备汇总。
229
+
221
230
  - `svgaWorkerFrameBudgetMs?: number`
222
231
  SVGA Worker 连续执行 JS 循环的时间片上限,默认 `4ms`,范围 `1-8ms`。单次 WASM protobuf 调用和单次原生 API 调用仍不可抢占。
223
232
 
224
233
  - `svgaWorkerTaskConcurrency?: number`
225
- parser、图片解码、atlasclip CPU 密集 Worker 的全局并发上限,默认 `1`。Atlas 首帧页面可提前返回,但后台 PNG 编码完成前仍持有该名额,避免与其他重载 Worker 叠加。
234
+ parser、图片解码、atlasclip 和命令表 Worker 的全局并发上限,默认 `1`。命令任务每个时间片重新排队,前台解析/首帧优先,同级 FIFO;连续 8 次前台许可后允许一个后台片段。Atlas 首帧页面可提前返回,但后台 PNG 编码完成前仍持有该名额,避免与其他重载 Worker 叠加。
226
235
 
227
236
  - `svgaWorkerImageDecodeConcurrency?: number`
228
237
  图片解码 Worker 内 `createImageBitmap` 并发上限,默认 `2`。运行时可按批次耗时收缩并发,负载恢复后回升,但不会超过该上限。
@@ -236,7 +245,9 @@ envelope 使用绝对毫秒半开区间 `[startMs,endMs)`,支持 `linear` / `h
236
245
  - `svgaParseProfile?: boolean`
237
246
  是否输出 `[GiftStage:SVGA:Profile]` 结构化解析日志,默认 `false`。日志包含 `DecompressionStream` 格式尝试、输入/输出 chunk、解压耗时以及 protobuf/payload 构建耗时;WASM payload 路径还会拆分 `prostDecodeMs`、`metadataAndImagesMs`、`frameTableMs`、`finalizeMs` 和 WASM 边界复制耗时。缓存命中不输出。
238
247
 
239
- SVGA 礼物在加载阶段被 `destroy()` / `removeGift()` 时,会取消排队任务并终止正在执行的 parser、图片解码、atlas clip Worker。相同 URL 的共享加载按消费者计数,单个礼物取消不会中断其他仍在等待的礼物。
248
+ SVGA 礼物在加载阶段被 `destroy()` / `removeGift()` 时会取消相应订阅。相同 URL 的共享加载按消费者计数;裁剪生产和命令表属于资源,资源释放或 Stage 销毁才取消生产。命令任务使用 ID/代次隔离,取消一个资源不会终止其他资源的 Worker。
249
+
250
+ 同一个 Stage 的裁剪预热、渲染和命令构建共用分类/矩形分析;重复路径只保留小型分析结果,网格缓存与磁盘格式不变。首帧只等待该帧裁剪与纹理,其余准备推迟到首帧绘制后。渲染循环不再同步解析未准备好的裁剪路径,继续按整帧等待处理。
240
251
 
241
252
  - `onError?: (error: Error) => void`
242
253
  统一错误回调。
@@ -15,7 +15,7 @@ export declare class GiftStage {
15
15
  private readonly sharedSVGAEntities;
16
16
  private readonly pendingSharedSVGAEntities;
17
17
  /** One full clip-prewarm task per entity, shared by every slot using that entity. */
18
- private readonly svgaFullClipPrewarmPromises;
18
+ private svgaFullClipPrewarmPromises;
19
19
  /** Deferred persistent-cache writer captured while a URL-backed entity is being assembled. */
20
20
  private readonly svgaPersistentCacheWriters;
21
21
  private readonly svgaPersistentCacheWritePromises;
@@ -54,6 +54,9 @@ export declare class GiftStage {
54
54
  private reservedSVGAGpuFrameTableBytes;
55
55
  private svgaBackendLost;
56
56
  private svgaPreparingEntities;
57
+ private svgaCommandControllers;
58
+ private svgaPreparationSequence;
59
+ private svgaPreparationProfiles;
57
60
  private activeSVGATimelineEntities;
58
61
  private svgaEntitySources;
59
62
  private runtimeFallbackCount;
@@ -95,6 +98,7 @@ export declare class GiftStage {
95
98
  * so those focused harnesses exercise SVGA loading without having to mirror
96
99
  * every constructor-only field.
97
100
  */
101
+ private getSVGAPreparationProfile;
98
102
  private ensureSVGATimelineBookkeeping;
99
103
  private emitRuntimeDiagnostic;
100
104
  private recordObserverError;
@@ -1,3 +1,4 @@
1
+ import type { SVGAPreparationRecorder } from '../utils/svga-preparation-profile.js';
1
2
  import type { GPUBackend, GiftSlot, GiftHandle, GPUTextureHandle, VideoEntity } from '../types/index.js';
2
3
  import { type SVGAClipMeshMap } from '../renderers/svga-batch-renderer.js';
3
4
  import { PostAnimator } from './post-animator.js';
@@ -127,7 +128,10 @@ export declare class RenderManager {
127
128
  * cannot bypass media side effects while seeking the visual frame.
128
129
  */
129
130
  applyPlaybackScopeMediaTime(id: string, timeMs: number, emitInitialFrame?: boolean, discontinuous?: boolean): void;
131
+ releaseSVGAPreparation(entity: NonNullable<GiftSlot['videoEntity']>): void;
132
+ get svgaClipAnalysis(): import("../utils/svga-clip-analysis.js").SVGAClipAnalysisCache;
130
133
  prewarmSVGAClipMeshes(entity: NonNullable<GiftSlot['videoEntity']>, options?: {
134
+ profile?: SVGAPreparationRecorder;
131
135
  frameBudgetMs?: number;
132
136
  workerTimeSliceMs?: number;
133
137
  useWorker?: boolean;
@@ -135,6 +139,7 @@ export declare class RenderManager {
135
139
  signal?: AbortSignal;
136
140
  }): Promise<number>;
137
141
  prewarmSVGAClipMeshesForFrame(entity: NonNullable<GiftSlot['videoEntity']>, frame: number, options?: {
142
+ profile?: SVGAPreparationRecorder;
138
143
  frameBudgetMs?: number;
139
144
  workerTimeSliceMs?: number;
140
145
  useWorker?: boolean;
@@ -145,6 +150,10 @@ export declare class RenderManager {
145
150
  retainSVGAHybridMeshes(entity: NonNullable<GiftSlot['videoEntity']>): void;
146
151
  releaseSVGAHybridMeshes(entity: NonNullable<GiftSlot['videoEntity']>): void;
147
152
  hydrateSVGAClipMeshes(meshes: SVGAClipMeshMap | null | undefined): void;
153
+ hydrateSVGAClipMeshesCooperative(meshes: SVGAClipMeshMap | null | undefined, options?: {
154
+ frameBudgetMs?: number;
155
+ signal?: AbortSignal;
156
+ }): Promise<void>;
148
157
  snapshotSVGAClipMeshes(entity: NonNullable<GiftSlot['videoEntity']>): SVGAClipMeshMap;
149
158
  private renderLoop;
150
159
  private drawPreparedFrameWithReplay;