Archive for the 'Technology' Category

Mar 26 2009

Exploded Schematic View of Flash and Flex Apps

Published by Corey under Technology, Toys

I am not sure who wrote FlexSpy back in the day but it struck me that such a tool could benefit from an interactive schematic view of the display list it’s introspecting. If anything it’s useful to see sometimes just how a component or UI is composed.

 

Included along with this post is a sketch (proof of concept) I put together over coffee this morning. Give it a run (just click on the image below to launch the sample, requires Flash Player 10):


LayoutSchematic

 

Initially you’ll see a vanilla Flex 4 dialog based UI. Push the ‘E’ key and the UI will transition to an interactive exploded view of the display tree. Push ‘E’ again to tuck things back where they started.

 

I’d imagine the approach would work with any 2D Flash or Flex content, though it really doesn’t make much sense with 2.5D centric apps. The basic idea is to just walk the display list and assign an appropriate z value to each depth level. I’ve offset siblings so they can be differentiated a bit, and injected a surrogate parent for the application so that I can adjust the registration point of the main application itself.

 

I have some ideas for use cases but I’d prefer to leave it to your imagination. The source is included in the SWF, please use at your own risk. If anyone feels like continuing to play with it please do, just let me know what other interesting ideas you come up with.

There are certainly bugs. When returning to the default 2D view for example, most nodes end up with zombie matrix3D instances, which cause Flex a few headaches and make the UI appear anti-aliased. As I have time I may toss a few fixes into the sample.

4 responses so far

Mar 25 2009

Some System.gc() and System.totalMemory Tips

Published by Corey under Technology, Work

When profiling a Flash or Flex application it’s sometimes useful to explicitly request that the player VM perform garbage collection. When used correctly this can help identify and track down memory leaks.

Some quick tips:

  • System.gc() is asynchronous! I can’t tell you how many times I’ve seen developers make the call to gc() and then immediately query System.totalMemory! I’ve also seen people call it twice in a row (just to make sure it sticks ??) . Internally System.gc() simply queues up a garbage collection pass for the next frame interval. So make sure you query totalMemory on the next frame (listen for enterFrame), or use callLater if within a Flex application.
  • System.gc() only works in a debugger player, and is a noop in the release build of the player. If you must do release mode profiling (which I highly recommend), you can utilize a well-known hack to force the player to garbage collect. Of course you do not want to make use of this in a production application, and the usual disclaimer applies, specifically this hack is not guaranteed to work in future versions of the player runtime.
     

    Keep in mind that the release mode GC hack is in fact synchronous, however in this case the internal player code also queues up additional collection for the next frame interval so it’s best practice to wait a frame even then, such that anything pinned in memory due to just being on the callstack can be cleaned up.

  •  
    1
    2
    3
    4
    5
    // Release mode gc().
    try {
        new LocalConnection().connect('_noop');
        new LocalConnection().connect('_noop');
    } catch (e:*) {}
  • System.totalMemory does not reflect all of the memory the player instance allocates. totalMemory is useful in most cases, since it reflects all of the memory that the internal player’s custom allocator has been asked to allocate for the bulk of the internal player constructs (inclusive of all script objects). Keep in mind however that not everything allocated in the player is allocated by the internal allocator, nor reported through totalMemory…namely anything allocated by OS system calls, memory associated with platform bitmap data, and the JIT buffer associated with the Actionscript VM.
     

    At times it’s useful to make use of other tools to glean the total memory used by the player. I recommend testing within a standalone release player and leveraging Process Explorer and its ‘private bytes’ metric when on Windows, or Activity Monitor’s ‘private memory’ metric on OS X. Steer clear of Task Manager, as it incorporates uncommitted virtual memory that may or may not be used and is lazily reclaimed by the OS.

     

    The next major release of the player will provide a new API which will more accurately reflect the cumulative memory in use by the player.

  • Not all players and SWFs are created equal. Memory usage of a debugger player rendering a debug SWF will be significantly higher than the same player rendering a release build of the same SWF. It also holds true that the memory usage of a debugger player rendering a release SWF will be significantly higher than a release player rendering the same release SWF. So long story short, it’s always best to do your profiling and performance testing in a release player (against a release SWF) when at all possible.

5 responses so far

Mar 25 2009

Player 10 Performance Gotcha - Sneaky Surfaces

Published by Corey under Technology, Work

When optimizing a production application, regardless of the SDK or technology used to build it, it’s important to understand the performance characteristics of the various APIs, primitives, and data structures that make up your SDK. When becoming proficient with a given platform it’s inevitable that you stumble upon nuances, inefficiencies, or just plain bugs…and over time your learn to “work with” (or around) said limitations.

Here’s one of the “plain ol’ bugs” you should be aware of when scrubbing your Flash or Flex application of performance issues.

