FrameBuffer 在Android中並不像在其它GUI那樣直觀,抽象的層次比較多,加上GUI的更新是經過OpenGLES來作的。因此讓人很難搞清GUI更新的整個流程,最近要準備一個講稿,因此花了一些去研究,這裏作點筆記供你們參考,源代碼是基於高通平臺的,這些代碼在網上均可如下載。html
FrameBuffer 的相關組件以下圖所示:linux
圖片貼不過來,請到原地址去查看http://www.linuxgraphics.cn/android/framebuffer_arch.htmlandroid
mNativeWindow = new FramebufferNativeWindow(); framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) { overlay_control_open(module, &mOverlayEngine); } surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); eglMakeCurrent(display, surface, surface, context);
這兩個函數由eglSwapBuffers調過來,調到:算法
egl_window_surface_v2_t::swapBuffers: nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->dequeueBuffer(nativeWindow, &buffer);
OverlayControlChannel用於設置參數,好比設置Overlay的位置,寬度和高度:緩存
mNativeWindow = new FramebufferNativeWindow(); framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) { overlay_control_open(module, &mOverlayEngine); } surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); eglMakeCurrent(display, surface, surface, context);
這兩個函數由eglSwapBuffers調過來,調到:函數
egl_window_surface_v2_t::swapBuffers: nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->dequeueBuffer(nativeWindow, &buffer);
OverlayControlChannel用於設置參數,好比設置Overlay的位置,寬度和高度:post
bool OverlayControlChannel::setPosition(int x, int y, uint32_t w, uint32_t h) {
ov.dst_rect.x = x;
ov.dst_rect.y = y;
ov.dst_rect.w = w;
ov.dst_rect.h = h;
ioctl(mFD, MSMFB_OVERLAY_SET, &ov);
}ui
OverlayDataChannel用於顯示Overlay,其中最重要的函數就是queueBuffer:.net
bool OverlayDataChannel::queueBuffer(uint32_t offset) { mOvData.data.offset = offset; ioctl(mFD, MSMFB_OVERLAY_PLAY, odPtr)) }
framebuffer只是/dev/graphic/fb0的包裝,Surface的Buffer則是對/dev/pmem、ashmem和GPU內存(msm_hw3dm)的包裝,它的目標主要是方便硬件加速,由於 DMA傳輸使用物理地址,要求內存在物理地址上連續。插件
#define MSM_PMEM_MDP_SIZE 0x1B76000 #define MSM_PMEM_ADSP_SIZE 0xB71000 #define MSM_PMEM_AUDIO_SIZE 0x5B000 #define MSM_FB_SIZE 0x177000 #define MSM_GPU_PHYS_SIZE SZ_2M #define PMEM_KERNEL_EBI1_SIZE 0x1C000
msm_msm7x2x_allocate_memory_regions分配幾大塊內存用於給pmem作二次分配。
Kernel Graphics System Layer (KGSL),3D圖形加速驅動程序,源代碼drivers/gpu/msm目錄下,它是對GPU的包裝,給OpenGLES 2.0提供抽象的接口。
這個我在內核中沒有找到相關代碼。
msm_fb.c: framebuffer, overlay和blit的用戶接口。
mdp_dma.c: 對具體顯示設備的包裝,提供兩種framebuffer更新的方式:
mdp_refresh_screen: 定時更新。
mdp_dma_pan_update: 經過pan display主動更新。
mdp_dma_lcdc.c:針對LCD實現的顯示設備,mdp_lcdc_update用更新framebuffer