Sunday, October 17, 2010

Pixel Manipulation: Qt vs. HTML5 Canvas

(see the live interactive demo and the demo video)

Since I've been working on the web technologies side of things after I left Trolltech/Nokia, both at Qualcomm and now Sencha, I tend to think a lot more in terms of HTML5 rather than C++ or Qt. This used to be true for non-graphical magic only, but all is changing. I wanted to check the performance of pure pixel manipulation on the web compared to a native-code application. I remembered a wicked cool VGA mode 13h plasma effect written in Turbo Pascal (and some mixed x86 Assembly code) by me and another first-year college fellow some 12 years ago. It used a palette rotation technique, extremely useful in the old 8-bit indexed video cards.

I focused on porting it to Qt and adding full control of every parameter via keyboard to throw in some extra coolness. I first used an Indexed8 QImage because it kind of emulates the old frame buffer, but the extra color conversion costs when blitting made me go for a full-color canvas.

To my surprise, it also worked quite well on a S60 device running Qt's Symbian port. Same went for a Nexus One running the experimental and unofficial Qt for Android. Thesource code of the native side of this experiment is available at the X2's repo widget folder. Below is a (rather laggy and compressed) video capture of the demo.

After I got my Canvas version running, the results were rather disappointing: 5-20 fps depending on the browser. Due to my newbie nature with JS, I was almost sure the issue was in my code (i.e. Canvas couldn't be that bad). That's when I found a great presentation by Nicholas C. Zakas. After applying his tips on JS optimizations, the frame rate fired all the way up to ~60 fps on all browsers, achieving the same performance as its native cousin. The code was definitely uglier and harder to read, but the performance felt natural.

All's not that great, though. For high resolutions, Canvas won't be able to maintain the high target frame rate. Let's face it, manipulating all pixels in every frame is an extremely heavy operation. However, this is not a common use case, even less with high resolutions, even less happening in real-time.

I believe canvas was more designed to support image and music editing, relatively lightweight gamesvisualization widgets, and a bunch of other ultra cool applications. And, for most of it, it's quite there already. Higher-resolution and heavier stuff will get its prime time very soon with WebGL, and I believe it will change the way we use a computer and browse the web completely.

See the Canvas implementation source code, and make sure you don't miss the live demo.