Fun with code (since 2006)

Why cacheAsBitmap is bad!


09.30.08 Posted in Actionscript 3, Books & Articles by

One of the feature I would really love to see in a future release of the Flash Player is a native rasterizer for display objects. Imagine something like :

myMovieClip.rasterize = true;

This code would rasterize your DisplayObject as an animated PNG. It would bring crazy improvements for designers and coders who want to improve the rendering performance of any animation. This would be in fact the same behavior as the Banana Slice component I talked about.

When talking about this, some people could think "Well, you have cacheAsBitmap for that". The reason why such a feature would rock is mainly due to the fact that cacheAsBitmap is very dangerous. Well, it won't hurt you :), but it can definitely hurt your application performance.

As I said before, when cacheAsBitmap is set, the DisplayObject is cached as a bitmap on memory and the Flash Player is using this copy to render it on screen. The main problem that we have here is that if you do more than moving this DisplayObject on x and y, for each frame the Flash Player is updating the cached copy on memory before updating the screen. So if you apply any rotation, scale, alpha, or even if you have any key frames in your DisplayObject you will get performance decrease.

Hopefully, you can bypass this limitation by creating a BitmapData by yourself, draw the MovieClip on it, and pass it to multipe Bitmap instances. So let's take a simple example, in the folllowing movie, when you click on the "cacheAsBitmap" button, I create multiple instances of an Apple MovieClip, set cacheAsBitmap, and move them on screen :

var apple:Apple;

for (var i:int = 0; i< 100; i++)
{
apple = new Apple();

apple.cacheAsBitmap = true;

addChild ( apple );
}

When you click on the "draw" button, I first create an instance of the apple MovieClip, draw it on a BitmapData and then create Bitmap instances linked to the one and unique BitmapData instance :

var source:AppleSource = new AppleSource();

var buffer:BitmapData = new BitmapData ( source.width, source.height, true );

buffer.draw ( source );

var bitmapApple:BitmapApple;

for (var i:int = 0; i< 100; i++ )
{
bitmapApple = new BitmapApple( buffer );

addChild ( bitmapApple );
}

Online demo :

A Flash animation should have appeared here, but it seems that your browser has an older version of the Flash Player or it is not installed at all. Please, install the last release of the Flash Player now, then reload this page.

As you can see, manual rasterizing is king :)

You can download the sources here



