重新堆叠GUI堆栈

2020-06-27 16:09:22

由于我目前正在对Genode的低级GUI堆栈进行意义深远的修改,我想分享一下这项工作背后的一些背景:为什么、什么和如何。

Genode当前版本的低级GUI相关界面与我们在2006年最初创建的第一个版本几乎完全相同。Genode对客户端和服务器组件之间的关系有非常强烈的非对称概念。在此关系中,客户端依赖于服务器,但服务器不依赖于客户端。

在最低级别,帧缓冲区驱动程序和输入驱动程序被设想为向更高级别的GUI组件提供帧缓冲区和输入会话接口的服务器。从我们以前的学术观点来看,这感觉很自然,因为这些驱动程序为其他组件提供了资源。提供..。发球..。服务器!NitPicker GUI服务器使用这些低级服务来实现最终允许图形和输入多路复用的高级服务。NitPicker虚拟化了低级帧缓冲区和输入接口,同时补充了可见视图和输入焦点的概念。这样的系统看起来如下所示:

驱动程序和NickPicker GUI服务器显示为红色,因为它们是服务器。右侧的GUI应用程序是挑剔的客户端。反过来,NitPicker是帧缓冲区和输入驱动程序的客户端。

NitPicker GUI服务器的客户端界面是一个成功的案例。尽管做了一些进化上的调整,但原始设计可扩展到Sculpt OS的窗口工作环境,同时保留了NickPicker GUI服务器的微小复杂性。

然而,将帧缓冲区和输入驱动程序建模为服务器的方法是一条死胡同,原因如下。

驱动程序有时非常复杂。例如,当考虑到Intel帧缓冲区驱动程序(从Linux内核移植)的复杂性时,相信它不会失败会让人觉得很愚蠢。但是,因为NickPicker GUI服务器依赖于驱动程序的活跃性,所以驱动程序的正常运行是整个GUI堆栈和所有GUI应用程序的关键路径。

在不重新启动GUI堆栈和所有GUI应用程序的情况下,不可能在运行时透明地重新启动或替换驱动程序。这是因为NitPicker GUI服务器作为客户端连接到驱动程序。这些连接就像GUI服务器的生命线。切断这些最终会杀死GUI服务器。

添加辅助显示相当困难,因为这需要ickicker知道有哪些帧缓冲区服务器,并请求多个帧缓冲区连接。添加这样的协议会增加挑剔的复杂性。

要克服这些限制,我们必须打破GUI服务器对驱动程序的依赖,如下所示:

在此方案中,GUI服务器不再使用驱动程序,但驱动程序使用GUI服务器。这种关系是颠倒的。只有NickPicker GUI服务器保持红色。当然,驱动程序不能通过NitPicker的常规客户端界面与NitPicker GUI服务器通信。取而代之的是,两个新接口进入画面:

类似于原始FrameBuffer会话接口的反转。它允许客户端从服务器获取像素数据。从GUI服务器的角度来看,帧缓冲区驱动程序就像一个帧捕获设备--的确如此。

类似于原始输入会话接口的反转。与允许客户端获取输入事件的输入会话不同,事件会话允许客户端引发输入事件。NitPicker是一个事件服务器,它使用来自驱动程序的输入事件。

低复杂性的GUI服务器仍然是唯一不会出现故障的组件,这使得GUI堆栈与今天相比具有更强的弹性。

由于NitPicker GUI服务器不再依赖于驱动程序,因此它可以在驱动程序运行之前启动,从而加快了图形化场景的启动时间。在电源管理严格的情况下,我们可以删除图形驱动程序,并关闭图形设备,同时GUI服务器和所有GUI应用程序保持完好。

驱动程序可以随时重新启动。从NitPicker GUI服务器的角度来看,这看起来像是客户机断开连接。也可以在运行时替换驱动程序,例如,交换VESA和英特尔驱动程序。

将多个驱动程序连接到NitPicker GUI服务器在概念上变得很简单。这为多头支撑扫清了道路。

NitPicker GUI服务器的新捕获会话界面将是实现屏幕截图/屏幕截图应用程序或远程桌面服务器的右钩。

与捕获设备类似,输入设备可以在不中断的情况下随时进入和离开系统,这将允许对USB HID设备进行细粒度管理。考虑一下在您的雕塑系统中插入一个新的HID设备。一个新的USB设备将会出现。用户可以利用将驱动程序的事件会话路由到系统GUI服务器的选项来部署匹配的HID驱动程序。那不是很棒吗?

不利的一面是什么?这是一项繁重的工作!这将引导我们进入下一节。

颠倒低级会话接口是一种侵入性操作,必须分几个步骤执行,每个步骤都会产生中间一致的状态。

我们从一些低风险的修饰更改开始,即将挑剔会话接口重命名为会话。在特定实现之后,会话接口的奇怪标记是早期遗留下来的。此更改已进入Genode的主分支机构。

所有驱动程序和应用程序一致使用32位RGB作为像素格式。这是一个长期存在的功能要求,它消除了颜色空间转换的需要,通常可以提高输出质量。这相当费力,因为它需要我测试许多不同的硬件平台,包括驱动程序vea_fb_drv、fb_SDL、intel_fb_drv、imx53_fb_drv、imx8_fb_drv、rpi_fb_drv、boot_fb_drv、omap4_fb_drv、exynos5_fb_drv。这一变化已经进展顺利。

引入一个nitPicker选项,在使用请求的帧缓冲区会话(如今天所做的那样)、使用捕捉客户端进行像素输出或使用另一个GUI服务器(用于堆叠多个nitPicker实例)之间选择帧缓冲区后端。

将";Framebuffer&34;驱动程序转换为";Capture&34;客户端,涵盖上述所有驱动程序。铲土密码。调整所有现有方案以使用NitPicker的捕获服务。

修剪帧缓冲区客户端接口的剩余使用。实际上,完成后,我希望完全删除Framebuffer::连接。这将需要重新处理终端、Mesa后端、几个测试和Liquid_Frame Buffer。在这个过程中,我希望在很大程度上消除nit_fb(现在称为gui_fb)组件的用例,以便最终可以删除该组件。

将其他一些帧缓冲区客户端转换为捕获服务器,特别是test-frame buffer、fb_bench和test-driver_manager。

删除";Framebuffer";会话接口,仅将该接口保留为GUI会话的一部分。

引入新的事件会话接口,并将其实现添加到NitPicker GUI服务器。

随着结构变化的完成,现在将是优化的时候了。作为无撕裂动画的先决条件,帧缓冲将从客户端移动到NickPicker GUI服务器。首先,这对大多数客户端都是透明的。随后移除客户端缓冲是第二个独立的步骤。作为另一个优化,我计划遍历所有使用像素抖动的地方。

在这些主题中,帧缓冲区驱动程序的返工肯定是最详细的。我正在考虑放弃Exynos5和OMAP4驱动程序。尽管我努力将输入会话接口替换为新的事件会话接口,但对我来说,修改输入驱动程序的任务范围还不是完全明确的。