Design and Implementation of Mobile Device-oriented Vector Drawing Platform
引用本论文: 张云贵. 面向移动设备的矢量绘图平台设计与实现[D]. 北京:北京理工大学软件学院, 2013.
本论文的相似度为0%,是源创论文。欢迎评阅讨论,请勿抄袭,如需更多资料请在博客留言。
如果在研究或论文中使用到,欢迎回复或私信你的学校、姓名、研究领域,并在论文中添加引用或致谢。感谢你对开放成果的尊重和鼓励。
本章描述在移动设备上绘图所涉及的关键技术,后续章节将用到这些技术。
2.1 iOS相关技术
2.1.1 设备参数
表2‑1列出了iOS设备的参数[1]。可见其CPU和GPU的配置相当高。考虑到Retina高清屏在UIKit中每点对应两个像素,可知iOS设备具有较单一的分辨率、显示精度高:iPad系列的DPI为132,iPhone/ iPod Touch/ iPad Mini系列的DPI为163,iPad/iPad Mini系列按点计算的分辨率都为1024×768。
注:今天发现一个更全的表格:Blake's iOS Device Specifications Grid (2014-2-20)
设备 |
内存 |
屏幕、分辨率、PPI |
CPU |
PowerVR GPU |
iPad 1 |
256MB |
9.7" 1024×768 132 |
A4单核 1GHz |
SGX535 |
iPad 2 |
512MB |
9.7" 1024×768 132 |
A5双核 1GHz |
SGX543双核 |
iPad 3 |
1GB |
9.7" 2048×1536 264 |
A5X双核 1GHz |
SGX543四核 |
iPad 4 |
1GB |
9.7" 2048×1536 264 |
A6X双核 1.4GHz |
SGX554四核 |
iPad Mini |
512MB |
7.9" 1024×768 163 |
A5双核 1GHz |
SGX543双核 |
iPhone 3GS |
256MB |
3.5" 480×320 163 |
Cortex-A8 600MHz |
SGX535 |
iPhone 4 |
512MB |
3.5" 960×640 326 |
A4单核 1GHz |
SGX535 |
iPod Touch 4 |
256MB |
3.5" 960×540 326 |
A4单核 1GHz |
SGX535 |
iPhone 4S |
512MB |
3.5" 960×640 326 |
A5双核 1GHz |
SGX543双核 |
iPhone 5 |
1GB |
4" 1136×640 326 |
A6双核 1.3GHz |
SGX543三核 |
iPod Touch 5 |
512MB |
4" 1136×640 326 |
A5双核 1GHz |
SGX543双核 |
2.1.2 iOS绘图相关框架
iOS上绘图相关框架有UIKit、Quartz 2D、OpenGL ES,其关系如图2‑1所示。UIKit界面框架包含UIView、UIImageView、UIScrollView等视图类,基于CoreAnimation框架实现图形渲染。CoreAnimation动画框架使用OpenGL ES框架进行动画显示和硬件加速,包含CALayer层类。每个视图都有一个CALayer对象(实质是矩形纹理),用于缓存绘图内容和供GPU加速显示。
Quartz 2D二维图形库用于绘制界面大多数内容,是Core Graphics框架的一部分。后者还包含Quartz Compositor层合成模块,用于对各个层基于GPU进行纹理合成。OpenGL ES是2D/3D图形框架,可以直接在矩形纹理上使用GPU硬件加速渲染。Quartz 2D在用于屏幕显示时自动使用OpenGL ES在CALayer上显示(由CoreAnimation在初始化CGContext时启用)。此时没有使用GPU的加速能力[2]。在位图等其他目标上绘图时基于CPU进行渲染,没有硬件加速能力。
2.1.3 Quartz 2D图形库和显示原理
Quartz 2D以设备上下文(CGContext)的画布模型提供绘图接口,可以在屏幕视图、层、位图、PDF等目标上绘图,只有在屏幕视图和层上绘图时能基于GPU加速绘图,在位图和PDF上绘图时不自动使用OpenGL ES渲染。对于离屏渲染,苹果官方不建议在位图上绘制图形,建议在层上绘制图形提高性能。
Quartz 2D使用绘制模型进行描绘,所有基于路径的矢量图形、图像和文字内容都叠加描绘到一个虚拟的画布上。
UIKit的坐标系默认是ULO类型,原点在视图左上角,单位为点。Quartz 2D的默认坐标系是LLO类型,原点在绘图目标的左下角,单位是像素。窗口显示时由UIKit自动设置Quartz 2D的坐标系为ULO类型,其他绘图目标需要单独设置坐标系(设置当前变换矩阵),否则就是默认的LLO类型坐标系。使用UIKit的函数创建位图或PDF上下文时,会自动设置坐标变换矩阵。
在视图显示时,绘图内容会缓存在后备缓冲(CALayer对象)中。在视图的drawRect函数中使用Quartz 2D等图形引擎绘图,或者直接指定内容到CALayer。可以指定图像(CGImageRef)到视图的层,或者指定矢量图形路径对象到CAShapeLayer,或者指定图像(UIImage)到图像视图。
视图的内容模式默认为自动撑满模式,在旋转屏幕或改变显示属性时自动将CALayer中已缓存内容重新显示到屏幕上,不会调用drawRect函数重新输出图形,这在图形较复杂时能减少CPU的消耗量。如果视图的内容模式为重绘模式,或者调用setNeedDisplay函数,视图的drawRect函数将会再次被调用。通过调用setNeedDisplay函数可以让视图显示新的图形内容,实现交互式绘图。交互式绘图的另一种实现方式是使用离屏渲染技术,在单独线程中预先将图形渲染到图像或层对象中,将新的图像或层对象应用到视图,实现快速显示动态图形的效果。
2.1.4 离屏渲染技术
离屏渲染技术又称为预渲染技术,是移动设备上常用的加速绘图技术,其原理是在线程中绘制图形到CALayer中,在界面显示时由GPU合成到屏幕帧缓存中。为了更快的显示复杂内容,可采用渐进式渲染技术,在用户交互变慢或CPU空闲时在后台线程中进行填充等更丰富的渲染操作。为了避免了位图复制操作,可以使用透明视图进行触摸响应和动态图形显示,在其下层采用图像视图,在触摸结束后合并到图像视图。
2.2 Android相关技术
2.2.1 SWIG的编程语言转换
SWIG是支持C/C++与主流编程语言集成的工具。在SWIG接口文件中指定要转换的C++头文件和转换配置信息,在编译阶段运行SWIG程序后,自动从C++头文件生成其他编程语言可调用的代码文件(对于Android就是JNI类)和C++封装实现文件,允许Java、C#、Python等代码使用相同编程语言调用C++的函数,在不同平台复用已有的C++代码。
SWIG通过类型重定向(TypeMap)将C++中的数据结构和变量类型映射到目标语言中的类型,在目标语言中能使用熟悉的类型调用C++中的接口功能。
SWIG通过重定向机制(Director)为有虚函数的C++类分别生成C++子类和目标语言的类(假定为B),在C++子类的重载函数中调用目标语言的基类B,基类B的派生类的相应重载函数就能被执行。该机制是基于虚函数的回调机制。
Android的Dalvik虚拟机对JNI本地动态库有特殊限制:(1)必须实现JNI_OnLoad()函数;(2)不能使用弱引用对象;(3)不能超过256个本地引用对象。在编写SWIG接口文件时需要注意这些限制,必要时修正SWIG所生成的封装文件。
2.2.2 Android开发方式
在Android平台上主要使用Java及Android SDK开发应用程序,使用C/C++及Android NDK开发本地动态库,本地动态库和应用程序通过JNI衔接。可以使用SWIG自动生成JNI类,以重定向回调机制在Android程序中扩展功能。
Android程序的开发工具通常是跨平台的Eclipse集成开发环境和ADT(Android Development Tools)插件,后者提供了调试(DDMS)和日志(LogCat)功能。Android本地库的调试配置工作较复杂,可使用日志辅助调试,2013年发布的ADT Bundle套件(含ADT 21.1)针对本地库提供了简易的集成调试功能,能避免繁琐的配置工作。
2.2.3 Android绘图相关框架
在Android上,常见的绘图框架及其关系如图2‑2所示。
绘图视图主要有三种类型:(1)SurfaceView类,有独立的Surface(会占用较多显示内存),可在线程中获取画布进行绘图,实现快速动态绘图。该类基于CPU绘图,没有硬件加速能力。(2)基于OpenGL ES的GLSurfaceView类,是特殊的SurfaceView类,可直接在Surface上硬件加速渲染图形,高帧率显示图形。(3)其他视图类,如普通视图(View)、图像视图(ImageView)。这些视图共同在一个Surface上绘图,由根视图遍历调用所有子视图的显示函数实现Surface渲染。从Android 3.0起HWUI组件允许这些视图使用GPU的硬件加速能力,先在视图的显示列表中自动缓存绘图指令,然后使用OpenGL ES 2.0对绘图指令进行渲染。
Canvas画布类提供了二维图形、图像和文本的绘制接口,在没有硬件加速的条件下使用Skia图形库实现绘图接口,在具备硬件加速的条件下使用OpenGL ES 2.0实现绘图接口。仅在视图显示(由HWUI组件启用加速)和层显示时才能使用GPU硬件加速能力,在位图上绘图是采用软件渲染方式。
Surface对应于显示内存区域(即SurfaceFlinger进程中的Layer对象,通常有两个缓冲区,前台缓冲区用于合成显示,后台缓冲区用于图形渲染),OpenGL ES或Skia在其上渲染图形。Surface缓存了显示内容,由GPU对其进行合成和动画渲染。
普通视图默认没有层,多个视图在同一个surface上渲染。Android 3.0以后可以设置视图的层类型,其渲染方式见表2‑2,绘制速度由快到慢依次是硬件层、默认的显示列表方式、软件层。
层类型 |
视图启用加速 |
视图不硬件加速 |
无(默认) |
在surface上加速显示 |
在surface上软件渲染 |
硬件层 |
在GPU纹理上加速渲染 |
在位图上软件渲染 |
软件层 |
在位图上渲染,不加速 |
在位图上软件渲染 |
2.3 本章小结
本章分析了iOS绘图相关框架及其关系,总结了要实现高性能交互式绘图的方法:充分利用CALayer的图形缓存和图形处理器的硬件加速能力,结合离屏渲染技术提高交互式绘图的显示帧率。
对于Android,本章给出了SWIG的核心功能和注意点,结论是SWIG用于本地动态库的开发中是可行的。分析了Android绘图相关框架的关系和特点,总结了普通视图和SurfaceView在绘图速度和内存占用上的差异,为合理选择视图类型和离屏渲染技术提供了设计依据。
在后续章节将根据本章的分析结论设计绘图方案,在iOS和Android上实现高性能的交互式矢量绘图平台。
[1] http://en.wikipedia.org/wiki/List_of_iOS_devices
[2] http://robots.thoughtbot.com/post/36591648724/designing-for-ios-graphics-performance