需要在Linux framebuffer

时间:2016-06-22 15:02:35

标签: linux cursor framebuffer

我需要在没有X11的Linux下在屏幕上绘制光标(鼠标指针)。这适用于嵌入式系统,其中所有其他绘图直接在帧缓冲区(/dev/fb0)中发生。

  1. 我目前正在查看的GUI库不提供任何游标支持。
  2. 我可以自己做blitting,但我关注外观和性能,部分原因是因为我似乎无法与vsync(FBIO_WAITFORVSYNC)同步。
  3. 我知道几乎每个图形芯片都支持硬件游标,但是DirectFB已经死了,libdrm需要X11,同样对于Mesa。
  4. What is hardware cursor and how does it work?中,OP声称已经通过ioctl调用实现了这一点,声明它很简单,但拒绝提供更多详细信息,因为他的代码是专有的。我知道FBIO_CURSOR,但它似乎是非标准的,并且总是在我的3.10.0内核上返回EINVAL

    在没有X11的情况下绘制帧缓冲光标的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

我最终推出了自己的游标支持,因为看起来内核支持依赖于特定视频驱动程序支持的内容。表演结果非常适合我的目的。这就是我的所作所为:

  • 打开/ dev / fb0帧缓冲区,根据需要调整vinfo,mmap帧缓冲区和malloc两个与帧缓冲区大小相同的缓冲区。其中一个缓冲区是我的后台缓冲区,其中所有绘图都发生了。另一个是我的光标"用于绘制光标的缓冲区。
  • 打开相应的/ dev / input / eventX以准备读取鼠标事件。
  • 定义"刷新"每当有东西被拉入后缓冲区时,或者只要有鼠标活动,就会调用函数。
  • poll用于具有合理超时的鼠标事件。我使用了500毫秒的超时并将其置于pthread内,因此它的性能开销非常小。
  • "刷新"函数memcpy将后台缓冲区放入游标缓冲区,并将光标绘制在游标缓冲区之上。 (我擦除光标下的掩码位并根据图像here绘制光标位。)然后将光标缓冲区memcpy添加到帧缓冲区中。
  • (我使用两个互斥锁保护刷新功能以获得更好的性能。我在将后缓冲区复制到游标缓冲区之前获取第一个并在绘制光标后释放它。我在绘制光标之前获取第二个并在之后释放它将光标缓冲区复制到帧缓冲区。这样可以在进行大量快速绘制时显着提高性能。)

我的一些决定的几个原因:

  • 写入帧缓冲区的速度相当快,但从中读取速度要慢得多,因此对后端和光标缓冲区使用常规malloc内存。
  • memcpy比我能编写的任何内容都快得多,并且是线程安全的。
  • 对帧缓冲区的并发访问速度很慢,可能是因为memcpy在尝试访问当前正在使用的区域时会锁定区域和块。这就是我使用两个互斥锁来保护副本从后台缓冲区到游标缓冲区,以及从游标缓冲区到帧缓冲区的原因。
  • 具有poll超时的
  • 0相当于使用大量CPU周期的紧密循环,因此使用非零超时。但是,只要输入有活动,poll就会返回,因此响应能力很强。

在我的硬件上,我没有找到一种与垂直消隐同步的有用方法(某些ioctl显然是无操作),但上述方法展示了没有特别的撕裂。是的,这种方法使用两个屏幕外缓冲区,每个缓冲区在我的1920 x 1080 16位/像素屏幕上需要4 MB,但它非常简单,足以满足我的需求。