关于使用SurfaceFligner进行绘图的具体实现方法
2011-05-09 13:08
1301 查看
了解老码农个人隐私,请看这里:http://www.koulianbing.com/?page_id=12
SurfaceFligner是Android画形化的核心,网上有几篇关于这个C/S系统的分析,着实不错,我在文章最后的参考文章中都列出来了,大家可以先看一下那些文章从原理上对SurfaceFlinger系统的分析再看我这篇文章。我这篇文章偏重于具体代码上的实现,最后汇总成一个小的应用程序来演示如何与SurfaceFlinger交互,例子中使用的2D图形引擎。
源码在这里:http://code.google.com/p/flying-on-android/
使用的SurfaceFlinger系统可以分为这么几步:建立连接、创建Surface、取得Canvas、绘制、提交Canvas。下面来具体分析一下
1、建立连接
这个比较简单,先把示例代码贴上来
session = new SurfaceComposerClient;
代码很简单,具体SurfaceComposerClient如何通过IBinder与SurfaceFlinger通信比较复杂,可以本文后面列出的“参考文章“当中其它作者的分析。
2、创建Surface
在Java层,View树最后是绘制在Surface上面的,一个Surface对应了SurfaceFlinger中的一个Layer。我们要绘画,必须先取得一个Surface并在上面画东西,画完了通过session向SurfaceFlinger一提交,就显示在屏幕上了。
呵。。。似乎只要涉及到代码,都很简单了。
surfaceControl = session->createSurface(getpid(), 0, display.w, display.h,
PIXEL_FORMAT_RGBA_8888);
surfaceControl用来控制Surface属性。
surface = surfaceControl->getSurface();
surface才代表真正的Surface。
3、取得Canvas
用程序绘制UI,其实就是借助图形引擎提供的点、线、面函数最后形成一个包含像素信息的数组并提交给图形驱动(Linux上是FrameBuffer)的过程。现在我们拥有一个Surface,那么就可以取得Surface属性信息并把这些信息提供给图形引擎(这里是skia),图形引擎根据这些信息就可以构造出一张Bitmap的形式提供给我们。我们拿到Bitmap是不可以直接在上面绘画的,还需要把它包装成Canvas。这样,我们调用Canvas的绘画API时,最终改变了Bitmap的内容。Bitmap的数据都存储在一个二维数组中,每个数组的元素代表了一个像素值。看一下关键代码
surface->lock(&info, &dirtyRegion);//获取Surface属性信息到info当中
bitmap.setPixels(info.bits);//构造Bitmap
canvas.setBitmapDevice(bitmap);//把Bitmap封装成Canvas
4、绘制
Canvas构造好了,就可以调用drawLine,drawColor等进行绘制了。这里我们做的很简单,只是把整个Canvas渲染成黑色。
canvas->drawColor(0xff000000);
5、提交Canvas
提交过程,实际上就是把Bitmap中的像素数组通过Surface传递给服务端SurfaceFlinger中与我们拥有的这个Surface对应的Layer,并告诉SurfaceFlinger把它渲染到屏幕。一句代码就可以搞定了。
surface->unlockCanvasAndPost();
我自己学习工作时,深刻体会到十篇讲原理的不如一段演示代码来的实在,就把这个过程写成了一个可以编译运行的小程序放到了这里:
如何你对这个话题比较感兴趣,可以把例子下载下来一边看代码一边看这篇文章。只要把它放到/frameworks/base/cmds目录下,然后切换到这个模块下运行mm命令,会自动编译成一个名字为flying的程序安装到/system/bin,只要把它复制出来放到机器的/system/bin目录下,然后在通过Shell运行就可以了。我是在Android2.3下面完成的,其它的系统版本没有试过。
如果只要看效果的话,资源中也包含可执行文件,直接把它复制到/system/bin下面运行即可。
参考文章
android的surfaceflinger原理讲解
http://my.chinaunix.net/space.php?uid=20564848&do=blog&id=96788
冷冰所写,著名的Android核心分析中与SurfaceFlinger相关的部分
http://blog.csdn.net/maxleng/archive/2010/06.aspx
下面这位博客中有一个系列是专门针对SurfaceFlinger原理进行分析的,很全面很到位。
http://blog.csdn.net/DroidPhone/category/721261.aspx
SurfaceFligner是Android画形化的核心,网上有几篇关于这个C/S系统的分析,着实不错,我在文章最后的参考文章中都列出来了,大家可以先看一下那些文章从原理上对SurfaceFlinger系统的分析再看我这篇文章。我这篇文章偏重于具体代码上的实现,最后汇总成一个小的应用程序来演示如何与SurfaceFlinger交互,例子中使用的2D图形引擎。
源码在这里:http://code.google.com/p/flying-on-android/
使用的SurfaceFlinger系统可以分为这么几步:建立连接、创建Surface、取得Canvas、绘制、提交Canvas。下面来具体分析一下
1、建立连接
这个比较简单,先把示例代码贴上来
session = new SurfaceComposerClient;
代码很简单,具体SurfaceComposerClient如何通过IBinder与SurfaceFlinger通信比较复杂,可以本文后面列出的“参考文章“当中其它作者的分析。
2、创建Surface
在Java层,View树最后是绘制在Surface上面的,一个Surface对应了SurfaceFlinger中的一个Layer。我们要绘画,必须先取得一个Surface并在上面画东西,画完了通过session向SurfaceFlinger一提交,就显示在屏幕上了。
呵。。。似乎只要涉及到代码,都很简单了。
surfaceControl = session->createSurface(getpid(), 0, display.w, display.h,
PIXEL_FORMAT_RGBA_8888);
surfaceControl用来控制Surface属性。
surface = surfaceControl->getSurface();
surface才代表真正的Surface。
3、取得Canvas
用程序绘制UI,其实就是借助图形引擎提供的点、线、面函数最后形成一个包含像素信息的数组并提交给图形驱动(Linux上是FrameBuffer)的过程。现在我们拥有一个Surface,那么就可以取得Surface属性信息并把这些信息提供给图形引擎(这里是skia),图形引擎根据这些信息就可以构造出一张Bitmap的形式提供给我们。我们拿到Bitmap是不可以直接在上面绘画的,还需要把它包装成Canvas。这样,我们调用Canvas的绘画API时,最终改变了Bitmap的内容。Bitmap的数据都存储在一个二维数组中,每个数组的元素代表了一个像素值。看一下关键代码
surface->lock(&info, &dirtyRegion);//获取Surface属性信息到info当中
bitmap.setPixels(info.bits);//构造Bitmap
canvas.setBitmapDevice(bitmap);//把Bitmap封装成Canvas
4、绘制
Canvas构造好了,就可以调用drawLine,drawColor等进行绘制了。这里我们做的很简单,只是把整个Canvas渲染成黑色。
canvas->drawColor(0xff000000);
5、提交Canvas
提交过程,实际上就是把Bitmap中的像素数组通过Surface传递给服务端SurfaceFlinger中与我们拥有的这个Surface对应的Layer,并告诉SurfaceFlinger把它渲染到屏幕。一句代码就可以搞定了。
surface->unlockCanvasAndPost();
我自己学习工作时,深刻体会到十篇讲原理的不如一段演示代码来的实在,就把这个过程写成了一个可以编译运行的小程序放到了这里:
如何你对这个话题比较感兴趣,可以把例子下载下来一边看代码一边看这篇文章。只要把它放到/frameworks/base/cmds目录下,然后切换到这个模块下运行mm命令,会自动编译成一个名字为flying的程序安装到/system/bin,只要把它复制出来放到机器的/system/bin目录下,然后在通过Shell运行就可以了。我是在Android2.3下面完成的,其它的系统版本没有试过。
如果只要看效果的话,资源中也包含可执行文件,直接把它复制到/system/bin下面运行即可。
参考文章
android的surfaceflinger原理讲解
http://my.chinaunix.net/space.php?uid=20564848&do=blog&id=96788
冷冰所写,著名的Android核心分析中与SurfaceFlinger相关的部分
http://blog.csdn.net/maxleng/archive/2010/06.aspx
下面这位博客中有一个系列是专门针对SurfaceFlinger原理进行分析的,很全面很到位。
http://blog.csdn.net/DroidPhone/category/721261.aspx
相关文章推荐
- [转]关于使用SurfaceFligner进行绘图的具体实现方法
- 关于VC++中,两种自定义消息的发送与接收的方法实现进行说明
- SSH pager-taglib分页的实现 具体使用方法 分页pager
- 关于Override在JDK1.5和JDK1.6上子类实现接口中方法使用@Override注解编译错误.
- C#使用iCSharpcode进行文件压缩实现方法
- Linux系统平台下关于GCC编译及使用的方法(-Werror,它要求GCC将所有的警告当成错误进行处理 )
- 使用花生壳、路由器、个人电脑进行站点部署并实现外网域名访问图文详解(花生壳设置方法 使用方法 使用教程)
- 使用Java的Graphics类进行绘图的方法详解
- 机器学习之-使用Apriori算法进行关联并分析-具体怎么实现及应用
- Linux系统平台下关于GCC编译及使用的方法(-Werror,它要求GCC将所有的警告当成错误进行处理 )
- SSH pager-taglib分页的实现 具体使用方法 分页pager
- 关于MAC上使用pycharm进行创建project的方法
- PHP使用CURL实现对带有验证码的网站进行模拟登录的方法
- 报错:对象必须实现 IConvertible;以分隔符进行分割链接concat_ws的使用方法;mysql数据类型转换cast,convert
- 本文给出了一种方便实用的解决大文件的读取、存储等处理的方法,并结合相关程序代码对具体的实现过程进行了介绍
- asp.net中使用DatagridView的增删改方法具体实现
- 关于飞鸽传书软件的实现原理,配置及使用方法
- 五星-原型模式常使用于以下场景--而JAVA中的任何类只要实现了Cloneable标识接口,就可以使用clone方法来进行对象的拷贝
- 在WCF中使用SoapHeader进行验证的两种实现方法