Generator 是可控数据流阀门、生命周期协作者与调度上下文载体,用于动态分块加载异构材质,支持按需触发、中断、回退及跨帧协同调度。

在高度复杂的画布渲染引擎中,用 Generator 动态控制异构材质的按需分块加载流水线,核心不是“写个 for 循环 yield”,而是把 Generator 作为**可控的数据流阀门 + 生命周期协作者 + 调度上下文载体**,嵌入材质加载全链路中。它要解决的不是“能不能分块”,而是“哪一块该在什么时机、以什么优先级、带什么上下文、失败后如何回退”——尤其当材质来源混杂(本地纹理包、CDN 压缩图、WebGPU 纹理数组、实时生成的 SDF 字体、AI 超分后的 HDR 贴图)时。
把 Generator 当作材质加载的“可暂停调度器”
传统 Promise.all 加载会一次性拉取全部分块,内存暴涨且无法中断;而 Generator 函数天然支持 next() 按需触发、throw() 主动中断、return() 提前收尾。关键在于:每个 yield 不返回数据,而是返回一个可执行、可校验、可熔断的加载任务描述对象,例如:
{ type: 'texture', src: '/tiles/0_1.webp', region: [0, 128, 256, 256], priority: 0.8 }{ type: 'sdf-font', char: 'A', atlasId: 'roboto-sdf-24', fallback: 'system' }{ type: 'webgpu-mip', level: 3, data: new GPUBufferDescriptor(...) }
引擎主循环根据视口变化、帧耗时、GPU 内存余量等信号,调用 generator.next() 获取下一个待加载项,并交由对应适配器执行——真正实现“需要哪块、才加载哪块、卡了就停、切走了就弃”。
与渲染管线深度协同:让 yield 成为帧节奏锚点
Generator 不孤立运行,而是绑定到渲染帧周期中。例如在 WebGPU 的 requestAnimationFrame 或鸿蒙 Renderer Core Scheduler 的帧时间监控回调里驱动:
- 若当前帧剩余时间 < 3ms,跳过本次
next(),避免掉帧 - 若检测到 VSYNC 同步延迟,主动
generator.throw('vsync_drift')触发降级策略(如跳过 mip-level 3+ 加载) - 利用
yield* subGenerator实现材质类型分组调度:先 yield 所有高优先级 UI 图标块,再 yield 场景背景分块,再 yield 动态粒子贴图
这样,Generator 就从语法特性升维为跨帧资源节拍器,和内核调度层形成双向反馈。
承载上下文契约,支撑异构材质熔断与回退
不同材质加载失败后果不同:一张 UI 图标加载失败可降级为纯色占位;但 SDF 字体缺失会导致文本不可读;WebGPU 纹理创建失败可能引发整个管线崩溃。Generator 在 yield 前可注入强契约信息:
-
inputSchema:声明所需解码器(WebP / AVIF / KTX2)、GPU 格式(gpuTextureFormat: 'rgba8unorm-srgb')、内存对齐要求 -
fallback:指定降级路径(本地兜底图、ASCII 替代符、空 buffer + debug log) -
timeoutMs和retry: { max: 2, backoff: 'exponential' }
当适配器执行失败,不直接 reject,而是 generator.throw(new LoadError(task, error)),由上层统一做熔断决策——比如标记该材质为“暂不可用”,后续 next() 自动跳过同类请求,或触发预加载备用通道。
支持热插拔与运行时重编排
工业级画布常需动态切换材质策略(如从 CDN 切到边缘节点、从 CPU 解码切到 WebGPU Video Decoder)。此时无需重启 Generator,只需:
- 调用
generator.return()终止当前流水线 - 基于新配置重新
createMaterialLoaderGenerator(viewport, config) - 复用原 Generator 实例的
context对象(含已加载块缓存、历史优先级权重、设备特征指纹)
这种设计让 Generator 成为状态可携带、策略可热更、流程可审计的材质加载中枢,而非一次性的迭代器。

















