Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Multithreaded Drawing by Eric Lanz

Multithreaded Drawing by Eric Lanz

Eric discusses multithreaded drawing with Core Graphics at CocoaHeads August in Raleigh

Triangle Cocoa

August 23, 2012
Tweet

More Decks by Triangle Cocoa

Other Decks in Programming

Transcript

  1. What you should do • Get an artist to make

    all your graphics up front • Use tools like GraphicsMagick, OptiPng and PVRTC (OpenGL) • Use built in cache mechanisms • UIKit -> Core Animation -> OpenGL
  2. What if you can’t • User defined image data at

    run-time • Continuous animation responding to user interaction • Too much image data to pre-process and ship with the app
  3. Know when to draw View Controllers Drawables Drawables Drawables Drawables

    User Input • User triggers redraw • View controllers determine layout • Don’t directly call draw on a drawable
  4. Synchronous Data API View Controllers Drawables Drawables Drawables Drawables Data

    Controller User Input Core Data No Local Copy? Return a fake object while you wait for the API
  5. Asynchronous Draw API View Controllers Drawables Drawables Drawables Drawables Data

    Controller User Input Core Data Targeted NSNotifications: @”ObjectUpdate_XYZ”
  6. Drawing Pipeline Render Controller Drawable • Drawable asks to be

    drawn using some template • Entire operation contained in a block
  7. Dispatch Serial Queue Draw Controller Drawable Dispatch_Serial Template Core Graphics

    Cache 2 Create a serial dispatch queue, this will run one task at a time on a worker thread.
  8. Dispatch Global Queue Draw Controller Drawable Dispatch_Global Template Core Graphics

    Cache 3 Use the Global dispatch queue, this runs tasks concurrently on multiple worker threads.
  9. All Together Now Draw Controller Drawable Dispatch_Global Template Core Graphics

    Cache 3 Dispatch_Serial Template Core Graphics Cache 2 Direct Template Core Graphics Cache 1
  10. Dispatch Serial Queue UIGraphicsPushContext(c); [[UIColor blackColor] setFill]; [@"Sample" drawInRect:CGRectMake(0, 4,

    width, height) withFont:[UIFont fontWithName:@"Helvetica" size:fontSize] lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentCenter]; UIGraphicsPopContext(); CGContextRelease(c); CGColorSpaceRelease(genericRGBColorspace); GLubyte *imageData = (GLubyte *) calloc(1, width * height * 4); CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB(); CGContextRef c = CGBitmapContextCreate(imageData, width, height, 8, width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
  11. Dispatch Global CGContextScaleCTM(c, 1.0, -1.0); CGContextTranslateCTM(c, 0, -height); CGMutablePathRef circlePath

    = CGPathCreateMutable(); CGPathAddEllipseInRect( circlePath , NULL , CGRectMake(1, 1, width-2, height-2) ); CGContextAddPath(c, circlePath); CGContextClip(c); UIImage * personImage = [UIImage imageWithContentsOfFile:path]; CGContextDrawImage(c, CGRectMake(0, 0, width, height), personImage.CGImage); CGContextRelease(c); CGColorSpaceRelease(genericRGBColorspace); GLubyte *imageData = (GLubyte *) calloc(1, width * height * 4); CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB(); CGContextRef c = CGBitmapContextCreate(imageData, width, height, 8, width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
  12. Final Thoughts • No architecture is perfect • Maintain balance

    • Make it easy to tweak • Don’t get lost in the details