我需要在没有X11的Linux下在屏幕上绘制光标(鼠标指针) . 这适用于嵌入式系统,其中所有其他绘图直接在帧缓冲区( /dev/fb0
)中发生 .
-
我'm currently looking at doesn'提供任何游标支持的GUI库 .
-
我可以自己做blitting,但我似乎能够与vsync同步(
FBIO_WAITFORVSYNC
) . -
我知道几乎每个图形芯片都支持硬件游标,但是DirectFB已经死了,libdrm需要X11,同样对于Mesa也是如此 .
在What is hardware cursor and how does it work?中,OP声称已经通过 ioctl
调用实现了这一点,声称它很简单,但拒绝提供进一步的细节,因为他的代码是专有的 . 我知道 FBIO_CURSOR
,但它似乎是非标准的,并且总是在我的3.10.0内核上返回 EINVAL
.
在没有X11的情况下绘制帧缓冲光标的正确方法是什么?
1 回答
我最终滚动自己的光标支持,因为看起来内核支持依赖于特定视频驱动程序支持的任何内容 . 表演结果非常适合我的目的 . 这是我做的:
打开/ dev / fb0帧缓冲区,根据需要调整vinfo,
mmap
帧缓冲区和malloc
两个与帧缓冲区大小相同的缓冲区 . 其中一个缓冲区是我的后台缓冲区,其中所有绘图都发生了 . 另一个是我的"cursor"缓冲区,其中绘制了光标 .打开相应的/ dev / input / eventX以准备读取鼠标事件 .
定义一个"refresh"函数,以便在将某些内容绘制到后台缓冲区时或每当有鼠标活动时调用 .
poll
用于具有合理超时的鼠标事件 . 我使用了500毫秒的超时并将其置于pthread
内,因此它的性能开销非常小 ."refresh"函数
memcpy
将后台缓冲区放入光标缓冲区,并将光标绘制在它上面 . (我擦除光标下的掩码位并按照图像here绘制光标位 . )然后将光标缓冲区memcpy
'加入帧缓冲区 .(我使用两个互斥锁保护刷新功能以获得更好的性能 . 我在将后缓冲区复制到游标缓冲区之前获取第一个并在绘制光标后释放它 . 我在绘制光标之前获取第二个并在复制后释放它游标缓冲区到帧缓冲区 . 这样可以在进行大量快速绘制时显着提高性能 . )
我的一些决定的几个原因:
写入帧缓冲区的速度相当快,但从中读取速度要慢得多,因此对后端和光标缓冲区使用常规内存 .
memcpy
比我能编写的任何内容都快得多,并且是线程安全的 .对帧缓冲区的并发访问速度很慢,可能是因为
memcpy
在尝试访问当前正在使用的区域时会锁定区域和块 . 这就是为什么我使用两个互斥锁来保护从后台缓冲区到游标缓冲区的副本,以及从游标缓冲区到帧缓冲区的副本 .具有
0
超时的poll
相当于使用大量CPU周期的紧密循环,因此使用非零超时 . 但是只要输入有活动,poll
就会返回,因此响应速度很快 .在我的硬件上,我找不到与垂直消隐同步的有用方法(有些_2360694的显然是无操作),但上述方法没有表现出特别的撕裂 . 是的,这种方法使用两个屏幕外缓冲区,每个缓冲区在我的1920 x 1080 16位/像素屏幕上需要4 MB,但它非常简单,足以满足我的需求 .