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

Android 为什么调用SurfaceTexture.detachFromGLContext会删除OpenGL ES纹理对象?,android,opengl-es,Android,Opengl Es,我指的是,它提到,“OpenGL ES纹理对象将作为此调用的结果被删除。” 任何人请解释为什么框架在调用detach时需要删除此纹理对象,因为该纹理是在SurfaceTexture外部创建的,并提供给构造函数。所以,我希望即使在分离之后也能使用纹理,并且创建者应该能够控制它的生命周期 我们正试图结合使用attach方法和MediaCodec。在我们的用例中,我们需要复制视频帧纹理以备将来使用 以下是创建SurfaceTexture的示例代码: int[] textures = new int[1

我指的是,它提到,“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,以便稍后使用,解码器可以将另一帧解码为新纹理

surfaceTexture.detachFromGLContext();
surfaceTexture.attachToGLContext(newTexture);

但问题是android框架会删除纹理。我的观点是,它应该是一个bug,或者应该有删除纹理的理由。

每个openGL项目都绑定到一个上下文,因此当它被分离时,它也必须被删除

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

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

“OpenGL ES纹理对象将作为此调用的结果被删除。”


注意,对于外部表面,删除纹理对象与删除物理内存不同;物理外部内存缓冲区不归GL所有,但仍将分配并可供重用(如果重新导入GL,您只需重新创建GL纹理对象以重新包装即可)。

我添加了代码示例,以进一步解释我的问题。我的观点是在我的GL中创建的纹理,为什么调用会删除它。因为分离surfaceView时支持纹理对象的内存会消失。我添加了更多代码示例来解释用例,请检查。这不是多线程。你能不能简单地创建一个新的表面纹理,并将其作为当前的注入,同时保留旧的,直到你需要它?或者,如果可能,将新纹理id设置为表面纹理。在您的案例中,脱离上下文不是您想要的。在某一点上至少需要2个纹理,并且它们都需要附加。不,除了MediaCodec videoDecoder之外,没有其他方法可以将SurfaceTexture传递给MediaCodec。配置(…,surface,null,0);是的,但曲面似乎包裹了包裹纹理的SurfaceTexture。因此,至少改变其中一个应该是可能的。例如,使用相同的纹理id创建另一个SurfaceTexture。