Linux Graphics 周刊(第 1 期)

(2020.8.10 ~ 2020.8.16)

DRM

1. 彻底废弃 drm_driver 中的 prime callbacks,全面启用 GEM Object functions

从 kernel 4.19 开始,DRM 框架引入了 shmem GEM 后端,随该 patch 一同合入的还有 drm_gem_object_funcs 结构体。该结构体的引入,极大的统一了 GEM Prime 接口的管理。以前,凡是和 prime 相关的接口都是放在 drm_driver 结构体中的,这使得 drm_driver 结构体变得越来越臃肿,框架调用也显得比较凌乱。而引入 drm_gem_object_funcs 之后,只需要通过 drm gem object 就可以调用相关的回调函数,而无需访问 drm_driver 指针。这才真正体现了 kernel 的面向对象思想,以前 gem object 中只有数据,没有方法(即回调函数),现在的 gem object 成了一个鲜活的对象,它既有数据又有方法,拿到 gem object 就可以完成所有与 GEM 相关的操作,非常方便,且可读性强。

虽然从 2018 年就合入了 drm_gem_object_funcs 的功能,但大部分 drm 驱动仍然保持着原有的 drm_driver prime 接口,drm_gem_object_funcs 的普及率并不高。如今,是时候该对这些驱动进行清理了。Thomas Zimmermann( drm-misc Maintainer, SUSE)为我们做了这件事,他总共提了 20 笔 patch,其中第 1~ 19 笔 patch 是专门用来清理各个 drm 设备驱动的,第 20 笔 patch 则是彻底删除 drm_driver 中 gem prime 相关 callbacks 的。

更多详细内容,请查阅 dri-devel 邮件列表:[PATCH 00/20] Convert all remaining drivers to GEM object functions

2. 为 GEM vmap 添加 I/O memory 的支持

drm prime exporter 中有一个 vmap 接口,专门用于将后端内存映射到一片连续的虚拟地址空间上(kernel 空间),方便在 kernel 空间使用 CPU 去访问这段内存。但如果要访问的物理内存是在 IO 端口上呢?目前的接口对于 ARM 平台来说都没有什么大问题,访问 IO 地址空间和访问普通的内存没有什么区别。但对于 sparc64 或 X86 这种架构的平台来说可能就不那么方便了,众所周知,在这类平台上如果要访问 IO 端口地址空间,需要使用专门的 IO 指令,如 X86 上的 IN 和 OUT。对于这类平台,就需要对 vmap 接口进行 hack 了,否则返回的 IO 地址被拿去当 CPU 地址使用可就麻烦了。

为了解决 bochs drm 驱动中的 sparc64 IO memory 映射问题,Thomas Zimmermann(drm-misc maintainer, SUSE)新增了 drm_gem_membuf 结构体,用于保存 vmap 返回的地址,不过该地址不再是简单的 CPU 指针,而是 CPU 地址和 IO 地址的联合体,通过 is_iomem 变量来进行区分。同时,所有 gem prime vmap 接口返回的地址都被修改成了 drm_gem_membuf 结构体指针,以此来兼容 IO memory 的映射。

更多详细内容,请查阅 dri-devel 邮件列表:[RFC][PATCH v2 0/4] Support GEM object mappings from I/O memory

3. dma-heap:添加 system-uncached HEAP

ION 是 Android 系统下专用于分配 Graphic Buffer 的内存分配器,它是基于 DMA-BUF 实现的,可以在多个设备之间实现 buffer 共享。不过它的代码一直存放在 staging 目录下,再过几年可能就不复存在了,而 dma-heap 则是专门用来取代 ION 的。用过 ION 的同学都知道,ION 在 SYSTEM_HEAP 上分配内存时,既可以分配带 cache 的 buffer,也可以申请不带 cache 的 buffer,这个过程是通过传入 ION_FLAG_CACHED 标志位来实现的。

而现有的 dma-heap 功能还比较单一,只支持 SYSTEM HEAP(物理非连续 buffer) 和 CMA HEAP(物理连续 buffer),而且 SYSTEM HEAP 默认只支持带 Cached 的 buffer,不带 cache 的 buffer 目前还不支持。通常,只有 CPU 需要参与访问的 buffer 才需要带 cached,这样可以加快 CPU 的访问速度,但是在 CPU 和 DMA 设备之间共享内存时,需要来回刷 Cache,这会增加系统开销。不带 cached 的 buffer 则通常只用于 DMA 设备之间的 buffer 共享,因此省去了 Cache 同步所带来的额外开销,提高了设备之间的访问效率。

