Recently at the office we’ve been dealing with a strange BitmapData memory occupation behavior I want to share with you guys.

On this subject the AS3 reference reads “A BitmapData object contains an array of pixel data. This data can represent either a fully opaque bitmap or a transparent bitmap that contains alpha channel data. Either type of BitmapData object is stored as a buffer of 32-bit integers. Each 32-bit integer determines the properties of a single pixel in the bitmap.”

This should be meaning that a BitmapData object should be represented in memory as a sequence of 32 bits integers, one for each pixel in the bitmap, hence width*height*4 bytes which definitely makes sense.
However the actual behavior is significantly different and you can easily find out that the real BitmapData size in memory is not proportional to its area as it should be.
Let’s see an example (code shared at wonderfl)

BitmapData Memory Allocation – wonderfl build flash online

The example shows how different the size of a BitmapData is depending on its maximum dimension: the code instantiates 4096 images with an increasing area from 1 up to 4096 pixels, first with a horizontal extension (width is the increasing dimension, blue line in the chart) then with a vertical extension (height is the increasing dimension, red line in the chart).
You can notice that the behaviors of the lines in the chart are very different and the blue line’s Y is increasing only few times whilst the red one’s (vertical bitmap) is increasing much more frequently and is reaching much higher values.
So what’s the real memory representation of a BitmapData? For sure it isn’t a width*height*4 matrix as it should be and it is stricly related to the dimension the BitmapData is extended on.

We worked a bit on this thing at the office (thanx to Matteo Lanzi) and we found out that BitmapData object memory allocator has a strange behavior: it allocates N chunks of memory aligned to 256bytes (64 pixels) at time.
This would be a useful behavior if the BitmapData object would be resizable via actionscript, but it is not, or if the freed chunks were put in a memory pool and used by the next BitmapData requiring memory, but it doesn’t seem to do that ( the only case we noticed that the memory is reused is when a NxM BitmapData is created, deleted and recreated with the same N and M dimensions ).
If it was only this however it wouldn’t have been such a big problem to deal with, the real big issue is that a 256b chunk is representing a sequence of pixels with a defined horizontal orientation.
This hardcoded behavior leads to a very unpleasant side effect: a BitmapData instance with a high number of little rows (high height, little width,, hence a ‘vertical’ orientation) is occupying a HUGE AMOUNT OF MEMORY while it should be occupying the same memory of a bitmap with the same area rotated by 90°.
Let’s seesome more example just to clear out the problem:

Case 1:
- width 1px
- height 1px
- expected allocation: 4 bytes
- actual allocation: 256 bytes (minimum chunk)

a 1×1 px BitmapData allocates in the heap 1 chunk of 256 bytes while only 4 bytes would be needed!! 63x overhead!!!

Case 2:
- width 64px
- height 1px
- expected allocation: 256 bytes
- actual allocation: 256 bytes (fits exactly the minimum chunk)

the same 256 bytes are allocated by a 64×1 bitmap and the overhead disappears, what does happen with a 65×1 one?

Case 3:
- width 65px
- height 1px
- expected allocation: 260 bytes
- actual allocation: 512 bytes (2 chunks)

with a ‘max chunk size plus one’ size a 65 px wide image allocates 2 chunks, the overhead is set to approx 1.9x.

Case 4
- width 1px
- height 64px
- expected allocation: 256 bytes (same area of the 64×1 one…)
- actual allocation: 16 Kb!!!!!

this is the worst case, every in 1xN bitmaps have the maximum overhead possible: 63x!
So try to think about an image very narrow and high, let’s say a 1×4096 one: you would expect it to be 16kb in memory (4096*4 bytes) but it actually is 1 whole megabyte (4096*4*256!!)!!

So, the formula to calculate the ACTUAL memory allocated by a BitmapData expressed in bytes I came up with is:

Math.max( 1 , height*(width/64)>>0 )*256

