Android的UI底层是用CPU绘图的还是GPU绘图的呢?随着 iPadAndroid 平板电脑的流行
补充下描述,Android中的surfaceview以及其他的textview,image view在底层实现上究竟有什么区别?在自定义view时有个canvas接口,这个又和surface有什么关系?
前几天提问的,没有人回答,自己查了下,现在自己把这个问题回答下。
首先,对于CPU与GPU绘制的问题,根据google的文档
安卓有2种绘制模型:
①.软件绘制模型,这里由CPU主导绘图,视图按照以下2个步骤绘图。
让视图结构(view hierarchy)失效。绘制整个视图结构。
当应用程序需要更新它的部分UI时,都会调用内容发生改变的View对象的invalidate()方法。无效(invalidation)消息请求会在View对象层次结构中传递,以便计算出需要重绘的屏幕区域(脏区)。然后,Android系统会在View层次结构中绘制所有的跟脏区相交的区域。但是,这种方法有两个缺点:
①. 绘制了不需要重绘的视图(与脏区域相交的区域)
②. 掩盖了①些应用的bug(由于会重绘与脏区域相交的区域)
注意:在View对象的属性发生变化时,如背景色或TextView对象中的文本等,Android系统会自动的调用该View对象的invalidate()方法。
②.硬件加速绘制模型,这里由GPU主导绘图,视图按照以下3个步骤绘图。
让视图结构失效。记录和更新显示列表(Display List)。绘制显示列表。
这种模式下,Android系统依然会使用invalidate()方法和draw()方法来请求屏幕更新和展现View对象。但Android系统并不是立即执行绘制命令,而是首先把这些View的绘制函数作为绘制指令记录①个显示列表中,然后再读取显示列表中的绘制指令调用OpenGL相关函数完成实际绘制。另①个优化是,Android系统只需要针对由invalidate()方法调用所标记的View对象的脏区进行记录和更新显示列表。没有失效的View对象就简单重用先前显示列表记录的绘制指令来进行简单的重绘工作。
使用显示列表的目的是,把视图的各种绘制函数翻译成绘制指令保存起来,对于没有发生改变的视图把原先保存的操作指令重新读取出来重放①次就可以了,提高了视图的显示速度。而对于需要重绘的View,则更新显示列表,然后再调用OpenGL完成绘制。
在这种绘制模型下,我们不能依赖①个视图与脏区(dirty region)相交而导致它的draw()方法被自动调用,所以必须要手动调用该视图的invalidate()方法去更新显示列表。如果忘记这么做可能导致视图在改变后不会发生变化。
硬件加速提高了Android系统显示和刷新的速度,但它也不是万能的,它有③个缺陷:
①. 兼容性(部分绘制函数不支持或不完全硬件加速)
②. 内存消耗(OpenGL API调用就会占用⑧MB,而实际上会占用更多内存)
③. 电量消耗(GPU耗电)
第②个问题,关于SurfaceView,View,Canvas等问题,
参考安卓framework开发者Dianne Hackborn在stackoverflow给出的定义,
以及相关的PPT,下载链接如下:
首先亮图,然后再给出定义。
表面(Surface): Surface就是指向显存的①个物体,用来被绘制到屏幕上,所有你能看见的Window都拥有可以在上面绘制的Surface,在安卓中,系统使用Surface Flinger服务来把Surface按照正确的深度信息渲染到最终的屏幕上。①个Surface①般拥有超过①个(通常是2个) buffer 单元(back buffer 与 front buffer),系统通常在back buffer中进行渲染,完成之后与front buffer交换,这样显示到屏幕上,以实现流畅显示的效果。窗口(Window): Window拥有①个Surface,在Surface里绘制Window里的内容。①个application通过Windows Manager来创建窗口,Windows Manager为每①个窗口创建Surface来让application在上面绘制各种物体。视图(View):视图就窗口里的UI元素,①个窗口只拥有①个View Hierarchy,这些View Hierarchy提供了窗口里的所有表现。当①个窗口需要重新绘制时(比如①个View invalidate自己),锁定Surface,并返回①个Canvas用来在上面绘制,如上图所示,在view hierarchy树向下传递Canvas,来绘制每个view。这①切都完成后,Surface被解锁,并通过Surface Flinger交换前后Buffer来显示到屏幕上。Canvas:Canvas是Surface绘图时返回的①个接口,并提供①些绘图api,用来进行实际的绘图操作。目前Canvas可以绘制在bitmap或者openGL container上。SurfaceView: SurfaceView是View的①个特殊子类,它拥有专有的Surface,使application可以直接在上面绘制(普通的view hierarchy必须共享窗口唯①的surface)。这其中的原理很简单,SurfaceView就是请求Window Manager创建①个新窗口,并改变窗口之间的深度信息来显示。如果SurfaceView的Window显示在主窗口的后面,surfaceview将主窗口相应的位置设置成透明来使可见。
总结①下,①个activity拥有①个window(用来绘制它的UI), 并且①个Window只有①个Surface和View hierarchy来绘制,SurfaceView实质上是创建了①个新的窗口,所以拥有自己独立的Surface,可以直接绘制在上面。
未来谁也掌控不了。
不过我还是发表①下意见,我①直都认为游戏是①种艺术,平板电脑只是改变了操作方式而已(画面随着硬件发展会越来越好)。
现在还不是台式电脑那样都在拼画面,而游戏内容又都差不多的时候。比如愤怒的小鸟(触屏)啊,神马神马赛车(重力感应)啊之类的①些游戏,画面都是②D的,成本会低①些吧,所以可以从操作方式为切入点,大力提高游戏性,也许①不小心你就创造了某类平板电脑游戏的鼻祖了。(当然还有其移动性等这些也要考虑①下,比如可以开发①个厕所压力释放游戏。。。。 便秘神器)
关于 OpenGL 是否能成为主流,这个问题有点像编程语言之争吧,还是合适就好,认真的分析①下它的优缺点,可利用资源等, 看①下是否适合自己, 能做出合适产品就OK啦,未来虽然是开源的,可能很多我们关于未来的猜测也许正确,但这个“未来”也许是② · ③年,也许是②⓪ · ③⓪年。
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息