Android:是否可以在没有SurfaceView的情况下创建SurfaceTexture?

13
我想创建一个可以管理的带有OpenGL纹理的SurfaceTexture,类似于这个答案中的设置。 (在此引用:)
  1. 通过OpenGL创建纹理
  2. 将该纹理传递给新SurfaceTexture的构造函数。
  3. 将此新SurfaceTexture提供给相机。
  4. 确保使用OES_External(有关详细信息,请参见文档)。
然而,创建OpenGL纹理(作为答案的第1步)需要EGL上下文,这需要使EGLSurface当前,这又需要一个SurfaceTexture。似乎创建EGL上下文的唯一方法是创建SurfaceView(或具有SurfaceTexture的另一个视图),并使用它来初始化EGLSurface,然后使EGLContext当前。
我的目标是在后台线程中创建EGLContext并使其成为当前线程,以对摄像头预览图像进行一些离屏计算(主要使用NDK)。 我想创建一个库,并尽可能地使其独立于UI。两个相关问题:
在Java方面,是否可以在先前没有创建SurfaceTexture的情况下创建EGLContext?
在NDK方面,以前有一个私有API调用来创建本地窗口android_createDisplaySurface(),但它不再起作用了,而且它是一个私有API。是否有任何方法使用NDK创建Surface?
我对使用EGL还很新,我无法理解为什么需要EGLSurface才能使EGLContext成为当前状态。在iOS中,可以首先创建EAGLContext,然后根据需要创建framebuffer。使用EGL似乎总是需要一个本地窗口。
1个回答

8
你可以在Grafika中看到许多操作相机输出、SurfaceTexture和EGL的示例。 "Continuous capture" 活动是其中之一,但它使用了你提到的技术:为了避免创建EGLSurface,它只是借用了附近SurfaceView的一个。

你确实需要一个EGLSurface,但它不需要是window surface。你可以创建一个1x1的pbuffer surface并使用它。这是通过eglCreatePbufferSurface()调用完成的;请参见Grafika中的EglCore类的示例。

这些示例是用Java编写的,但Java实现只是包装了本地的EGL/GLES调用。

android_createDisplaySurface()是一个内部调用,正如你发现的,在新设备上无法使用。请搜索NDK,找到ANativeWindow

更新:对于任何通过搜索到达此处的人,android_createDisplaySurface() 依赖于一个名为 FramebufferNativeWindow 的内部类,在 Android 5.0 中被标记为过时,详见this change。使用它的内部 OpenGL ES 测试代码已经在this change中更新为基于 SurfaceFlinger 的替代品。原始版本的测试代码需要关闭 Android 应用程序框架才能抓取帧缓冲区;而新版本只需向 SurfaceFlinger 请求一个覆盖屏幕并在其他所有内容上合成的窗口即可。

是的。看看 Grafika,它是一个很棒的项目。 - user1906
@fadden:在没有AOSP / GraphicBuffer的NDK中,我选择了一个合适的EGL_NATIVE_VISUAL_ID配置,成功创建了一个PbufferSurface,创建了一个上下文,并使用这些displaysurfacecontext使其成为当前上下文。我需要传递什么作为(EGLClientBuffer)eglCreateImageKHR()?从我所读到的内容来看,它应该以某种方式使用ANativeWindow,但我无法弄清楚如何做到! - Adi Shavit
@user1906:你成功使用eglCreateImageKHR()和pbuffer进行直接渲染了吗? - Adi Shavit
@fadden:Grrr..看到你在这个主题上的所有答案和深入的知识帖子,我真的很希望会知道:-(。那么什么时候使用ANativeWindow是有用的呢? - Adi Shavit
@fadden:我明白了。谢谢。 - Adi Shavit
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接