使用Skia库实现支持Vulkan的LibreOffice用户界面

2020-08-22 23:35:41

刚刚发布的LibreOffice7.0包括一个基于Skia库的新绘图后端,它允许LibreOffice使用现代的Vulkan API进行图形操作。该可视化类库(Visual Class Library,VCL)后端是Windows平台上的默认后端,取代了基于OpenGL的后端。

拥有多个VCL后端有与不同操作系统集成的好处,但每个后端执行自己的呈现实现远非最佳,因为我们不能添加新的呈现功能并假设它将跨平台工作。许多跨不同平台和工具包的后端错过了各种渲染任务的优化路径。这增加了复杂性,并且很难确保在任何地方都以加速的方式渲染对象。

另一个问题是,多个后端定期执行从VCL的API到现代工具包提供的内容的相同类型的映射。这种重复不仅意味着维护成本,还可能导致必须在多个地方修复同一个bug。

VCL库负责小部件(按钮、控件等)。和基本渲染。它不直接实现绘图,但提供了一个内部API,由实现实际图形操作的各种后台实现。这些后端通常使LibreOffice适应每个平台,例如,‘win’后端在Windows上使用,‘kf5’和‘gtk3’后端分别用于使用KDE框架和Gtk3图形工具包的类Unix平台,还有一个‘Headless’后端,用于不渲染到屏幕的测试。

每个VCL后端使用平台上可用的底层图形API来执行图形操作。Cairo库由一些类Unix和‘Headless’后端使用,‘OSX’后端使用MacOS Quartz。在Windows上,“Win”后端有几个Plugable Drawing实现:

GDI绘图。此代码相对较旧,并且有几个限制,例如不是双缓冲的。

OpenGL绘图。此代码提供GPU加速绘图。OpenGL是直接使用的,所以包括OpenGL着色器在内的所有相关代码都需要在LibreOffice中实现。OpenGL API在业界也在慢慢被淘汰。

SkiA画。Skia库隐藏了实现细节,并提供了几种呈现方法,包括Vulkan API。

Skia库不是以二进制形式发布的,甚至不是由第三方提供商(如Linux发行版)提供的。它仅作为源代码提供,在项目中使用它的通常方式是将其与该项目一起提供。LibreOffice将Skia作为第三方库包含在内,幸运的是,使用LibreOffice gbuild系统构建它相当简单。另一个复杂的问题是,Skia大约每6周提供一个新版本,通常只有最新的版本才会收到任何修复,需要重复更新。由于Skia在不断发展,因此每次更新也可能需要调整(尽管到目前为止,这些调整似乎一般都很小)。

Skia API一般都有很好的文档,但它似乎主要针对已经在使用Skia的项目中工作的开发人员,比如Chrome。重要的类已经很好地描述了它们的API,但可能很难找到它们的教程,有些类在开始时更难理解(例如,SkPixmap、SkBitmap、SkImage和SkSurface都是代表可绘制的类,但一开始不清楚每个类适合它们的用例是什么)。

同样,在新项目中如何使用Skia也不是很明显。文档中似乎没有任何关于Skia的实际开发人员介绍,也没有任何关于如何使用Skia设置新的或独立项目的文档。Examples/目录中有一个Hello-World示例,它基于平台集成代码,该代码不是Skia库本身的一部分,但位于tools/目录中的sk_app/目录中。该代码可用于LibreOffice,但需要打补丁以满足LibreOffice的需要(例如,代码为每个顶层窗口创建了一个新的图形上下文,Skia要求在绘图操作中使用正确的图形上下文,但LibreOffice代码有时不知道哪个顶层窗口将使用绘图结果)。

LibreOffice是一个相当老的代码库,仍然使用相对较旧的概念,如调色板位图、低分辨率位图(如4bpp)或使用像素XOR操作的绘图。SkiA是一个相对较新的库,其功能假定使用了现代概念(例如,对于未使用的Alpha通道,要求RGB位图为32bpp,不支持24bpp RGB位图)。

一旦最初的学习期结束,Skia的API是一致的,使用也是相当灵活的,因此进展相对较快。使用Skia的代码可读性非常好,并且使用Skia可以使将来的维护任务更容易执行。即使是一些旧的概念,例如LibreOffice对Alpha通道使用单独的位图,有时解释为8bpp,有时解释为Alpha,后来与数据位图混合以获得实际结果,也可以主要使用Skia API实现,使它们由GPU加速。

虽然有人担心,与OpenGL驱动程序和硬件实现相比,迁移到Skia会如何影响性能,但事实证明,LibreOffice中的性能至少相当于OpenGL版本,合成基准测试表明还有改进的空间。

虽然一开始有点复杂,但总的来说,在LibreOffice中使用Skia是一种相当愉快的体验。在未来,LibreOffice对Skia的使用可能会扩展到其他平台,减少使用的平台呈现API的数量,消除重复代码,减少错误数量,并全面提高质量。

作为比较,LibreOffice OpenGL绘图代码大约有12k行代码,而Skia绘图代码只有4k。

除了直接的好处,迁移到Windows上的Skia和Vulkan还为单一的、强大的、硬件加速的渲染API跨平台铺平了道路。

迁移到Windows上的Skia需要大约7个人月的时间,这让我们可以使用Vulkan加速,而不需要很大的实现成本。看看在接下来的几年里,从降低的维护成本中节省了多少时间,这将是一件有趣的事情。由此产生的工作足够成熟,在性能上没有真正的负面变化,而且我们还没有开始大量优化。