fix(app): 修复笔画缓存 use-after-dispose — 移除增量合成时的提前 dispose

- _compositeIncremental 中不再 dispose strokeImage,因为 _cache 持有同一引用
- 提前 dispose 导致 syncStrokes/clear/dispose 时 double-dispose(use-after-free)
- 单笔画 image 生命周期由缓存统一管理:移除/清除/销毁时释放
- 更新 _rebuildComposite 注释,移除过时说明

审计 ID: 8b-R01
This commit is contained in:
iven
2026-06-03 01:06:34 +08:00
parent e0052ea99b
commit 9ce300ddb9

View File

@@ -232,14 +232,10 @@ class StrokeRasterCache {
_canvasSize.height.toInt().clamp(1, 4096),
);
// 单笔画图像已合成,释放以节省 GPU 内存
strokeImage.dispose();
// 注意:从 _cache 中移除该条目的 image保留 stroke 引用以备重建)
// 不,缓存保留 image 引用以便撤销时重建。增量合成时释放 strokeImage
// 但 _cache 仍持有引用,所以需要用另一个方式
// 实际上增量合成后可以释放单笔画图像——合成图已包含其内容
// 但撤销时需要重建,需要原始数据。保留 Stroke 数据,释放 image。
// 如果后续撤销syncStrokes 会重新光栅化。
// 注意:不在此处 dispose strokeImage
// _cache 和此方法持有同一 image 引用,提前 dispose 会导致
// syncStrokes/clear/dispose 时 use-after-dispose审计 ID: 8b-R01
// 单笔画 image 由缓存统一管理生命周期(移除/清除/销毁时释放)。
_layerVersion++;
}
@@ -265,8 +261,7 @@ class StrokeRasterCache {
);
// 按笔画顺序重新绘制所有单笔画
// 注意:增量合成时已释放了单笔画 image这里需要重新光栅化
// 所以全量重建时,直接用 stroke 数据重绘路径(不依赖缓存的 image
// 直接从 stroke 数据重绘路径,确保与增量合成结果一致
for (final entry in _cache.values) {
final stroke = entry.stroke;
final outlinePoints = pointsToOutline(