0
votes

I'm building a simple eBook for tablets in Flash Pro. All the pages are images (Bitmaps in library) and there's about 80 of them. To maintain good quality for large tablets, bitmaps are quite big (3999x2999).

This eBook has vertical and horizontal scrolling and these are working fine, but; due to huge amount and size of these images, I can't add all of them to stage when app starts, so I ended up adding only the closest pages to current page always after scrolling tween. This works ok, but causes always a delay after page scroll (even several seconds with older tablet, and with new iMac it's almost 1s, so it's notable). This is basicly what I do per image/page:

var bitmapdata:BitmapData = new bitmapArray[i](); //linkage name
var hRatio:Number = stage.stageHeight / bitmapdata.height;
var bitmap:Bitmap = BitmapScaled(bitmapdata, bitmapdata.width * hRatio, bitmapData.height * hRatio);
target.addChild(bitmap); //target is a MovieClip (I have one Mc for each vertical pile of pages)

And BitmapScaled function:

function BitmapScaled(source0:BitmapData, width0:Number, height0:Number):Bitmap{
  var mat:Matrix = new Matrix();
  mat.scale(width0/source0.width, height0/source0.height);
  var bmpd_draw:BitmapData = new BitmapData(width0,height0,false);
  bmpd_draw.drawWithQuality(source0,mat,null,null,null,true,StageQuality.BEST);
  return new Bitmap(bmpd_draw);
}

Also, after scrolling I clean up the ones that aren't next to new current page:

function clear(targetArray:Array):void{
  for(var i:int = 0; i<targetArray.length; i++){
    targetArray[i].bitmapData.dispose();
    targetArray[i].bitmapData = null;
    targetArray[i].parent.removeChild(targetArray[i]);
    targetArray[i] = null;
  }
  if(targetArrays[targetArrays.indexOf(targetArray)] = new Array();
}

How often: After horizontal scroll I add one new horizontal page and one new vertical page, and remove one horizontal and at least one vertical page. After vertical scroll I add only one new vertical page (if next vertical page is one that I already haven't added), so vertical pages I keep in stage untill next horizontal scroll happens. This takes a smaller delay, but also notable.

I know Flash/AIR is not the best way for this, but it's all I have now. How could I get rid of the addChild-delay? Yeah you can't, so any better ways to do all this? I'm pretty sure I'm using the hard way with something here, but just can't figure out what and how I should do it.

2
Where is the actual time being spent? In your BitmapScaled function or the actual addChild function?SushiHangover
Do not draw bitmapData on mobile devices, this operation is too slow, 1 second or more for big bitmaps depending on device. Your assets must be ready to display before they are needed.BotMaster
@BotMaster thanks, that surely explains the reason. Should I turn them into Mc's and addChild/removeChild the same way as now, or is it enough if I just adjust visible property of them while all of them are already added to stage? Or any better ways I should try? Any good if I do draw's on start and just addChild/removeChild the final bitmaps?kaarto
you can draw on start if you want, still slow and expensive though. better add bitmap as you need them and remove them as you need them. Ideal would be to include few different resolution of your bitmaps in the package and display the one resolution you need per device, this is the typical way Android and Ios app are done.BotMaster
Thanks, you saved hours and hours of my time (once again).kaarto

2 Answers

1
votes

BitmapData drawing on mobile device is too slow to be used on the fly, if you must use it do your drawing on app start (still slow though). BitmapData blitting is a little bit faster but still too slow to be used on mobile device.

With large amount of assets like in your case, Stage3D frameworks like Starling might not be the best solution either as texture uploading is also slow and limited in memory amount (when limit is reached the app crashes).

Best might just be to copy what typical Android/Ios development use: Few different resolutions for all assets with a minimum of 1x and 2x.

I personally use 0.5x, 1x, 2x, 3x and developed a framework that switches resolution according to different settings (very much like XCode does). But still you can keep things simple without a framework and just set at app start the asset resolution you'll use for the app. I would also make sure to remove and add those assets on screen as they are needed.

0
votes

don't use that "new BitmapData" in conjunction with the "dispose". when you load your bytes load it directly into the already existing bitmaps on the stage. try to have as little modification of the allocated memory as possible through your load-resize-display pipe.

removing and dumping pixels onto the renderer is far slower than changing already existing ones.