Ios GPU等待纹理

Ios GPU等待纹理,ios,opengl-es,opengl-es-2.0,Ios,Opengl Es,Opengl Es 2.0,我正在使用着色器处理和渲染视频帧。所以我需要在每次绘制调用之前更新纹理。一切正常,但当我运行OpenGL profiler时,它向我显示了以下警告: 您的应用程序试图更新到当前正在使用的纹理 用于渲染。这会导致CPU等待GPU完成 翻译解决此问题的一种方法是使用双精度或环 缓冲方法,以便应用程序不会更新纹理 用于作为图形调用的一部分。另一种可能性是 以允许GPU完成使用的方式重新排序操作 更新前的纹理 我找到了这个。如果我理解正确,建议使用第二个纹理作为附加缓冲区,并与第一个纹理互换使用。所以我

我正在使用着色器处理和渲染视频帧。所以我需要在每次绘制调用之前更新纹理。一切正常,但当我运行OpenGL profiler时,它向我显示了以下警告:

您的应用程序试图更新到当前正在使用的纹理 用于渲染。这会导致CPU等待GPU完成 翻译解决此问题的一种方法是使用双精度或环 缓冲方法,以便应用程序不会更新纹理 用于作为图形调用的一部分。另一种可能性是 以允许GPU完成使用的方式重新排序操作 更新前的纹理

我找到了这个。如果我理解正确,建议使用第二个纹理作为附加缓冲区,并与第一个纹理互换使用。所以我更新了我的代码:

//use current texture
glBindTexture(GL_TEXTURE_2D, current_texture);

//update texture data
glTexImage2D(...);

//use the next texture and bind it
current_texture = (current_texture + 1)%2;
glBindTexture(GL_TEXTURE_2D, current_texture);

[and then draw smth using this texture];
工作正常,但我仍然收到来自探查器的相同警告。即使我使用3、4和更多的附加纹理,也无济于事

正如我后来发现的,这个问题可以通过使用
像素缓冲区对象来解决,但似乎OpenGL ES 2.0不支持它们

我错过了什么

我错过了什么

OpenGL是一个异步API。调用返回的时间可能比执行实际渲染的时间早得多。让我们看看这个简化的绘图循环:

for(i=0; ; i++) {
    glBindTexture(…, tex[i % 2]);
    glTexSubImage2D(…);

    glBindTexture(…, tex[(i + 1) % 2]);
    draw_image();
}
现在关键是,在循环迭代i增量之后,这意味着我们可以将此代码重写为

glBindTexture(…, tex[0]);
glTexSubImage2D(…);

for(i=1; ; i++) {
    glBindTexture(…, tex[i % 2]);
    draw_image();
    glTexSubImage2D(…);
}

我想现在已经很清楚发生了什么。

@Boris:不,我的意思是,实际上你的动画循环已经在绘图调用后立即发出纹理更新。后一个循环是,您实际上已经在程序中拥有了什么。你问问题的原因是什么。至于如何解决这个问题,有各种各样的方法,最简单的方法就是不去关心它,因为当你在使用纹理时重新定义纹理的数据时,OpenGL将有效地执行双重缓冲。除非你真的使用PBO,否则如果只是处理纹理id,性能提升的空间就很小。但实际上,除了PBO和id处理之外,还有什么可能的解决方案呢?@Boris:最重要的事情是在绘制之前对texID[(i+1)%n]执行所有纹理更新(双缓冲)。通过这种方式,纹理数据上传和绘制并行地发生在不同的纹理对象中。@Boris-如果您试图更新仍在用于渲染的纹理,您可能试图以比屏幕更新更快的速度渲染,或者渲染运行时间超过1/30秒(摄像机帧速率)。前者似乎不适合视频源,因此对于后者,您可能需要在某个点删除帧。你可以看看我在这里做了什么:在iOS上高效地处理各种视频源。特别是,请看GPUImageVideoCamera类。作为旁注,永远不要使用
glTexImage2D
更新纹理数据,只用于初始化/分配(随着
glTexStorage2D
的出现,
glTexImage2D
最终完全过时)。