Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreGraphics slower on iPhone4 than on 3G/3GS

I have a chart drawn with CoreGraphics.

This chart can be scrolled horizontally and it's drawn as we scroll it.

The problem is that on 3G/3GS the speed and performance of the scroll is good but on iPhone 4 is slower than expected.

I suppose this is a issue related to the higher resolution of the iPhone 4. Is that correct?

How can I increase the performance on iPhone 4? Does the framework automatic conversion to draw on iPhone 4 resolution or is it my work?

Thank you very much.

like image 631
emenegro Avatar asked Dec 21 '25 14:12

emenegro


1 Answers

The iPhone 4 can be much slower when it comes to CoreGraphics processing.

One possible idea for your case. When the user is scrolling, rather than draw full resolution, draw your CoreGraphics related stuff a half resolution context. Then take that context as a bitmap and scale it up to full resolution. This would be for iPhone4 only and you would lose the nice higher resolution quality, but only be while the user is scrolling.

Here's some code I wrote up for testing between the different devices.

My results when displaying the view at full screen.

  • 3G, 9 FPS
  • 3GS, 16 FPS
  • i4, 5 FPS (bummer)

CoreGraphicsTestView.h

#import <UIKit/UIKit.h>
@interface CoreGraphicsTestView : UIView 
{
    int displayCounter;
    float displayInterval;
    char fps[50];
}
@end

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
like image 105
tidwall Avatar answered Dec 23 '25 07:12

tidwall