You can see a more detailed and complete dataset in this google spreadsheet http://bit.ly/FlashBitmapDataAllocation (feel free to spread the link) containing data for BitmapData memory occupation from 1×1 to 1×4096 and from 1×1 to 4096×1.
The test to reproduce the dataset is available on github at this url https://github.com/pigiuz/Tests/blob/master/src/BitmapDataMemoryAllocation.as (feel free to share this link as well)

This behavior has been tested in AIR 3.1 for Mac OSX 10.6 (snow leopard), 10.7 (lion) (thanx to Marco Nava for testing on lion), Window 7, Android 4.0, iOS 5 (thanx to Shawn Blais for testing on mobile),
Flash Player 11,1 by yourself (if you ran the swf linked backward in the post and noticed the same behavior).

After figuring out the problem we opened a bug in adobe’s jira, if you have comments which can raise the attention of adobe on this stuff or add something to the discussion please feel free to comment at this url https://bugbase.adobe.com/index.cfm?event=bug&id=3094186 (you’re welcome to comment here too btw :D )

Few more points worth some attention:
I tried to measure the memory in 3 ways:
- the data got back from flash.sampler.getSize() was not accurate, most of the time it was totally wrong and not predictable (or perhaps I didn’t get how it works in relation with BitmapData objects)
- the delta calculated with a pre and post sampling of System.privateMemory is more accurate than getSize() and fits the expected results in AIR but it’s not as accurate as I expected: in the spreadsheet linked backwards you can see that the results have a coherent trend, but there’s a lot of garbage data and little bitmaps weren’t detected at all.
- the delta calculated witn a pre and post sampling of System.totalMemory is more accurate than System.privateMemory only in flash player.

 

That said,
I find this allocation behavior weird, and the worst thing is that it UNDOCUMENTED and the docs are saying a different thing. I see one VERY significant bad side effects in this way of allocating bitmaps memory that involve how BitmapData objects are stricly tied to the Flash Player’s and AIR runtime’s APIs:
flash.display.Loader generates BitmapData instances when it loads images from URL or streams, so if an application needs to load many bitmaps that don’t fit the memory alignment there will possibly be a HUGE memory waste.
A possible solution could be the creation of few additional functions such as

loadInto(urlrequest:URLRequest, destination:ByteArray):void

and

loadBytesInto(bytes:ByteArray,destination:ByteArray):void

which both take a data source and a preallocated bytearray as input and put outputs to the preallocated bytearray called destination.

 

This is the first shot, I’d really like you guys to spread the word and help me to make adobe sensible on this topic as it’s really worth some effort to make flash and air runtimes even better than what they are now.

Thank you all in advance,
ciao,

pigiuz

 

I just submitted my idea for a book to Packt Publishing.
One of the main lack I see in the panorama of flash books is all about industrializing projects. There are few\no books about coding conventions, code management, environment setup, code reutilization, unit testing, ecc ecc… and a plenty of “making (little) games with flash”, “using (basic) 3d with flash”, etc.

The idea I submitted is called “Creating and Managing Flash Enterprise Projects”.
My plan is to talk about how to setup and maintain an enterprise level project built over the flash platform… if you like such an idea, please vote for me here >>>> http://t.co/2xxmchp

thanx,
ciao ;)

 

I’m doing some experiments with “Broomstick“, the new born (alpha) version of Away3D which leverages the brand new Stage3D (molehill) of flash player 11 (incubator).

Here’s the coded formula to obtain pixel perfect sprites by moving the camera in the Z axis just before rendering:

// camera is the current Camera3D object with a PerspectiveLens
// h has to be the height of your current viewport
var h:Number = /*current viewport*/stage3DProxy.viewPort.height;
var fovy:Number = (camera.lens as PerspectiveLens).fieldOfView*Math.PI/180;
camera.z = -(h/2) / Math.tan(fovy/2);

…just a snippet, hope you find it useful ;)

More on this topic:
- http://knol.google.com/k/perspective-transformation
- http://en.wikipedia.org/wiki/3D_projection

 

This post is to summarize my session at the FlashCamp.

Here’s the preso: (italian only)

and here are the examples shown during the session:

Garbage collector in action:
this example shows the memory allocation behavior. Take a look to the saw tooth yellow line in the graph.

Weak vs Strong references:
two examples to show the difference between weak and strong references: basically weak do not increment reference count, strong do that.
If you store keys in a dictionary using weak references your keys are getting cleaned by the garbage collector ( example )
otherwise the GC doesn’t clean your keys ( example ).

Blitting in order to ease the GC:
The GC iterates through each reachable node starting from the roots, one of these roots is the displaylist. So in order to ease the GC work we could flatten the whole displaylist to one bitmap by leveraging the usage of the blitting technique.
These examples display about 1000 new objects drawn each frame by using the display list ( example ) or the blitting technique ( example ). The difference in performances are not only due to the different compositing techniques (built in compositing when using the displaylist VS manual compositing when using the blitting technique ) but also to the lower number of instances to be collected by the GC.

NOTE: both examples are very cpu intensive

Don’t let the GC start by using the memory pool technique:
The GC freezes the program when freeing the memory. The memory pool technique consists in reusing the instances of your objects preventing the GC to identify those objects as garbage.
This makes your app memory utilization stable (a straight yellow line ) and removes every glitch due to the garbage collection.
These examples show a simple particle fountain implemented by leveraging the memory pool technique ( example ) or not ( example ).

Finally:
here’s the source, it’s not the best commented nor the best implemented files out there, but just take a look at them to have a full comprehension of what’s going on ;)

If you need further help, please comment this post and let me know.
ciao

PS: obviously mario copyright is property of nintendo :)

 

Yesterday it has been a great day!
Yesterday we had the FlashCamp here in Milan, hosted by WhyMCA mobile conference (thanks guys).

Flash Camp at WhyMCA

Lots of fun, lots of people (450 nerds) from the most different beliefs (html5ers, javascripters, objective-Cers, androiders, whateverers :) ), a great happening to spread the word about what you can do with the flash platform and how it can ease your work when deploying on mobile devices.
Thanks to Adobe we even had a welcome guest: Mihai Corlan, who presented very cool new stuff putting his hands on Flex Builder 4.5 and the Flex Hero SDK.
Moreover it has been totally the best possible way to meet other people from the community of Milan, TheFlashMind, and to spread the word about our cool AUG :)

I really enjoyed the FlashCamp, it has been a pretty unique conference in Italy and it has been even more successful than we expected.
As the camp was in “Eataly” we had an Eatalian FlashCamp party at the end, a cool way to make developers meet each other and to make them drunk :)
Someone even twitted that it was the best part of the FlashCamp in Milan :)

Last but not least: my friend Luca already uploaded some pics to his flickr account.

See you at the next camp ;)

 
 
November 18th, 2010

Short tips post :)

BitmapData size limit:
Up to flash 9 the size limit for a BitmapData object was 4096×4096 pixels.
With flash player 10 that limit was removed, but what does this exactly mean? May we be able to create 4097×4097 sized bitmapdata instances? the answer is NO, we can’t.
I just found an official explanation of that here http://kb2.adobe.com/cps/496/cpsid_49662.html

Just in case you don’t have the time\will to read it:
- we still have a limit!
- the limit is set to the maximum amount of pixels (16,777,215 (the decimal equivalent of 0xFFFFFF))
- the maximum valid size of the bounding rectangle side is 8191

Stage size limit:
It actually depends on the stage quality.
With a high quality set the bound limit is 4050×4050, if your content exceeds it gets cropped.
With a low or medium quality the bound limit increases, there’s no official documentation about that (or at least I didn’t find it).
Note that Adobe’s saying that “graphic artifacts” could be displayed when our stage “approaches” 3840 pixels range.

have fun :)

 
 
November 10th, 2010

