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_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
struct 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_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */
#endif
char __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_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 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;
};
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);
};