views:

777

answers:

2

Hi everyone

I have a small run speed problem. On load, I generate a CGMutablePath containing at least 1000 points. I want to scroll this path on the screen, so I use this kind of code :

-(void) drawRect:(CGRect)rect {

    /*
    Here, I have a timer calling drawRect 60 times per second.
    There's also code for the scale and currentTime, based on
    an MP3 playback (AVAudioPlayer);
    */

    CGContextRef ref = UIGraphicsGetCurrentContext();   
    CGContextClearRect(ref, [self frame]);

    CGContextSaveGState(ref);
    CGContextTranslateCTM(ref, s.width/2+currentTime, 1);
    CGContextScaleCTM(ref, scale, 1);
    CGContextAddPath(ref, myGraphPath);
    CGContextSetRGBFillColor(ref, .1, .1, .1, .8);
    CGContextFillPath(ref);
    CGContextRestoreGState(ref);
}

The problem is that it's a bit slow, not very much, but as I need to add a whole lot more of graphic code... I was wondering if the device is drawing the whole path (once the scale is applied, the path is about 10.000 pixels wide), or just the part visible on the screen ? What can I do to optimize this ?

A: 

Drawing a 1,000-point or 10,000-point path 60 times per second is really going to slow your application down, if it's possible at all. If the path is static, you really should look at only drawing it once within your UIView, so that it is cached within the UIView's layer, and animating the layer around. It it needs to be animated, you could look at the new CAShapeLayer, which provides the ability to animate a Bezier path simply by applying an animation to its path property.

However, 10,000 pixels will be wider than the maximum texture size on the iPhone (2048 x 2048), so you'll have problems displaying that in any standard view or layer and may need to either break it up into smaller chunks or use a CATiledLayer to render it to the screen.

Brad Larson
The path's points coordinates are static, but I need to scroll the path along x axis depending on the scale factor. If I draw the shape on a layer right after generation then scale it, I'm having a lot of blur (by the way, max scaling factor is around 1000). If I scale the path before drawing to the layer, I only get s.width worth of pixels drawn. And creating a layer of this size won't give me a lot of improvements :/Gonna check CAShapeLayer, I did not hear of it yet.My last bet is trying to use openGL, but with this much polygon, not sure it will really be useful.
melka
+1  A: 

After trying a lot of things (like dividing my huge 1000 points path into smaller 10 points paths etc...), I've ported everything to openGL, using simple vertex arrays. It took me about 4 hours to port everything (even scaling the path, scrolling it, etc...) and now, I get a full 60fps animation all the time, when I was having only 22fps average with peaks at 28 when using the CoreGraphics.

melka
I'm glad you figured it out, but it's worth noting that there is a lot that you can do with CG to optimize it to work just as well, if not possibly better.
Sneakyness