记 移植ipad牙位图

10月开始牙位图,一开始是老大给了张图片,说能不能实现,有没有想法,我原本以为是图像处理,给出了可以尝试当时程序中已经存在的一段处理人体图(OXH所写,已离职)的代码处理试试,然后老大让开始做demo,过程如下:
1. 找到程序出处,来自ipad一个牙位图程序,售价299美元,简单了解操作流程。


2. 尝试自己用Tilemap架构 设计了一个牙位图demo,采用CImage+双缓冲,引入了层的概念, 并且采用图片替换的方法,而非图像处理,效果不错,但是局限性在Tilemap地图式架构不够灵活,CImage只能简单图像处理。




2. 由于采用图像替换,需要大量的图片,而部门中没有美工无法提供,所以尝试先从ipa牙位图中提取程序,并且提取出资源图片png(mac编码和windows不同,费了一些时间),提取出1800张图片,变相的发现了其实ipad牙位图也是采用的图像替换的方法。

3. 确定非图像处理,而是采用图像替换,即一种状态一种图像,开始重构牙位图架构(想做成通用),参考了cocos程序的架构(2D引擎),引入了场景的概念,并且使用GDI+替换CImage,使图像处理更加灵活(埋下祸根,后文再表),写了3个基础框架类Scene->Layer->canvas。


4. 制作类似ipad上的菜单,采用牙位图相同架构,制作出效果类似的demo, 并且引入帧的概念,实现动画效果,但是以在PC上不如使用右键菜单的理由被否决…


附上结构图:


以上就差不多实现了一个除具体业务外的功能系统。

接下来是优化的过程,起源来自于我无意中发现,开启牙位图后,我的CPU占用会达到12%左右,此前设计中,我是采用定时器来定时刷新界面,刷新频率为100MS,我的电脑是I5 4200U,虽然是U核,但是也属于不错的CPU了,想想现场的老爷机,还是优化吧。


1.一开始怀疑是定时器的问题(后来发现不是),猜测可能是因为定时器设置频率过快,导致每一帧还没刷完(也就是图片放入统一缓存,再打到屏幕)一帧,下一个定时器又来了,导致了等待,所以CPU占用高。

解决方法:使用线程,主线程中调用绘图线程,绘图线程设置了无限绘图,每绘一次 sleep(50),CPU占用仍然是12%左右,帧数是9帧/S,排除了是定时器的问题, 这时也发现了帧数很低,说明绘图的过程很慢。

2.接下来发现内存跳动很快,猜测是绘制过程中不断的new了,发现Graphics 在构造函数中new了对象(构造函数new.....),等于是每一帧都new一次,释放一次,改为成员变量,发现CPU占用不见好转,但是内存相对稳定(其实看不大出来)。

3.然后接下来的问题要先说说程序的架构,牙位图是由一张缓存图片,然后将LAYER缓存(缓存:其实有一个更新标志,如果未更新,就是一张图片图片,更新,则重新生成缓存,把一系列图片绘制在一张图片缓存中)打入缓存中,然后绘制选择流动矩形框,最后再将这张缓存打到屏幕上。查看了层Layer发现有60几层,30几层牙齿+30几层文字,其实在平时不动的时候绘制,这60几层是不变的,变的只有流动矩形框,所以再做一层缓存,只在这60几层中的缓存更新时再进行重绘的操作。相当于一个空间换时间的操作。完成后发现CPU大概到10左右,仍然不明显。

4.该想的优化都做了,谷歌吧,发现了几篇文章说是GDI+的问题,可以提到帧速(这和CPU什么关系,扯远了),特别的DrawImage,效率十分低下,而且如果不在一开始指定图片缓存特定格式,则生成的缓存格式为不定,参考一篇外文,http://www.codeproject.com/Tips/66909/Rendering-fast-with-GDIplus-What-to-do-and-what-no.aspx ,全部初始化为PixelFormat32bppPARGB格式,发现CPU显著降低了,大概在4%左右。

5.最后的最后本来想做GDI+和GDI混合使用的优化,因为GDI在这块效率会比GDI+好,但是项目时间问题,没有继续。

总结下优化:
        // 1、缓存GDI+对象,避免构造函数的new操作
// 2、只在层中有变化时重新绘制场景,其余则只在场景之上绘制矩形框,然后打到屏幕
// 3、构造函数时format为相同格式图片,避免不同格式各种转换消耗CPU
// 4、尽量使用GDI,而不是GDI+,特别是DrawImage,效率非常低下(此条未实现)
// 参考文章:http://www.codeproject.com/Tips/66909/Rendering-fast-with-GDIplus-What-to-do-and-what-no.aspx
// 还有其他相关文章关键词:GDI+优化

至此,就是一些业务性的东西了,附上一些性能的图片吧

优化前:

优化后:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章