首先介绍有关色彩深度的知识。
计算机显示器上同时能显示的颜色数量是由色彩深度(Color Depth)决定的,例如色彩深度若为16则同时能显示2的16次方即65536种颜色,色彩深度若为24则同时能显示2的24次方即16777216种颜色。在显卡驱动设置里通常把16位色模式称为“增强色”,24位色模式称为“真彩色”。至于显卡支持的 32位色模式,只是为了更好地处理色彩,实际上液晶面板能支持的色彩深度通常还是24位,也就是红绿蓝各8位。
正常人眼可分辨的颜色种类可达几十万种以上,而用测色器则可以分辨出一百万种以上的颜色。所以一般来说24位色(即真彩色)已经能很好地表现人眼所能看到的自然界真实的色彩,比如数码相机拍摄的照片一般就是以24位色模式保存的。
一台显示器实际能显示的最大色彩深度由硬件和软件两方面决定。硬件方面,CRT显示器的R、G、B由模拟信号控制,理论上能显示的色彩种类是无穷多的,液晶显示器则取决于液晶面板和驱动电路对色彩的处理能力,以及显卡支持的色彩深度。目前计算机用的液晶显示器至少都可以支持24位色显示,显卡也没有任何问题。软件方面,则要看显卡驱动程序和操作系统是否能支持24位色显示,目前的主流 PC操作系统如 Windows 系列、Linux 也都没问题。
实际上通常情况下人眼也不易分辨出16位色与24位色的差异,若将计算机显卡设为16位色模式观看数码相机拍的照片,通常看不出来与在真彩色模式下有什么差别。
但如果在屏幕上显示色彩连续渐变的图形,不同的色彩深度就会看到明显的差异。如下图所示(此图片引用自http://www.hi-pda.com/forum/viewthread.php?tid=501100),最左边的图片是原始图,颜色从橙色到红色过渡很平滑,中间和右边的图是在16位色的系统上显示的效果,色彩渐变的过渡带出现了明显的色斑。
一般来说,象这种由于色彩连续渐变导致出现色斑的情形在数码相机拍摄的自然界景物的照片中并不多见,所以数码照片无论是在16位色还是在真彩色模式下看起来的效果其实差别不大;但在人工设计的图片中则比较常见这种情形,比如在手机产品开发中,有些UI设计师喜欢用绚丽多变的色彩来吸引用户的眼球,包括大量使用渐变色,他们设计的 UI图片如果在 16位色的手机上显示就会出现上述的色斑,严重影响了视觉效果,为了解决这种问题,要么修改UI设计,尽量避免使用渐变色,要么就只能修改软硬件实现真正的24位真彩色显示。
对于 PC来说,支持 24位真彩色显示没有任何问题,但对于手机来说就不一定了。首先手机用的显示屏出于成本的考量不一定支持24位色彩深度,可能只有18位、16位,早期的彩屏手机甚至只支持 4096色;其次手机操作系统也往往不支持 16位以上的色彩深度,比如微软的 Windows Mobile各版本始终只能支持 16位色以至于常遭一些用户诟病(最新的 Windows Phone 7 我不清楚是否还是这样?)。
大部分手机不能支持24位色真彩色显示其实也是有道理的,就象上面说的,只要设计 UI时尽量避免使用渐变色就不会影响用户视觉体验(个人认为这是完全可以做到的,很多优秀的UI设计并不依靠绚丽的色彩取胜),另一方面使用较少的色彩位数有利于降低对内存和处理器性能的要求,屏也不需要支持24位,可以大大降低成本。但技术在飞速发展,智能手机的硬件配置和运算能力已经越来越接近PC,用户对界面显示效果的要求也越来越高,所以手机制造商也考虑在显示上支持 24位真彩色。
最近两年在智能手机市场火起来的Android 的早期版本也象Windows Mobile 一样只支持16位色,并不支持 24位真彩色显示。去年5月上市的联想的乐phone应该是世界上第一款真正支持 24位色显示的 Android手机,为了实现这个特性,我们对乐phone 所使用的 Android 1.6(Donut)进行了修改和优化。下面就以高通 QSD8250平台为例介绍在 Donut 上实现 24位真彩色显示的前提条件和大致方法。
1.
2.
3.
4.
5.
6.
7.
经过上述修改后在Android 1.6(Donut)上实现了24位真彩色显示,在UI设计中如果使用了色彩连续渐变的图就不会出现色斑,使界面色彩更加丰富炫丽,比其他Android手机更能吸引用户的眼球。总的代码修改量并不大,不影响Android原有的图形显示架构。
虽然24位真彩色给UI设计带来了好处,但因为原生的Donut并不支持24位色,上述修改也会带来副作用以及一些没有预见到的问题。
首先是性能问题,如前所述,24位色下的2D图形性能稍低于16位色,也会占用更多内存,经分析瓶颈在2D图形库skia,该库是Android图形显示系统的核心模块,其性能对UI操作的流畅度影响很大,在Donut中skia并未针对硬件平台进行优化,更没有考虑对RGBA8888色彩模式的优化。为此我们利用ARMv7的neon指令对skia中涉及RGBA8888模式的关键代码及bionic中的memcpy进行优化,同时对UI动效设计进行优化,结果benchmark得分及实际用户体验不逊于原生Donut。
其次是某些应用程序的背景色在原生Donut上运行时为黑色,但在修改后的24位色系统上运行时变成透明色,原因在于使用了@android:color/transparent或@null作为背景色,对应为全0的颜色值,而全0在RGB565模式就是黑色,但在RGBA8888模式则是全透明(即alpha为0),其实这是正常现象,不能算是系统的bug,但为了保持与原生Donut的一致性,修改了有关代码将上述颜色值强制为使用黑色(即@android:color/black)。
Android升级到Eclair之后,显示部分的架构发生了较大变化,并逐渐增强了对24位真彩色模式的支持,同时对skia进行了针对ARMv7处理器的优化。在Froyo里framebuffer缺省已经是32位,因此只需较少的修改就可实现24位真彩色,但标志位eGPU已被取消,不能在函数SurfaceFlinger::createNormalSurfaceLocke
到了Gingerbread更进了一步,在高通等平台上的Gingerbread原生代码缺省已经支持完全的24位真彩色,我们自己不需要再做任何修改,可见Google也认为有必要在手机等移动设备上支持24位真彩色显示。阅读代码可见Google做的修改很多与我们在Froyo上改的是相同的,但在函数SurfaceFlinger::createNormalSurface中casePIXEL_FORMAT_OPAQUE:下面的format是采用的PIXEL_FORMAT_RGBX_8888,这个更合理。
(完)