views:

428

answers:

3

I have recently added some Core Graphics elements to my app and it has slowed dramatically, rendering it just about useless. I am not sure if I am just not using Core Graphics efficiently (how do I make it faster?) or if this problem is inherent in the use of Core Graphics. My code is below, after this description:

There are speech bubbles that move around the screen (in x & y). Each bubble has a corresponding image at the bottom of the screen that also moves in x & y. I am using Core Graphics to draw a triangle from the speech bubbles, terminating at the bottom images. There can be more than 10 of these triangles on the screen at once, all moving. Every 1/10th of a second a timer fires, calculates the positions of everything, and calls setNeedsDisplayon the triangle object I have built.

Code for the triangle object:

- (void)drawRect:(CGRect)rect {
    // Drawing code
 // Drawing code
 CGContextRef ctx = UIGraphicsGetCurrentContext(); //get the graphics context
 CGContextSetRGBStrokeColor(ctx, 1.0, 0, 0, 1); //there are two relevant color states, "Stroke" -- used in Stroke drawing functions and "Fill" - used in fill drawing functions

 //Create an array of points for triangle  
 CGPoint leftTrianglePoint;
 CGPoint rightTrianglePoint;
 rightTrianglePoint = CGPointMake(pointBlob.x, (pointBlob.y + 10.0));
 leftTrianglePoint = CGPointMake(pointBlob.x, (pointBlob.y - 10.0));

 CGPoint triangleArray [] =
 {
  pointGrid,
  rightTrianglePoint,
  leftTrianglePoint,
 pointGrid,};

 //Add lines to the context
 CGContextAddLines( ctx, triangleArray, 4);
 //draw the path

 //color the context - using a function for gray, to matche the saved blobs
 CGContextSetGrayFillColor(ctx, 0.0, .7);

 //Now fill the path 
 CGContextFillPath(ctx);
}

How can I speed this up / build efficiency so my graphics move smoothly again?

+1  A: 

Hate to say it, but drop Core Graphics and do it with OpenGL. OpenGL loves triangles. It will blit thousands per second for you at high speed. Many people think OpenGL is just for 3D stuff but what you are doing in 2D also works extremely well with it.

St3fan
Ugh. Your answer is scary, although it matches some other resources I have found. Thanks for your quick response (even if it isn't the magic pill I wanted)
KLC
It is not that difficult. Google for OpenGL 2D tutorials for the iPhone. There are a bunch of good ones. Sorry, don't have a link handy.
St3fan
A: 

If you want to simplify the OpenGL port, try using an OpenGL library like Cocos2D.

However, it seems to me you could speed up your code substantially by drawing into separate CALayers just once, and simply moving them around (since all of your triangles seem to be fixed in size, just varying in placement). I would highly recommend you look into a Core Graphics book.

Kendall Helmstetter Gelner
So the triangles are not fixed in size - I should have made this more clear - pointGrid, leftTrianglePoint and rightTrianglePoint are always constantly changing. The size and angles are always changing
KLC
The other thing to think about is - do you have ten different UIViews with drawRect going on? If you could have them all draw in one view, that would also be more efficient. It just doesn't seem like that's too much stuff to draw. Also, are you sure your time only fires once every 1/10 a second and not way more often...
Kendall Helmstetter Gelner
A: 

As Kendall suggests, if you just need to move the triangles around, draw them once in a UIView or CALayer and animate the positions and / or rotations of those items. Redrawing the triangles each frame using Core Graphics will be terribly slow, because it will require the recaching of the layer or the view's layer every time you draw.

However, it sounds like you need to animate the actual shape of the triangle. For that, I recommend looking at the newly added (in iPhone OS 3.0 and Snow Leopard) class CAShapeLayer. You can set a path (with fill and stroke) to be drawn by this layer, then smoothly animate it to a different path (with the same number of control points) using a CABasicAnimation. There are examples of this here and here.

Brad Larson
Thanks Brad. This is what I started to do, in an attempt to avoid adding OpenGL to our architecture - now I am having a little difficulty with the CABasicAnimation. See here: http://stackoverflow.com/questions/2233601/cashapelayer-path-dissapears-after-animation-need-it-to-stay-in-the-same-place
KLC