目录
1 基础知识
2 surface使用
3 surfaceTexture使用
4 surfaceTexture 结构分析
5 surfaceTexture 源码分析
6 SurfaceFlinger
7 QA
8 参考与附录
正文
一##. 概述
Android系统中图形系统是相当复杂的,包括WindowManager,SurfaceFlinger,Open GL,GPU等模块。 其中SurfaceFlinger作为负责绘制应用UI的核心,从名字可以看出其功能是将所有Surface合成工作。 不论使用什么渲染API, 所有的东西最终都是渲染到”surface”. surface代表BufferQueue的生产者端, 并且 由SurfaceFlinger所消费,这便是基本的生产者-消费者模式. Android平台所创建的Window都由surface所支持,所有可见的surface渲染到显示设备都是通过SurfaceFlinger来完成的.
Android画图两个模块,opengl和surface(buffer)。
1 基础知识
1) 画家:程序员.参数gl=手.画布:TexureView。OpenGL ES(render):画笔。SurfaceTexture:作品。Surface: 画纸。Graphic Buffer:画板。SurfaceFlinger显示。
- Surface、SurfaceView和SurfaceHolder 搞清楚这3个核心概念就搞懂了surface
surface是buffer.surface==eglsurface=framebuffer;
surfaceview是view.它是xml中的config,不到它的存在.是屏幕显示size即surface中的图片的显示大小.可以说surfaceview是surface的前端.
surfaceholder=surface,实际是surface的listener。任何surface变化都会调用surfaceholder。surface consumer 是双缓冲. - SurfaceTexture和TextTexture都是把内容流上的图像转成纹理,然后输出.
SurfaceTexture是buffer.SurfaceTexture 绑定surface.SurfaceTexture 是jave view 层,surface 是 native层。
TextTexture=SurfaceView+SurfaceTexture。SurfaceView在主线程,SurfaceTexture在渲染线程 - Glsurfaceview,egl, render,opengl ,drawer,关系?
GLsurfaceview=surfaceview+surfaceTexture+Opengl+egl。直接使用最上层即可.
数据流:Glsurfaceview.setRender->render.ondrawFrame(display)->opengl->eglsurfaceC->屏幕Glsurfaceview. -
Egl,Surface,Opengl什么关系
egl=context+surface+display. egl因为被封装在GLsurfaceview中,所以应用层看不到它的存在.
context可以绑定多个surface,实现share context(eg:绑定codec surface和屏幕surface consumer).
surface->display:双缓冲.swapbuffer将backbuffer 上的filter渲染发送到frontbuffer 即display
2 surface使用
scenario1: surface与camera:采集callback:调用setOnFrameAvailableListener()函数将VideoDumpRenderer(实现SurfaceTexture.OnFrameAvailableListener接口)作为SurfaceTexture的Listener.
scenario2: surface与filter: 一个surface一个filter texture
- 表面(Surface): Surface就是指向显存的一个物体,用来被绘制到屏幕上,所有你能看见的Window都拥有可以在上面绘制的Surface,在安卓中,系统使用Surface Flinger服务来把Surface按照正确的深度信息渲染到最终的屏幕上.Surface通常在back buffer中进行渲染,完成之后与front buffer交换,这样显示到屏幕上,以实现流畅显示的效果.
- 窗口(Window): 一个application通过Windows Manager来创建窗口,Windows Manager为每一个窗口(windows)创建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: 它是View的一个特殊子类,它拥有专有的Surface,使application可以直接在上面绘制(普通的view hierarchy必须共享窗口唯一的surface)。
原理是surfaceview请求Window Manager创建一个新窗口,并改变窗口之间的深度信息来显示。如果SurfaceView的Window显示在主窗口的后面,surfaceview将主窗口相应的位置设置成透明来使可见。
总结一下,一个activity拥有一个window(用来绘制它的UI)-->一个Window只有一个Surface&View hierarchy来绘制=SurfaceView实质上是创建了一个新的窗口,所以拥有自己独立的Surface,可以直接绘制在上面。
surfaceView:
虽然在App端它仍在View hierachy中,但在Server端(WMS和SF)中,它与宿主窗口是分离的。这样的好处是对这个Surface的渲染可以放到单独线程去做,渲染时可以有自己的GL context。这对于一些游戏、视频等性能相关的应用非常有益,因为它不会影响主线程对事件的响应。但它也有缺点,因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能放在其它ViewGroup中,一些View中的特性也无法使用
Textureview和surfaceTexture连用,弥补了surfaceview的不足。但是比surfaceview慢
3 surfaceTexture使用
与opengl连用
4 surfaceTexture 设计
surfaceTexture 是什么?
surfaceTexture是buffer .但是,它又不是简单的一个buffer,而是由两个buffer queue组成 .
下面这个整体结构图给力。把数据流向,输入输出,模块组成和作用说的很清楚. 但是,仍然容易理解错误.
实际surfaceTexture=surface+一个queue, product 和consumer是两个线程,两个线程操作同一个queue.
数据流程:camera-->surfaceTexture'surface-->surfaceTexture's queue-->opengl Texture buffer-->native surface-->surfaceFinger-->eglsurface-->framebuffer
-->surfaceview/Textureview/Mediacodec
注意surfaceTexture的surface是给camera等采集端的,native的surface是给输出端的。它们是两个不同的surface.
- camera etc采集
- 图像流通过Surface入队到BufferQueue,并通知到GLConsumer。
- GLConsumer从BufferQueue获取图像流GraphicBuffer,并转换为Opengl纹理(updateTexImage)。
- Opengl filter 渲染(上特效) (option)
-
数据输出到GLsurfaceview 和Mediacode (sharecontext技术)
surfaceTexture=surfaceTexture product +surfaceTexture consumer queue+中间控制.
不同于一个buffer,只有生产者,消费者。它有生产者,中间商和消费者。
SurfaceTexture核心是BufferQueue.
5 SurfaceFlinger
[https://blog.csdn.net/fdsafwagdagadg6576/article/details/116352477]
6 SurfaceTexture源码分析
示意图说明: 左边:主线程GLSurfaceView,使用渲染线程GLRender,GLRender使用主线程surface。右边surfaceholder和左边surface是一个。左边是新用法,右边是过去用法.
Surface实例分析: 参见:Android音视频(六) 使用OpenGL ES 3.0预览Camera https://juejin.cn/post/6844903962248740871
Android图形系统之SurfaceTexture http://www.zyiz.net/tech/detail-135826.html
QA:
surfaceTexture与opengl textureid buffer的关系.why 要texturebuffer,而不是直接在gpu上run qsurface呢? GPU需要自己的内存。
surfaceTexture update之后就可以读下一张图片product了,理解为上一张处理完 在consmer中。
camera preview,codec,surfaceview的surface是同一个吗?no. codec surface 单独,camera preview is surfaceP,surfaceview的surface is surfaceviewC
参考:
1 Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView:[https://blog.csdn.net/jinzhuojun/article/details/44062175]
文章说明: 内容较好:
- 上文中的uml图和时序图很好,将类的结合,类的框架画的很清楚。
- surfaceview的底层实现是bufferqueue.时序图说明了消息流程.
- 说明了java-jni-native
- 说明了render线程.
缺点:介绍过多,重点不突出,没有小结.
附录:
1) 此图只是surfaceTexture内部更详细一步.(不需要掌握):
2) 下面blog更详细到了框架源码中的底层(不需要掌握):
Android图形系统分析与移植--四、Surface Manager(Surface Flinger简介):https://blog.csdn.net/louiswangbing/article/details/6606810
blog说明1、Surface manager架构分析:camera->Surface manager Client端(filter)->Surface manager Server端(SurfaceFlinger:back buffer)->(eglswapbuffer)->front buffer ->Display. "3Surface Flinger的基本组成框架以下" 不需要看,过于详细(Flinger内部介绍&dispay还有一个硬件buffer(graphicplane->nativewindow->framenativewindow->hardware buffer).
bufferqueue的实现:BufferQueue 学习总结(内附动态图)(https://blog.csdn.net/hexiaolong2009/article/details/99225637) 赞动图
3 ) GUI显示系统之SurfaceFlinger---章节目录
https://blog.csdn.net/xuesen_lin/article/details/8954508
4) Android图形系统之SurfaceTexture https://juejin.cn/post/6844904161645953038 -surfaceTexture 源码实现
5 Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView
https://blog.csdn.net/jinzhuojun/article/details/44062175 介绍概念比较全,类图多但是没有流程图和代码分析,所以理解不深入,适合总结不适合分析