Sunday, September 1, 2013

New Drawing Algorithm

I recently implemented a new drawing algorithm for morphs. The algorithm is similar to the algorithm in Pharo/Squeak and redraws only the parts of the world that changed, instead of the whole world.

When a morph issues a redraw, the world's damage recorder is notified to add the damaged area (outer shape in global pixel coordinates) to its damage area list. This is list of rectangles that defines the area to be redrawn.

The damage recorder redraws the world as fast as possible, i.e. there is a "loop" running in the background that redraws the world. This loop is created with the JavaScript function "setInterval" which takes a function (BlockClosure) and an interval (that is zero). Since JavaScript is single-threaded, the function is evaluated only when there is no other code running at the moment. Note that it not possible to replace this implementation with a "while(true)" loop, because then the browser would become unresponsive (because there is always JavaScript running and the browser does not update the content, process event and no other Smalltalk code can run).

At some point, the damage recorders issues a redraw of the damaged parts of the world (AthensWorldMorph>>redrawNow:). The damage recorder provides the list of damage rectangles. The morph first redraws itself (without submorphs) and clips the drawing area by the polygon resulting of the accumulation of all damage rectangles. Then the morph checks, for every submorph, if the submorph's outer shape intersects with at least one of the damage rectangles. If so, the submorph is redrawn recursively using the same algorithm. For every recursive call, the list of damage rectangles might become smaller, because the algorithm passes only those rectangles to the submorph which insect with its outer shape.

If you want to take a closer look at the redrawing algorithm, you can activate a graphical visualization of the redrawn parts (similar to flashing damage rects in Pharo), by executing "AthensGlobalMorphSettings instance showDamageArea: true".

No comments:

Post a Comment