Josh Brittain
Josh Brittain

Reputation: 2212

Adobe AIR - How to optimize for Mobile

I am in the process of converting a flash browser game to Mobile using AIR. Using the flash builder profiler I have found that my bottlenecks are

[render] - 42.31% [pre-render] - 41.41%

over 80% of the time my application is spent rendering. The game currently uses vector graphics for UI elements, characters and pets (there can be up to 15 characters and 15 pets). The background is a bitmap.

We have messed with converting the vector characters and pets into bitmaps and found that in some cases where the vector art animates a lot we get a large gain but for other characters with little animation it actually runs slower (I believe because the redraw regions on the vector art are so small).

I believe the biggest gain we can get on the rendering front is to remove vector art but I don't think our basic approach to animating bitmaps is better in every case. Are there any optimized AS3 libraries that handle animating bitmaps or converting vector art? Any resources you could point me to for research on these topics is greatly appreciated.

Thank you!

Upvotes: 0

Views: 665

Answers (4)

Nikolay Nankov
Nikolay Nankov

Reputation: 273

  • As everybody mention don't use vector or draw it in a bitmapdata
  • Use GPU Rendering
  • You can't use filters in GPU mode so you will have to use BitmapData.applyFilter if you use any
  • Check out Starling or Flixel
  • Use copyPixel instead of BitmapData.draw wherever you can
  • If you are rendering a lot of content that will animate after that, aways skip one ENTER_FRAME event before animating the objects. This will make all transitions and animations as smooth as possible (this one actually made a lot of difference in all the apps that I have made)

Upvotes: 1

moot
moot

Reputation: 653

You can create regular mcs (vector, jpgs, bitmaps, dynamic text, whatever), create bitmap copies, and remove regular mcs. You can put the bitmaps in movieclips and sub-movieclips and move them around smoothly at 60fps as long as you're reasonable with total ram you're using (pool when needed). Scout will show you

Here's some code pieces showing converting regular mcs to bitmap tiles - you have to keep the dimensions of your bitmaps under the device's maximum so the easy solution is to use the device's screen dimensions as a max.

//  set the bmp dimensions to device screensize to prevent exceeding device's max bmp dimensions
if (bStagePortrait) {
    iTileWidth = Capabilities.screenResolutionX;
    iTileHeight = Capabilities.screenResolutionY;
} else {
    iTileWidth = Capabilities.screenResolutionY;
    iTileHeight = Capabilities.screenResolutionX;
}

//  mcList.mcListVector is the source mc - a regular mc containing mcs, jpgs, dynamic text, vector shapes, etc.
//  mcList.mcListBmp is an empty mc

aListTiles = new Array();
iNumberOfTiles = Math.ceil(mcList.height / iTileHeight);

for (i = 0; i < iNumberOfTiles; i++) {
    var bmpTile: Bitmap;
    //  move the source mc
    mcList.mcListVector.y = -(i * iTileHeight);
    bmpTile = fDrawTile(mcList, 0, 0, iTileWidth, iTileHeight);
    mcList.mcListBmp.addChild(bmpTile);
    bmpTile.x = 0;
    bmpTile.y = (i * iTileHeight);
    aListTiles.push(bmpTile);
}

//  remove the regular mc
mcList.mcListVector.removeChild(mcList.mcListVector.mcPic);
mcList.mcListVector.mcPic = null;
mcList.removeChild(mcList.mcListVector);
mcList.mcListVector = null;
}


function fDrawTile(pClip: MovieClip, pX: int, pY: int, pWidth: int, pHeight: int): Bitmap {
    trace("fDrawTile: " + pX + "," + pY + "  " + pWidth + "," + pHeight);
    var rectTemp: Rectangle = new Rectangle(pX, pY, pWidth, pHeight);
    var bdClip: BitmapData = new BitmapData(pWidth, pHeight, true, 0x00000000);
    var bdTemp: BitmapData = new BitmapData(pWidth, pHeight, true, 0x00000000);
    bdClip.draw(pClip, null, null, null, rectTemp, true);
    bdTemp.copyPixels(bdClip, rectTemp, new Point(0, 0));
    var bmpReturn: Bitmap = new Bitmap(bdTemp, "auto", true);
    return bmpReturn;
}

This conversion will choke your fps for a second but then you can move mcList around using regular code (tweening) at 60fps.

Upvotes: 1

BotMaster
BotMaster

Reputation: 2223

. Avoid Vector graphics all together.

. Keep Starling engine and similar for desperate cases where graphic display performance must be optimal. Using those engine require ultra precise GPU memory management + uploading to GPU is very slow and heavy on CPU (app crashes possible due to memory overload). If you must use it, use it only for the graphic parts you need performance for.

. Use blittering and BitmapData a lot. In most cases that technic would be enough to get very fast and flexible graphic display.

Upvotes: 1

user45623
user45623

Reputation: 621

This is a very broad question and might not be particularly well suited to Stack Overflow, but I'll give you some pointers:

Since you are using vector graphics, I assume you are running with the native display list in CPU mode. Basic vector shapes like rectangles have good performance on AIR for mobile in CPU mode, but more advanced shapes can quickly overwhelm mobile CPUs and lead to some loss in framerate.

If you have a lot of vector graphics, you are probably better off running in GPU mode and caching the vector shapes with the cacheAsBitmap property: http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001283.html#374074 Note that this can murder your performance if the graphics are very large or cause rendering artifacts if you use cacheAsBitmap on objects that have children.

The real answer is that you should switch to a high-performance library like the free and open-source Starling: http://gamua.com/starling/ I haven't used the native display list in several years, because the performance in Starling is significantly better. Starling integrates very easily with AIR and emulates the behavior of the display list as much as possible, so the transition to Starling is almost effortless.

A caveat is that it doesn't support vector graphics, but you can render them to bitmaps and then load those into Starling textures. Even better, render your graphics into sprite sheets and import them into Starling as texture atlases, which gives you excellent performance and easy asset management.

Upvotes: 2

Related Questions