4
votes

I have the following code below, It's basically one slice of a PieChart with many of these slices. Each slice is drawn in it's own CALayer and is added to a custom views layer using addSublayer:.

The problem is that I'm updating the pie chart dynamically as the user drags their finger (They can edit the pie chart values by dragging). It works well, but there is very noticeable lag when re-drawing these pie 'slices'. I've look at the iOS Profiling tool, and it shows that >50% of the time is in CGContextDrawPath() as it has to redraw the pie slice each time the user moves a certain number of degrees.

My question is, What can I do to improve the speed of this code? Is there something I'm missing?

Also as a side note, this code is running well on an iPad 2 (acceptable levels of fps) but on iPad 3 it runs dreadful, from my estimations it is 2x slower. Can anyone explain this? Is it just the retina display?

-(void)drawInContext:(CGContextRef)ctx {

    // Create the path
    CGRect insetBounds = CGRectInset(self.bounds, self.strokeWidth, self.strokeWidth);
    CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
    CGFloat radius = MIN(insetBounds.size.width/2, insetBounds.size.height/2);

    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, center.x, center.y);

    CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));
    CGContextAddLineToPoint(ctx, p1.x, p1.y);

    int clockwise = self.startAngle > self.endAngle;
    CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);

    CGContextClosePath(ctx);

    // Color it
    CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
    CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
    CGContextSetLineWidth(ctx, self.strokeWidth);

    CGContextDrawPath(ctx, kCGPathFillStroke);
}
1

1 Answers

1
votes

Drawing graphics to the iPad 3 Retina display is slower than drawing to the iPad 2 non-Retina.

I recall Apple originally claiming that iPad 3 is "4x faster graphics than iPad 2". Which doesn't seem to be the case. If it were then rendering Retina (which is 4x more pixels) to the screen should be at least the same speed as a non-retina iPad 2.

The same issue happened when Apple released the iPhone 4. The iPhone 4 was actually slower than both the 3GS and the 3G.

CoreGraphics slower on iPhone4 than on 3G/3GS

To increase the fps, you need decrease the number of pixels the drawRect needs to draw to. I suggest drawing your CoreGraphics related stuff a half resolution context. Then take that context as a bitmap and scale it up to full resolution. But only while the user is dragging.