Reputation: 19005
I'm working on an iPad app that displays lightmapped scenes. Loading the 20 or so 1Kx1K textures that are involved is taking a while, and when I started timing the various operations I found it was taking slightly less than 1/2 second per texture.
It turns out that loading a texture image from the filesystem is pretty fast, and that the bottleneck is in copying the UIImage
to a CGContext
in order to pass the image to a glTexImage2D()
I've tried two different ways of making the copy:
CGContextSetInterpolationQuality(textureCopyContext, kCGInterpolationNone);
CGContextDrawImage( textureCopyContext, CGRectMake( 0, 0, width, height ), image);
and
UIGraphicsPushContext(textureCopyContext) ;
[uiImage drawInRect:CGRectMake(0, 0, width, height)] ;
UIGraphicsPopContext() ;
and both take about 0.45 seconds. This strikes me as excessive, even for a relatively underpowered device.
I'm relatively new to iOS development, so I just want to ask whether the times I'm seeing are reasonable, or whether they can be improved.
Update: I'm aware of the PVRTC alternative, but for now I've got to stick with PNGs. However, there is an excellent summary of the pros and cons of PVRTC in this answer. The same answer also hints at why PNGs result in such long texture setup times -- "internal pixel reordering". Can anybody confirm this?
Upvotes: 4
Views: 356
Reputation: 2809
Switching texture context has traditionally been expensive, dating back to desktops (it's alot faster on modern GPUs). You could try using texture atlas, depending how big your textures are this is the most efficient approach. A texture Atlas is putting the textures together, I believe the iPad is able to load 2048 by 2048 textures, you could squash 4 textures together.
The other alternative, use pvrtc texture compression, you can reduce file size by about 25% depending on quality. The PowerVR chip stores it on device using this compression so it saves time AND bandwidth copying. This can look lossy on occasion with lower settings, but for 3d textures it is the best option, whereas 2d sprites prefer the first option.
Let me know if you need more clarification. Don't forget that png files are compressed when loaded from file system and expanded into the full-size bit buffer which is ALOT bigger.
Upvotes: 1
Reputation: 23398
I'd start by taking a look at how it's done in https://github.com/cocos2d/cocos2d-iphone/blob/develop/cocos2d/CCTexture2D.m. I hope there's something in there that helps. There they're doing glTexImage2D straight from the image data, no CGContext involved.
Upvotes: 0