TextureView与GLSurfaceView或如何将GLSurfaceView与EGL14一起使用

时间:2014-01-23 10:36:40

标签: android glsurfaceview textureview

我对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记录了一些图表:

这里的TextureView有自己的EGL处理: enter image description here 顶部的Thread是一个唤醒Thread中间的时钟,它呈现在TextureView上。之后将调用主线程,用于重绘TextureView。

...这里有GLSurfaceView和他们自己的EGL处理 这次时钟位于中间,它调用顶部的线程将我的图像渲染成帧缓冲区,我直接将其提供给SurfaceView(RENDERMODE_WHEN_DIRTY)并调用requestRender来请求视图渲染。 enter image description here

正如您可以看到的那样,通过GLSurfaceView,它看起来比使用TextureView更清晰。

在这两个例子中,屏幕上没有任何其他内容,并且它们使用相同的着色器呈现完全相同的网格物体。

我的问题: 有没有办法将GLSurfaceView与EGL14上下文一起使用?

我做错了吗?

2 个答案:

答案 0 :(得分:45)

您可能想要做的是使用普通SurfaceView

这是简短版本:

  • SurfaceView有两个部分,SurfaceView中的一些虚假内容。 Surface直接传递给曲面合成器(SurfaceFlinger),因此当您使用OpenGL绘制它时,开销相对较小。这使得它很快,但它也使得它无法在View层次结构中正常运行,因为Surface位于一个层上,而基于视图的UI位于不同的层上。
  • TextureView也有两个部分,但你绘制的部分生活在幕后(SurfaceTexture进来的地方)。框架完成后,您绘制的内容将显示在视图图层上。 GPU可以快速完成这项工作,但是有些工作可以做到这一点。总是慢于"没有工作"。
  • GLSurfaceView是一个SurfaceView,它有一个包装类,可以为您完成所有EGL设置和线程间消息传递。

修改:长版本可用here

如果您可以自己进行GL / EGL设置和线程管理 - 如果您现在在TextureView上运行,那么您显然可以 - 那么您应该使用普通SurfaceView

说了这么多,应该可以使原始代码与GLSurfaceView一起使用。我希望您能够在与eglPresentationTimeANDROID()共享的EGL上下文中调用GLSurfaceView,而不是在GLSurfaceView本身内调用GLSurfaceView,因此GLSurfaceView并不重要1}}在内部使用EGL10。共享上下文的关键是上下文客户端版本(例如GLES2与GLES3),而不是用于配置上下文的EGL接口版本。

您可以在Grafika中查看所有这些内容的示例。特别是:

  • "显示+捕捉相机"使用GLSurfaceView,相机和视频编码器。请注意,EGL上下文是共享的。这个例子很复杂,有些痛苦,主要是因为它故意尝试使用TextureView和共享的EGL上下文。 (更新:注意this issue有关共享上下文的竞争条件。)
  • "播放视频(TextureView)"和#34; TextureView中的基本GL"显示SurfaceView正在行动中。
  • "用FBO"记录GL应用程序使用普通{{1}}。

答案 1 :(得分:8)

感谢fadden!它按预期工作。

对于那些考虑做类似事情的人:

使用(GL)SurfaceView在其上渲染图像具有优点和缺点。

我在上面的帖子中的测试结果在屏幕上没有任何其他内容,而不是渲染图像本身。 如果您在屏幕上有其他UI元素,特别是如果它们经常更新,您应该重新考虑我喜欢(GL)SurfaceView的选择。

SurfaceView在Android Windows系统中创建一个新窗口。它的优点是,如果SurfaceView被刷新,则只刷新此窗口。如果你另外更新UI元素(在windowsystem的另一个窗口中),那么两个刷新操作都会阻止它们(特别是当ui绘图是硬件支持时),因为opengl无法正确处理多线程绘制。

对于这种情况,使用TextureView可能会更好,因为它不是Android Windows系统的另一个窗口。因此,如果刷新View,则所有UI元素也会刷新。 (可能)一切都在一个线程中。

希望我能帮助你们中的一些人!