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

and*_*dre 25 android glsurfaceview textureview

我对EGL感到困惑.

我的GLSurfaceView创建了一个EGLContext.现在我创建一个共享上下文.现在我需要使用EGLExtension.

我必须使用的方法称为(> = API18):

EGLExt.eglPresentationTimeANDROID(android.opengl.EGLDisplay display, android.opengl.EGLSurface surface, long time);
Run Code Online (Sandbox Code Playgroud)

问题是,GLSurfaceView只创建了javax.microedition.khronos.egl.EGLContext.

这告诉我,不要使用GLSurfaceView.所以我尝试了稍微类似的TextureView,区别在于你必须处理自己的EGL内容.哪个对此有益.

但是:TextureView速度较慢,至少它看起来像那样,所以我用Method Profiler记录了一些图表:

这里的TextureView有自己的EGL处理: 在此输入图像描述 顶部的Thread是一个唤醒Thread中间的时钟,它呈现在TextureView上.之后将调用主线程,用于重绘TextureView.

......这里的GLSurfaceView有自己的EGL处理这次时钟在中间,它调用顶部的线程将我的图像渲染成帧缓冲区,我直接将其提供给SurfaceView(RENDERMODE_WHEN_DIRTY)并调用requestRender请求视图呈现. 在此输入图像描述

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

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

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

我做错什么了吗?

fad*_*den 47

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

这是简短的版本:

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

编辑:这里有长版本.

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

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

你可以在Grafika看到所有这些工作的例子.特别是:

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


and*_*dre 8

感谢fadden!它按预期工作.

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

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

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

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

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

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