维刻 Vex
GitHub
维刻 Vex / 文档 / Windows 源码按行布局与渲染后端复验(2026-10-17)

Windows 源码按行布局与渲染后端复验(2026-10-17)

变更范围

Windows 源码视图采用 Re-Editor 0.10.0 的原生可见行布局及双向滚动。MarkdownEditorController / MarkdownSession 继续管理源文、选区和唯一撤销栈;桥接层保留 UTF-16 偏移、未修改区域的混合 CRLF / LF / CR、末尾空行、列表回车续写、工具栏及查找选区。每份文档分别保留横纵滚动位置,异步粘贴在控件销毁后停止。

源码关闭自动换行。上游在向上远跳时会逐行排版中间行,本轮通过公开的 forceRepaint 接口,在向上跳过一屏以上时重建可见段落缓存,按固定行高直接定位;选区、源文和历史不变。没有修改 pub 缓存或分发私有依赖补丁。

Windows 启动器使用 DartProject.set_impeller_switch(ImpellerSwitch::Disabled) 固定 Skia,直接启动的 Release 程序也使用该设置。Android、iOS、macOS、Linux、Web 及其他未原生验收的平台保留 TextField 输入链路。本轮没有更新 Android 预览 APK。

后端对照与回退记录

后端 / 轮次 已完成操作 整轮结果
Impeller GLES,首次 124 原生进程堆损坏退出,中断
Impeller GLES,抓取转储复跑 50 再次原生堆损坏退出,中断
Skia,首次对照 292 演示导图适配断言失败,未完整通过
Skia,完整复跑、尚未处理向上远跳 756 稳定性通过,但源码深滚动构建帧回退至 666.278 ms

两次 Impeller 故障的 Windows 异常码为 0xC0000374。本地转储使用匹配的 Flutter 引擎 PDB 解析,堆损坏在栅格线程释放 std::function 时被发现,调用栈包含 impeller::EncodeCommandsInReactor、RenderPassGLES::OnEncodeCommands 和 ReactorGLES::FlushOps。这是故障被发现的位置,尚不能据此认定最初越界写入的根因。

首次 Skia 对照未发生同类进程退出,但导图宽度 942 对视口宽度 0 的断言失败。因此 292 项和零操作异常不代表整轮通过。原生压力测试现会把外层断言失败保存为 testFailure,汇总脚本据此标记失败,并允许零操作的失败结果。

匿名数据:Impeller 首次中断、Impeller 转储复跑中断、Skia 首次未完成、修复远跳前的完整复跑。原始文档、绝对路径和崩溃转储均不提交。

验证方法

Windows x64 原生 Profile,Flutter 3.47.7 / Dart 3.13.5;自定义标题栏、最大化窗口,外框 3456×1408、客户区 3440×1392、DPR 1。沿用前次六份样本、八种布局、六轮反向切换、深滚动及正文 / 导图演示工作负载。输入只读加载到内存仓储,逐项核对文档不变且不产生脏状态。

计时包括测试手势及等待界面稳定;不包含磁盘读取。RSS 为操作结束采样值,并非连续峰值。旧全文 TextField 基线使用 Impeller,本轮使用 Skia,因此不计算只归因于编辑器的优化百分比,也不据此声称 60 FPS。

复跑命令(应用目录):

powershell
flutter drive --profile -d windows --no-enable-impeller --driver test_driver/integration_test.dart --target integration_test/document_stress_test.dart --no-pub
flutter drive --profile -d windows --driver test_driver/integration_test.dart --target integration_test/source_editing_test.dart --no-pub

第一项使用 VEX_STRESS_INPUTS(路径 JSON 数组)、VEX_STRESS_OUTPUT、VEX_STRESS_ROUNDS=6、VEX_STRESS_DEEP_SCROLL=1。第二项沿用输入数组,并用 VEX_SOURCE_RESULT 输出匿名检查结果;省略数组时只运行合成样本。第二项不传后端参数,使用启动器的默认 Skia 设置。

Release 关闭复验使用 test_driver/window_shutdown_smoke.dart,复用实际工作区、标题栏关闭回调及 Windows Runner,仓储换成内存实现,不读写用户配置或原始文档。分别检查干净文档直接关闭、脏文档取消后保留草稿关闭;测试入口等待原生消息循环自行退出,不从 Dart 调用 exit(0)。

先以 flutter build windows --release --target test_driver/window_shutdown_smoke.dart --no-pub 构建测试入口,再使用仓库的 scripts/test_windows_shutdown.ps1,传入该可执行文件绝对路径(-Executable)和全新输出目录(-OutputDirectory)。父进程验证退出码、关闭前已刷新草稿的检查点和内容,并查询本轮 Windows Application 1000 / 1001 故障事件。processLifetimeMs 包含启动及全部测试步骤,不是关闭延迟。

关闭复验后必须使用 flutter build windows --release --target lib/main.dart --no-pub 重建正式程序入口,避免把关闭测试程序留作产品构建。

本轮结果

修复向上远跳后的原生 Profile 完整压力测试通过:756 项、零操作异常、testCompleted: true、pending: null。每项操作核对源文不变、未产生脏状态,并保持最大化窗口。驱动不再传后端覆盖参数,实际使用 Windows Runner 的 Skia 设置。最终匿名结果。

同一 Skia 后端、相同工作负载的两轮完整观测:

项目 处理远跳前 处理远跳后
已完成操作 756 756
源码深滚动最大构建帧 666.278 ms 18.010 ms
全部操作最大构建帧 666.278 ms 89.327 ms
全部操作最大栅格帧 26.324 ms 23.372 ms
操作结束采样最大 RSS 1060.004 MiB 388.609 MiB

源码深滚动统计包含单源码、源码+导图、源码+阅读及三视图中的源码窗格,共 60 项。最终最慢构建发生于大型混合文档反复切入三视图,仍超过一帧预算,不能声明全程无卡顿或达到 60 FPS。

最终首次切入源码的观测值:

样本 UTF-16 长度 操作至稳定 最大构建帧
document-1 68,379 383.399 ms 15.207 ms
document-2 882,163 399.826 ms 54.011 ms
document-3 21,796 353.448 ms 7.025 ms
document-4 435,304 368.644 ms 27.056 ms
document-5 64,584 356.676 ms 14.688 ms
document-6 30,990 355.297 ms 7.362 ms

旧全文 TextField / Impeller 最大化基线的全部操作最大构建帧为 1344.730 ms、采样最大 RSS 为 1070.648 MiB;这组数跨越后端和实现变化,仅作历史参照。

原生源码编辑检查通过:真实平台剪贴板、UTF-16 选区、混合换行、Ctrl+Z / Ctrl+Y、Ctrl+S、工具栏加粗、阅读/源码往返、任务回车续写、草稿刷新及原生关闭请求取消。六份原始文档均只读加载到内存副本,在约 85% 位置插入中文和 emoji,撤销/重做、保存后撤销并再保存,最终全文恢复且无脏状态。原生编辑结果;合成样本截图。其中每份样本 1.57–1.93 秒是六次快捷键及显式等待的组合耗时,不是单次输入延迟。

应用 44 项、编辑器 36 项测试通过。Windows 控件测试覆盖合成 delta / composing、混合换行、共享历史、两轴滚动恢复、远处往返定位、外部查找选区及控件关闭后迟到的剪贴板回调。关闭失败重试测试现明确使用 Windows 源码视图。

Release 原生关闭复验通过:退出结果。干净源码文档直接关闭、脏文档取消关闭后保留草稿关闭,两次进程退出码均为 0。父进程核对草稿中的中文、emoji 及混合换行;本轮 Windows Application 1000 / 1001 查询未发现新的 Vex / flutter_windows 故障事件。进程生命周期分别约 1.05 秒和 2.41 秒,包含启动及全部步骤,不作为关闭延迟。

最终静态分析无问题;Windows x64 Release 已重新以 lib/main.dart 构建成功,构建配置已核对为正式程序入口,未遗留测试入口。输出为 apps/vex/build/windows/x64/runner/Release/vex.exe(整个同级目录为运行依赖,构建产物不提交)。本轮关闭结论来自上述自动化 Release 测试入口,没有将其描述为手工操作已安装程序的验收。

验收边界

本轮针对 Windows 源码布局、数据完整性与关闭稳定性。中文 / 日文系统输入法尚未进行真人组合输入验收;合成 composing / delta 测试和剪贴板 Unicode 测试不能替代这项验收。复杂语法、高亮、跨块编辑和其他平台性能仍需继续验证。没有据此声明原型达到 98%,也没有创建正式 tag 或 Release。

💬 评论暂未开启
有疑问或建议,欢迎到 GitHub 提交 Issue 参与讨论。
tems[selIndex] as HTMLAnchorElement).click(); } } });