display模块的主要功能:
提供 显示设备属性 和 用于显示的函数
主要用于字体显示和图片显示。
display模块包含两个文件,display_manager.c和fb.c,其中fb.c为支持的显示设备,display_manager.c通过链表管理可支持的设备。
display_manager.c
|
fb.c
底层设备如fb.c,向上注册DispOpr结构体,提供该设备的 属性 和 操作函数。fb.c中的函数都是static,只能在本文件调用,其它文件要使用这些函数要通过它的接口函数disp_manager.c来调用。
typedef struct DispOpr {
char *name; /* 显示模块的名字 */
int iXres; /* X分辨率 */
int iYres; /* Y分辨率 */
int iBpp; /* 一个象素用多少位来表示 */
int iLineWidth; /* 一行数据占据多少字节 */
unsigned char *pucDispMem; /* 显存地址 */
int (*DeviceInit)(void); /* 设备初始化函数 */
int (*ShowPixel)(int iPenX, int iPenY, unsigned int dwColor); /* 把指定座标的象素设为某颜色 */
int (*CleanScreen)(unsigned int dwBackColor); /* 清屏为某颜色 */
int (*ShowPage)(PT_VideoMem ptVideoMem); /* 显示一页,数据源自ptVideoMem */
struct DispOpr *ptNext; /* 链表 */
}T_DispOpr, *PT_DispOpr;
display_manager.c通过链表管理底层支持的显示设备向上注册的DispOpr结构体,并向外部提供对底层的 操作函数。display_manager.c提供的函数,前部分是对lcd的操作,后部分是关于显存管理的函数。
/* 显示区域,含该区域的左上角/右下角座标,图标的文件名*/
typedef struct Layout {
int iTopLeftX;
int iTopLeftY;
int iBotRightX;
int iBotRightY;
char *strIconName;
}T_Layout, *PT_Layout;
//额外分配内存描述结构体
typedef struct VideoMem {
int iID; /* ID值,用于标识不同的页面 */
int bDevFrameBuffer; /* 判断:1: 这个VideoMem是显示设备的显存; 0: 只是一个普通缓存 */
E_VideoMemState eVideoMemState; /* 这个VideoMem的状态:空闲/用于预先准备显示内容/用于当前线程 */
E_PicState ePicState; /* VideoMem中内存里图片的状态:空白/正在生成/已经生成 */
T_PixelDatas tPixelDatas; /* 内存: 用来存储图像 */
struct VideoMem *ptNext; /* 链表 */
}T_VideoMem, *PT_VideoMem;
//显示模块
typedef struct DispOpr {......}
//注册"显示模块", 把所能支持的显示设备的操作函数放入链表
int RegisterDispOpr(PT_DispOpr ptDispOpr)
//根据名字取出指定的"显示模块"
PT_DispOpr GetDispOpr(char *pcName)
//根据名字取出指定的"显示模块", 调用它的初始化函数, 并且清屏
void SelectAndInitDefaultDispDev(char *name)
//程序事先用SelectAndInitDefaultDispDev选择了显示模块,本函数返回该显示模块
PT_DispOpr GetDefaultDispDev(void)
//获得所使用的显示设备的分辨率和BPP
int GetDispResolution(int *piXres, int *piYres, int *piBpp)
//VideoMem: 为加快显示速度,我们事先在缓存中构造好显示的页面的数据,(这个缓存称为VideoMem)显示时再把VideoMem中的数据复制到设备的显存上
int AllocVideoMem(int iNum)
//获得一块可操作的VideoMem(它用于存储要显示的数据), 用完后用PutVideoMem来释放
PT_VideoMem GetVideoMem(int iID, int bCur)
//使用GetVideoMem获得的VideoMem, 用完时用PutVideoMem释放掉
void PutVideoMem(PT_VideoMem ptVideoMem)
//获得显示设备的显存, 在该显存上操作就可以直接在LCD上显示出来
PT_VideoMem GetDevVideoMem(void)
//把VideoMem中内存全部清为某种颜色
void ClearVideoMem(PT_VideoMem ptVideoMem, unsigned int dwColor)
//把VideoMem中内存的指定区域全部清为某种颜色
void ClearVideoMemRegion(PT_VideoMem ptVideoMem, PT_Layout ptLayout, unsigned int dwColor)
获得所使用的显示设备的分辨率和BPP
int GetDispResolution(int *piXres, int *piYres, int *piBpp){
if (g_ptDefaultDispOpr){
*piXres = g_ptDefaultDispOpr->iXres;
*piYres = g_ptDefaultDispOpr->iYres;
*piBpp = g_ptDefaultDispOpr->iBpp;
return 0;
}
else
return -1;
}
把VideoMem中内存全部清为某种颜色
void ClearVideoMem(PT_VideoMem ptVideoMem, unsigned int dwColor){
unsigned char *pucVM;
unsigned short *pwVM16bpp;
unsigned int *pdwVM32bpp;
unsigned short wColor16bpp; /* 565 */
int iRed,iGreen,iBlue;
int i = 0;
pucVM = ptVideoMem->tPixelDatas.aucPixelDatas;
pwVM16bpp = (unsigned short *)pucVM;
pdwVM32bpp = (unsigned int *)pucVM;
switch (ptVideoMem->tPixelDatas.iBpp){
case 8:{
memset(pucVM, dwColor, ptVideoMem->tPixelDatas.iTotalBytes);
break;
}
case 16:{
/* 先根据32位的dwColor构造出16位的wColor16bpp */
iRed = (dwColor >> (16+3)) & 0x1f;
iGreen = (dwColor >> (8+2)) & 0x3f;
iBlue = (dwColor >> 3) & 0x1f;
wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
while (i < ptVideoMem->tPixelDatas.iTotalBytes){
*pwVM16bpp = wColor16bpp;
pwVM16bpp++;
i += 2;
}
break;
}
case 32:{
while (i < ptVideoMem->tPixelDatas.iTotalBytes){
*pdwVM32bpp = dwColor;
pdwVM32bpp++;
i += 4;
}
break;
}
default :{
DBG_PRINTF("can't support %d bpp\n", ptVideoMem->tPixelDatas.iBpp);
return;
}
}
}
把VideoMem中内存的指定区域全部清为某种颜色
void ClearVideoMemRegion(PT_VideoMem ptVideoMem, PT_Layout ptLayout, unsigned int dwColor){
unsigned char *pucVM;
unsigned short *pwVM16bpp;
unsigned int *pdwVM32bpp;
unsigned short wColor16bpp; /* 565 */
int iRed,iGreen,iBlue;
int iX,iY;
int iLineBytesClear;
int i;
pucVM = ptVideoMem->tPixelDatas.aucPixelDatas + ptLayout->iTopLeftY * ptVideoMem->tPixelDatas.iLineBytes + ptLayout->iTopLeftX * ptVideoMem->tPixelDatas.iBpp / 8;
pwVM16bpp = (unsigned short *)pucVM;
pdwVM32bpp = (unsigned int *)pucVM;
iLineBytesClear = (ptLayout->iBotRightX - ptLayout->iTopLeftX + 1) * ptVideoMem->tPixelDatas.iBpp / 8;
switch (ptVideoMem->tPixelDatas.iBpp){
case 8:{
for (iY = ptLayout->iTopLeftY; iY <= ptLayout->iBotRightY; iY++){
memset(pucVM, dwColor, iLineBytesClear);
pucVM += ptVideoMem->tPixelDatas.iLineBytes;
}
break;
}
case 16:{
/* 先根据32位的dwColor构造出16位的wColor16bpp */
iRed = (dwColor >> (16+3)) & 0x1f;
iGreen = (dwColor >> (8+2)) & 0x3f;
iBlue = (dwColor >> 3) & 0x1f;
wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
for (iY = ptLayout->iTopLeftY; iY <= ptLayout->iBotRightY; iY++){
i = 0;
for (iX = ptLayout->iTopLeftX; iX <= ptLayout->iBotRightX; iX++){
pwVM16bpp[i++] = wColor16bpp;
}
pwVM16bpp = (unsigned short *)((unsigned int)pwVM16bpp + ptVideoMem->tPixelDatas.iLineBytes);
}
break;
}
case 32:{
for (iY = ptLayout->iTopLeftY; iY <= ptLayout->iBotRightY; iY++){
i = 0;
for (iX = ptLayout->iTopLeftX; iX <= ptLayout->iBotRightX; iX++){
pdwVM32bpp[i++] = dwColor;
}
pdwVM32bpp = (unsigned int *)((unsigned int)pdwVM32bpp + ptVideoMem->tPixelDatas.iLineBytes);
}
break;
}
default :{
DBG_PRINTF("can't support %d bpp\n", ptVideoMem->tPixelDatas.iBpp);
return;
}
}
}