My blog has been moved to ariya.ofilabs.com.

Wednesday, May 20, 2009

Chrome Experiments, Flash-killer, Monster Evolution

These days I am juggling balls. Beside fixing QtWebKit-related bugs, writing more examples on using QtWebKit, I am helping the Kinetic guys with Graphics View optimizations, and working on new Graphics View feature I still can't elaborate (sorry for the teaser :-). On top of that, I already started to work on Qt Script, learning the intricacies of JavaScript along the way, stress-testing Kent's Qt Script binding generators, and surely also playing around with the brand-new Qt Script debugger in Qt 4.5. For the latter, even if you are not really into Qt Script, I highly recommend giving it a try, at least watch the screencast from Kent for a start.

Unless you stayed under the rock for the last few weeks, you already heard about Chrome Experiments. These are some extremely cool demos designed to run in a web browser. Of course, there are already tons of demos out there. Chrome Experiments are however different. It relies on a high-performance browser. The reason: the demo is JavaScript intensive and thus a blazing-fast JavaScript engine will make a different. Coupled with the use of HTML 5 Canvas, some of demos simply show many things which are not possible before. Flash will be still here to stay (due to its authoring tools, advanced features, libraries collections, and so on). But I won't be too surprised if this is going to be a Flash-killer technology. There is O3D but I reckon it tackles a different market segment.

My favorite Chrome Experiment is Monster Evolution, an fantastic demo written by Dean McNamee. Try to launch it in your browser (warning: extremely slow if you don't use state-of-the-art browser). Or just watch the YouTube video. Impressive, isn't it?

When I saw Monster demo for the time, I thought it would be cool to be able to run it as a Qt application. Porting the demo from JavaScript to C++/Qt is one way to do it, but to make the challenge even more painful, I decided to run the monster.js code directly (warning: it's minified, better check Dean's open-source 3-D engine behind the demo). There are tons of ways to do, I almost tried every possible permutations. In the end, I managed to run Monster Evolution smoothly, at more than 25 fps on a fairly modern machine. What was to be just a quick hack turned into a struggling but delirious adventure, resulting in a three-installment series.

For the YouTube generation, here is the time-lapsed screencast (if you prefer, grab the 3 MB AVI).

In the first part, The QtScript Menace, I used Qt's built-in ECMAScript interpreter to run the demo. The performance was not my main concern (though it gave me the chance of using our work-in-progress Qt Script version that uses JavaScriptCore as the back-end), rather the trick on how to run it with as little code as possible. I ended up with a hackish pure JavaScript implementation of the canvas object, along with few lines of glue code, using Qt Script's feature of making a QObject instance available to the script engine. Surprisingly, it works pretty well. It downloads the JavaScript code from the Internet, setups some stuff and then runs it. For a program comprises 240 lines of C++ and 140 line of JavaScript, I am pretty happy.

For the second attempt, Attack of the SquirrelFish, JavaScriptCore was chosen as the engine that powers the demo, used via QtWebKit. Again the same trick was employed, with the glue code now relies on QWebFrame's addToJavaScriptWindowObject and evaluateJavaScript. This requires only minimal changes, with an improved performance as the result (significant and noticeable), especially when JIT is available.

The saga was closed with the third episode, Revenge of the Cylinders. This time the victim was V8, the JavaScript engine which powers Google Chrome. Again, the code change was minimal, consider that V8 glue code to this little Qt application needs to be written manually. Of course this requires you to build V8, I have included the instructions (works on Linux, Mac, Windows) in the accompanying README on how to do that.

Feel free to try all three methods and let us know the frame-per-second speed-up that you get!

3 comments:

Anonymous said...

OMG! It actually works with Konqueror! A bit slowly but works which is nnnnice to see.

Luis Augusto said...

Works perfectly smooth on Google Chrome.

blauzahl said...

@Anonymous

Konqueror was actually the first browser to have canvas implemented.

It also has its own bytcode interpreter for javascript called Frostbyte. It's been there since 4.1.2.