Unable to Release Quartz 2D and Core Text created Images
Asked Answered
G

1

1

I am having a problem deleting my OpenGL ES textures are created via Quartz 2D and Core Text as shown below :

- (void)drawText:(CGContextRef)contextP startX:(float)x startY:(float)
y withText:(NSString *)standString
{
    CGContextTranslateCTM(contextP, 0, (bottom-top)*2);
    CGContextScaleCTM(contextP, 1.0, -1.0);

    CGRect frameText = CGRectMake(1, 0, (right-left)*2, (bottom-top)*2);

    NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:standString];
    [attrString addAttribute:NSFontAttributeName
                       value:[UIFont fontWithName:@"Helvetica-Bold" size:12.0]
                      range:NSMakeRange(0, attrString.length)];

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attrString));
    struct CGPath * p = CGPathCreateMutable();
    CGPathAddRect(p, NULL, frameText);
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,0), p, NULL);

    CTFrameDraw(frame, contextP);

    CFRelease(framesetter);
    CFRelease(frame);
    CGPathRelease(p);

    standString = nil;
    attrString = nil;

}

- (UIImage *)drawTexture : (NSArray *)verticesPassed : (UIColor *)statusColour : (NSString *)standString {

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();

    CGRect shp = [self boundFromFrame:verticesPassed];

    CGContextRef conPattern = CGBitmapContextCreate(NULL,
                                                    shp.size.width*sceneScalar,
                                                    shp.size.height*sceneScalar,
                                                    8,
                                                    0,
                                                    rgbColorSpace,
                                                    (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);

    CGColorSpaceRelease(rgbColorSpace);

    CGContextSetLineWidth(conPattern, 2);
    CGContextSetStrokeColorWithColor(conPattern, [UIColor blackColor].CGColor);

    Line * start = [sortedVertices objectAtIndex:0];
    StandPoint * startPoint = start.origin;

    CGContextMoveToPoint(conPattern, ([startPoint.x floatValue]-shp.origin.x)*sceneScalar , ([startPoint.y floatValue]-shp.origin.y)*sceneScalar);
    for (Line * vertice in sortedVertices) {
        StandPoint * standPoint = vertice.origin;
        CGContextAddLineToPoint(conPattern, ([standPoint.x floatValue]-shp.origin.x)*sceneScalar, ([standPoint.y floatValue]-shp.origin.y)*sceneScalar);
    }

    CGContextAddLineToPoint(conPattern, ([startPoint.x floatValue]-shp.origin.x)*sceneScalar , ([startPoint.y floatValue]-shp.origin.y)*sceneScalar);

    CGContextSetFillColorWithColor(conPattern, statusColour.CGColor);

    CGContextDrawPath(conPattern, kCGPathFillStroke);

    [self drawText:conPattern startX:0 startY:20 withText:standString];

    CGImageRef cgImage = CGBitmapContextCreateImage(conPattern);

    UIImage *imgPattern = [[UIImage alloc]initWithCGImage:cgImage];
    //UIImageWriteToSavedPhotosAlbum(imgPattern, nil, nil, nil); Uncomment if you need to view textures (photo album).

    self.standHeight = (top - bottom)*sceneScalar;
    self.standWidth = (right - left)*sceneScalar;
    self.xOffset = [startPoint.x floatValue]*sceneScalar;
    self.yOffset = (-[startPoint.y floatValue]*sceneScalar)+standHeight;

    CFRelease(cgImage);
    CGContextRelease(conPattern);

    return imgPattern;

}

However when I try to delete the textures as follows in viewWillDisappear, I can see (in instruments) that the memory is not released :

for (PolygonObject * stand in standArray) {
            GLuint name = stand.textureInfo.name;
            // delete texture from opengl
            glDeleteTextures(1, &name);
            // set texture info to nil
            stand.textureInfo = nil;
        }

I think that something is being retained in the texture somewhere in the code above. Can anyone suggest where ?

Gangrel answered 10/12, 2013 at 9:36 Comment(2)
check yours CTFramesetterRef releasing with this answerTeutonic
looks like issue not in OpenGL, try just create image and delete then, without creating texture. And replace on -[UIImage imageWithCGImage:]Teutonic
D
0

As far as I can see, there's no memory leak in your code if you're using ARC. However, the UIImage returned from drawTexture may be retained by some other objects or by the auto release pool.

To check if this is the case, you may subclass UIImage, say UIDebugImage, override the dealloc method and set a breakpoint there to see if it's called.

Daumier answered 11/12, 2013 at 2:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.