多窗口 overlay
移植lcd驱动后,发现/dev/下只有一个fb0,但是s3c-fb支持5个window叠加,应该有5个设备节点。
分析代码:
s3c-fb.c
调用关系
static int __devinit s3c_fb_probe(struct platform_device *pdev)
s3c_fb_probe_win(sfb, win, fbdrv->win[win], &sfb->windows[win]);
/* run the check_var and set_par on our configuration. */
printk("win:%d,framebuffer:0x%08lx\n",win_no,fbinfo->fix.smem_start);
register_framebuffer(fbinfo);
而在注册之前,判断s3c_fb_platdata是不是又win[x]的信息,如果没有则不能注册。
/* we have the register setup, start allocating framebuffers */ for (win = 0; win < fbdrv->variant.nr_windows; win++) { if (!pd->win[win]) continue; if (!pd->win[win]->win_mode.pixclock) s3c_fb_missing_pixclock(&pd->win[win]->win_mode); ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win], &sfb->windows[win]); if (ret < 0) { dev_err(dev, "failed to create window %d\n", win); for (; win >= 0; win--) s3c_fb_release_win(sfb, sfb->windows[win]); goto err_pm_runtime; } }
static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = { .win[0] = &smdkv210_fb_win0, .win[1] = &smdkv210_fb_win1, .win[2] = &smdkv210_fb_win2, .win[3] = &smdkv210_fb_win3, .win[4] = &smdkv210_fb_win4, .vidcon0 = (4<<6) | (1<<4)|(1<<0)|(1<<1),//VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 =1<<5 | 1<<6, //VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, .setup_gpio = s5pv210_fb_gpio_setup_24bpp, };
static struct s3c_fb_pd_win smdkv210_fb_win0 = { .win_mode = { .left_margin = 45,//46-1 .right_margin = 209,//210-1 .upper_margin = 22,//23-1 .lower_margin = 21,//22-1 .hsync_len = 39, .vsync_len = 19, .xres = 800, .yres = 480, }, .max_bpp = 32, .default_bpp = 24, }; static struct s3c_fb_pd_win smdkv210_fb_win1 = { .win_mode = { .left_margin = 45,//46-1 .right_margin = 209,//210-1 .upper_margin = 22,//23-1 .lower_margin = 21,//22-1 .hsync_len = 39, .vsync_len = 19, .xres = 800, .yres = 480, }, .max_bpp = 32, .default_bpp = 24, }; static struct s3c_fb_pd_win smdkv210_fb_win2 = { .win_mode = { .left_margin = 45,//46-1 .right_margin = 209,//210-1 .upper_margin = 22,//23-1 .lower_margin = 21,//22-1 .hsync_len = 39, .vsync_len = 19, .xres = 800, .yres = 480, }, .max_bpp = 32, .default_bpp = 24, }; static struct s3c_fb_pd_win smdkv210_fb_win3 = { .win_mode = { .left_margin = 45,//46-1 .right_margin = 209,//210-1 .upper_margin = 22,//23-1 .lower_margin = 21,//22-1 .hsync_len = 39, .vsync_len = 19, .xres = 800, .yres = 480, }, .max_bpp = 32, .default_bpp = 24, }; static struct s3c_fb_pd_win smdkv210_fb_win4 = { .win_mode = { .left_margin = 45,//46-1 .right_margin = 209,//210-1 .upper_margin = 22,//23-1 .lower_margin = 21,//22-1 .hsync_len = 39, .vsync_len = 19, .xres = 800, .yres = 480, }, .max_bpp = 32, .default_bpp = 24, };
在dev下可以看到有5个fb的设备节点
测试代码 :
第0、1、2、3分别显示出来,叠加的效果,然后第4层滚动的效果
#include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <linux/fb.h> #define WIN_MAX 5 const char * fb_file_path[5] = { "/dev/fb0", "/dev/fb1", "/dev/fb2", "/dev/fb3", "/dev/fb4" }; int color[5] = { 0x50ffffff, 0x50ff0000, 0x5000ff00, 0x500000ff, 0x50000000, }; int main(int argc, char *argv[]) { int i,j,k; int ret; struct fb_var_screeninfo var; int blank; int fd[5]; int width; int height; int *p[5]; /* open framebuffer */ for(i=0; i<WIN_MAX; i++) { fd[i] = open(fb_file_path[i], O_RDWR); if( fd[i] < 0 ) { printf("open %s failed\n", fb_file_path[i]); goto end; } printf("open %s success:%d\n", fb_file_path[i],fd[i]); } ret = ioctl(fd[0], FBIOGET_VSCREENINFO, &var); if(ret < 0) { printf("ioctl %s FBIOGET_VSCREENINFO failed\n", fb_file_path[0]); goto end; } width = var.xres; height = var.yres; printf("width:%d,height:%d\n",width, height); printf("set screeninfo ok\n"); for(i=0; i<WIN_MAX; i++) { p[i] = (int *)mmap(NULL, width * height * 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd[i], 0); if((p[i] == NULL) || (p[i] == -1)) { printf("the mmap:%d is NULL\n",i); goto end; } } for(k = 0; k < WIN_MAX; k++) { for(i = 0; i < height - (k * 100); i++) for(j = 0; j < width; j++) { p[k][i * width + j] = color[k]; } printf("draw %d, 0x%08lx\n",k, color[k]); } while(1) { for(i = 0; i < height; i++) { for(j = 0; j < width; j++) { p[4][i * width + j] = 0x50ff0000; } usleep(1000); } for(i = 0; i < height; i++) { for(j = 0; j < width; j++) { p[4][i * width + j] = 0x00000000; } usleep(1000); } } end: return 0; }