SurfaceView VS TextureView

详细区别参阅 SurfaceView、GLSurfaceView、SurfaceTexture、TextureView 区别

SurfaceTexture工作原理

Android开发文档里对SurfaceTexture的工作流有简单的介绍

相机采集的图像经SurfaceTexture处理后,输送到OpenGLES,gl处理完再输送到SurfaceView展示,最后由SurfaceFlinger合成;或经OpenGLES处理后,输送到MediaCodec编码,编码成视频文件。

抽出SurfaceTexture的核心逻辑,如下图。SurfaceTexture中维护了一个队列,存储图像Buffer,从Camera、Decoder等模块输入数据,转换成纹理,输送到OpenGL处理。这是一个典型的生产-消费模式。

注意:在GL环境中处理Texture时,key是“GLES11Ext.GL_TEXTURE_EXTERNAL_OES”,什么是TEXTURE_EXTERNAL_OES呢?

如上图所示,camera等采集的图像数据,不能直接用于opengl,需要以拓展纹理的方式处理,实际经过EglImageKHR转换,这部分工作是EGL做的。我的理解是,图像的生产不在GL线程中,纹理不能共享给OpenGL线程,另外采集的图像数据是YUV格式的,需要转换成普通的RGB。

关于EglImageKHR,详细参考.

SurfaceTexture代码分析

代码分析参考谈一谈 Android 上的 SurfeceTexture

来看看SurfaceTexture里的代码,建立直观的认识.

SurfaceTexture构造函数中调用nativeInit初始化

// 构造函数
// singleBufferMode是否是单buffer,默认为false
public SurfaceTexture(int texName, boolean singleBufferMode) {
mCreatorLooper = Looper.myLooper();
mIsSingleBuffered = singleBufferMode;
//native方法nativeInit
nativeInit(false, texName, singleBufferMode, new WeakReference(this));
}

重点在nativeInit方法里,生成生产者和消费者,创建图像缓冲队列。调用updateTexImage,会读取缓冲队列里的数据到TextureId绑定的纹理内存中

// frameworks\base\core\jni\SurfaceTexture.cpp
// texName为应用创建texture名
// weakThiz为SurfaceTexture对象弱引用
static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
jint texName, jboolean singleBufferMode, jobject weakThiz) {
sp producer;
sp consumer;
// 创建IGraphicBufferProducer及IGraphicBufferConsumer

BufferQueue::createBufferQueue(&producer, &consumer);

if (singleBufferMode) {
consumer->setMaxBufferCount(1);
}

sp surfaceTexture;
// isDetached为false
if (isDetached) {

} else {
// 将consumer和texName封装为GLConsumer类对象surfaceTexture
surfaceTexture = new GLConsumer(consumer, texName,
GL_TEXTURE_EXTERNAL_OES, true, !singleBufferMode);
}

// 收到帧数据是会触发ctx->onFrameAvailable方法
surfaceTexture->setFrameAvailableListener(ctx);
SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
}

原理先讲到这了,下面我们来一段实践,将前面所学的都结合起来,实现一个动效.

实践.基于SurfaceTexture预览+gl特效

完整工程:完整工程 CameraDemo

github.com/ChinaZeng/O…

注意替换fragment_shader_screen.glsl里的逻辑,默认是没有特效的

代码结构:

代码说明:

参考上图,做一些说明辅助理解。

CameraEglSurfaceView

CameraEglSurfaceView继承自GLSurfaceView,作为默认的渲染屏幕。

CameraFboRender

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

这里我特地整理了一份《Android开发核心知识点笔记》,里面就包含了自定义View相关的内容

如果你有需要的话,可以私信我【进阶】发给你

除了这份笔记,还给大家分享 Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。

如果你有需要的话,可以点击我的GitHub免费获取!

分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

csdn.net/topics/618156601)**

[外链图片转存中…(img-zeZ6RmDi-1711288698959)]

分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

喜欢本文的话,给我点个小赞、评论区留言或者转发支持一下呗~

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