Take the following code snippet towards the end of this post… Pretty simple, just creates a couple hundred Sprite instances, applies a quick opaque fill, and adds them to the stage. Taking a look at System.totalMemory, memory increases by about ~500K. Nothing mysterious.

Now, imagine we were to ask the player to cache each Sprite instance as a bitmap, e.g. via:

    currentSprite.cacheAsBitmap = true;

So for 250 display object instances, one would expect that the resulting ~ 3MB of memory usage sounds about right (32 bpp RGBA buffers). Again, nothing mysterious.

  

Now, let’s run the same test, but instead of setting cacheAsBitmap… what if we simply read the value of cacheAsBitmap for each Sprite instance:

    var test:Boolean = currentSprite.cacheAsBitmap;

Whoa! Again, we see ~ 3MB worth of surface allocations! For simply reading the property?!

Beware, this issue also affects a few other properties, some that may make it even more likely you’ll run into this… For example, simply asking a display object whether or not it has a scrollRect will cause a back buffer to be allocated for that object. Testing the opaqueBackground property also results in a similar fate.

Note: The problem as described currently affects the production Player 10 versions (10.0.12.36 and 10.0.22.87). The issue itself has been addressed and should be taken care of in the next non-incremental release of the player. Just tread lightly. :)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    creationComplete="updateMem()">
 
    <mx:Script>
    <![CDATA[
        [Bindable]
        private var totalMem:String;
 
        private function startTest():void
        {
            for (var i:int = 0; i < 250; i++)
            {
                var currentSprite:Sprite = new Sprite();
                currentSprite.graphics.beginFill(0x000000);
                currentSprite.graphics.drawRect(0,0,300,100);
                currentSprite.graphics.endFill();
               
                // Uncomment to allocate surfaces for each Sprite instance (+ ~3MB).
                //currentSprite.cacheAsBitmap = true;
               
                // Uncomment to (surprisingly) take the same surface hit (+ ~3MB)
                //var test:Boolean = currentSprite.cacheAsBitmap;
                //var test2:Object = currentSprite.scrollRect;
                //var test3:Object = currentSprite.opaqueBackground;
               
                canvas.rawChildren.addChild(currentSprite);
            }
            System.gc();
            callLater(updateMem);
        }
       
        private function updateMem():void
        {
            totalMem = String(System.totalMemory / 1024) + " KB";
        }
    ]]>
    </mx:Script>
 
    <mx:Canvas id="canvas" width="300" height="100" />
    <mx:Button label="Start Test" click="startTest()" />
    <mx:Label text="Total Memory: {totalMem}"/>

</mx:Application>

One response so far

Mar 24 2009

Improving Perceived Layout Performance in Flex

Published by Corey under Technology, Work

The Problem

For a typical browser-based Flex application, as the brower is resized by the end user, it’s very common to see the Flex content lag behind the browser frame. As the Flex app is resized very often you can see the Stage background paint, before the Application background can catchup.

Take the following example SWF (click to open):


Layout Sample

After launching the sample, resize the browser frame quickly left and right, and up and down from the bottom right corner of the browser chrome. You’ll notice that along the right and bottom edge of the viewport, the green stage background can be seen, as the content tries to keep up with the resize events. This “lag” is most commonly seen on Mac OSX 10.4 and later when running in the standalone Flash 10 player, Safari, or Firefox. On Windows, the lag is most commonly seen within the Firefox browser, but depending on your hardware configuration, can also occur in IE, AIR, and the standalone player.

The Solution

Whenever the player Stage is resized, the Stage issues a ‘resize’ event. In Flex, our top level Application object listens for the resize event. When it’s received Flex invalidates the display list, then queues up a layout request. Only later, when we eventually receive a ‘render’ event from the Stage, or an ‘enterFrame’ do we actually layout and update our display list.

Flash delivers stage resize events pretty much in lock step with the browser or parent container, but render and enterFrame events are tied to the player’s natural update interval. Since Flex waits until the following update interval to actually paint, we’ll always see this lag.

In the sample above, I’ve added a checkbox, which when enabled, demonstrates a smoother resize approach. Essentially we just ensure that we ‘validate’ our display list upon receipt of every Stage resize event. The solution is to ensure that when our root application is resized, that we follow suit with a validation (layout) as soon as we can, rather than deferring as is the typical case when child elements are resized on their own. Perceived performance can be greatly enhanced.

The Catch

Why don’t we make this change within the core SDK itself? Unfortunately, there’s a catch - an existing player bug we would have to work around, primarily on Windows. When the plug-in version of the player has its WMODE rendering mode set to “transparent”, or any other non-default value for that matter, display list corruption with TextFields can occur (specifically those using system text). When WMODE is set to transparent for example, and TextFields are present in the display tree, the raster representation of these text elements becomes visibly corrupt when they are moved and updated within a Stage resize event handler. A player bug is logged and the issue is being addressed.

