title: Optimizing Quartz2D performance on touch events
body: <p>What I am doing is on every touch event I am creating an image from unsigned char *. Here is my function</p>
  
  <pre><code>-(void)paint:(ImageWarper::WarpedImage *)warpedImg isCircleRequired:(bool)doDrawCircle atPoint:(CGPoint)pt{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  if(!mWarper) 
      return;
  unsigned char *pixelData = warpedImg-&gt;Image.Data;
  int imageHeight  = warpedImg-&gt;Image.Height;
  int scanWidth = warpedImg-&gt;Image.ScanWidth;
  int imageWidth = warpedImg-&gt;Image.Width;
  CGDataProviderRef provider = CGDataProviderCreateWithData(
                                                            NULL, 
                                                            pixelData, 
                                                            imageHeight * scanWidth, 
                                                            (CGDataProviderReleaseDataCallback)&amp;freeRawData); 
  CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
  CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
  CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
  int bytesPerPixel = warpedImg-&gt;Image.Bpp;
  CGImageRef imageRef = CGImageCreate(imageWidth,
                                      imageHeight,
                                      BitsPerComponent,
                                      bytesPerPixel * BitsPerComponent,
                                      scanWidth,
                                      colorSpaceRef,
                                      bitmapInfo,
                                      provider,
                                      NULL,
                                      YES,
                                      renderingIntent);
  if(!imageRef)
      return;
  
  UIImage *uiImage = [UIImage imageWithCGImage:imageRef];
  imgScrollView.imgView.image = uiImage;
  UIGraphicsBeginImageContext(mbmpImage.size); 
  CGContextRef ctx = UIGraphicsGetCurrentContext();
  CGContextSetLineWidth(ctx, 1.5);
  CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
  
  [mbmpImage drawInRect:CGRectMake(0, 0, mbmpImage.size.width, mbmpImage.size.height)];
  
  [uiImage drawInRect:CGRectMake(warpedImg-&gt;Position.X, warpedImg-&gt;Position.Y, warpedImg-&gt;Image.Width, warpedImg-&gt;Image.Height)];         
  
  if(doDrawCircle){
      [mbmpImage release];
      mbmpImage = [UIGraphicsGetImageFromCurrentImageContext() retain];       
  
      CGContextStrokeEllipseInRect(ctx,CGRectMake(pt.x - mRadius, pt.y - mRadius, mRadius*2, mRadius*2));
  }
  else{
      [mbmpImage release];
      mbmpImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
  }
  UIImage * resultingImage = [UIGraphicsGetImageFromCurrentImageContext() retain];    
  
  UIGraphicsEndImageContext();
  imgScrollView.imgView.image =  resultingImage ;
  
  if(!doDrawCircle)   {   
      [mbmpImage release];
      mbmpImage = [resultingImage retain];
  
  }
  if(doDrawCircle){
      CGPoint pt2 = [self.view convertPoint:pt fromView:imgScrollView];
      imgPreview.hidden = NO;
      [self addText:mbmpImage text: @"+" atPoint:pt atRect:(warpedImg-&gt;Position.X, warpedImg-&gt;Position.Y, warpedImg-&gt;Image.Width, warpedImg-&gt;Image.Height)];
  }
  else{
      [popoverController dismissPopoverAnimated:YES];
  }
  [resultingImage release];
  CGColorSpaceRelease(colorSpaceRef);
  CGDataProviderRelease(provider);
  CGImageRelease(imageRef);
  
  [pool drain];
   }
  </code></pre>
  
  <p>This Function is called as follows: </p>
  
  <pre><code>NSMutableDictionary *d = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSValue valueWithPointer:wp1],@"warper", @"YES",@"isCircleRequired",
                                    [NSValue valueWithCGPoint:location],@"point",nil];
  [self performSelector:@selector(paintDic:) withObject:d];
  [d release];
  wp1 = nil;
  
  -(void)paintDic:(NSMutableDictionary *)dictionary{
  ImageWarper::WarpedImage *wp1 =  (ImageWarper::WarpedImage *)[[dictionary objectForKey:@"warper"] pointerValue];
  [self paint:wp1
      isCircleRequired:[dictionary objectForKey:@"isCircleRequired"] 
      atPoint:[[dictionary objectForKey:@"point"] CGPointValue]];
  }
  </code></pre>
  
  <p>I am using following callback function to release data. </p>
  
  <pre><code>void freeRawData(void *info, const void *data, size_t size) {
  data = nil;
  }
  </code></pre>
  
  <p>Can any one help me how do I optimize the speed of this. It is working fine on new iphone but not older iphones. </p>
  
  <p><strong>I am calling paint in perform selector so that I dont get hold of execution while it completes its creation of images. 
   Also any help to create images directly from raw data i.e. unsigned char * will be appreciated.</strong></p>