我正在重构基于iOS OpenGL的渲染管道。我的管道由许多渲染步骤组成,因此我需要大量的中间纹理来渲染和读取。这些纹理有各种类型(无符号字节和半浮点),并且可能拥有不同数量的通道。
为了节省内存和分配工作,我回收了管道中先前步骤使用的不再需要的纹理。在我之前的实现中,我是自己完成的。
在我的新实现中,我想使用核心视频框架提供的API;特别是因为它们提供了从CPU到纹理存储器的更快的访问。我知道CVOpenGLESTextureCache
允许我用CVPixelBuffer
创建OpenGL纹理,这些纹理可以直接创建或使用CVPixelBufferPool
创建。然而,我找不到任何文件来描述他们是如何真正工作的,以及他们是如何一起玩的。
以下是我想知道的事情:
- 为了从
CVOpenGLESTextureCache
获得纹理,我总是需要提供一个像素缓冲区。如果我无论如何都需要提供内存,而无法检索旧的、未使用的纹理,为什么它被称为"缓存" CVOpenGLESTextureCacheFlush
功能"刷新当前未使用的资源"。缓存如何知道资源是否"未使用"?当我释放相应的CVOpenGLESTextureRef
时,纹理是否返回到缓存?同样的问题也适用于CVPixelBufferPool
- 我是否能够在一个纹理缓存中维护具有不同属性(类型、#通道…)的纹理?它知道纹理是否可以重复使用或需要根据我的请求创建吗
CVPixelBufferPool
似乎只能管理相同大小和类型的缓冲区。这意味着我需要为我使用的每个纹理配置创建一个专用池,对吗
如果至少其中一些问题能够得到澄清,我会非常高兴。
是的,实际上你什么都找不到。我看了又看,简单的答案是,你只需要测试一下,看看实现是如何工作的。你可以在opengl_write_texture_cache上找到我关于这个主题的博客文章以及示例代码。基本上,它的工作方式似乎是纹理缓存对象"保持"缓冲区(池中)和OpenGL纹理之间的关联,OpenGL纹理在执行三角形渲染时绑定。结果是,在OpenGL完成后,池才应该返回相同的缓冲区。在某种竞争条件的奇怪情况下,池可能会增加1个缓冲区,以解决缓冲区过长的问题。纹理缓存API真正好的地方在于,只需要向数据缓冲区写入一次,而不是调用像glTexImage2D()这样的API将数据"上传"到图形卡。