As my previous post was announcing, cancelling and reannouncing, I’m speaking at WebTech Conference here in Milan.
Here’s my presentation slides

And here’s the examples zip: www.flashfuck.it/webtech/examples.zip
If you need something to be more clear or some further explanation please feel free to comment this post :)

 

!!!ONE MORE UPDATE!!!
I’ll be speaking :)
The session will be “Flash graphics unleashed”. 30 mins to dig into flash graphics capabilities.
See you there
ciao

!!!UPDATE!!!
Some work appointments came through and I’ll not be able to be back for WebTech :\
But don’t worry! there’s a HUUUUGE “replacement”, Sandro Ducceschi from SFUG has took over my slots! :)
so guys, have fun, I’ll be there with my soul :)
—————————-

Yup, back on stage :)

I’ll be speaker at WebTechCon Italy, it’s the first year for this German conference in Italy and there are a HUGE amount of good reasons for you to come.

First of all it’s not all about flash!! There are 5 main tracks: webtech, flash day, silverlight day, javascript day and php4 frontend day… yes, “day” is not to be intended as “whole day” but much more as “track”.

It’s a good opportunity to put an eye on what’s going on on the html5 or silverlight fields and learn something new.

On the flashy side there are a bunch of well known and surely attractive speakers:

Luca Mezzalira ,Andrea Trento ,Marco Casario …I’m sure you all know what those guys are known for… then… well…. there’s me :D

Further, it’s a good way to meet other guys from TheFlashMind AUG ;)

I’ll be speaking twice on flash graphics and pureMVC.

Be sure you buy a ticket and come, one month’s left, then… rock n roll

 

Today I had to install the must-have flash switcher extension for firefox (by Alessandro Crugnola) and I found that it’s not compatible with firefox versions after 3.0 …

I trust in sephiroth’s extension going to work properly even in unsupported firefox versions, and however it’s worth the attempt, so, how to install it anyway?

First of all, download the flash switcher extension from the mozilla addons site ( https://addons.mozilla.org/en-US/firefox/addon/5044/ ) and save it on your hard drive.

Now that you have the .xpi file rename it to .zip and decompress it, you’re getting a plugin and content folders, chrome.manifest and install.rdf files.

Open install.rdf with a text editor and examine this tag


here min and max versions are defined for the extension, so just change em:maxVersion from 3.0pre to 3.8 (or whatever) and save the file.

Now select all files and folders (not the parent folder!!!) (plugin, content, chrome.manifest, install.rdf) and zip all together, then change the extension from .zip to .xpi.

Open firefox, File>Open, browse to the .xpi file, install… done and working!! w00t! :)

My unsupported (but properly working) version of firefox is 3.6.8, the flash switcher extension version is 2.0.2.

enjoy :)

 

I just found a very exciting demo from Ryan Stewart on how to mash up Google Maps 3D APIs and Air 2 multitouch gestures.
You can find his experiment’s source code on his blog here with a great video demo.

By the way, I started looking at the video from YouTube and noticed a new awesome feature: audio transcription and audio translation! w00t!
I tried out that wonderful piece of technology. I am Italian, so I tried to translate it on the fly…the result was ASTONISHING: no word was translated correctly, no sentence had a real meaning, if you run a Math.random() on the italian dictionary and start making a speech you’re likely having something better.

I guessed the problem was with the translation, but I was wrong :\
at 1’46” you can find out that “To change the rules the perspective of a man San Diego freemen will concede you and all of the police on the street is the ability to going to fly over the map, she’s the perspective”… wtf!?
at 2’25” is even better: “but combining the there to gestures and grownups three the FBI a critic of the Iraq war unique way to browse and that’s really true that Bosnia really customize how the contents of the views that no one of the three demoted from a player and disturbing experience”….

Cool! An Adobe evangelist talking about Iraq war, FBI and Bosnia while free men will concede to you in San Diego…
Please, don’t trust that feature.
#google #fail