Skip to main content
Inspiring
December 9, 2011
Question

Blitting is slow in the iPad 2

  • December 9, 2011
  • 2 replies
  • 1263 views

Hello, I've been trying to implement the blitting technique (as explained here: http://gotoandlearn.com/play.php?id=145 )

to add some slide screen transitions in my app. To do that, I capture the screens with the draw() method of BitmapData

an perform a Tween animation between both using a Bitmap canvas.

This is my code:

private var canvas:BitmapData, canvasBitmap:Bitmap, currentScreen:Sprite, zeroPoint:Point = Point(0,0);

public var fromScreen:BitmapData, toScreen:BitmapData, currentX:int, slideAni:Tween, goingBack:Boolean;


public function transition_start(noCapture:Boolean = false):void

{

    screenCapture(toScreen, currentScreen);

    addChild(canvasBitmap);

    slideAni = new Tween(this, 'currentX', fl.transitions.easing.Regular.easeOut,

                                        (goingBack ? stage.width : 0),

                                        (goingBack ? 0 : stage.width),

                                        Settings.screenAnimationTime / 1000,

                                        true

    );

    slideAni.addEventListener(TweenEvent.MOTION_CHANGE, transition_render);

    slideAni.addEventListener(TweenEvent.MOTION_FINISH, transition_end);

}

private function transition_render(event:TweenEvent): void

{

    canvas.copyPixels((goingBack ? toScreen : fromScreen), new Rectangle(currentX, 0, stage.width - currentX, stage.height), zeroPoint);

    canvas.copyPixels((goingBack ? fromScreen : toScreen), canvas.rect, new Point(stage.width - currentX, 0));

}

private function transition_end(event:TweenEvent): void

{

    slideAni.removeEventListener(TweenEvent.MOTION_FINISH, transition_end);

    slideAni.removeEventListener(TweenEvent.MOTION_CHANGE, transition_render);

    slideAni = null;

    removeChild(canvasBitmap);

    goingBack = false;

}

public function screenCapture(bd:BitmapData, dispObj:DisplayObject):void

{

     bd.fillRect(bd.rect, Settings.appBackgroundColor);

     bd.draw(dispObj);

}

The above code may be missing some stuff, but it's just so you get the idea.

This works fine in the PC, but in the iPad 2 the animation is quite jerky in both CPU and GPU modes.

Isn't blitting supposed to be very fast because it's just copying pixels in a canvas instead of moving actual displayobjects?

This animation is not smooth at all.

I've seen Flex has some transition animations: http://devgirl.org/2011/05/12/flex-4-5-using-mobile-view-transitions/

Is it possible to use them in a regular AIR project?

This topic has been closed for replies.

2 replies

Inspiring
December 13, 2011

Hi OMA2k,

I've actually been working on an iPad app myself over the last few days, and I'm also trying to scroll large bitmaps. Here's what I've discovered: (my app is in CPU mode)

- I tried using the copyPixels() method described in the tutorial, but it seemed sluggish for me as well. Also, doing the 'initial cache' technique crashes the app. I think it's the sheer amount of bitmap data that is loaded into VRAM ends up breaking it. I don't know if this is a bug Adobe knows about, or is just a limitation.

- I then just simply tried stringing the bitmaps together in a Sprite container, and bingo, smooth scrolling... the only caveat is that the bitmaps are all smaller than 1024x1024. I read somewhere that iPad needs textures smaller than this size so it doesn't have to constantly recache. I don't know if it's true or not but it worked.

- Oh btw, I'm building with AIR 3.1

- One kind of dumb thing I did - your fps will periodically spike down if you are in a remote debugging session.

So basically, I load in a number of png files, which are stored as Bitmaps (all less than 1024x1024). I add them as children to the sprite container. I then scroll the sprite, by simply translating on y. The sprite is masked. As I'm scrolling the fps drops to a minimum 15fps on iPad1 (but still appears very smooth), and no lag at the start.

-rich

Inspiring
December 10, 2011

Sorry if this is a naive question...

Why are you doing a copyPixels operation every frame instead of just moving the bitmap on x, y?

Inspiring
December 10, 2011

Ok I think you were referring to this tutorial:

http://www.gotoandlearn.com/play.php?id=143

Lee Brimelow talks about using copyPixels to blit your bitmaps into a viewable area, which works well when publishing to CPU mode.

- Are you publishing to CPU mode?

- Do you do a pre-load read of the bitmaps in order to pull them into memory? If you don't there may be a lag the first time scrolling through as AIR pulls the bitmaps into memory. Here's the code he gave to do the preload:

canvas.copyPixels(photos, new Rectangle(0,0,1,1), zp);

This just copies a single pixel from your images (fromScreen and toScreen?) and puts them into the canvas, as a way to access the data and pull it into fast memory (as I understand)

-rich