Android display架构分析(五)

   

Display 接口介绍

1、 User Space


      在 Android 平台下,应用程序面对的显示部分的接口就是 HAL ,参考 copybit.c ,具体接口如下介绍:


open_copybit


       初始化相关变量,并调用 open("/dev/graphics/fb0", O_RDWR, 0); 打开 fb 设备。


set_parameter_copybit


       设置各种操作参数,如 rotate 、 alpha 、 dither 等。


stretch_copybit


       Copy 一块数据( Rectangle )到显存,然后并命令 msm_fb 进行显示。


close_copybit


       调用 close(ctx->mFD); 关闭 fb 设备。


Note :另外,应用程序在使用上面接口之前,需要调用 mapFrameBuffer 接口( EGLDisplaySurface.cpp ),其功能如下:


1、 初始化显示相关参数,并设置到底层。


2、 映射出显存的虚拟地址。


2、 Kernel


      Kernel 部分显示的接口全部都在 fbmem.c 中,这里详细介绍一下:


fb_open


     打开 Linux 下 fb 设备。


fb_read/fb_write




fb_ioctl


     对显示设备的命令操作。如 get 或 set 一些显示参数、通知底层进行刷屏等。


在典型应用中,画屏的一般步骤如下:


1 . 打开/dev/fb 设备文件。


2 . 用ioctrl 操作取得当前显示屏幕的参数,如屏幕分辨率,每个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。


3 . 将屏幕缓冲区映射到用户空间。


4 . 映射后就可以直接读写屏幕缓冲区,进行绘图和图片显示了。


典型程序段如下:


#include <linux/fb.h> 
int main() 
{ 
int fbfd = 0; 
struct fb_var_screeninfo vinfo; 
struct fb_fix_screeninfo finfo; 
long int screensize = 0; 
/* 打开设备文件*/  
fbfd = open("/dev/fb0", O_RDWR); 
/* 取得屏幕相关参数*/  
ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo); ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo); 
/* 计算屏幕缓冲区大小*/  
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; 
/* 映射屏幕缓冲区到用户地址空间*/  
fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED, fbfd, 0); 
/* 下面可通过fbp 指针读写缓冲区*/ 
...
}




3 典型应用flow 分析


在不同应用程序中,上层的调用会有所不同,比如Andriod 下会选择应用程序跳过Linux fb 操作层,直接操作显卡驱动层,称之为BLT accelerator 。


下面看一下Android 平台下画屏的操作流程。


1、 通过mapFrameBuffer 直接把用户空间的数据映射到显存中。


2、 调用HAL 中的stretch 函数直接命令MSM 设备提取显存数据然后送入MDP PPP 进行处理并经MDDI 接口送到外围LCD 组件。


具体的函数调用流程如下:


copybit_open (); // 打开 BlitEngine ,同时也打开 fb
mapFrameBuffer();//
copybit->stretch(copybit, &dst, &src, &sdrect, &sdrect, &it);//


接下的流程是:


stretch_copybit-> msm_copybit->  fb_ioctl()->msm_fb_ioctl(MSMFB_BLIT)->  msmfb_blit->  mdp_blit->  mdp_ppp_blit->  mdp_start_ppp->MDP&MDDI HW operation