glReadPixel sgx error: corrupt command buffer iOS 4.0

Hi everyone,

I am working with OpenGL ES 2.0 and I am trying to take a snapshot of a view with the following code:


- (UIImage *)eaglImageCapture {
    UIImage *image = nil;
    
    NSLog(@"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    NSLog(@"~~~~~~~~~~~~ Image Capture ~~~~~~~~~~~~~~~");
    NSLog(@"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");    

    
    // We synchronize this call to avoid glReadPixels from being called concurrently
    @synchronized(self) {    
        
        glBindFramebuffer(GL_FRAMEBUFFER, _viewFramebuffer); 
        glBindRenderbuffer(GL_RENDERBUFFER, _viewRenderbuffer);
         
        int scale = self.contentScaleFactor;
        
        const int w = self.frame.size.width;
        const int h = self.frame.size.height;
        const NSInteger myDataLength = w * h * 4 * scale * scale;

        // allocate array and read pixels into it.
        GLubyte *buffer = (GLubyte *)malloc(myDataLength);
        glReadPixels(0, 0, w*scale, h*scale, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

        // gl renders "upside down" so swap top to bottom into new array.
        GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
        for(int y = 0; y < h*scale; y++) {
            memcpy( buffer2 + (h*scale - 1 - y) * w * 4 * scale, buffer + (y * 4 * w * scale), w * 4 * scale );
        }
        free(buffer); // work with the flipped buffer, so get rid of the original one.
        
        // make data provider with data.
        CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);

        // prep the ingredients
        int bitsPerComponent = 8;
        int bitsPerPixel = 32;
        int bytesPerRow = 4 * w * scale;
        CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
        CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
        CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

        // make the cgimage
        CGImageRef imageRef = CGImageCreate(w*scale, h*scale, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

        // then make the uiimage from that
        image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
        
        CGImageRelease(imageRef);
        CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorSpaceRef);
        //free(buffer2);
    }
    return image;
}

This code takes the snapshot correctly but at some point in the code, an error: “sgx error: corrupt command buffer” happens at the glReadPixel call.

The idea here is that I use only one EAGLContext for all my views and I switch the frameBuffer and the colorBuffer when I switch view.

This error happens on a iPad 2 with iOS 4.X but doesn’t happen on a iPad 3 with iOS 5.X.

Did any of you encounter such a problem?

Thanks!

Ok, I fixed the problem. Previously, I was using a “global” context that I init in the viewController and that every view could use. I changed this to share groups and it seems to fix this specific issue.

That being said, I still don’t know what the cause of this problem is. From what I read, it could be related to multi-threading. If another thread tried to use the OpenGL context at the same time, maybe this problem could happen…

I’m really not sure as to what the problem was so if anyone has some better explanation, please post them!

Thanks!

Beginning with Android 4.0, there is now a better way to do this. Use the new TextureView class and the getBitmap() method to capture the rendered OpenGL ES framebuffer.

Regards, Clay

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.