2
votes

So suppose you had to draw 100,000 lines onto a UIView that's maybe 3,000 x 3,000 in size. It sits inside of a UIScrollView, by the way. I did this the regular way with Quartz-2D, writing a regular drawRect, and it takes way too long (a couple of minutes on the latest hardware). I have done some research and there seem to be 2 faster methods:

1) Use Quartz-2D, but draw to an offscreen buffer, then load onto the UIView

2) Use OpenGL ES, draw the lines, print to a UIImage, and load onto the UIView

Do you have any sense of the difference in performance between the original and these 2 methods? Do you have any sample code I could use to accomplish either (1) or (2)? It seems like a straightforward task, but I'm a bit lost.

For option (1), here is my attempt from what I could find online:

- (CGContextRef) createOffscreenContext: (CGSize) size  {
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 
  size.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
  CGColorSpaceRelease(colorSpace);
  CGContextTranslateCTM(context, 0, size.height);
  CGContextScaleCTM(context, 1.0, -1.0);
  return context;
}


- (void)drawRect:(CGRect) rect {
  self.backgroundColor = [UIColor clearColor];
  CGSize size = self.frame.size;
  drawingContext = [self createOffscreenContext: size];
  UIGraphicsPushContext(drawingContext);
  //draw stuff here
  CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext); 
  UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage];
  UIGraphicsPopContext();
  CGImageRelease(cgImage);
  [uiImage drawInRect: rect];
  [uiImage release];
}

Thoughts? Any help and/or advice is appreciated.


UPDATE: I implemented the 1st solution and it is in fact a ton faster. However it makes the program pretty unstable, and sometimes calling setNeedsDisplay crashes it. Will try to work on an OpenGL solution next.

1
OpenGL can be as fast as you are looking for. However if you aren't used to it the learning curve can be pretty steep.user349819
If it's much faster, I may have to venture down that path. If you've got any sample code links that mirror my request closely (i.e. drawing openGL primitives and sending to a UIView as a UIImage), would be greatly appreciated. Otherwise it looks like I got quite a lot of reading to do.Roman V
The code I have was taken from the project template for an OpenGL ES application. It was really just an aggressive expansion of what was there. (Understanding what I could remove took quite a bit of time though). I created a new one just now, and the code i modified was in the drawFrame method of the TestProjectViewController that got created (my Project was name TestProject). You said specifically that you wanted to save the buffer and send it to an UIImageView. There are several functions for rendering a layer in a context, and you'd supply the GL Layer context to those.user349819

1 Answers

0
votes

This blog post my Matt Gallagher might interest you. He's talking about QuartzGL vs. "regular" drawing though (so not exactly what you're after), but I think you might be in a somewhat similar situation. Basically, it boils down to "it doesn't matter" / "you can't tell".

In the end, I guess you should try to implement both options and see which one performs better.