正是基于以上原因,John Stultz(dma-heap maintainer, Linaro)给 dma-heap 提交了 system-uncached heap 的 patch,这样应用程序就可以申请不带 cache 的 buffer 了(默认为 writecombine),极大的提高了 DMA 设备访问 buffer 的效率。

更多详细内容,请查阅 dri-devel 邮件列表:[RFC][PATCH v2 2/2] dma-heap: Add a system-uncached heap

4. DMA Heap vs GEM

DMA Heap 是用来替代 ION 的内存分配器,主要用于多媒体设备的 Graphic Buffer 分配。而 DRM 下的 GEM 则是专用于 Display 和 GPU 显存相关的 buffer 分配。二者从功能上来讲,都是 buffer 分配,且都能将所分配的 buffer 转换成 dma-buf fd 进行设备间的共享。这就给部分开发者带来了困惑,如 Mikko Perttunen 就在社区表达了自己的疑惑:

他认为,现今的 dma-heap 已经能很好的满足 TegraDRM 内存分配需求,可以完全抛弃传统的 GEM 框架,不用再实现驱动自定义的 GEM IOCTL 内存分配接口,直接使用 dma-heap 来代替就可以了。但是他又觉得头疼的是,dma-heap 相比 GEM 有一个劣势,就是 dma-heap 所分配的 buffer 只能以 fd 的形式导出给上层应用。大家都知道,fd 属于进程资源,每个进程的 fd 总数是有限制的(一般最大 1024 个),一旦应用程序的 fd 被用尽,则无法再获取到 dma-buf fd,即无法通过 dma-heap 分配内存。而 DRM GEM 分配内存时,直接返回给应用程序的是 GEM OBJ ID,而不是 dma-buf fd,所以 GEM 不会有这类风险。因此他的问题是:dma-heap 在 kernel 中到底扮演着什么样的角色?如果 dma-heap 的最终目的是成为一个通用的多媒体 buffer 分配器,那么上面提到的 fd 限制问题是否应该被解决掉?还是说将该问题留给应用程序自己去处理?

对于该问题,Daniel Vetter(drm-misc Maintainer, Intel) 的回答是:目前没人知道答案。不过他认为,dma-heap 只是个可以跨设备共享的内存分配器,分配出来的 dma-buf 主要用于在多个设备之间共享,因此它更侧重于“共享”二字。而 GEM 则是专用于分配具有硬件加速功能的 buffer(如 GPU 显存、或特殊地址的 memory),该 buffer 可以给其他设备共享,也可以自己私有访问,因此它更侧重于“专用”二字。因此他并不认为 dma-heap 可以替代 GEM,而且对于 TegraDRM,明明有现成的 GEM IOCTL 接口,为什么非要用 dma-heap 呢?

John Stultz (dma-heap maintainer, Linaro)的回答似乎有点偏题,他并没有直接回答该问题,而是提到了另一个问题:我们是否需要给 dma-heap 添加 in-kernel use 的接口?因为他发现,有的驱动想直接把 dma-heap 作为自己 buffer 分配的后端分配器,但是 dma-heap 又没有提供以 dma-buf 指针作为返回值的接口,使得它们不得不重写一套和 dma-heap 重复的 exporter 代码。他在想 Mikko 是不是也是有类似的需求,如果是的话,他们可以进一步探讨 dma-heap 新增 in-kernel use 接口的可能性。但是站在框架层的角度考虑,他认为 buffer 分配还是应该由应用层来发起,而不应该由 kernel 层发起,因为只有应用程序才最清楚它所需要的 buffer 将传递给哪个设备,因此才能将更为准确的 buffer 属性传给 dma-heap 驱动。

更多详细内容,请查阅 dri-devel 邮件列表:Role of DMA Heaps vs GEM in allocation

5. dma-buf: 为每个进程添加 buffer 使用状态的 ftrace 信息

Kalesh Singh(Google)为 dma-buf 添加了 ftrace 跟踪信息,可用于跟踪每个进程对 dma-buf 的分配/释放/mmap/munmap操作。这对于系统面临大量内存使用压力的情况,能提供有效的性能分析方法。

