提高AlphaBlend效率的实际验证

来源:互联网 发布:网络用语gb是什么意思 编辑:程序博客网 时间:2024/06/03 00:38

原文地址::http://blog.csdn.net/alien75/article/details/6061907


在前一篇文章<关于提高AlphaBlend效率的思考>中曾经提到几种提高效率的方法,但是都只是想法并没有得到实际的验证。最近通过查找一些资料并亲自动手验证发现还是有很多地方可以改进的,现总结如下:

一、基础知识
1、什么是BPP16、BPP24、BPP32:略
2、什么是RGB555、RGB565、RGB888:略
3、什么是色深
色深应该是指R、G、B能够表示的色彩级数,象BPP24或BPP32位单一色都是8位,它的色深就是256级。而window系统的BPP16实际上是RGB555,所以色深就是32级,要想在windows下生成RGB565是需要用其它工具的。可以看用画图工具生成的BPP24位图,然后用acdsee来编辑就只能转换成BPP15。关于这一点可以用第三方工具生成RGB565图,它的属性中位深度是32位图得到验证。

二、分析
BPP16的色深是32级,而BPP24或BPP32是256级。从MSDN对AlphaBlend计算公式的描述来看(级数常量是255)它应该是不支持BPP16混合运算的,但是经过实际验证发现对于常量级的混合运算BPP16是可以的,而象素级则不行(这是因为BPP16没有A通道信息),因此需要自实现BPP16的象素级混合运算(这个算法对于常量级运算应该也是可行的)。
在<关于提高AlphaBlend效率的思考>一文中提到过用PNG和BMP各有优缺点,但是如果用RGB565也能用自实现算法实现常量级混合运算,那么一来文件大小减小(RGB565/BPP16只有RGB888/BPP32的一半)、二来省掉了PNG解码过程,理论上是可以进一步提高效率的。当然,如果要实现象素级的混合运算,是需要维护一个A通道信息文件的,这样尽管大小只减少了四分之一但有胜于无。
对于图像资源多的情况,可以考虑将它们打包存放,需要的时候加载到内存解压在处理,这个应该是可以提高效率的,在有时间的时候验证一下。
在进行验证的时候,测试平台是VS2005SP1(Release模式、优化速度)、DeviceEmulatorBSP生成的800*480*BPP16的模拟器,采用的是两张存放在SD卡上的BPP32或BPP16全屏的位图进行系统或自定义AlphaBlend函数运算再贴到设备DC,只统计混合运算的时间(计5次取平均值),这个时间在实际的设备上应该有所不同,但从纵向的角度来看应该是类似的。图片资源放在SD卡或Nandflash上也会有所不同。

三、测试例子
1、用系统DIB方式(SHLoadDIBitmap)加载BPP16进行系统的AlphaBlend常量级运算
耗时367ms(设备248ms)
2、用系统DIB方式加载BPP32(无A通道)进行系统的AlphaBlend常量级运算
耗时376ms(设备258ms)
3、用系统DIB方式加载BPP32(有A通道)进行系统的AlphaBlend象素级运算
耗时438ms(设备295ms)
4、用自实现DIB方式加载BPP32带A通道的图像进行自定义象素级运算
耗时34ms(设备61ms)
5、用自实现DIB方式加载BPP16(RGB565)图像进行混合运算
(1)将源和目标的R、G、B拆分后分别计算再合并(见引用二)
耗时24ms(设备36ms)
(2)不将源和目标的R、G、B拆分经预处理后直接运算(见引用一)
耗时16ms(设备25ms)
(3)一次计算源和目标的两个象素(见引用二)
耗时18ms(设备30ms)
(4)用汇编对(2)的单一象素运算函数MakeAlpha进行优化
耗时32ms(设备35ms)
(5)用汇编对(3)进行优化
TODO
(6)用SIMD指令进行优化(ARMV6架构开始才有SIMD)
TODO

四、总结
1、算法很重要
2、局部汇编对效率提高影响不大
3、发现了一个使用CreateDIBSection一直存在的误区
当创建RGB565的DIB时需要指定一个颜色表,这个其实也就是R、G、B的mask(R对应0xF800、G对应0x07E0、B对应0x001F)用于将R、G、B从象素中提取出来。这个信息是由BITMAPINFO(CreateDIBSection第二个参数)的成员bmiColors来携带,如果不指定那显示的时候会出现偏色。但是BITMAPINFO的成员bmiColors只有一个DWORD是无法携带所有数据的,因此需要先动态分配一个缓冲(长度为40+16=56Byte)或者另行定义BITMAPINFO结构才能正常显示RGB565。如果使用静态的系统结构BITMAPINFO,将bmiColors强制转换成DWORD指针进行颜色表赋值实际上是越界操作了。这样的后果就是在Debug模式下可以正常显示而在Release模式下偏色(见引用三)
4、系统的SHLoadDIBitmap和自实现DIB方式加载位图时间差不多

五、问题
在验证过程中用的是最理想例子,并没有考虑到对pitch、stide、zoom等情况的处理,在实际应用中是需要处理这些情况的。

六、引用
引用一:http://linux.chinaunix.net/bbs/thread-1117753-1-1.html
引用二:http://blog.csdn.net/linzhengqun/archive/2009/06/15/4269259.aspx
引用三:http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesnative/thread/57bf9025-e536-499e-a343-77c7dd93189e


//=================================================

备注::

1.发现了一个使用CreateDIBSection一直存在的误区
当创建RGB565的DIB时需要指定一个颜色表,这个其实也就是R、G、B的mask(R对应0xF800、G对应0x07E0、B对应0x001F)用于将R、G、B从象素中提取出来。这个信息是由BITMAPINFO(CreateDIBSection第二个参数)的成员bmiColors来携带,如果不指定那显示的时候会出现偏色。但是BITMAPINFO的成员bmiColors只有一个DWORD是无法携带所有数据的,因此需要先动态分配一个缓冲(长度为40+16=56Byte)或者另行定义BITMAPINFO结构才能正常显示RGB565。如果使用静态的系统结构BITMAPINFO,将bmiColors强制转换成DWORD指针进行颜色表赋值实际上是越界操作了。这样的后果就是在Debug模式下可以正常显示而在Release模式下偏色(见引用三)


原创粉丝点击