详细区别参阅 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。
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
注意替换fragment_shader_screen.glsl里的逻辑,默认是没有特效的
代码结构:
代码说明:
参考上图,做一些说明辅助理解。
CameraEglSurfaceView
CameraEglSurfaceView继承自GLSurfaceView,作为默认的渲染屏幕。
CameraFboRender
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
这里我特地整理了一份《Android开发核心知识点笔记》,里面就包含了自定义View相关的内容
如果你有需要的话,可以私信我【进阶】发给你
除了这份笔记,还给大家分享 Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。
如果你有需要的话,可以点击我的GitHub免费获取!
分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~
csdn.net/topics/618156601)**
[外链图片转存中…(img-zeZ6RmDi-1711288698959)]
分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~
喜欢本文的话,给我点个小赞、评论区留言或者转发支持一下呗~