android studio 显示图形_显示服务器实现(一)
在一個多窗口的圖形化操作系統中,顯示服務器的任務就是組織這些窗口展現給用戶。實際的顯示服務器有Linux世界基于X11協議的XServer或者Wayland協議的Weston,還有Android里的SurfaceFlinger。但是除了顯示,他們同時包含了輸入管理(鼠標、鍵盤等)的功能,本文主要還是討論圖形顯示部分,通過將顯示服務器用到的技術分解,實際來看看如何實現一個顯示服務器。
需求分析
在命令行Linux操作系統中實現一個支持GPU圖形應用的顯示服務器:
一個簡單的OpenGL應用
這是一個在Linux X11系統下簡單的OpenGL應用【1】,效果是在一個X11窗口中繪制一個紅色三角形。我們看看OpenGL應用是如何跟顯示服務器(XServer)交互的。注意這里忽略了無關參數和代碼,下同。
Display首先用EGL從X11的Display和Window創建Context,然后用OpenGL進行實際繪制,最后用EGL的eglSwapBuffers將繪制好的緩沖交給XServer去顯示。
這個例子的目的,一是看看OpenGL應用和顯示服務器的接口,二是看看在顯示服務器那邊,我們也想用OpenGL做窗口組裝的話還需要什么。
以下三個例子會展示如何解決:
無顯示服務器的OpenGL繪制
例二【2】是在沒有顯示服務器的情況下,用EGL+GBM做OpenGL繪制的例子:
intGBM是一個GPU緩沖管理的API,可以直接從GPU的設備文件(/dev/dri/renderD128)創建一個gbm_device,然后再創建一個代表GPU緩沖的gbm_surface。支持EGL_MESA_platform_gbm擴展【5】的EGL接口可以利用gbm_device和gbm_surface來創建EGLDisplay和EGLSurface。接下來就和EGL+X11那個例子一樣了。
顯示器顯示幀緩沖
顯示幀緩沖可以參考例三【3】,首先打開GPU設備文件/dev/dri/card0(這個文件同時支持繪圖和顯示,而/dev/dri/renderD128只有繪圖功能)。然后就能調用KMS接口獲取當前連著顯示器的Connector/Encoder/Crtc,這三個模塊的功能:Crtc從幀緩沖讀取數據給Encoder,Encoder編碼數據給Connector,Connector輸出HDMI/DP/VGA接口的信號。最后drmModeFBPtr代表Crtc要讀取的幀緩沖。當前drmModeFBPtr所指向的幀緩沖里面應該是命令行界面,我們需要為自己的繪圖緩沖創建一個新的drmModeFBPtr。
int在上一個例子中我們將圖形繪制在了gbm_surface上,這里就從gbm_surface創建一個新的drmModeFBPtr然后取代原來的命令行drmModeFBPtr給drmModeCrtcPtr顯示:
struct應用和顯示服務器間傳遞緩沖
現在我們知道自己實現的應用和顯示服務器端如何用OpenGL進行繪制,而且顯示服務器如何將繪制好的幀緩沖拿去顯示。最后的一個問題就是應用如何將緩沖傳遞給顯示服務器用于組裝。應用和顯示服務器是兩個獨立進程,這個需求只能用進程間通信來解決,但是圖形系統所需傳遞的數據量巨大(一幀往往需要幾MB,每秒60幀,就是上百MB/s,這還只是一個應用), 如果用傳統的進程間通信方法比如Socket和System V IPC,性能會很差。所以我們需要一種零拷貝的進程間共享緩沖的方式。
例四【4】展示了使用dma-buf+unix local socket達到應用和顯示服務器間零拷貝傳遞緩沖的實現。里面是應用部分的代碼,是顯示服務器部分的代碼。首先我們創建兩個進程分別代表應用和顯示服務器,用socketpair建立unix local socket連接(出于演示方便,真實的顯示服務器會用完整的socket listen/bind/connect/accept流程):
int然后是應用端,我們用GBM接口獲得緩沖的文件描述(File Descriptor),這個文件描述只是一個句柄,在Linux內核里代表了一個關聯緩沖的dma-buf結構體。我們只需要在進程間傳遞這個文件描述就可以共享他所代表的緩沖而不用拷貝。傳遞文件描述的方法就是這個Unix Local Socket的sendmsg函數。
// 獲得緩沖最后是顯示服務器端,用recvmsg接收應用傳送來的文件描述,然后還原為gbm_bo。支持EGL_KHR_image_pixmap擴展【6】的EGL可以將gbm_bo轉換為EGLImageKHR(對于支持EGL_EXT_image_dma_buf_import擴展【7】的EGL可以直接將文件描述轉換為EGLImageKHR)。支持GL_OES_EGL_image擴展【8】的OpenGL可以將EGLImageKHR轉換為貼圖,這樣就能將應用的緩沖作為一個OpengGL的貼圖進行組裝成幀緩沖的繪圖操作了。
// 接收dma-buf結語
本文介紹的這些技術是顯示服務器實現的基礎,下一篇文章我們會討論更深入的應用和顯示服務器間的同步問題。
引用
總結
以上是生活随笔為你收集整理的android studio 显示图形_显示服务器实现(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 罗永浩宣布退出所有社交平台!新浪:其微博
- 下一篇: 【转】RAX,eax,ax,ah,al