• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
Locked
0

Blitting is slow in the iPad 2

Engaged ,
Dec 09, 2011 Dec 09, 2011

Copy link to clipboard

Copied

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?

TOPICS
Development

Views

1.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 10, 2011 Dec 10, 2011

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 10, 2011 Dec 10, 2011

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 10, 2011 Dec 10, 2011

Copy link to clipboard

Copied

flextnet wrote:

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?

Because this "blitting" technique using copyPixels is supposed to be faster than moving a regular DisplayObject. What I'm trying to do is move the entire screen - well, in fact, two whole screens, since I'm transitioning from one screen to another one - so if I move two container Sprites (containing two whole 1024x768 screens) using the x property, then lots of DisplayObject components inside those two sprites would have to be redrawn during the animation, so the animation speed would be even worse than using copyPixels.

flextnet wrote:

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

Sorry, I actually meant that tutorial, yes.

I'm publishing to CPU mode (I also tried with GPU and there is not much improvement, if at all, in fact it might be even worse).

In my case, what I need to do is capturing the screen in whatever state the user left it when leaving the screen, so I can't do a preload. I also perform a capture of the newly created screen, which might have all kinds of different content depending on user's input in the previous screen, so I can't preload that as well. To do both screen captures I use the draw() method of the BitmapData class (see screenCapture function in my code above). So you mean that because I capture and immediately perform the animation, that's why it has poor framerate? I don't think that's the reason, since capturing could maybe delay the animation start (until both captures are done), though I don't see any noticeable delays before the animation starts. But once the captures are ready, the animation should be smooth.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Dec 12, 2011 Dec 12, 2011

Copy link to clipboard

Copied

I think CPU is supposed to be faster when working with bitmapdata, also, 1024x768 is quite large to be copying twice, x times a second. What's the framerate you're trying to run it at?

Btw: you could do some very small improvements by caching stuff like stage.stageHeight in local variables i/o calling them every frame.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 12, 2011 Dec 12, 2011

Copy link to clipboard

Copied

Yeah, I guess fullscreen iPad is a bit big for that kind of animation. But native iOS applications

have that kind of transition with perfectly smooth animation, and it's even much easier

to implement than in AIR (it's already implemented in the OS, so no need for complex blitting or anything).

The same happens with the lack of native scrolling in AIR: http://forums.adobe.com/message/4073706

Why have AIR apps to be second rate like this? No scroll, no transitions, no nothing...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Dec 12, 2011 Dec 12, 2011

Copy link to clipboard

Copied

LATEST

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines