← 返回博客

Zed for Windows:为什么花了这么长时间?!

2025 年 8 月 19 日

很多人问我们Zed 什么时候在 Windows 上发布。Windows 移植最初是一个一人项目,但在过去 6 周里,我们有一个由四名工程师组成的小组全职专注于 Windows。我们对所取得的进展感到兴奋,并希望分享我们正在进行的工作的最新情况。

添加渲染后端

当我们最初在 Windows 上运行 Zed 时,我们使用了与 Linux 上相同的渲染后端,该后端基于 Vulkan 图形 API。能够在平台之间重用代码很有用,但是我们收到了用户报告,由于 Vulkan 依赖,Zed 无法在他们的机器上运行。

为了解决这个问题,我们为 Zed 创建了一个基于 DirectX 11 的新渲染后端。DirectX 11 保证在 Windows 7 或更高版本(包括 Windows VM)上可用,因此现在 Zed 应该适用于绝大多数 Windows 用户。新后端还显著减少了 Zed 的内存占用。

以前,我们有两个 GPU 着色器实现:一个用于 macOS 的 MSL 实现,一个用于 Vulkan 的 WGSL 实现。为了使用 DirectX 11,我们不得不在 HLSL 中创建第三个实现。调试新的渲染管道和着色器的过程将我们带入了一个有趣的兔子洞:字形光栅化。

为了调试,重新实现了字形光栅化

在开发 Zed 最初的 macOS 渲染器时,我们严重依赖 Xcode 的 Metal 调试器。它允许您在应用程序中捕获一帧,逐步执行该帧中发生的所有绘图调用,并检查场景几何中的每个顶点以及渲染图像中的每个像素。

在 Windows 上,最好的图形调试工具是 RenderDoc。不幸的是,在 RenderDoc 下运行时 Zed 会在启动时崩溃,因为我们依赖 Direct2D API 进行文本渲染,而 RenderDoc 不支持使用 Direct2D 的应用程序。为了解决这个限制,我们决定停止使用 Direct2D,转而使用 DirectWrite 光栅化字形。在此过程中,我们修复了字形边界计算不正确导致某些字符和字体大小裁剪不正确的问题。

Inspecting Zed's rendering using RenderDoc. Here we're viewing the glyph atlas—a GPU texture that contains one copy of every glyph in the frame
使用 RenderDoc 检查 Zed 的渲染。这里我们正在查看字形图集——一个包含帧中每个字形副本的 GPU 纹理

扁平化 VRAM 使用

随着越来越多的 Zed 团队成员开始在 Windows 上日常使用 Zed,有些人遇到了由于 GPU 内存分配失败导致的崩溃。Zed 在某些情况下似乎低效地使用了 GPU 内存。我们没有在 macOS 上注意到这一点,因为最近的 Mac 拥有统一内存。但在大多数运行 Windows 和 Linux 的计算机上,GPU 拥有独立的、更有限的内存。

幸运的是,我们得到了 Longbridge 团队的帮助,他们将 Zed 的 UI 框架用于他们自己的桌面应用程序。他们发现了我们渲染*路径*的方法存在效率低下之处——路径是您可以用来绘制任意形状的线条和曲线的组合。我们在 Zed 中使用路径来渲染选择和文本高亮。

为了创建平滑的路径边缘,我们使用了多样本抗锯齿 (MSAA)——我们以每个像素多个颜色样本的方式将路径绘制到中间纹理,然后将平均像素值复制到最终渲染目标。以前,我们在 MSAA 纹理中排列路径的方式类似于我们在纹理图集中排列字形的方式——我们在纹理中分配了足够的空间来放置每个可见路径,*不重叠*。这有时会导致我们分配大量非常大的纹理。

Longbridge 的人提出了一个初步的解决方案来解决这个问题,该方案完全移除了中间纹理,并为我们的整个场景启用了 MSAA。不幸的是,这最终导致 Intel GPU 上的性能大幅下降,因为它们的 MSAA 实现效率较低。但是我们找到了另一种避免高 VRAM 使用的 MSAA 方法:我们现在将所有路径绘制到一个与渲染目标大小相同的单色 MSAA 纹理中,允许路径像在最终场景中一样重叠。然后我们直接从这个纹理复制到渲染目标。这个改变解决了高 VRAM 使用问题,也提高了 Zed 在所有平台(甚至 macOS)上的渲染性能。

Using RenderDoc to inspect the draw call where paths are copied from an intermediate MSAA texture into the final scene
使用 RenderDoc 检查将路径从中间 MSAA 纹理复制到最终场景的绘制调用

更新我们的自动更新器

图形并不是 Windows 上唯一不同的地方;文件系统操作也有独特的限制。特别是,您不能在 .exe 文件运行时覆盖它。这意味着我们需要一种新的策略来执行自动更新。在 macOS 和 Linux 上,我们只需在下载更新后将新的应用程序包复制到相应位置,覆盖旧的应用程序包。但在 Windows 上,我们必须在 Zed.exe 未运行时执行此步骤。

经过几次迭代,我们确定了一种方法,即在 Zed 退出或重新启动时调用一个专门的“自动更新帮助器”二进制文件。自动更新帮助器完成可执行文件的就位移动,然后在需要时重新启动 Zed。

崩溃报告

在 Windows 上,即使是崩溃也与众不同!我们不得不重做我们的崩溃报告基础设施,因为在 Windows 上,符号化堆栈跟踪需要一个 .pdb 文件,该文件太大,无法作为安装程序的一部分发送给用户。对于允许的用户,我们现在收集minidump 文件,以帮助我们跟踪和调试用户遇到的崩溃,并在上传后在服务器端符号化这些崩溃。

后续步骤

在宣布 Windows 版 Zed 可以普遍使用之前,还有一些问题需要解决。以下是我们未来几周关注的领域

  • 按键绑定 - Windows 用户对按键绑定的显示方式以及将绑定的键盘快捷键类型有不同的期望,具体取决于他们的键盘布局。
  • SSH 远程 - 当从 Windows 客户端编辑远程 Linux 机器上的文件时,目前存在与不同文件系统路径约定相关的错误。此外,SSH 本身在 Windows 上的工作方式也不同。
  • WSL - 尽管目前可以通过本地 SSH 连接编辑 Linux 子系统中的文件,但我们正在添加对 WSL 的一流支持。
  • 扩展 - Zed 扩展是跨平台 WASM 二进制文件,并通过 WebAssembly System Interface 访问标准文件系统 API。在 Windows 上,扩展和主机之间的路径约定存在一些不匹配,我们需要加以考虑。
  • 性能 - 我们将密切关注我们新图形后端以及任何其他特定于操作系统的代码路径的性能,以确保 Windows 应用程序像我们的 macOS 版本一样流畅。

参与其中


正在寻找更好的编辑器吗?

您今天就可以在 macOS、Windows 或 Linux 上试用 Zed。立即下载


我们正在招聘!

如果您对我们博客中涵盖的主题充满热情,请考虑加入我们的团队,帮助我们实现软件开发的未来。