Android启动画面

Android有三种启动画面

1. 在kernel framebuffer驱动中的logo, 具体参见kernel/drivers/video/fbmem.c,这是最早的静态启动画面

2. init进程加载的启动画面,具体参考android/system/core/init/init.c 中load_565rle_image的实现

3. bootanimation动画,一般来说init.rc中会有下面一段:

service bootanim /system/bin/bootanimation
    user graphics
    group graphics
    disabled
    oneshot

bootanimation的实现参考frameworks/base/cmds/bootanimation/目录,这个进程会显示一段动画


这里要描述的是第二种开机画面

1 load_565rle_image源码

105 int load_565rle_image(char *fn)
106 {
107     struct FB fb;
108     struct stat s;
109     unsigned short *data, *bits, *ptr;
110     unsigned count, max;
111     int fd;
112
113     if (vt_set_mode(1))
114         return -1;
115
116     fd = open(fn, O_RDONLY);
117     if (fd < 0) {
118         ERROR("cannot open '%s'\n", fn);
119         goto fail_restore_text;
120     }
121
122     if (fstat(fd, &s) < 0) {
123         goto fail_close_file;
124     }
125
126     data = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
127     if (data == MAP_FAILED)
128         goto fail_close_file;
129
130     if (fb_open(&fb))
131         goto fail_unmap_data;
132
133     max = fb_width(&fb) * fb_height(&fb);
134     ptr = data;
135     count = s.st_size;
136     bits = fb.bits;
137     while (count > 3) {
138         unsigned n = ptr[0];
139         if (n > max)
140             break;
141         android_memset16(bits, ptr[1], n << 1);
142         bits += n;
143         max -= n;
144         ptr += 2;
145         count -= 4;
146     }
147
148     munmap(data, s.st_size);
149     fb_update(&fb);
150     fb_close(&fb);
151     close(fd);
152     unlink(fn);
153     return 0;
154
155 fail_unmap_data:
156     munmap(data, s.st_size);
157 fail_close_file:
158     close(fd);
159 fail_restore_text:
160     vt_set_mode(0);
161     return -1;
162 }
163 


2 rle图像文件格式

load_565rle_image 函数的输入参数是一个rle文件,该函数会把这个文件内容转换为rgb565,写入framebuffer。

以下百度百科来的rle简介 http://baike.baidu.com/view/18819.htm?fromTaglist

--------------------

RLE全称(run-length encoding),翻译为游程编码,又译行程长度编码,又称变动长度编码法(run coding),在控制论中对于二值图像而言是一种编码方法,对连续的黑、白像素数(游程)以不同的码字进行编码。游程编码是一种简单的非破坏性资料压缩法,其好处是加压缩和解压缩都非常快。其方法是计算连续出现的资料长度压缩之。

-------------------

RLE文件格式为 [count(2 bytes), color(2 bytes)], count最大为65535;color为RGB565, 当然也可以是YUV422,我觉得只要是2bytes以下的都可以,但是由于最终我们写入到framebuffer中的都是RGB565,从效率的角度,rle文件的color值为RGB565最好。

3 写入framebuffer

load_565rel_image 源码第141行:写入n个像素点,像素点的color值是rle中的原始数据,这对于rgb565的framebuffer没有问题,但是如果framebuffer是RGB32(ARGB),就无法工作了。解决办法是做个转换,把2bytes的RGB565转换为4 bytes的ARGB 即可。

上代码

#define rgb32_r(rle) (((rle & 0xf800) >> 11) << 3)
#define rgb32_g(rle) (((rle & 0x07e0) >> 5 << 2))
#define rgb32_b(rle) (((rle & 0x001f) << 3))
#define rgb32(rle) (rgb32_r(rle) << 16 | rgb32_g(rle) << 8 | rgb32_b(rle) << 0) 


        unsigned int *bits;
        bits = (unsigned int *)fb.bits;
        while (count > 3) {
            unsigned n = ptr[0];
            if (n > max)
                break;
            out = rgb32(ptr[1]);
            android_memset32(bits, out, n << 2);
            bits += n;
            max -= n;
            ptr += 2;
            count -= 4;

4 现在再回去,看看怎么得到rle格式的文件,一般来说分两步走,先把原始图片转为RGB565,然后再把RGB565转为rle(当然不是必需的,如果有个能把png直接转为rle的工具)。

a) 先用GMIP生成一个800X480的png文件,为什么是800x480,图片大小必须和屏大小一致,至于是不是png无所谓,只要有工具能转为RGB565即可

b) convert命令png为RGB565: convert -depth 8 android_logo.png rgb:android_logo.raw

c) 转换RGB565为rle文件:rgb2565 -rle < android_logo.raw > initlogo.rle

5. 替换ramdisk中的initlogo.rle,重新启动即可看到新的启动画面


注意load_565rle_image 152行 unlink(fn)会删除initlogo.rle文件,进入系统后,会发现/initlogo.rle文件已经被删除了,这样可以节约一点ramdisk文件系统的内存空间,

对于ramdisk做rootfs,这没有问题,因为ramdisk镜像本身并没有被修改

但是如果根文件系统是其他文件系统,就需要把unlink(fn)注释掉,以防止initlog.rle被永久删除。


android/system/core/init/logo.c 可扩展性并不是很好,代码假定framebuffer是RGB565,实际上我接触到的就有其他格式的FB,比如YUYV和ARGB,如果碰到这种情况就要对这个文件代码做修改





  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值