29 Responses to “Why cacheAsBitmap is bad!”

  1. GillesV says:

    Indeed. I’ve come to the same conclusion when I was asked to create a really animation-heavy tile-based game.

    I wrote my own “slicing” class to easily rasterize movieclips and have them play back at different framerates.

    The only downside to this is memory. BitmapData is stored in RAM uncompressed, so a simple animation can quickly eat up dozens of MB’s of RAM if you’re not careful.

    You can read my original post here: http://blog.vandenoostende.com/?p=47 and download the scripts there.

    But yeah, a native animation rasterizer would be neat ;)

  2. TK says:

    We could create something like this as a subclass of Sprite or movieclip. Is this the same thing as frame-ripping?

  3. Tek says:

    I don’t know why but it remember me some really recent debate with the worst flash activist ever. :)

    Really enjoying the post and the example. I hope that Adobe will do something special for your “rasterize” idea.

  4. zedia.net says:

    In your code, I think you did 2 errors, in the first sample, I think it should be
    var apple:Apple;
    instead of
    var apple:Pomme;

    And in the second sample:
    var bitmapApple:BitmapApple; intsead of
    var bitmap:AppleBitmap;

    Nice work on the demo.

  5. Thibault Imbert says:

    Hi Gilles,

    I saw your AnimationSlicer which is very nice. I agree with you, the only drawback here is memory usage. In common cases it is reasonable, and having a native rasterizer could solve such behavior. I will definitely push such a feature for a future release.

    TK,

    Yes, there are many ways to do it. In this example I extended Bitmap and passed the BitmapData to it, but you could extend MovieClip and do all the rasterizing inside it and add a final bitmap showing each frame as a child.

    Tek,

    hehe yes, I was sure you would remember it :)

  6. Thibault Imbert says:

    Hi Zedia,

    Thanks ;) Copy & paste doh !

  7. julien says:

    impressive difference, thanks for the tip

  8. Macaca says:

    A sliced game may well use 100 mb of RAM.. so what about it? I don’t have a problem with that. Your average downloadable game will do that too. It’s actually very smart: usethe vectors/gradients/etc for data storage (=download time), and unpack (rasterize) for hyper run speed.

  9. Thibault Imbert says:

    Hi Mr.doob,

    Nice class :) You could also use the getBounds method to detect if the DisplayObject is not aligned at 0,0. Use a matrix and translate the matrix passed to the draw method, to always have your bitmap entirely drawn.

  10. [...] Why cacheAsBitmap is bad [ by Thibault Imbert ] [...]

     
  11. Mr.doob says:

    You’re right!! Will put that on the next version, thanks! :D

  12. [...] Why cacheAsBitmap is bad [ by Thibault Imbert ] (from ByteArray.org) Share and Enjoy: [...]

     
  13. tomsamson says:

    yeah, nice.
    tek: can´t be the worst flash activist ever if everyone remembers him and even if people kid about him he inspires others :)

  14. [...] ne pas utiliser le fameux cacheAsBitmap de Flash? En fait pas mal de raisons explique ce choix, mais surtout, je n’ai jamais trouvé moyen d’obtenir d’aussi [...]

     
  15. [...] Why cacheAsBitmap is bad Flex Move Effect Messes Up Mask Alignment [...]

     
  16. P48l0 says:

    WOW this really add some speed! i´m getting %600 speed improve on a site i was having using cacheAsBitmap on some sprites.

  17. Doooooo says:

    Would this benefit a case where only one DisplayObject is on screen?

  18. Thibault Imbert says:

    Hi Doooooo,

    Yes, this would benefit if the DisplayObject is moving and contains complex content like gradients, alpha transparency.

    In terms of rendering performance, bitmap will always win :)

    best,

    Thibault

  19. [...] – Consider bitmaps versus vectors. I’ve shown to the audience a benchmark application that demonstrates the good usage of the cacheAsBitmap property. My advice is the following. If you manipulate graphical elements using the X and Y axis only, please set the cacheAsBitmap property to true. It will dramatically improve the performances of your applications. Transparency is very expensive, avoid the alpha channel, avoid filters and blend modes. If you use the rotation property, don’t use cacheAsBitmap, but the Draw sample detailed here: http://www.bytearray.org/?p=290 [...]

     
  20. [...] Great tip: ByteArray.org – Why cacheAsBitmap is bad [...]

     
  21. [...] release of the Flash Player is a native rasterizer for display objects. Imagine something like : view source [...]

     
  22. Brian says:

    When you rewrite the movieclip to a Bitmap, you are changing the registration point. I’ve been trying for several hours to be able to use this code to improve performance, but I need to keep rotating my object around the center like hands of a clock… Any ideas of if this is even possible?

  23. MatrixTurn says:

    An Easy way to optimize is to use a simple library MatrixTurn and boost your fps. All shape of movieclipclip are automatically “cacheAsBitmap” in execution and also a lot of effects are possible.

    Check the source here :
    http://sourceforge.net/projects/matrixturn/

  24. [...] I always thought it would help, but it doesn’t. I stumbled across this article: “Why cacheAsBitmap is bad!” by Thibault Imbert and learned why I should use BitmapData.draw of the cacheAsBitmap property. [...]

     
  25. [...] really hard to build things efficiently on top of it. I wrote a blog post a long time ago on why cacheAsBitmap is evil and how similar results could be achieved using lower-level primitives with minimal side [...]

     

Leave a Reply

Open Sort Options

Sort comments by:
  • * Applied after refresh

ByteArray.org
Fun with code since 2006.