I need to draw a cursor (mouse pointer) on the screen under Linux without X11. This is for use in an embedded system where all of the other drawing happens directly in a framebuffer (
I ended up rolling my own cursor support, since it appeared that the kernel support was dependent on whatever the particular video driver supported. The performance ended up great for my purposes. Here's what I did:
mmapthe framebuffer, and
malloctwo buffers the same size as the framebuffer. One of the buffers is my back buffer where all the drawing happens. The other one is my "cursor" buffer where the cursor is drawn.
pollfor mouse events with a reasonable timeout. I used a 500 ms timeout and put this inside a
pthreadso that it had very little performance overhead.
memcpy'ies the back buffer into the cursor buffer, and draws the cursor on top of it. (I erase the mask bits under the cursor and draw the cursor bits, as per the images here.) The cursor buffer is then
memcpy'ed into the framebuffer.
A few reasons for some of my decisions:
malloc'ed memory for the back and cursor buffers.
memcpyis much faster than anything I can write and is thread-safe.
memcpylocks regions and blocks when trying to access a region currently in use. This is why I used two mutexes to protect copies from the back buffer to the cursor buffer, and from the cursor buffer to the framebuffer.
0timeout is equivalent to a tight loop that uses a lot of CPU cycles, hence the use of a non-zero timeout. But
pollreturns as soon as there is activity on the input, so the responsiveness is great.
On my hardware, I didn't find a usable way to synchronize with the vertical blanking (some of the
ioctl's are apparently no-ops), but the approach described above exhibited no particular tearing. Yes, this approach uses two offscreen buffers, each of which require 4 MB on my 1920 x 1080 16-bit/pixel screen, but it's very simple and sufficient for my needs.