您的位置:首页 > 移动开发 > Android开发

Android系统的开机画面显示过程分析(4)

2012-07-09 00:56 405 查看
函数fb_show_logo_line也是实现在文件kernel/goldfish/drivers/video/fbmem.c中,如下所示:

static int fb_show_logo_line(struct fb_info *info, int rotate,

const struct linux_logo *logo, int y,

unsigned int n)

{

u32 *palette = NULL, *saved_pseudo_palette = NULL;

unsigned char *logo_new = NULL, *logo_rotate = NULL;

struct fb_image image;

/* Return if the frame buffer is not mapped or suspended */

if (logo == NULL || info->state != FBINFO_STATE_RUNNING ||

info->flags & FBINFO_MODULE)

return 0;

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)

return 0;

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;

return 0;

}

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);

return logo->height;

}

参数logo指向了前面所准备的第一个开机画面的内容。这个函数首先根据参数logo的内容来构造一个fb_image结构体image,用来描述最终要显示的第一个开机画面。最后就调用函数fb_do_show_logo来真正执行渲染第一个开机画面的操作。 函数fbcon_switch实现在文件kernel/goldfish/drivers/video/console/fbcon.c中,显示第一个开机画面的过程如下所示:

static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,

int rotate, unsigned int num)

{

unsigned int x;

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;

}

} else if (rotate == FB_ROTATE_UD) {

for (x = 0; x < num && image->dx >= 0; x++) {

info->fbops->fb_imageblit(info, image);

image->dx -= image->width + 8;

}

} else if (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;

}

} else if (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就是用来在指定的帧缓冲区硬件设备渲染指定的图像的。
至此,第一个开机画面的显示过程就分析完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息