Android系统的开机画面显示过程分析(4)
函数fb_show_logo_line也是实现在文件kernel/goldfish/drivers/video/fbmem.c中,如下所示: staticintfb_show_logo_line(structfb_info*info,introtate, conststructlinux_logo*logo,inty, unsignedintn) { u32*palette=NULL,*saved_pseudo_palette=NULL; unsignedchar*logo_new=NULL,*logo_rotate=NULL; structfb_imageimage; /*Returniftheframebufferisnotmappedorsuspended*/ if(logo==NULL||info->state!=FBINFO_STATE_RUNNING|| info->flags&FBINFO_MODULE) return0; image.depth=8; image.data=logo->data; if(fb_logo.needs_cmapreset) fb_set_logocmap(info,logo); if(fb_logo.needs_truepalette|| fb_logo.needs_directpalette){ palette=kmalloc(256*4,GFP_KERNEL); if(palette==NULL) return0; if(fb_logo.needs_truepalette) fb_set_logo_truepalette(info,logo,palette); else fb_set_logo_directpalette(info,logo,palette); saved_pseudo_palette=info->pseudo_palette; info->pseudo_palette=palette; } if(fb_logo.depth<=4){ logo_new=kmalloc(logo->width*logo->height,GFP_KERNEL); if(logo_new==NULL){ kfree(palette); if(saved_pseudo_palette) info->pseudo_palette=saved_pseudo_palette; return0; } image.data=logo_new; fb_set_logo(info,logo,logo_new,fb_logo.depth); } image.dx=0; image.dy=y; image.width=logo->width; image.height=logo->height; if(rotate){ logo_rotate=kmalloc(logo->width* logo->height,GFP_KERNEL); if(logo_rotate) fb_rotate_logo(info,logo_rotate,&image,rotate); } fb_do_show_logo(info,&image,rotate,n); kfree(palette); if(saved_pseudo_palette!=NULL) info->pseudo_palette=saved_pseudo_palette; kfree(logo_new); kfree(logo_rotate); returnlogo->height; } 参数logo指向了前面所准备的第一个开机画面的内容。这个函数首先根据参数logo的内容来构造一个fb_image结构体image,用来描述最终要显示的第一个开机画面。最后就调用函数fb_do_show_logo来真正执行渲染第一个开机画面的操作。函数fbcon_switch实现在文件kernel/goldfish/drivers/video/console/fbcon.c中,显示第一个开机画面的过程如下所示: staticvoidfb_do_show_logo(structfb_info*info,structfb_image*image, introtate,unsignedintnum) { unsignedintx; if(rotate==FB_ROTATE_UR){ for(x=0; x<num&&image->dx+image->width<=info->var.xres; x++){ info->fbops->fb_imageblit(info,image); image->dx+=image->width+8; } }elseif(rotate==FB_ROTATE_UD){ for(x=0;x<num&&image->dx>=0;x++){ info->fbops->fb_imageblit(info,image); image->dx-=image->width+8; } }elseif(rotate==FB_ROTATE_CW){ for(x=0; x<num&&image->dy+image->height<=info->var.yres; x++){ info->fbops->fb_imageblit(info,image); image->dy+=image->height+8; } }elseif(rotate==FB_ROTATE_CCW){ for(x=0;x<num&&image->dy>=0;x++){ info->fbops->fb_imageblit(info,image); image->dy-=image->height+8; } } } 参数rotate用来描述屏幕的当前旋转方向。屏幕旋转方向不同,第一个开机画面的渲染方式也有所不同。例如,当屏幕上下颠倒时(FB_ROTATE_UD),第一个开机画面的左右顺序就刚好调换过来,这时候就需要从右到左来渲染。其它三个方向FB_ROTATE_UR、FB_ROTATE_CW和FB_ROTATE_CCW分别表示没有旋转、顺时针旋转90度和逆时针旋转90度。 参数info用来描述要渲染的帧缓冲区硬件设备,它的成员变量fbops指向了一系列回调函数,用来操作帧缓冲区硬件设备,其中,回调函数fb_imageblit就是用来在指定的帧缓冲区硬件设备渲染指定的图像的。 至此,第一个开机画面的显示过程就分析完成了。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967032,如需转载请自行联系原作者