将OpenGL帧缓冲区绘制到UIImage时出现内存泄漏

时间:2014-03-18 04:41:41

标签: ios memory-management opengl-es opengl-es-2.0

我正在使用OpenGL在屏幕上绘图,并希望将屏幕的一部分绘制到UIImage。这是代码我拼凑在一起查看可行的示例,但每次调用时都会产生内存泄漏。我在设备上测试了这个,泄漏仍然存在并最终导致崩溃。返回的UIImage保存为实例变量,稍后再次设置为nil。什么导致内存泄漏?

- (UIImage *)renderToImageWithContentFrame:(CGRect)contentFrame
                               exportFrame:(CGRect)exportFrame
                                     scale:(float)scale {

    float screenWidth = contentFrame.size.width * scale;
    float screenHeight = contentFrame.size.height * scale;

    GLuint framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    GLuint renderTex;
    glGenTextures(1, &renderTex);
    glBindTexture(GL_TEXTURE_2D, renderTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenWidth, screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTex, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glViewport(0, 0, screenWidth, screenHeight);

    [self _renderImageGL];

    // grabbing image from FBO

    NSInteger dataLength = screenWidth * screenHeight * 4;
    GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));

    glPixelStorei(GL_PACK_ALIGNMENT, 4);
    glReadPixels(0, 0, screenWidth, screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);

    glDeleteFramebuffers(1, &framebuffer);

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGImageRef iref = CGImageCreate(screenWidth, screenHeight, 8, 32, screenWidth * 4, colorspace,
                                    kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
                                    ref, NULL, true, kCGRenderingIntentDefault);

    float x = (exportFrame.origin.x - contentFrame.origin.x) * scale;
    float y = (exportFrame.origin.y - contentFrame.origin.y) * scale;
    float width = exportFrame.size.width * scale;
    float height = exportFrame.size.height * scale;
    CGImageRef cropped = CGImageCreateWithImageInRect(iref, (CGRect){x, y, width, height});

    UIGraphicsBeginImageContext((CGSize){width, height});
    CGContextRef cgcontext = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
    CGContextDrawImage(cgcontext, (CGRect){0, 0, width, height}, cropped);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    free(data);
    CFRelease(ref);
    CFRelease(colorspace);
    CGImageRelease(iref);
    CGImageRelease(cropped);

    return image;

}

1 个答案:

答案 0 :(得分:3)

变量renderTex未被释放(通过调用glDeleteTextures(1, &renderTex);)。我的猜测是,Instruments可能不知道OpenGL分配的内存,因为该内存可能驻留在显卡上,可能更难(或不可能)跟踪。 (虽然这主要是猜测。)