2016-06-22 76 views
1

我需要在沒有X11的Linux下在屏幕上繪製光標(鼠標指針)。這適用於嵌入式系統,其中所有其他繪圖直接在幀緩衝區中發生(/dev/fb0)。需要在Linux framebuffer中繪製光標

  1. 我目前正在查看的GUI庫不提供任何遊標支持。
  2. 我可以自己做blitting,但我擔心外觀和性能,部分原因是我似乎無法與vsync同步(FBIO_WAITFORVSYNC)。
  3. 我知道幾乎所有的圖形芯片都支持硬件遊標,但DirectFB已經死了,libdrm需要X11,Mesa也是如此。

What is hardware cursor and how does it work?,在OP聲稱已與ioctl調用實現這一點,說明它很簡單,但拒絕提供進一步的細節,因爲他的代碼是專有的。我知道FBIO_CURSOR,但它似乎是非標準的,並且在我的3.10.0內核上總是返回EINVAL

在沒有X11的情況下繪製幀緩衝光標的正確方法是什麼?

+0

喬希,你知道嗎?我今晚自己遇到了這個。 FBIO_CURSOR沒什麼特別。 –

+0

@Stéphane請參閱我剛發佈的答案。 –

回答

1

我最終滾動了我自己的光標支持,因爲看起來內核支持取決於特定的視頻驅動程序支持。表演結束了偉大的我的目的。下面是我所做的:

  • 打開的/ dev/FB0幀緩衝,調整vinfo根據需要,mmap幀緩衝,並malloc兩個緩衝區大小相同的幀緩衝。其中一個緩衝區是我所有繪圖發生的後臺緩衝區。另一個是我的「光標」緩衝區,其中繪製了光標。
  • 打開相應的/ dev/input/eventX準備讀取鼠標事件。
  • 定義一個「刷新」函數,以在任何東西被拖入後臺緩衝區或每當有鼠標活動時調用。
  • poll與一個合理的超時鼠標事件。我使用了500毫秒的超時時間,並將其放在pthread之內,這樣它的性能開銷就很小。
  • 「刷新」功能memcpy「IES後臺緩存到指針緩衝器,並提請在它上面的光標。 (I擦除掩碼比特光標下,繪製光標位,如每圖像here。)光標緩衝器然後memcpy「編入幀緩衝。我使用兩個互斥鎖來保護刷新功能以獲得更好的性能,我在獲取第一個數據之前先將後臺緩衝區複製到遊標緩衝區,並在繪製遊標後釋放它,在獲取第二個遊標之前先獲取第二個遊標,然後釋放它。複製指針緩衝器的幀緩衝這提高做大量的真快圖紙明顯時表現)

對我的一些決定有幾個原因:。

  • 寫入到幀緩衝區是相當快的,但是讀取速度要慢得多,因此使用常規的malloc'ed內存的後退和光標緩衝區。
  • memcpy比我能寫的任何東西都快,而且是線程安全的。
  • 對幀緩衝區的併發訪問很慢,大概是因爲memcpy在嘗試訪問當前正在使用的區域時會鎖定區域和塊。這就是爲什麼我使用兩個互斥鎖來保護從後臺緩衝區到遊標緩衝區以及從遊標緩衝區到幀緩衝區的副本。
  • poll0超時相當於使用大量CPU週期的緊密循環,因此使用非零超時。但poll只要輸入有活動就會返回,所以響應很好。

在我的硬件,我沒有找到一個可用的方式與垂直消隱(一些ioctl的顯然是無操作的)進行同步,但上述方法沒有表現出特別的撕裂。是的,這種方法使用兩個屏幕外緩衝區,每個屏幕緩衝區在我的1920 x 1080 16位/像素屏幕上都需要4 MB,但它非常簡單,足以滿足我的需求。