Biffsnot wrote:Hello. I am noticing this slowdown on almost all 2d games on the 3g with ios 4, including other roguelikes like iNethack and slash-em. Doing a little research I came across this, I dont know if it will help - but hell, couldnt hurt.
I’m talking about CGContextDrawImage. My two most popular games, reMovem and reMovem free, made heavy use of this functionality to draw the balls on the screen. It’s not uncommon, especially for code ported from Mac OS X, where Quartz 2D is widely used for drawing. I’m not sure how this is possible, but CGContextDrawImage (and its cousin [UIImage drawInRect:]) is measurably slower on older iPhone devices. In my case, where it used to take less than 20 ms to render key elements of the screen on iOS 3.x, it now takes around 500 ms. That is, suffice to say, enough to cripple these games.
With all the commotion around the successful iPhone 4 launch recently I’m sure Apple would rather not worry so much about compatibility and performance on older CPUs. Fortunately you don’t have to wait for Apple to address the problem. I solved it in reMovem by using CALayer to draw the images I needed, and was able to get a performance boost at the same time. The same key elements of my game now render in around 2 ms. Here’s how.
The key to using CALayer is to understand that each UIView is backed by a Core Animation layer object. Each layer can have multiple sublayers. Each layer object has numerous properties, many of which are animatable. Simply attach a sublayer to your view’s existing layer, set its content property to your image, and you are done. Well, sort of. A good place to learn more about Core Animation is the excellent Cocoa Is My Girlfriend blog by Matt Long and Marcus Zarra.
...
Adding CALayer drawing to you code requires a little setup, but that can be done once in an init function. In mine, we create a bunch of sublayers, modify the properties appropriately, and add them to the view’s main layer. The tradeoff here is we require slightly more resources (sublayer memory) but we obtain vast improvements in performance. Why’s that? I imagine Apple’s engineers are spending tons of time optimizing Core Animation, which is literally behind everything you see on the iPhone and iPad screen. Betting on CALayer is a safe bet for the foreseeable future. Here’s the new code, which is not too different from the old code:
This info is from
http://blog.mundue.net/2010/06/ios4-why-you-so-slow/ where the blogger put up several code snippets to get people rolling on it.
So this may or may not be valuable info for you, I am not sure.
It is very disheartening that apple would take something every 2d game uses and screw it up so bad. iNethack, Rogue Touch, and tons of other games take forever to scroll and update the screen now. Rogue Touch alone fades in so damn slow when starting or loading a game, and its a good half second lag from touch to move. I could go on about this but this isnt the place for venting my disappointment
One last bit - for those who want to know, you can indeed roll back to OS 3.1.3, though doing so is not as simple as upgrading. Google it and you can find info on downgrading, which I may very well do myself, because while Rogue Touch is being updated because its Dev is active, many other games will likely never get the proper fixes to repair this issue.
Keep up the great work and thanks for a fine roguelike for the iPhone. Good luck battling Apples bad decisions every update or so though
Hi Biffsnot! Thanks for reporting in
You are correct that Apple has a problem with CGContextDrawImage, and it does affect many 2-D games out there, especially the roguelike family you brought up. CGContextDrawImage has been slowed down roughly by a factor of 10! I've seen and worked a bit on the code for iNethack and SlashEm in the past, and can confirm that those same draw calls are used. Dirk Z. and I haven't spoken recently but I may have to check in with him to see if I can help a bit.
Regarding the info and site you found:
Actually, since version 1.0 Rogue Touch has been using CALayers to hold all drawn objects on screen. It was the only way to get decent performance... If I'd done all drawing straight to a single view, RT would never have seen the light of day. I'd found that article as well and groaned when I discovered that guy's revelation was actually something I have already been doing all along. That meant I needed to get more devious to find new levels of performance on iOS 4.
On the topic of Rogue Touch:
You have been playing with the latest, version 1.52, right? What zoom level do you usually play at? I notice you're on an iPhone 3G, which is the oldest and slowest device that iOS 4 can be installed on. If you can answer these questions it'll help me to help you more... so please let me know
I made some changes in 1.52 that optimized drawing quite a bit, and version 1.52 has been regarded as making the game very playable on more recent devices, or older ones if you keep the zoom level at 100%. Pinch zooming out to 50% or 25% is much slower, and I bet on an old 3G iPhone it is painful.
Since I am never one to stop tweaking, after version 1.52 was ready for download in iTunes I went back through and actually came up with some other methods to increase speed, including a very new and clever way to render the mini-map. All these new ideas combined for a pretty dramatic increase of speed in version 1.6. Also added in some new items, iOS 4 multitasking enhancements, and retina display support for good measure!
Version 1.6 was submitted to Apple today, 7/16/2010, and with any luck should be available by next weekend!
Final notes:
I can't really talk about what happens in Apple's private developer forums, but I can say that others have brought up the slow draw speed issue, and fairly high profile people at Apple have acknowledged its existence. At least enough to indicate they will look into it. Whether any action is taken in a firmware update and when, I have no idea.