title: UIView with drawRect/update image performance issue on Retina displays
body: <p><strong>The problem in short:</strong></p>
  
  <p>LooksLike <code>drawRect</code> itself (even empty) leads to a significant performance bottleneck depending on device's resolution - the bigger screen is the worse things are.
  Is there a way to speed up redrawing of view's content?</p>
  
  <p><strong>In more details:</strong></p>
  
  <p>I'm creating a small drawing app on iOS - user moves his finger over a display to draw a line.</p>
  
  <p>The idea behind this is quite simple - while user moves his finger <code>touchesMoved</code> accumulates  the changes into offscreen buffer image and invalidates the view to merge the offscreen buffer with the view's content.</p>
  
  <p>The simple code snippet may look like this:</p>
  
  <pre><code>@interface CanvasView : UIView
  ...
  end;
  
  
  @implementation CanvasView{
      UIImage *canvasContentImage;
      UIImage *bufferImage
      CGContextRef drawingContext;
  }
  
  - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
      // prepare drawing to start
      UIGraphicsBeginImageContext(canvasSize);
      drawingContext = UIGraphicsGetCurrentContext();
      ...
  
  }
  
  -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
      // draw to bufferImage
      CGContextMoveToPoint(drawingContext, prevPoint.x, prevPoint.y);
      CGContextAddLineToPoint(drawingContext, point.x, point.y);
      CGContextStrokePath(drawingContext);
      ...
      [self setNeedDisplay];
  }
  
  -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
      //finish drawing
      UIGraphicsEndImageContext();
      //merge canvasContentImage with bufferImage
      ...
  }
  
  -(void)drawRect:(CGRect)rect{
      // draw bufferImage - merge it with current view's content
  
      CGContextRef context = UIGraphicsGetCurrentContext();
      CGContextDrawImage(context, self.bounds, canvasContentImage.CGImage);
      CGContextDrawImage(context, imageRect, bufferImage.CGImage);
      ...
  
  }
  </code></pre>
  
  <p>I've also implemented a small helper class to calculate fps rate.</p>
  
  <p>So the approach above works rather good on non-retina screens producing nearly 60fps. However fps rate dramatically drops on retina-screens. For example on iPad Retina it is about 15-20 fps which is too slow.</p>
  
  <p>The first obvious reason I thought is that <code>setNeedsDisplay</code> causes to redraw a full screen which is a big wast of resources. So I moved to <code>setNeedsDisplayInRect</code> to update only a dirty region. Surprisingly it didn't change anything regarding to performance (at lest nothing noticeable according to measurements and visually).</p>
  
  <p>So I've started to try different approaches to figure out the bottleneck. When I've commented out all the drawing logic the fps rate still stayed at 15-20 - looks like the problem lies outside of drawing logic.
  Finally when I've fully commented out the <code>drawRect</code> method the fps rises to 60. Not that I removed only the implementation but even a declaration. Not sure of my terminology so here is the results:</p>
  
  <pre><code>//    -(void)drawRect:(CGRect)rect{
  //        // draw bufferImage - merge it with current view's content
  //        ...
  //    }
  </code></pre>
  
  <p>What is more interesting when I moved all the drawing code from <code>drawRect</code> method to <code>touchMoved</code> method it doesn't impact the performance, however the same amount of drawing/processing logic still remains comparing to the version with <code>drawRect</code> method - even updating the entire view every time still gives me 60fps. 
  One problem is that without drawRect I'm not able to visualize that changes.</p>
  
  <p>So I've came to what pregenerated <code>drawRect</code> method warns about:</p>
  
  <blockquote>
    <p>"Only override drawRect: if you perform custom drawing. An empty
    implementation adversely affects performance during animation."</p>
  </blockquote>
  
  <p>My guess is that the system creates and destroys graphics context every time custom <code>drawRect</code> is triggered leading to "dversely affects performance"</p>
  
  <p><strong>So the questions are:</strong></p>
  
  <ol>
  <li><p>Is there any way to speed up <code>drawRect</code> calls, like make the system reuse resources from call to call of <code>drawRect</code> or something?</p></li>
  <li><p>If this is a dead end, what other approaches available to update view's content? Moving to OpenGL is not an option at the moment as there are a lot of code/logic already implemented and it will take a lot of effort to port it.</p></li>
  </ol>
  
  <p>I'll be glad to provide any additional information needed.
  And Thanks in advance for any suggestions!</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>After some more investigation and experiments I've came to using UIImageView and it's image property to update view's content dynamically. It gave a small performance improvements (the drawing is more stable at 19-22 fps). However it is still far from target 50-60fps.
  One think I've noticed is that updating only a dirty part of offscreen buffer image really makes sense - without forcing the view's content update, pure logic of redrawing offscreen buffer gives around 60 fps.
  But once I'm trying to attach the updated image to UIImageView.image property to update it's content the fps drops to mentioned 19-22. This is reasonable as assigning the property forces whole image to be redrawn on view's side.</p>
  
  <p>So the question still remains - <strong>is there any way to updated only a specified portion of view's (UIImageView's) displaying content?</strong></p>