Thursday, July 10, 2008

ScatterBrain released


And now for something completely different...

ScatterBrain v1.0


Back in January I set out to create my own clone of a piece of software I thought was cool (a recurring theme I have). I call it ScatterBrain and it's a clone of the todo-list editor TaskPaper. Yes, I can hear the groans now, another todo-list program, yay!
It hasn't been in testing mode and it hasn't been in development mode either, it's just been sitting gathering dust for the past 4 months -- which is a waste. So I'm releasing it for free and without any sort of guarantee that it won't randomly crash or do anything else crazy.

Download

ScatterBrain v1.0 - OS X Leopard Only


If you do use it I'd love to hear from you @: grant -at- gxjones.com (Just know I cannot support this software unless I start charging for it. And if that's the case I recommend you go with the real thing: TaskPaper)

The Format:


It handles the typical taskpaper plaintext format:

Project:
- task

it also adds a group line which is identified by a '+' character and a section line which is identified by a '#':

#Some Section
+ A group

Clicking on the circle to the left of a task will mark is as "@done" as well as adding a @date tag with the current date.

Geeky details


Finally, if you absolutely need to change the color-scheme you can do it via tags within your text (I know that's uber geeky and not user friendly). Adding this to your ScatterBrain file results in project headers being black:

@pv_color_white(project-header-background-color,0.0,1.0)
@pv_color_white(project-header-gradient1-color,0.7,0.38)
@pv_color_white(project-header-gradient2-color,0.0,0.2)
@pv_color_white(project-color,1.0,0.75)


For reference, this is the default presentation context used:

@pv_color_rgb(group-color,0.0,0.5,0.0,1.0)
@pv_color_rgb(note-color,0,0,0,1.0)
@pv_color_white(background-color,1.0,1.0)
@pv_color_white(project-background-color,0.90,1.0)
@pv_color_white(project-header-background-color,0.85,1.0)
@pv_color_white(project-header-gradient1-color,0.86,0.65)
@pv_color_white(project-header-gradient2-color,0.66,0.3)
@pv_color_white(section-background-color,0.90,1.0)
@pv_font(project-font,user,24)
@pv_font(group-font,user,16)
@pv_color_white(project-color,0.25,1.0)



Development Status


I'd go back to it if there is interest. There were two killer features I was working on when I stopped development.

Known issues:


- large files will be fully reparsed and be very slow (so stick to smaller files); this was something I really wanted to address but never got around to it
- sometimes the formatting isn't updated
- formatting the background lags sometimes
- probably some memory leaks in there for good measure
- zero documentation - might be an issue for some people

Friday, July 4, 2008

FlashCanvas: 3 years too late?

So I guess I'm 3 years late to the canvas-emulation party:

  1. Manish Jethani mentions something about the canvas tag being used for a 3D game, John Dowdell from adobe responds in Nov. 2005

  2. Manish Jethani suggests a way to do a SWF-based Canvas on Dec 1st, 2005

  3. iecanvas from Emil A Eklund released December, 2005 (uses VML)

  4. excanvas from Google released March, 2006 (uses VML)

  5. AFLAX adds canvas emulation in March 2006


Overall, interest in this area seems to have died off - only recently with things like Processing.js and ContextFree.js has there been a renewed interested in backwards compatibility for the canvas tag.

side note: AFLAX uses the ExternalInterface just like FlashCanvas, so the performance observations would apply to AFLAX as well.

Thursday, July 3, 2008

FlashCanvas performance

Updated: see below.

The FlashCanvas experiment didn't really perform as well as I had hoped so I took a look to see where the slow down happens.
First, the speed of javascript execution was ruled out as the limiting factor. From the limited testing I did it is clear that javascript executes slower on internet explorer than ff or safari -- this is not news. Since flash is available on the platforms I can see they all perform roughly equivalent. This means that javascript execution is not the major performance bottleneck at this point because using a browsers native canvas element shows much better frame rates.

So this meant that the slowdown is occurring somewhere between the javascript call and the actual rendering to the flash MovieClip. I mocked up a dummy ping-pong page/flash file which simply calls a "ping" method from javascript into actionscript. The results revealed where the problem was:


note: JS2AS = JavaScript calling ActionScript; JS2AS2JS = Javascript calling ActionScript and ActionScript calling Javascript; os x and windows machines were physically different

Each call via the ExternalInterface is taking approximately 0.5 ms. Since the time it takes simply to call an actionscript method from javascript was now known I could then test to see if flash's rendering was taking up significant time: For the example1.htm page this means that it takes ~24 ms to render 20 individual lines. In Safari a call into actionscript is taking roughly 0.4 ms -- this is only the call time, it does not include the time to render anything. For example1.htm a single "particle" calls actionscript 3 times with the commands: [lineStyle,moveTo,lineTo]; each particle takes 1.2 ms in JS-to-AS calls; to take 1 second to render the frame ~833 particles need to be rendered. Changed the example code to render that many particles (and also time itself) results in:

(where time is in milliseconds)
So the time it takes for the javascript canvas wrapper, the javascript particle simulation and the actionscript code/line rendering is pretty much insignificant.

For comparison this is safari doing the same exact thing using it's native canvas element:

(where time is in milliseconds)

Next steps:

  • Investigate batching draw commands into an array to be passed only once into the flash renderer. Immediately this raises an issue about how the canvas API has been typically used: there is no explicit end of rendering or flush equivalent so the canvas-wrapper would never really know when drawing is finished. The most fine-grained control would be at the individual path level, which would result in nearly the same performance for something like the example1.htm file. Most graphics API have some sort of buffer flush either explicitly, like glFlush in opengl, or implicitly during a buffer swap.

  • Investigate other plugin technologies?




4-3-08 Update:
Batching commnads into an array does not eliminate the performance problem in ExternalInterface. FlashCanvas was changed to batch commands and then send them to flash with only one call via ExternalInterface. The result is only slightly faster (800 ms instead of 1 sec and a really slow 20 secs /frame in Internet Explorer 7). Since that part of flash is all closed I can't really take this any further -- my guess is that some sort of serialization/translation is taking all the time.

4-5-08 Update:
Try it at home: FlashCanvas 0.2. This includes the batched mode (which requires a call to context.fc_flush() when you want to send the commands to flash), see examples/example1_stress.htm to see how it works.

Tuesday, July 1, 2008

FlashCanvas


Download FlashCanvas 0.1
Released under the same Apache License as the exlorer canvas project.

What is FlashCanvas?


FlashCanvas is a canvas tag to flash bridge for browsers which do not support the canvas tag like Internet Explorer. FlashCanvas is an experiment to see if any performance improvement could be realized by using flash technology. The javascript code is a fork of the ExplorerCanvas project:
Firefox, Safari and Opera 9 support the canvas tag to allow 2D command-based drawing. ExplorerCanvas brings the same functionality to Internet Explorer. To use, web developers only need to include a single script tag in their existing web pages.


This FlashCanvas release only implements lines and fills. This is enough to support example1 and example2 from the ExplorerCanvas project.

FlashCanvas was put together in one day of hacking so it is pretty basic and has many bugs/quirks.

How does it work?


FlashCanvas is modeled after ExplorerCanvas which means it should be a drop-in module which provides canvas support. There are two main components combined together: the very basic FlashCanvas.swf flash file which compiles down to 688 bytes and the FlashCanvas.js wrapper/controller file. swfobject.js is used to embed flash into the page.

The FlashCanvas.js file implements a fake-canvas object and changes the existing canvas element into a a flash object (using swfobject.js). The javascript intercepts canvas commands and forwards them to the FlashCanvas.swf movie file using the ExternalInterface provided by the flash player. The flash movie clip then interprets the command and draws accordingly.

note: you must serve the files remotely. There exists a flash player bug which does not allow local connections to communication with actionscript from javascript using ExternalInterface even if permission is granted. (AS to JS does work with local connections however). A python script for running a SimpleHTTPServer instance is provided for testing purposes.


Why is ExplorerCanvas slow?


Although I'm not an expert on ExplorerCanvas, it is clearly not designed to do motion graphics. Almost everything ExplorerCanvas does is string manipulation to construct markup which is re-interpreted by Microsoft's Vector Markup Language. This method works sufficiently for static graphics but does not work well for motion graphics.

Does FlashCanvas provide better performance?


The short version: not really.
The longer version: All drawing commands are being forwarded from Javascript -> ExternalInterface (down into the browser) -> ActionScript -> Flash Drawing commands. This is a lot of overhead for drawing code. Doing something simple like a moveTo and lineTo would result in at a very minimum 8 separate levels of indirection.

FlashCanvas performance is discussed further here.

What other approaches could be taken?


Some other ideas:

  • Stop using broken browsers like internet explorer - We can dream...

  • A separate canvas plugin for internet explorer - this wouldn't be too difficult if the cairo graphics library were used as a starting point.

  • a more practical approach would be to abstract the canvas interface away by writing code targetted at the Processing language and then implement a processing flash interpreter (if one doesn't exist already)



How do I build FlashCanvas.swf?


The FlashCanvas.swf file is compiled using the MTASC and swfmill compilers.
Once those are installed run:
make