为什么OpenGL ES纹理对象会因调用SurfaceTexture.detachFromGLContext而被删除?

时间:2016-04-13 10:00:08

标签: android opengl-es

我指的是SurfaceTexture.detachFromGLContext,它提到了," OpenGL ES纹理对象将因此次调用而被删除。"

任何人都请解释为什么框架在调用detach时需要删除这个纹理对象,因为纹理是在SurfaceTexture之外创建的并提供给构造函数。因此,我希望即使在分离后也可以使用纹理,并且创建者应该能够控制其生命周期。

我们尝试将此方法与attach方法和MediaCodec结合使用。在我们的使用案例中,我们需要复制视频帧纹理以供将来使用。

以下是创建SurfaceTexture的示例代码:

int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
SurfaceTexture surfaceTexture = new SurfaceTexture(textures[0]);

然后将创建一个曲面并将其传递给MediaCodec,如下面的代码示例

Surface surface = new Surface(surfaceTexture);
MediaCodec videoDecoder.configure(..., surface, null, 0);

在执行解码时,一旦视频帧解码为纹理,我就会尝试保留纹理并为SurfaceTexture分配不同的纹理,这样我以后就可以使用它,解码器可以将另一帧解码为新纹理。 / p>

surfaceTexture.detachFromGLContext();
surfaceTexture.attachToGLContext(newTexture);
但问题是android框架删除了纹理。我的观点是它应该是一个错误,或者应该有理由删除纹理。

2 个答案:

答案 0 :(得分:0)

每个openGL项都绑定到一个上下文,因此它必须被删除。

上下文负责创建缓冲区和处理与某些id或枚举绑定的状态(同样的事情,但枚举是预定义的)。因此,当删除上下文时,其所有项目也将被删除。如果你有2个上下文,那么没有任何状态或缓冲区以任何方式连接,你对openGL的任何调用只会影响当前绑定的上下文。因此,分离项目意味着删除它,SurfaceTexture所拥有的唯一连接是纹理ID,然后在其他任何地方都无法使用。这可能会让人感到困惑,但是想一想:如果你删除了你的CPU对象(表面纹理)和GPU数据(纹理)之间的连接,那么应该删除纹理,否则纹理数据会变成垃圾而你会有内存泄漏

很难理解为什么你甚至想要从上下文中分离纹理,但如果由于某种原因你需要从上下文中移动它,你将需要另一个上下文,它是纹理的实际所有者。为此,您将需要一个共享上下文,这意味着创建一个新的上下文,主要的上下文作为构造函数中的参数。这样,您的主上下文应该能够访问共享上下文所拥有的纹理,反之亦然。这也将允许您使用多个线程,因为“当前上下文”是每个线程。

答案 1 :(得分:0)

“由于此次调用,OpenGL ES纹理对象将被删除。”

请注意,对于外部曲面,删除纹理对象与删除物理内存不同; GL不拥有物理外部存储器缓冲区,并且仍将被分配并可供重用(如果重新导入GL,则只需重新创建GL纹理对象以再次包装它)。