【问题标题】:Why The OpenGL ES texture object will be deleted as a result of call to SurfaceTexture.detachFromGLContext?为什么调用 SurfaceTexture.detachFromGLContext 会删除 OpenGL ES 纹理对象?
【发布时间】:2016-04-13 10:00:07
【问题描述】:

我指的是SurfaceTexture.detachFromGLContext,它提到,“OpenGL ES 纹理对象将因为这个调用而被删除。”

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

我们正在尝试将其与附加方法和 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框架删除了纹理。我的观点是它应该是一个错误,或者应该有理由删除纹理。

【问题讨论】:

    标签: android opengl-es


    【解决方案1】:

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

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

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

    【讨论】:

    • 我添加了更多代码示例来解释用例,请检查。这不是多线程。
    • 难道您不能简单地创建一个新的表面纹理并将其作为当前纹理注入,同时保留旧的纹理直到您需要它吗?或者,如果可能,将新纹理 ID 设置为表面纹理。脱离上下文不是您在您的情况下要寻找的。您在某个点至少需要 2 个纹理,并且它们都需要附加。
    • 不,除了 MediaCodec videoDecoder.configure(..., surface, null, 0); 没有其他方法可以将 SurfaceTexture 传递给 MediaCodec;
    • 是的,但是 Surface 似乎包裹了包裹纹理的 SurfaceTexture。所以至少改变其中一个应该是可能的。比如创建另一个具有相同纹理 id 的 SurfaceTexture。
    【解决方案2】:

    “此调用将删除 OpenGL ES 纹理对象。”

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

    【讨论】:

    • 我添加了代码示例来进一步解释我的问题。我的观点是在我的 GL 中创建的纹理,为什么调用删除它。
    • 因为当你分离surfaceView时支持纹理对象的内存消失了。
    猜你喜欢
    • 1970-01-01
    • 2012-05-02
    • 2012-01-27
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多