views:

2007

answers:

4

I asked before about pixel-pushing, and have now managed to get far enough to get noise to show up on the screen. Here's how I init:

CGDataProviderRef provider;
bitmap = malloc(320*480*4);
provider = CGDataProviderCreateWithData(NULL, bitmap, 320*480*4, NULL);
CGColorSpaceRef colorSpaceRef;
colorSpaceRef = CGColorSpaceCreateDeviceRGB();
ir = CGImageCreate(
320,
480,
8,
32,
4 * 320,
colorSpaceRef,
kCGImageAlphaNoneSkipLast,
provider,
NULL,
NO,
kCGRenderingIntentDefault
);

Here's how I render each frame:

for (int i=0; i<320*480*4; i++) {
bitmap[i] = rand()%256;
}
CGRect rect = CGRectMake(0, 0, 320, 480);
CGContextDrawImage(context, rect, ir);

Problem is this is awfully awfully slow, around 5fps. I think my path to publish the buffer must be wrong. Is it even possible to do full-screen pixel-based graphics that I could update at 30fps, without using the 3D chip?

+1  A: 

I suspect doing 614400 (320*480*4) memory writes, random number generation and making a new object each frame is slowing you down.

Have you tried just writing a static bitmap to screen and seeing how fast that is? Have you perhaps tried profiling the code? Do you also need to make a new CGRect each time?

If you just want to give the effect of randomness, there is probably no need to regenerate the entire bitmap each time.

freespace
A: 

To my knowledge, OpenGL is supposed to be the fastest way to do graphics on the iPhone. This includes 2D and 3D. A UIView is backed by a core animation layer, which ends up drawing with OpenGL anyway. So why not skip the middle-man.

Chris Lundie
+1  A: 

The slowness is almost certainly in the noise generation. If you run this in Instruments you'll probably see that a ton of time is spent sitting in your loop.

Another smaller issue is your colorspace. If you use the screen's colorspace, you'll avoid a colorspace conversion which is potentially expensive.

If you can use CoreGraphics routines for your drawing, you'd be better served by creating a CGLayer for the drawing context instead of creating a new object each time.

The bytesPerRow component is also important for performance. It should be a factor of 32 IIRC. There's some code available link text that shows how to compute it.

And yeah, for raw performance, OpenGL.

smeger
Ok, profiled a bit. Seems it's split quite evenly, even if I don't do any rand() setting at all and just call CGContextDrawImage, still 50% of CPU is being spent. I will try to see if your other suggestions won't make it any faster.
Bemmu
A: 

You can avoid the trip through CGContextDrawImage by assigning your CGImageRef to -[CALayer setContents:], just be sure not to free bitmap while you're still using it.

[[view layer] setContents:(id)ir];

Yes, I know this is old, I stumbled upon it from Google

rpetrich