8

I'm porting a 2D action game from Windows Phone 7 (developed in XNA 4.0) over to Android. I'm using a lot of Canvas.drawBitmap() calls - around 200-300 per frame update - with different Paints for each call to handle varying transparency and colourisation at draw-time. This is managing particle systems and various other overlays and in-game effects as well as a tiled background and in-game sprites. I'm not doing any on-demand resizing or rotating, it's simple src->dest rectangles of the same size.

On WP7 this runs at 30+fps but I'm struggling to get 12fps on my test 'droid hardware (Samsung Galaxy S). This is making the game unplayable. Having profiled the code, I've confirmed that all my time is being lost in Canvas.drawBitmap()

I seem to be following all the usual performance advice - using a SurfaceView, mindful of GC so not creating loads of throwaway objects, and avoiding Drawables.

Am I right in understanding that Canvas.drawBitmap() is CPU-bound, and if I want to improve performance I have to switch to OpenGL which will use the GPU? I can't find it stated that baldly anywhere, but reading between the lines of some comments I think that might have to be my next step...?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Paul Harman
  • 115
  • 1
  • 6
  • 1
    How are you drawing your bitmaps? What color format? What dimensions? In graphics programming, there are a *lot* of things to respect for things to go fast. Please post some code. – user703016 Jul 15 '11 at 10:11
  • 1
    Great question. I had the same issue with Canvas.drawBitmap() and ended up porting the game in openGl, but maybe I have missed a super-secret Canvas option? – Gautier Hayoun Jul 15 '11 at 10:11
  • The game is 100+ classes, tens of thousands of lines long. I'm not sure that I can post a reasonable extract that would be particularly informative. The Rects vary from 16x6 to 128x128 in size, all ARGB_8888 – Paul Harman Jul 15 '11 at 10:26

2 Answers2

7

This is normal. Canvas is amazingly slow when using transparency (like ARGB_8888).

2 options:

  • Switch to OpenGL ES
  • Use the least possible transparency on your bitmaps (i.e use RGB_565 the most you can).
user703016
  • 37,307
  • 8
  • 87
  • 112
  • Thanks. Just wanted to get this confirmed before I went off and learnt a whole new graphics stack, in case I was just doing something stupid... – Paul Harman Jul 15 '11 at 11:13
1

Perhaps this will run better on Android 3+ since it uses hardware acceleration for canvas operations.

RobotRock
  • 4,211
  • 6
  • 46
  • 86