title: CVOpenGLESTextureCacheCreateTextureFromImage instead of glReadPixels
body: <p>For 3 full days, I have been trying to improve the performance of my AVAssetWriter which is based on glReadPixels. I have gone through Apple's RosyWriter and Camera Ripple code and Brad Larson's GPUImage but I am still scratching my head. I've also been trying to use the implementations put down in these links:</p>
  
  <p><a href="http://allmybrain.com/2011/12/08/rendering-to-a-texture-with-ios-5-texture-cache-api/" rel="nofollow noreferrer">rendering-to-a-texture-with-ios-5-texture-cache-api</a></p>
  
  <p><a href="https://stackoverflow.com/questions/9550297/faster-alternative-to-glreadpixels-in-iphone-opengl-es-2-0">faster-alternative-to-glreadpixels-in-iphone-opengl-es-2-0</a></p>
  
  <p>...and many more but no matter what I try, I just can't get it to work. Either the video end up not being processed, or it comes out black or I get various errors. I won't go through all of it here.</p>
  
  <p>To simplify my question, I thought I'd focus around just grabbing a snapshot from my onscreen openGL preview FBO. If I can just get one single implementation of this working, I should be able to work out the rest. I tried the implementation from the first link above which looks something like this:</p>
  
  <pre><code>CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [glView context], 
                             NULL, &amp;texCacheRef);
  
  CFDictionaryRef empty = CFDictionaryCreate(kCFAllocatorDefault,
                             NULL,
                             NULL,
                             0,
                             &amp;kCFTypeDictionaryKeyCallBacks,
                             &amp;kCFTypeDictionaryValueCallBacks);
  
  CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                    1,
                                    &amp;kCFTypeDictionaryKeyCallBacks,
                                    &amp;kCFTypeDictionaryValueCallBacks);
  
  CFDictionarySetValue(attrs,
                       kCVPixelBufferIOSurfacePropertiesKey,
                       empty);
  
  CVPixelBufferRef renderTarget = NULL;
  CVPixelBufferCreate(kCFAllocatorDefault,
                      width,
                      height,
                      kCVPixelFormatType_32BGRA,
                      attrs,
                      &amp;renderTarget);
  
  CVOpenGLESTextureRef renderTexture;
  CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
                                                texCacheRef,
                                                renderTarget,
                                                NULL,
                                                GL_TEXTURE_2D,
                                                GL_RGBA,
                                                width,
                                                height,
                                                GL_BGRA,
                                                GL_UNSIGNED_BYTE,
                                                0,
                                                &amp;renderTexture);
  
  CFRelease(attrs);
  CFRelease(empty);
  glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  
  GLuint renderFrameBuffer;
  glGenRenderbuffers(1, &amp;renderFrameBuffer);
  glBindFramebuffer(GL_FRAMEBUFFER, renderFrameBuffer);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                         GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);
  
  //Is this really how I pull pixels off my context?
  CVPixelBufferLockBaseAddress(renderTarget, 0);
  buffer = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);
  CVPixelBufferUnlockBaseAddress(renderTarget, 0);
  </code></pre>
  
  <p>What exactly is supposed to happen here? My buffer ends up being a bunch of zero's so I guess I need to do something additional to pull the pixels from the context? ...or what am I missing?</p>
  
  <p>All I want to achieve is a faster equivalent of what I am using today:</p>
  
  <pre><code>int pixelsCount = w * h;
  buffer = (GLubyte *) malloc(pixelsCount * 4);
  glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  </code></pre>