I’m using openGL ES to display a YUV420 video on a UIView. I’m following this thread (CADisplayLink OpenGL rendering breaks UIScrollView behaviour) to achieve a 30fps. Everything seems to be okay. The playback is smooth. Now thought I running my app through Instruments and I get few warnings:
- Logical Buffer Load – Summary => slow framebuffer load
- GPU Wait on Texture – Summary => CPU wait for GPU on Texture Upload
- Texture Upload Non-Optimal GPU Utilization – Summary => Mid-frame texture upload
In my callback I do the following:
[EAGLContext setCurrentContext:_context];
glClear(GL_COLOR_BUFFER_BIT);
// load the color components into OpenGL
glBindTexture(GL_TEXTURE_2D, _textures[TEXTURE_Y]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frameWidth, frameHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (UInt8*)yuvFrame.luma.bytes);
glBindTexture(GL_TEXTURE_2D, _textures[TEXTURE_U]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frameWidth/2, frameHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (UInt8*)yuvFrame.chromaB.bytes);
glBindTexture(GL_TEXTURE_2D, _textures[TEXTURE_V]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frameWidth/2, frameHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (UInt8*)yuvFrame.chromaR.bytes);
// draw
glDrawElements(GL_TRIANGLE_STRIP, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_SHORT, 0);
[_context presentRenderbuffer:GL_RENDERBUFFER];
And prior to this call, in the init method of the UIView, I generate the textures and set some params, like this:
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glGenTextures(NUM_TEXTURES, _textures);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textures[TEXTURE_Y]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(_uniformSamplers[SAMPLER_Y], TEXTURE_Y);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _textures[TEXTURE_U]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(_uniformSamplers[SAMPLER_U], TEXTURE_U);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, _textures[TEXTURE_V]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(_uniformSamplers[SAMPLER_V], TEXTURE_V);
Although, like I said the playback seems to perform pretty well, I would like to try to fix those warnings. I tried several things without success. The only way I was able to remove them was by calling glGenTextures(NUM_TEXTURES, _textures)/glDeleteTextures(NUM_TEXTURES, _textures) at the beginning/ending of my callback but I don’t think that is the right way.
Does anyone have any suggestions?
The first warning on your list can sometimes be a false positive in Instruments, so it may not be a real issue at all. However, it may indicate that you haven’t properly cleared out the previous state of the framebuffer, so you could check to make sure that you don’t also have a depth buffer that needs to be cleared in addition to your
GL_COLOR_BUFFER_BIT.The other two are simply telling you that it’s taking a while to upload your image data via
glTexImage2D()on each frame. If you’re doing this on iOS 5.0, you could look at using texture caches to speed this upload process (CVOpenGLESTextureCacheCreate()and friends). They might help you squeeze out a little extra performance.