【问题标题】:Can I share a external texture between 2 OpenGL contexts, Android我可以在 2 个 OpenGL 上下文之间共享外部纹理吗,Android
【发布时间】:2015-08-12 01:06:05
【问题描述】:

我正在创建 2 个线程。每个线程都有自己的 EGL 上下文。 一个线程是原生的,我将在其中渲染到纹理,另一个线程在 Java 中,我想从该纹理中采样并渲染到屏幕/编码器(没关系)。 我不能让它工作。 我尝试在任一线程上生成纹理。我注意到纹理 ID 在两个线程上重复(我有其他不打算共享的纹理)。

我的问题是,是否可以在 2 个线程(和上下文)之间共享纹理?

编辑:解决方案

多亏了 Andon 和一些谷歌搜索,我才得以成功。我在线程一上用 Java 创建了一个上下文,并调用了 eglGetCurrentContext() 来获取 C++ 中的 EGLContext。后来,我在第二个线程上用 C++ 创建了第二个上下文:

eglCreateContext(mEglDisplay, mEglConfig, sharedContext, contextAttribs);

其中 sharedContext 是第一个上下文。

【问题讨论】:

  • 围栏同步对象将是同步的首选方法,但我认为您在 OpenGL ES 中没有这些? (顺便说一句,您的问题被标记错误 - 它应该是 OpenGL ES)
  • 您在标题中说“外部纹理”,但在未提及的问题中,听起来您只是在使用常规的 OpenGL 纹理。你能澄清一下是哪一个吗?
  • 是的,我正在使用外部纹理。
  • 使用外部纹理,您应该能够在不在同一个共享组中的上下文之间共享图像数据。它们甚至在进程之间工作。当然,每个共享组中都需要一个纹理对象,但纹理可以由同一图像支持。尽管如此,只要一切都在同一个过程中,就没有必要为外部纹理而烦恼。将上下文放在同一个共享组中并使用常规纹理可能要简单得多。
  • Grafika (github.com/google/grafika) 中的“显示 + 捕获相机”活动执行此操作,共享从相机接收到的外部纹理与不同线程中的两个 EGL 上下文(一个在屏幕上绘制,一个馈送MediaCodec 编码器)。它变得有点棘手,因为显示上下文由 GLSurfaceView 管理,这并不是共享的全部内容。

标签: java android c++ multithreading opengl-es


【解决方案1】:

是的,上下文之间的资源共享是可能的。

虽然共享上下文中的命令流不同步;如果您在一个线程中上传数据并在另一个线程中使用它,您必须格外小心,上传实际上是先完成的(glFinish (...),然后是您自己的一些同步结构,如信号量,就可以了)。

现在,百万美元的问题 - 您是否可以控制这些上下文的创建?这是在 EGL 中进行资源共享所必需的。您只需要自己创建一个;如果您已经给了另一个,则可以在创建第二个时将其用作您的共享上下文。

【讨论】:

  • 我可以完全控制这两种情况。我正在创建它们。 glFinish 是做什么的?正如我所提到的,它没有用。一个线程上的纹理渲染工作。但是当我从另一个线程的纹理 ID 中采样时,在另一个上下文中。我得到一个空白屏幕。
  • @MichaelP: glFinish (...) 阻塞,直到所有导致它的命令都完成。否则,GL 倾向于将命令放入队列并在 GPU 处理它时执行它们。这通常很好,但是当您进行多线程渲染时,这很糟糕,很糟糕,很糟糕。您需要在一个线程中生成纹理的东西之后立即调用glFinish (...),一旦该命令返回,您就可以向渲染线程发出信号,表明有有效的纹理数据等待绘制。否则两个线程异步操作,一团糟。
  • @MichaelP:通常在单线程/单上下文渲染场景中,您永远不必考虑这些东西,GL 会自动进行这种同步。但是当你使用两个独立的上下文时,它们每个都并行执行命令,你需要确保命令执行的顺序是一致的。 但是,如果您不通过将其中一个上下文传递给eglCreateContext (...) 来将其建立为共享上下文,那么这一切都将不起作用。
  • 成功了!谢谢@Andon,我会用解决方案更新问题
猜你喜欢
  • 2018-10-01
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多