Android game: Canvas or OpenGL?

seipey picture seipey · Jan 9, 2012 · Viewed 23k times · Source

I am to write a game for Android, and I have to choose between Canvas or OpenGL for drawing. I have read that Canvas doesn´t have a good frame rate, but what is good? Imagine you were going to write an Angry Birds type game, would Canvas frame rate be enough?

Answer

Twice Circled picture Twice Circled · Nov 6, 2012

I initially wrote my game using Canvas but then needed to switch to OpenGL for the following reasons:

  • Using Canvas, your sprites are stored on the heap (unless you specifically cache them to the disk) this puts a limit on the total size of your sprite assets depending on the phone - not good! I found this was around 42mb on my phone - note this is the uncompressed size of bitmaps. If you have several types of entity, each with different animations then you can reach this size very quickly.

  • OpenGL stores your sprite assets separately to the heap which increases the memory available dramatically.

  • Canvas doesn't scale very well. The more .draw(...) calls you make, the slower it will run. The relationship is fairly linear.

  • Using OpenGL you can batch your draw calls together to improve performance.

It can be intimidating starting with OpenGL which makes Canvas seem appealing. However from experience I wish I had just started with OpenGL. My recommendation would be to 'bite the bullet' and go with OpenGL if you are making a game.

To make things a bit easier to get started, I have written some helpful utility classes that do all the nitty gritty OpenGL for you. They allow you to make simple .draw(..) calls similar to when using Canvas. The following video tutorial should get you started:

http://www.youtube.com/watch?v=xc93rN2CGNw

EDIT: 03/04/13

It seems that as newer Android devices and operating systems come out Google have increased the performance of Canvas. A user of the utility class I describe above got back to me with the following email after doing some benchmarking:

Drawing 500 sprites at random positions across canvas each frame.

Here are the results: Huawei Honor (Gingerbread, single core 1.4 Ghz): SpriteBatcher: 19-20 FPS, Canvas: 23-24 FPS

Nexus 7 (JellyBean, 4 cores 1.3 Ghz): SpriteBatcher: 29-30 FPS, Canvas: 57-58 FPS

Now, in my reply to this user I explained that this could be to do with inefficiencies in the way I've written the utility class SpriteBatcher. However from my own experience with Canvas back on an HTC Desire running Froyo 2.2 I can say that it was definitely slower sprite for sprite!

On later operating systems and devices it may have overtaken on efficiency but some of the points in my original response are still valid. For example, getting around hitting an OutOfMemoryException without having to resort to caching textures onto the disc etc.

If I learn more, I'll continue to update this answer.