Android有其完整的顯示系統,上層顯示系統提供系統圖形的輸出裝置,java層的和和控制項的外觀和直接的圖形介面的繪製都是通過顯示系統呈現出來的。Android的底層顯示系統與Android的Surface庫部分有也著很強的聯絡。底層顯示系統提供的是基本的顯示輸出裝置的封裝,Surface庫部分是基於這個顯示終端,提供了多個圖層的支援以及圖層間的效果等功能。的是Android顯示系統的基於階層。
圖1 Android顯示系統的階層
在Android顯示驅動中,存在一個名為Gralloc的硬體模組,這個硬體模組位於libui與顯示裝置驅動之間,這個Gralloc作為顯示系統的硬體抽象層來使用。2所示。
圖2 Gralloc與Framebuffer驅動之間的聯絡
Gralloc模組有存在形式是一個放置在/system/lib/hw中的動態庫。系統的其他部分沒有串連這個動態庫,而是在啟動並執行過程中使用dlopen和dlsym的方式動態地開啟和取出符號來使用。Gralloc模組是一個可以移植的硬體抽象層。它是系統和顯示裝置的介面,以硬體模組的形式存在。Android系統通常使用framebuffer作為其驅動程式。但是如果使用Gralloc也可以不使用framebuffer裝置。在上層,主要由libui庫中的FramebufferNativeWindows.cpp部分是Gralloc模組的主要調用者。
libui是Android在本地層次一個架構性質的整合庫,它不僅是現實的中樞,也是整個AndroidGUI系統的中樞。這個庫提供了一些介面,由其他的庫通過類繼承方式來實現,而調用者只需要調用libui庫的介面即可。libui庫包含了顏色格式,Egl視窗(使用者顯示),按鍵及事件處理,Surface(顯示介面),Overlay(顯示疊加層介面),Camera(照相機介面)等多個方面的定義。
由於Android是基於Linux作業系統的,所以Android的底層顯示裝置驅動是framebuffer驅動。Framebuffer驅動是一個字元裝置驅動,它採用了“檔案層——驅動層”的介面方式。Linux為幀緩衝裝置定義的驅動層介面為fb_info結構體。在檔案層次上,使用者調用file_operations結構體的函數操作,其中間接調用fb_ops結構體的函數來操作硬體。在向核心註冊FB裝置的時候,也註冊了struct fb_ops的指標。當開啟FB裝置時,先調用fb_drivers[]的xxxfb_init()來初始化裝置。framebuffer驅動在檔案系統中的裝置節點通常是/dev/fbX。
Framebuffer裝置驅動在Linux核心源碼中主要基於三個檔案:
/include/linux/fb.h
/drivers/video/fbmem.h
/driver/video/xxxfb.c
fb.h主要是定義一些結構體和宏;fbmem.h實現了裝置初始化、卸載和檔案操作介面;xxxfb.c為自己添加的裝置驅動檔案(如 struct fb_info)實現了進入點函數xxxfb_init;xxxfb_setup。
framebuffer裝置最關鍵的一個資料結構體是fb_info結構體,它包括了關於幀緩衝裝置屬性和操作的完整描述,這個結構體的定義如下(include/linux/fb.h):
struct fb_info {int node;int flags;struct mutex lock;/* Lock for open/release/ioctl funcs */struct mutex mm_lock;/* Lock for fb_mmap and smem_* fields */struct fb_var_screeninfo var;/* Current var */struct fb_fix_screeninfo fix;/* Current fix */struct fb_monspecs monspecs;/* Current Monitor specs */struct work_struct queue;/* Framebuffer event queue */struct fb_pixmap pixmap;/* Image hardware mapper */struct fb_pixmap sprite;/* Cursor hardware mapper */struct fb_cmap cmap;/* Current cmap */struct list_head modelist; /* mode list */struct fb_videomode *mode;/* current mode */#ifdef CONFIG_FB_BACKLIGHT/* assigned backlight device *//* set before framebuffer registration, remove after unregister */struct backlight_device *bl_dev;/* Backlight level curve */struct mutex bl_curve_mutex;u8 bl_curve[FB_BACKLIGHT_LEVELS];#endif#ifdef CONFIG_FB_DEFERRED_IOstruct delayed_work deferred_work;struct fb_deferred_io *fbdefio;#endifstruct fb_ops *fbops;struct device *device;/* This is the parent */struct device *dev;/* This is this fb device */int class_flag; /* private sysfs flags */#ifdef CONFIG_FB_TILEBLITTINGstruct fb_tile_ops *tileops; /* Tile Blitting */#endifchar __iomem *screen_base;/* Virtual address */unsigned long screen_size;/* Amount of ioremapped VRAM or 0 */ void *pseudo_palette;/* Fake palette of 16 colors */ #define FBINFO_STATE_RUNNING0#define FBINFO_STATE_SUSPENDED1u32 state;/* Hardware state i.e suspend */void *fbcon_par; /* fbcon use-only private area *//* From here on everything is device dependent */void *par;/* we need the PCI or similiar aperture base/size not smem_start/size as smem_start may just be an object allocated inside the aperture so may not actually overlap */resource_size_t aperture_base;resource_size_t aperture_size;};
fb_info的成員變數fbops為指向底層操作的函數的指標,這些函數是需要驅動程式開發人員編寫的。
struct fb_ops {/* open/release and usage marking */struct module *owner;int (*fb_open)(struct fb_info *info, int user);int (*fb_release)(struct fb_info *info, int user);/* For framebuffers with strange non linear layouts or that do not * work with normal memory mapped access */ssize_t (*fb_read)(struct fb_info *info, char __user *buf, size_t count, loff_t *ppos);ssize_t (*fb_write)(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos);/* checks var and eventually tweaks it to something supported, * DO NOT MODIFY PAR */int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);/* set the video mode according to info->var */int (*fb_set_par)(struct fb_info *info);/* set color register */int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info);/* set color registers in batch */int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);/* blank display */int (*fb_blank)(int blank, struct fb_info *info);/* pan display */int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);/* Draws a rectangle */void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);/* Copy data from area to another */void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);/* Draws a image to the display */void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);/* Draws cursor */int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);/* Rotates the display */void (*fb_rotate)(struct fb_info *info, int angle);/* wait for blit idle, optional */int (*fb_sync)(struct fb_info *info);/* perform fb specific ioctl (optional) */int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,unsigned long arg);/* Handle 32bit compat ioctl (optional) */int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,unsigned long arg);/* perform fb specific mmap */int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);/* save current hardware state */void (*fb_save_state)(struct fb_info *info);/* restore saved state */void (*fb_restore_state)(struct fb_info *info);/* get capability given var */void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps, struct fb_var_screeninfo *var);/* teardown any resources to do with this framebuffer */void (*fb_destroy)(struct fb_info *info);};