In the mean time, if you know your interactive will never be using a non-standard WMODE, feel free to take the approach outlined. The results will be a much smoother, more responsive layout experience in most cases. Some cookbook code follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    applicationComplete="appComplete();">

    <mx:Script>
        <![CDATA[
           
            private function appComplete():void {
                stage.addEventListener(Event.RESIZE, onStageResize);
            }

            private function onStageResize(e:Event):void
            {
                validateNow();   
            }
        ]]>
    </mx:Script>
</mx:Application>

2 responses so far

Feb 08 2008

Flight 404

Published by Corey under Art, Technology

Today I learned:

  • Flight 404 is back!

I have been interested in generative art (art generated by code) for as long as I remember, and Flight 404 was always one of my favorite websites. I hadn’t checked for anything new until just today. Boy am I glad I did. Amazing stuff. Read about the process if you are interested… (part One, Two, and Three).


Magnetic Ink, Process video from flight404 on Vimeo.


As far back as I can remember Robert Hodgin did most of his work in Flash and Flight 404 was primarily used as his portfolio. For awhile now Robert has been dabbling in the Processing library for most of his experiments. Here’s another of his creations. Check out his blog for lots more!




Solar, with lyrics. from flight404 on Vimeo.

5 responses so far

Feb 03 2008

Adobe Week

Published by Corey under Technology, Work

Today I will learn:

  • What makes the Flex MXMLC (MXML compiler) tick.

I will be travelling to San Jose today to attend a week long internal developer’s conference at Adobe. In preparation for some minor compiler surgery I will be digging into the compiler guts on my flight there. I did learn this morning that a good portion of the compiler is based on Apache Velocity, so I’m snagging some research material and filling up the laptop.

While in San Jose I will also be attending a day long Hydra boot camp. If you aren’t familiar with Hydra (name to change soon), you can start here, or just Google around. Essentially though, it’s a shader language that will allow you to write to-the-metal (well, soft-metal anyways) pixel shaders for raster image manipulation. The sneak peaks making their rounds internally of potential use cases have been mind blowing.

So, lots to learn this week (and still make headway on my rework of the Flex State model).

Last week I learned:

  • Internet Explorer will finally nix the ‘click to activate’ behavior it’s had for years.

Sorry, I forgot to post this earlier, but last week I did receive confirmation from Microsoft that they have in fact settled their browser plugin grip with Eolas and will be soon releasing an update that finally rids the world of the ‘click to activate’ step for interacting with web based plugins (inclusive of Flash). But hey..fwiw, don’t stop using SWFKit and family, they are still a much cleaner way of embedding.

No responses yet

Jan 31 2008

Where’s Corey Now?

Published by Corey under Technology

Today I learned:

  • I can use my smart phone to track my location in real time.

If you are ever looking for me, I should be right about here:

Click here for a detailed view…

I was originally under the impression that I would have to purchases a subscription based service to make use of the GPS feature on my Blackberry Curve (either to access maps in real time or report my location to my personal site). Well, thanks to Doug McCune I found out that there is a great (and free) application from Mologogo that installs in no time flat. The app will display maps from either Microsoft or Google, and optionally feed your GPS stats (including elevation, etc.) to an URL of your choice. This allowed me to for instance embed a map of my location here. Any time you want to know where I am (and I have my cell phone with me), the map will reflect my realtime location. Doug’s inspiring post can be found here.

Some gotchas when I was trying to set things up:

  1. The download on Mologogo’s main site wasn’t auto-install enabled for my Blackberry (.jad file), but if you go to http://bb.mologogo.com there’s a compatible installer you can navigate to with your Blackberry.
  2. When setting up Mologogo to send data to an alternate URL it’s not enough to configure your profile on Mologogo’s site, you must also set the URL in the Mologogo app settings on the phone.
  3. Earlier in the day Mologogo’s website was down, and I wasn’t able to log in. I ended up surfing around and found another similar service called BlackberryTracker. There app also worked like a charm on my curve, and after you’ve registered for a developer key you can use their API directly to access your saved location data - so you don’t need your own server. Works pretty good but at the time of this writing their developer site is down (so you can’t get a key). But all in all much faster (less slick) application.
  4. For what it’s worth, the best tutorial to get you up and running and embedding your location on your own website or blog can be found in this wiki article.

 

Today I also learned:

  • There are some gotchas if you change jobs mid-year.

I ended up finally gathering up all my W2s, 1099s, 1098s, etc. and firing up ol’ Tax Cut. To our surprise it turns out we’re getting back a bit more than we thought we would. A welcome surprise, certainly better than if we found out that we owed. I really didn’t know that if you’d maxed out your social security contributions, then moved on to another employer, the new employer really has no clue, so continues to keep withdrawing social security. Good times.

2 responses so far