Android OpenGL ES预热: 视频展示控件之 SurfaceView、GLSurfaceView、SurfaceTexture、TextureView 对比总结

前言

OpenGL预热,为什么叫预热是因为太冷了。
建议去看参考文章。

SurfaceView:独立绘图层的View 、Surface就是指SurfaceView所拥有的那个绘图层,其实它就是内存中的一段绘图缓冲区、具有两个Surface,也就是双缓冲机制、SurfaceHolder就是Surface的持有者。
GLSurfaceView:GLSurfaceView作为SurfaceView的补充,可以看作是SurfaceView的一种典型使用模式。
SurfaceTextureandroid.graphics.SurfaceTexture SurfaceTexture和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。
用来捕获视频流中的图像帧的,视频流可以是相机预览或者视频解码数据。
TextureView:TextureView可以通过getSurfaceTexture()方法来获取TextureView相应的SurfaceTexture。但是最好的方式还是使用TextureView.SurfaceTextureListener监听器来对SurfaceTexture的创建销和毁进行监听,因为getSurfaceTexture可能获取的是空对象。

下面是google sourse给出的解释,学习了OpenGL就会更加明了::

  • SurfaceView 和 GLSurfaceView。SurfaceView 结合了 Surface 和 View。SurfaceView 的 View 组件由 SurfaceFlinger(而不是应用)合成,从而可以通过单独的线程/进程渲染,并与应用界面渲染隔离。GLSurfaceView 提供帮助程序类来管理 EGL 上下文、线程间通信以及与“Activity 生命周期”的交互(但使用 GLES 时并不需要 GLSurfaceView)。
  • SurfaceTexture。SurfaceTexture 将 Surface 和 GLES 纹理相结合来创建 BufferQueue,而您的应用是 BufferQueue 的消费者。当生产者将新的缓冲区排入队列时,它会通知您的应用。您的应用会依次释放先前占有的缓冲区,从队列中获取新缓冲区并执行 EGL 调用,从而使 GLES 可将此缓冲区作为外部纹理使用。Android 7.0 增加了对安全纹理视频播放的支持,以便用户能够对受保护的视频内容进行 GPU 后处理。
  • TextureView。TextureView 结合了 View 和 SurfaceTexture。TextureView 对 SurfaceTexture 进行包装,并负责响应回调以及获取新的缓冲区。在绘图时,TextureView 使用最近收到的缓冲区的内容作为其数据源,根据 View 状态指示,在它应该渲染的任何位置和以它应该采用的任何渲染方式进行渲染。View 合成始终通过 GLES 来执行,这意味着内容更新可能会导致其他 View 元素重绘。

参考文章

  1. https://www.cnblogs.com/renhui/p/8258391.html
  2. https://blog.csdn.net/jinzhuojun/article/details/44062175

使用总结

一、SurfaceView

SurfaceView继承自View,并提供了一个独立的绘图层,你可以完全控制这个绘图层,比如说设定它的大小,所以SurfaceView可以嵌入到View结构树中,需要注意的是,由于SurfaceView直接将绘图表层绘制到屏幕上,所以和普通的View不同的地方就在与它不能执行Transition,Rotation,Scale等转换,也不能进行Alpha透明度运算。

SurfaceView的Surface排在Window的Surface(也就是View树所在的绘图层)的下面,SurfaceView嵌入到Window的View结构树中就好像在Window的Surface上强行打了个洞让自己显示到屏幕上,而且SurfaceView另起一个线程对自己的Surface进行刷新。需要注意的是SurfaceHolder.Callback的所有回调方法都是在主线程中回调的。

SurfaceView、SurfaceHolder、Surface的关系可以概括为以下几点:

  • SurfaceView是拥有独立绘图层的特殊View。
  • Surface就是指SurfaceView所拥有的那个绘图层,其实它就是内存中的一段绘图缓冲区。
  • SurfaceView中具有两个Surface,也就是我们所说的双缓冲机制
  • SurfaceHolder顾名思义就是Surface的持有者,SurfaceView就是通过过SurfaceHolder来对Surface进行管理控制的。并且SurfaceView.getHolder方法可以获取SurfaceView相应的SurfaceHolder。
  • Surface是在SurfaceView所在的Window可见的时候创建的。我们可以使用SurfaceHolder.addCallback方法来监听Surface的创建与销毁的事件。

