porting skia

来源:互联网 发布:三国志13卡顿优化补丁 编辑:程序博客网 时间:2024/05/22 07:57

 

移植Android图形引擎库Skia到Windows的经验

关于Skia的基本介绍可以参考台湾的Jserv的blog:
http://blog.linux.org.tw/~jserv/archives/002095.html
    最近由于工作需要移植Android skia库的代码到Windows平台。目标是在Windows平台上,可以运行网上的测试代码。
首先的想法就是传统的,把所有的Skia代码加入VS工程,然后除错。基于这个思路:
1、选择的VS编译器是VS6。
2、把Android中所有的Skia代码加入工程编译。
3、编译发现VS6不能支持很多C++的标准,尤其是内部类的问题。升级到VS2005,这个问题解决。
4、现在就需要用标准的移植代码的方法来移植。除错,改代码!!
5、最后发现Skia依赖很多Linux的东西,这个东西也需要从Android移植?好像工作量太大了吧!最终除错剩下40左右的Error的时候,感觉移植非常吃力了。
     这时开始反思,自己是不是做的方向有所偏差呢?决定到Skia的官网去下载一份最新的代码,和Android代码进行一下比较,没准儿会发现惊喜。
    不比不知道,一比吓一跳。原来Skia最新源码中居然包括VS的工程,该工程主要是Skia的测试代码,这个可是大惊喜。经过code对比发现Android的为了精简代码,去除了不少和Windows平台的相关的code,为了移植必须要把这些code补充进去。另外最新代码中VS工程好像是以前版本的,反正我VS2005不能直接打开,不能打开没有关系啊,打开这个VS工程文件,就发现是XML,可以知道需要编译那些文件,各个文件的依赖关系,依赖头文件等信息,一目了然了。
   经过分析最新的代码,准备重新开始工作,选择递增式移植方式,先编译core部分,然后一部分一部分的加入。由于有了前面的经验,很容易移植成功了。
      剩下问题就是要找一个测试程序来验证Skia了,决定选择官方最新代码中的VC代码来验证,这个不多讲了。
总结:
1、移植Skia的代码到Windows平台,一定要选择一个好的编译器,VC6是不行的,主要是VC6对C++的标准支持不好。最好选择VC2003以上的版本。
2、一定要到官方网站下载一份最新的代码。毕竟Android是一个移动平台的框架,精简了很多和Linux无关的代码。这也给移植带来了很多麻烦。 以最新代码作参考,可以少走很多弯路。
3、Android为了精简代码去掉了一下和Windows相关的文件,为了移植必须要加入这些文件(最新代码中有)


经过前面移植工作,Skia经过VC2005编译已经可以生成静态库。测试程序是利用Skia提供的绘图接口和经过适配的Window类(底层调用Windows的窗口系统),把图形绘制在窗口类上面。
    经过学习台湾的Jserv先生的blog,觉得他提供的测试程序挺好的。这个测试程序是在内存的画布上面绘图,然后把图形输出到png文件中。这个测试程序另外一个优势在于,假如是嵌入式系统,可能没有屏幕,或者屏幕驱动还没有调试完成,怎样来验证Skia呢,解决办法就是把内存画布输出到图形文件。
     把Jserv先生的代码,拿过来用VC2005创建一个控制台程序,编译生成可执行文件。运行之后,发现并没有输出到PNG 文件中,经过跟踪分析发现移植Skia工程中并未包含编码PNG文件的模块。加入该模块,编译发现错误,分析发现该模块依赖于libpng,Skia用 libpng库来完成png的编码和解码工作。翻阅Android源码,发现里面有libpng的源码。
    移植libpng,该库的代码量不大,移植难度不大。移植过程中发现libpng依赖于libz,libz的源码也在 Android中有,一并移植到Windows平台。最后生成libpng.lib和libz.lib。
     再次编译前面的Skia工程,这次顺利编译通过,然后运行Jserv先生的测试程序,还是没有输出预期结果。这是进行单步跟踪,发现PNG的编码器没有向Skia注册。这是需要研究Skia的源码,看看编码器是如何注册的,经过研究发现这里面涉及到一个Windows静态库中链接的问题。代码本身并没有错,只是该代码在Windows用VC2005编译会有问题,主要是VC2005对静态库进行了优化,画蛇添足了。这个问题我会在其他的文章中讨论。经过分析研究,修改代码,解决这个静态库链接问题,这样png的编码器可以顺利注册到Skia库中。运行测试程序,这次输出了预期结果,一切OK!
      然后分析Skia输出模块,发现Skia可以把内存中的画布输出到窗口,图片文件中。图片文件类型主要取决于编码器的类型,我分析Skia源码发现,源码中包括png和jpg编码器。为了验证jpg输出。我又移植了libjpg模块,该模块在Android中有源码,并没有依赖其他模块,移植相对简单。同样的方法解决静态库链接问题。
    另外分析Skia代码发现,Skia也把图像文件读入到内存画布。Skia支持很多种文件解码包括BMP,jpg,png,gif等等。BMP只支持解码,不支持编码(个人觉得比较容易实现,因为bmp的格式比较简单);jpg和png即支持解码,也支持编码;gif只支持解码,不支持编码。
总结:
    Skia可以支持内存中画布输出到Window(Skia提供的OS窗口系统的适配)和图片文件中。
  如果想输出到图片文件需要提供各种图片文件的编解码器。编解码器的注册,Skia用了一个比较巧妙的方法来完成编解码的注册。这个方法在VC2005中不能通过,被优化掉了。需要为Windows修改代码

 

原创粉丝点击