1 SurfaceView
1 Surface
Surface 是一块用于填充图像数据的内存空间,例如你可以使用 SurfaceView 的 Surface 接收每一帧预览数据用于显示预览画面,也可以使用 ImageReader 的 Surface 接收 JPEG 或 YUV 数据。每一个 Surface 都可以有自己的尺寸和数据格式,你可以从 CameraCharacteristics 获取某一个数据格式支持的尺寸列表。
英文直译:表面
由源码可以得知:
- Surface是用来处理屏幕显示内容合成器所管理的原始缓存区工具
- Surface通常由SurfaceTexture或者MediaRecord来创建(消费者)
- Surface最后显示在MediaPlayer或者CameraDevice上(生产者)
- 通过Surface可以获得管理原始缓存区的数据
- 原始缓存区(rawbuffer)是用来保存当前窗口的像素数据
2 SurfaceView
extends MockView/View
一个有自己独立Surface、Window的view,负责把surface显示在屏幕的合适位置。通过控制surface的格式、大小等,可以看到surface的部分或者全部内容。
由于相机预览对更新速度和帧率要求较高,通常使用SurfaceView更新画面,以免普通View阻塞UI线程,优点如下:
- 不与其他普通的view共享Surface,在独立的线程绘制
- SurfaceView底层实现了双缓冲机制,解决了反复局部刷新带来的闪烁问题。双缓冲机制会及时把要处理的图像在内存中处理后,先画到一个内存区域,然后再整体绘制处理,显示在屏幕上。
缺点~~~~:因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能放在其它ViewGroup中,一些View中的特性也无法使用。
SurfaceView 采用与其他 View 相同的布局参数,因此可以像对待其他任何 View 一样对其进行操作,但 SurfaceView 的内容是透明的。
如需在创建或销毁 Surface 时收到回调,请使用 SurfaceHolder 接口。↓
3 SurfaceHolder
给持有Surface对象(通常是surfaceview这个类)来使用的抽象接口,通过这个接口控制surface的大小和格式,编辑surface中的像素和监听surface变化。
三者关系:
2 GLSurfaceView
extends SurfaceView
/**
* SurfaceView 的一种实现,它使用专用Surface来显示 OpenGL 渲染。
*
* A GLSurfaceView provides the following features:
* <li>管理一个Surface(一块特殊的内存,可以合成到 Android 视图系统中)。
* <li>管理 EGL 显示,使 OpenGL 能够渲染到Surface。
* <li>接受用户提供的进行实际渲染的 Renderer 对象。
* <li>在专用线程上渲染以将渲染性能与 主线程 分离 。
* <li>支持按需和连续渲染。
* <li>可选择包装、跟踪、和/或错误检查渲染器的 OpenGL 调用。
*
*/
加入了EGL(OpenGL ES:EGL接口解析与理解)管理,并且自带渲染线程,定义了用户需要实现的Render接口负责实际渲染。
由如下类图可知,类似SurfaceView的SurfaceHolder提供了一些操作Surface的接口,GLSurfaceView中的EglHelper实现了管理EGL环境的工作,GLThread作为渲染线程。
3 SurfaceTexture
SurfaceTexture 是 Surface 和 OpenGL ES (GLES) 纹理的组合。SurfaceTexture 实例用于提供输出到 GLES 纹理的接口。
SurfaceTexture 是一个BufferQueue的消费者。
并不是一个View,有自己的BufferQueue,可以用来生成Surface,传入到SurfaceTexture中的Buffer会被转化成GL纹理(纹理是一些数据,需要附加到View上才能显示),这个纹理交给TextureView或者GLSurfaceview进行显示。
用来从图像流中捕获帧,作为 OpenGL ES 纹理,图像流可能来自相机预览或视频解码。
不同于 SurfaceView 会将图像显示在屏幕上,SurfaceTexture 对图像流的处理并不直接显示,而是转为 GL 外部纹理。
可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)
输出目标是Camera或MediaPlayer时可以用SurfaceTexture代替SurfaceHolder
前面提到的,
- Surface通常由SurfaceTexture或者MediaRecord来创建(消费者)
- Surface最后显示在MediaPlayer或者CameraDevice上(生产者)
4 TextureView
TextureView 本质上是 SurfaceTexture 的 View 封装
TextureView 可用于显示内容流。例如,这样的内容流可以是视频或 OpenGL 场景。内容流可以来自应用程序的进程以及远程进程。
SurfaceView本身的输出不是通过Android的UI Renderer(HWUI),而是直接走系统的窗口合成器SurfaceFlinger,所以无法实现对普通view的完全兼容。
与SurfaceView不同,TextureView不会再WMS中单独创建窗口,而是作为一个普通的View,因此TextureView可以和普通View一样进行平移、旋转、缩放、动画等。
通过 SurfaceTextureListener监听 SurfaceTexture 的各种状态
缺点:
因为 TextureView 需要通过 UI Renderer 输出,也导致了新的问题的出现。除了性能比较 SurfaceView 会有明显下降外(低端机,高 GPU 负荷场景可能存在 15% 左右的帧率下降),另外因为需要在三个线程之间进行写读同步(包括 CPU 和 GPU 的同步),当同步失调的时候,比较容易出现掉帧或者吞帧导致的卡顿和抖动现象。
5 BufferQueue
Gralloc
gralloc是Android中负责申请和释放GraphicBuffer的HAL层模块,由硬件驱动提供实现,为BufferQueue机制提供了基础。gralloc分配的图形Buffer是进程间共享的,且根据其Flag支持不同硬件设备的读写。
从系统层级来看,gralloc属于最底层的HAL层模块,为上层的libui库提供服务,整个层级结构: