TextureView 与 GLSurfaceView 或如何将 GLSurfaceView 与 EGL14 一起使用
Posted
技术标签:
【中文标题】TextureView 与 GLSurfaceView 或如何将 GLSurfaceView 与 EGL14 一起使用【英文标题】:TextureView vs. GLSurfaceView or How to use GLSurfaceView with EGL14 【发布时间】:2014-02-13 20:27:08 【问题描述】:我对 EGL 感到困惑。
我的 GLSurfaceView 创建了一个 EGLContext。现在我创建一个共享上下文。现在我需要使用 EGLExtension。
我必须使用的方法被称为(>=API18):
EGLExt.eglPresentationTimeandroid(android.opengl.EGLDisplay display, android.opengl.EGLSurface surface, long time);
问题是,GLSurfaceView 只创建 javax.microedition.khronos.egl.EGLContext s。
这告诉我,不要使用 GLSurfaceView。所以我尝试了 TextureView,它有点相似,不同的是你必须处理你自己的 EGL 东西。哪个对这个目的有好处。
但是: TextureView 比较慢,至少看起来是这样,所以我用 Method Profiler 记录了一些图表:
这里是带有自己的 EGL 处理的 TextureView: 顶部的 Thread 是一个时钟,用于唤醒中间的 Thread,渲染到 TextureView 上。之后将调用主线程,用于重绘 TextureView。
...这里是带有自己的 EGL 处理的 GLSurfaceView 这次时钟在中间,它调用顶部的 Thread 将我的图像渲染到帧缓冲区中,我将其直接交给 SurfaceView (RENDERMODE_WHEN_DIRTY) 并调用 requestRender 请求视图进行渲染。
正如您已经看到的那样,使用 GLSurfaceView 看起来比使用 TextureView 更干净。
在这两个示例中,我没有在屏幕上显示任何其他内容,它们使用相同的着色器渲染完全相同的网格。
我的问题: 有没有办法将 GLSurfaceView 与 EGL14 上下文一起使用?
我是不是做错了什么?
【问题讨论】:
【参考方案1】:您可能想要做的是使用普通的SurfaceView。
这是简短的版本:
SurfaceView
有两个部分,Surface
和 View
中的一些假东西。 Surface
直接传递给表面合成器 (SurfaceFlinger),因此当您使用 OpenGL 在其上绘制时,开销相对较小。这使得它很快,但它也使它不能很好地与 View 层次结构配合,因为Surface
位于一个层上,而基于 View 的 UI 位于另一个层上。
TextureView
也有两个部分,但你所绘制的部分生活在幕后(这就是 SurfaceTexture
的用武之地)。帧完成后,您绘制的内容会被粘贴到视图层上。 GPU 可以快速做到这一点,但“一些工作”总是比“没有工作”慢。
GLSurfaceView
是一个 SurfaceView
,带有一个包装类,可以为您完成所有 EGL 设置和线程间消息传递。
编辑:长版可用here。
如果您可以自己进行 GL/EGL 设置和线程管理 - 如果您现在在 TextureView 上运行,那么您显然可以 - 那么您可能应该使用普通的 SurfaceView
。
说了这么多,应该可以使您的原始代码与GLSurfaceView
一起工作。我希望您想在与GLSurfaceView
共享的EGL 上下文中调用eglPresentationTimeANDROID()
,而不是从GLSurfaceView
本身内部调用,因此GLSurfaceView
在内部使用EGL10 并不重要。共享上下文重要的是上下文客户端版本(例如 GLES2 与 GLES3),而不是用于配置上下文的 EGL 接口版本。
您可以在Grafika 中查看所有这些工作的示例。特别是:
“显示 + 捕获相机”使用GLSurfaceView
、相机和视频编码器。请注意,EGL 上下文是共享的。该示例令人费解且有些痛苦,主要是因为它故意尝试使用GLSurfaceView
和共享的EGL 上下文。 (更新:请注意 this issue 关于共享上下文的竞争条件。)
“播放视频 (TextureView)”和“TextureView 中的基本 GL”展示了 TextureView
的实际应用。
“使用 FBO 记录 GL 应用”使用普通的 SurfaceView
。
【讨论】:
你能帮我解决这个问题吗Question【参考方案2】:感谢fadden!它按预期工作。
致所有想做类似事情的人:
使用 (GL)SurfaceView 在其上渲染图像具有优点和缺点。
我在上面帖子中的测试结果在屏幕上除了渲染图像本身之外没有其他任何东西。 如果您在屏幕上有其他 UI 元素,尤其是如果它们经常更新,您应该重新考虑我更喜欢 (GL)SurfaceView 的选择。
SurfaceView 在 Android Windowsystem 中创建一个新窗口。它的优点是,如果 SurfaceView 被刷新,只有这个窗口会被刷新。如果您另外更新 UI 元素(在窗口系统的另一个窗口中),那么两个刷新操作都会阻止自己(尤其是当 ui 绘图是硬件支持时),因为 opengl 无法正确处理多线程绘图。
对于这种情况,最好使用 TextureView,因为它不是 Android Windowsystem 的另一个窗口。所以如果你刷新你的视图,所有的 UI 元素也会被刷新。 (可能)一个线程中的所有内容。
希望我能帮助你们中的一些人!
【讨论】:
SurfaceView 可以根据需要透明:***.com/a/7061396/671393以上是关于TextureView 与 GLSurfaceView 或如何将 GLSurfaceView 与 EGL14 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
TextureView 与 GLSurfaceView 或如何将 GLSurfaceView 与 EGL14 一起使用
android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系