更多详细内容,请查阅 dri-devel 邮件列表:[PATCH 0/2] Per process tracking of dma buffers

6. backlight: 代码优化,新增宏定义及操作接口

Sam Ravnborg(drm-misc maintainer)为简化 backlight 驱动编写,新增了 4 个宏定义和 5 个 set/get 辅助接口:

宏定义:

  • BACKLIGHT_PROPS
  • DECLARE_BACKLIGHT_INIT_RAW
  • DECLARE_BACKLIGHT_INIT_PLATFORM
  • DECLARE_BACKLIGHT_INIT_FIRMWARE

通过上面的宏定义,我们可以在 backlight 驱动中简化背光初始化的参数。

set/get helper:

  • backlight_get_actual_brightness
  • backlight_get_max_brightness
  • backlight_set_brightness
  • backlight_set_power_on
  • backlight_set_power_off

如果没有这些接口,我们只能通过 bd->props.xxx 来访问,每次还要做空指针判断,代码繁琐。现在有了这些 helper 接口,我们的代码就会干净许多。

更多详细内容,请查阅 dri-devel 邮件列表:[RFC PATCH v1 0/22] backlight: add init macros and accessors

7. Huawei Hikey970 DRM/KMS 驱动 Upstreaming

Hikey970 是华为 2018 年推出的一款开源 96Board,基于海思麒麟970 SoC,CPU 为 4 核 A73 + 4 核 A53,GPU 采用 ARM Mali-G72 MP12,性能强劲,主要用于 AI 高性能计算。

前不久 Mauro Carvalho Chehab(华为?)向社区提交了 Hikey970 的 DRM/KMS 驱动,该驱动来源于 Linaro Hikey 官方 kernel 仓库,目前该驱动显示功能还存在一定 bug (如休眠唤醒后显示器将无法恢复到之前的时钟频率),不过这并不影响 Mauro 的 upstreaming 计划。目前主要是接受社区人员的 comment,好做进一步调整,预计离真正 merge 还有很长一段路要走。

更多详细内容,请查阅 dri-devel 邮件列表:DRM/KMS experimental drivers for HiKey 970



以下内容因为工作太忙,没来得及详细介绍,大家就直接访问原链接吧。

Mesa

AMD R600 骨灰级显卡 Gallium3D 驱动新增 Computer Shader 功能
详情:R600 Gallium3D Now Has Compute Shaders Working With NIR

Wayland

1. [ANNOUNCE] weston 8.0.92

2. [ANNOUNCE] libinput 1.16.1

3. RFC: libei - emulated input in Wayland compositors

其他

1. Fedora’s FESCo Approves Using DXVK As Their Default Wine Direct3D Back-End

2. What is PVRTune Complete?

Linux系统上使用Graphics2D进行图形绘制时遇到中文乱码的问题,通常是因为编码设置不匹配导致的。Graphics2D默认处理的是字节流,如果处理的字符串不是UTF-8编码,就可能出现乱码现象。解决这个问题的一般步骤包括: 1. **检查字体**:确保你的字体支持中文字符。Linux系统自带了一些支持中文的字体,如华文宋体、SimHei等。 2. **设置字体资源**:在绘图前,需要明确设置当前使用的字体,并确保它包含中文字符。例如,在Java中可以这样做: ```java Graphics2D g = (Graphics2D) yourDrawingCanvas.getGraphics(); g.setFont(new Font("SimHei", Font.PLAIN, 16)); ``` 3. **设置文本编码**:当使用String绘制文本时,确保转换成正确的编码,如UTF-8。例如: ```java String chineseText = "你好"; byte[] bytes = chineseText.getBytes(StandardCharsets.UTF_8); // 然后使用bytes绘制到Graphics2D ``` 4. **使用`setRenderingHint`**:有些情况下,可能需要设置渲染提示来控制文字的绘制,比如`FontRenderContext`: ```java g.setRenderingHint(RenderingHints.KEY_FONTPROPERTIES, RenderingHints.VALUE_FONTPROPERTIES_DEFAULT); ``` 如果你已经尝试了以上步骤还是出现问题,可能需要查看具体的代码环境,或者检查应用程序的配置文件,确保整个流程都设置了正确的字符编码。如果涉及到跨平台操作,可能还需要考虑使用专门处理字符集的库,如BMPFont或FreeType。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何小龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值