Flash Player Mental Model The Elastic Racetrack

Posted on

Having worked with Flash since FutureSplash, I have come to some conclusions about how to think about the player during development. Welcome to the elastic racetrack.&

I think about the Flash Player as a racetrack. There are 2 distinct sections of the racetrack, one for executing ActionScript (subsection for event processing) and one for rendering content to screen. While running, the Flash Player loops around this racetrack at a preset speed designated as FPS in the SWF file. At all times the player will attempt to maintain the speed set regardless of what the player is asked to do. The designated FPS is the maximum speed of the racetrack and processing can never go faster than this limit but can go slower.A SWF file tells the player to do certain things at certain times. As the player processes these instructions, the racetrack is stretched in either the ActionScript section or the Rendering section or both. If you are processing lots of data or rendering lots of clips, either half expands to process everything you add in a single loop of the track. The player will not skip over anything that it is asked to do and will always attempt to finish a loop in the least amount of time possible but never faster than the designated FPS.There are several additional aspects that compound this model. First off, the player structures graphical elements into a descending tree. Starting at the base node(_leve0), there can be many branches each with frame content and sub nodes/timelines. With every loop of the player all of the elements on the tree must be processed. In the current F7 player, frame content is swept and processed in depth order as needed from the _level0 node. In terms of graphical performance, the key is to keep the tree shallow combined with making elements as simple as they need to be. The fewer items in the tree and the shallower the tree, the faster the graphics will render.

The tree structure also applies to ActionScript bytecode processing. In the AS phase, the tree is swept for bytecode given the trees current state. Should any events be designated they will be processed in depth order. ActionScript is stack based and thus all bytecode is pushed onto the stack and processed in a linear fashion down the tree. Depending on the volume of code and events on a given frame, the AS portion of the racetrack elongates. As there is no build-in way to defer code execution, the player will process everything that it is asked to process in a given frame loop. It is interesting to note that even code that uses functions and events can be sequenced into a long line of bytecode to be processed. In a sense the player is never lossless, it will always do all the work you ask of it and never defer to a later frame cycle. The key is to never ask the player to do too much on a given frame and to be able to defer logic and events to later frames optionally.

As for Flash 8, from the looks of the beta player, cacheAsBitmap allows the graphics renderer to cache a MovieClip branch as a Bitmap. In caching vector graphics to an to a Bitmap, the renderer does not need to rerender until the graphics have changed (dirty). Ideally this allows the player to focus rendering on different areas of the player and specialize how the vector renderer is utilized. In a tree based rendering model, assuming some branches of the tree are set to branch.cacheAsBitmap=true, the renderer will create a Bitmap on the first pass and reuse this Bitmap until the vector graphicis of this area are marked as dirty. In the same light, if the cacheAsBitmap branch is dirty every frame(animated), you have forced the player to generate a Bitmap (processing + memory) with every frame cycle. In my testing, optimizing using cacheAsBitmap is not as straightforward as it seems.

In summary, the player performance is a combination of 2 distinctly different elements, graphics processing and ActionScript bytecode processing. If you abuse one or both of these aspects the player will slow down to make sure everything is completed before the next cycle. In development of larger projects, the elastic racetrack has helped me explain the logic behind many seemingly strange performance optimizations for Flex and Flash development.