iPhone 4 can be a lot slower when it comes to handling CoreGraphics.
One possible idea for your business. When the user scrolls through rather than displaying the full resolution, draw CoreGraphics-related material in a half-resolution context. Then take this context as a bitmap and enlarge it to full resolution. This will only be for iPhone4 and you will lose good quality with a higher resolution, but only while scrolling the user.
Here is the code I wrote to test between different devices.
My results when displaying a view in full screen.
- 3G, 9 FPS
- 3GS, 16 FPS
- i4, 5 FPS (bummer)
CoreGraphicsTestView.h
CoreGraphicsTestView.m
#import "CoreGraphicsTestView.h" #define RNDN(s, e) ((((CGFloat)rand() / (CGFloat)INT_MAX) * ((e)-(s)) + (s))) #define RNDX(s, e, r) (RNDN((s), (e)) * (r).size.width) #define RNDY(s, e, r) (RNDN((s), (e)) * (r).size.height) #define RNDR(r) (CGRectMake(RNDX(0,0.50,(r)),RNDY(0,0.50,(r)),RNDX(0.50,1.0,(r)),RNDY(0.50,1.0,(r)))) @implementation CoreGraphicsTestView - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { self.backgroundColor = [UIColor blackColor]; srand(time(NULL)); fps[0] = '\0'; } return self; } - (void)updateDisplayCounter:(CGContextRef)c rect:(CGRect)rect { displayCounter++; float now = (float)clock() / (float)CLOCKS_PER_SEC; if (now - displayInterval > 1) { sprintf(fps, "%0.0f", displayCounter / (now - displayInterval)); printf("%s\n", fps); displayInterval = now; displayCounter = 0; } CGContextTranslateCTM(c, 5, 40); CGContextScaleCTM(c, 1.0, -1.0); CGContextSetFillColorWithColor(c, [UIColor whiteColor].CGColor); CGContextSelectFont(c, "Arial", 18, kCGEncodingMacRoman); CGContextShowTextAtPoint(c, 0, 0, fps, strlen(fps)); } - (void)setRandomColor:(CGContextRef)c { CGFloat components[4] = {1,RNDN(0, 1),RNDN(0, 1),RNDN(0, 1)}; CGContextSetFillColor(c, components); } - (void)drawRect:(CGRect)rect { CGContextRef c = UIGraphicsGetCurrentContext(); for (int i=0;i<5;i++) { [self setRandomColor:c]; CGContextFillRect(c, RNDR(rect)); [self setRandomColor:c]; CGContextFillEllipseInRect(c, RNDR(rect)); } [self updateDisplayCounter:c rect:rect]; [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.0]; } @end