SurfaceView和TextureView都是继承view。
SurfaceTexture是一个管理图像流的类,它将图像流转为GL外部纹理交给TextureView显示,是可用于图像流数据的二次处理。
它核心管理着一个BufferQueue的Consumer和Producer两端。
Producer端用于内容流的源输出数据,Consumer端用于拿GraphicBuffer并生成纹理。
1、在Server端的一些区别
SurfaceView有自己的Surface,虽然在Client端(App)它仍在View hierachy中,但是在WindowManagerService中有自己的WindowState,在SurfaceFlinger中有自己的Layer,所以Server端(WMS和SF)中,它与宿主窗口是分离的。
这样的好处是对这个Surface的渲染可以放到单独线程去做,渲染时可以有自己的GL context。也因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能进行截图。
TextureView作为View hierachy中的一个普通View,不会在WMS中单独创建窗口,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化,但是它必须在硬件加速的窗口中使用。它可以将来自App进程或是远端进程的内容流直接投影到View中,可以用于实现Live preview等功能。它重载了draw()方法,其中主要是SurfaceTexture中收到的图像数据作为纹理更新到对应的HardwareLayer中。在5.0以前在主线程渲染,5.0以后有单独的渲染线程。
2、性能对比
SurfaceView在更新视图时用到了两张Canvas,一张frontCanvas和一张backCanvas。
每次实际显示的是frontCanvas,backCanvas存储的是上一次更改前的视图。
使用lockCanvas()获取backCanvas 进行绘制新视图,再unlockCanvasAndPost(canvas)此视图,那么backCanvas将替换原来的frontCanvas作为新的frontCanvas,原来的frontCanvas将切换到后台作为backCanvas。
这样做的有点自然是高效,相比TextureView,会延迟1~3帧。
TextureView总是使用GL合成,而SurfaceView可以使用硬件overlay后端,可以占用更少的内存,消耗更少电量。
3、使用选择
从性能和安全性角度出发,使用播放器首选SurfaceView。
在android 7.0上系统surfaceview的性能比TextureView更有优势,
支持对象的内容位置和包含的应用内容同步更新,平移、缩放不会产生黑边。
在7.0以下系统如果使用场景有动画效果,可以选择性使用TextureView。
其他:
SurfaceView有自己的Surface,而一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DecorView,也就是根结点视图,才是对WMS可见的。这个DecorView在WMS中有一个对应的WindowState。相应地,在SF中对应的Layer。
参考
OpenGL的Context
SurfaceView, TextureView, SurfaceTexture等的区别
网友评论