上面的文章结合下面更容易理解:
SurfaceView它继承自类View,因此它本质上是一个View。但与普通View不同的是,它有自己的Surface。我们知道,一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DecorView,也就是根结点视图,才是对WMS可见的。这个DecorView在WMS中有一个对应的WindowState。相应地,在SF中对应的Layer。而SurfaceView自带一个Surface,这个Surface在WMS中有自己对应的WindowState,在SF中也会有自己的Layer。
如下图所示:


图片

也就是说,虽然在App端它仍在View hierachy中,但在Server端(WMS和SF)中,它与宿主窗口是分离的。这样的好处是对这个Surface的渲染可以放到单独线程去做,渲染时可以有自己的GL context。这对于一些游戏、视频等性能相关的应用非常有益,因为它不会影响主线程对事件的响应。但它也有缺点,因为这个Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能放在其它ViewGroup中,一些View中的特性也无法使用。

二、TextureView

TextureView专门用来渲染像视频或OpenGL场景之类的数据的,而且TextureView只能用在具有硬件加速的Window中,如果使用的是软件渲染,TextureView将什么也不显示。也就是说对于没有GPU的设备,TextureView完全不可用。
和SurfaceView不同,它不会在WMS中单独创建窗口,而是作为View hierachy中的一个普通View,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化。

TextureView 有两个相关类 SurfaceTexture、Surface,下面说明一下几者相关的特点:

  • Surface就是SurfaceView中使用的Surface,就是内存中的一段绘图缓冲区。
  • SurfaceTexture用来捕获视频流中的图像帧的,视频流可以是相机预览或者视频解码数据。SurfaceTexture可以作为android.hardware.camera2, MediaCodec, MediaPlayer, 和 Allocation这些类的目标视频数据输出对象。可以调用updateTexImage()方法从视频流数据中更新当前帧,这就使得视频流中的某些帧可以跳过。
  • TextureView可以通过getSurfaceTexture()方法来获取TextureView相应的SurfaceTexture。但是最好的方式还是使用TextureView.SurfaceTextureListener监听器来对SurfaceTexture的创建销和毁进行监听,因为getSurfaceTexture可能获取的是空对象。
  1. TextureView继承自View,它与其它的View一样在View hierachy中管理与绘制。
  2. TextureView重载了draw()方法,其中主要把SurfaceTexture中收到的图像数据作为纹理更新到对应的HardwareLayer中。
  3. SurfaceTexture.OnFrameAvailableListener用于通知TextureView内容流有新图像到来。
  4. SurfaceTextureListener接口用于让TextureView的使用者知道SurfaceTexture已准备好,这样就可以把SurfaceTexture交给相应的内容源。
  5. Surface为BufferQueue的Producer接口实现类,使生产者可以通过它的软件或硬件渲染接口为SurfaceTexture内部的BufferQueue提供graphic buffer。

盗用一张图演示:


图片

三、GLSurfaceView

GLSurfaceView作为SurfaceView的补充,可以看作是SurfaceView的一种典型使用模式。在SurfaceView的基础上,它加入了EGL的管理,并自带了渲染线程。另外它定义了用户需要实现的Render接口,提供了用Strategy pattern更改具体Render行为的灵活性。作为GLSurfaceView的Client,只需要将实现了渲染函数的Renderer的实现类设置给GLSurfaceView即可。

四、SurfaceTexture

SurfaceTexture和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后可以交给GLSurfaceView直接显示,也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。首先,SurfaceTexture从图像流(来自Camera预览,视频解码,GL绘制场景等)中获得帧数据,当调用updateTexImage()时,根据内容流中最近的图像更新SurfaceTexture对应的GL纹理对象,接下来,就可以像操作普通GL纹理一样操作它了。

强调一下

GLSurfaceView的特性:
1.管理一个surface,这个surface就是一块特殊的内存,能直接排版到android的视图view上。
2.管理一个EGL display,它能让opengl把内容渲染到上述的surface上。
3.用户自定义渲染器(render)。
4.让渲染器在独立的线程里运作,和UI线程分离。
5.支持按需渲染(on-demand)和连续渲染(continuous)。
6.可以封装、跟踪并且排查渲染器的问题。
因为下面我们要做的事情就是在 GLSurfaceView上面进行的!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343