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

Thursday, December 16, 2010

motion vs orientation

I already showed the use of device orientation in a fun game called Box of Marbles. Based on my experience trying out this API implementation, often it is easy to get confused by device motion vs device orientation. Thus, I created two web-based applications (using on Sencha Touch): Device Motion and Device Orientation. Each basically just visualizes the values of the data in a bunch of sliders:

You can find the code in the usual X2 repository, under the subdirectory javascript/devicemotion and javascript/deviceorientation, respectively. Obviously, the rest of Sencha Touch library is needed before you can deploy and run the examples. For the lazy, just run the live demo for Device Motion and Device Orientation (they support offline mode).

While right now only iOS 4.2 on iPhone/iPad/iPod Touch implements this API, I have a strong hope that Android (post Gingerbread) and Nokia (thanks to QtWebKit and Qt Mobility) will support this cool API in the near future. Well, at least I do plan to revive my Symbian setup to custom compile QtWebKit and test it on Nokia N8.

Side note: from my limited understanding, seems that both accelerometer and gyroscope are needed in order to supply the accurate data, much like in an inertial navigation system ("Inertial Phone", anyone?).

Monday, December 13, 2010

the art of repository access

team

What will occur when a software team is working on a project? How to tackle the change control?

The first and foremost obvious approach is simply giving full access for everyone. This is what typically happens in a group of friends working together on a cool project, a school assignment, a short hackathon, an early prototype, or any other collaborative efforts.

While this approach is very democratic (all developers are created equal), it is not very scalable. It works on a small and agile team, mainly because everyone knows each other. Once the team grows beyond a certain limit, the overhead of the communication makes it impossible to continuously get a full picture of what is being work on by whom.

Usually this problem is minimized by having somebody responsible for each module, essentially putting some organizational hierarchy in the project. However, a slight problem in the communication (which happens quickly, we're talking about engineers here) is enough to provoke a situation where conflict occurs due to a certain check in which carries over the problems and bugs from one module to another (Law of Unintended Consequences).

Another approach, certainly an evolution from the first one, is limited commit access. This particularly works well if there is a dedicated army of maintainers, whose job is to review incoming patches, give feedback, check them in. Usually this approach is very beneficial for the new members of the team, because they can learn what works and what does not work (since they are indirectly guided by the maintainer).

Quality control is definitely easier since all patches will be always filtered. Limiting the damage due to a broken commit is also not difficult since the repository can be frozen while the disaster mitigation team carries out the work.

This approach however falls apart if there is not enough maintainers and/or the rate of submitted patches increases. The symptoms are easy to spot: patches stay far too long in the queue, a maintainer has no time to do his own development, bad patches sneak in due to the time pressure, etc.

Keep in mind that due to its implicit (often also explicit) social stratification, it is important to take into account what everyone thinks about the approach. There should not be someone who feels left behind because only certain chosen guardians have the ultimate privilege access the repository. When such a situation is not tackled early on, it would grow latently and explode at some point in the future.

If there is a worry like that, then another (slightly reversal) evolution is inevitable: full access to everyone, as long as the patch is reviewed. The gut of this approach is basically "Let's trust each other, but let's also watch each other's back". Thus, inherent code review becomes mandated as well. Everyone is free to check in his patch directly to the repository, as long as some other competent fellow has looked at it and gave the green light. In fact, this should be called "brotherhood repository access" except that it may sound too exclusive and mystical.

Sometimes the system is also setup as far as rejecting the commit (e.g. from the server-side) when the log does not contained something like Reviewed by: Joe Sixpack. This is of course not always necessary, it may even require a consensus from everyone, under the pretext of preventing accidental check in.

This last approach may still not work in some situations. For example, if the team is global and located in different time zones, then coordinating the review becomes challenging (distributed control system may alleviate the problem). When code review is not a encouraged culture, counterproductive dead lock can be depressing. Also, because it is based on mutual trust, it breaks down when some people do not play by the same rule. In short, the approach depends heavily on the strong and committed communication between the team members.

In the end, the repository access approach must be evaluated on a case by case basis. Of course, in some places, no approach will work to satisfy everyone. In that case, consider again that technology can't and won't solve every social problem.

What kind of repository access do you have in your group? Which one do you prefer and why?

Saturday, December 11, 2010

ubiQt

devdays

Since coming back from Qt Developer Days 2010 in San Francisco (more precisely in Burlingame, near SF airport), one thought really bothered my mind: "when will Qt become ubiquitous?".

Now, if you are active in the KDE and Qt community, this seems like a strange question. But ubiquitous means omnipresence, in particular for the whole developer community.

Flash back to ages ago. You wrote a cool Python script (could be also in Ruby, or Lua, pick your battle) to do FooBar, everyone you know was impressed, you wanted to share the love with the world and then some fellow hacker noticed, "That's cool, man. But I don't want to install Python, can you give me the executable?". What would you think?

The situation is similar with Qt these days. You write a nice Qt-based utility, running on different platforms, somebody spots it and the first thing he asks is "Where is the binary?"; never mind he has just grabbed and installed hundreds MB worth of utilities.

These days, when you are developing some software, the first thing you'd do on a fresh machine is to download and install a gazillion tools (Xcode with iOS SDK weighs around 3.8 GB). With the initiative towards open governance, I hope Nokia and others will be able to steward Qt in that direction: being included in the de-facto standard of development tool sets. The most interesting challenge is to overcome the doubt, "Why do I need to install some Nokia SDK to use your cool app?".

Saturday, November 27, 2010

Box of Marbles meets Device Orientation

Remember my Box of Marble demo?. It was a native Qt/C++ application running on Maemo-powered Nokia N900.

With the wave of DeviceOrientation Event Specification implementation, now it's possible to have the demo as a web app, running just inside the web browser. In fact, this is what you can see from this demo: ariya.github.com/js/marblebox.

Right now, it works with iPhone or iPad or iPod Touch running the new iOS 4.2, due to the brand new DeviceMotionEvent support. If you own a MacBook with accelerometer and you use Google Chrome, that works as well (tilt your laptop to see the gravity effect). But fear not, with the recent support to hook the acceleration data from Qt Mobilty to QtWebKit, don't be shocked if the next Nokia phone with built-in QtWebKit sports this feature as well.

While my previous demo uses Chipmunk physics engine, this web version relies on box2d-js instead, mostly because I am too lazy to port Chipmunk to JavaScript and also I want to try something else. If you are curious about the code, check the usual X2 repository under javascript/marblebox directory. Enjoy!

Wednesday, November 10, 2010

V8 + jslint + vim

Usually, you would want to use scripting solution, e.g. Perl/Python/whatever, to manipulate file contents. Somehow, it's also fun to use JavaScript instead. After I did the V8-based jsbeautify, I was doing V8-based jslint as well. Then I realized, let's just extend it to be generic. With API loosely modelled after CommonJS, filejs was born. Find it in the usual X2 repository under the javascript/filejs. There are two examples so far, ROT-13 and line counter. If you write more examples, feel free to pass them to me!

Of course, the twist is: use filejs to drive a command-line jslint. This is one way to do it. First build filejs (follow the instructions in the included README), then place the executable in your PATH. Create a simple shell script, which contains one line filejs /path/to/filejs/jslint.js $1 and make it executable. That's it! If you also store this shell script in your PATH, then you just need to run:

jslint source-code.js

If you use vim, jslint can be combined with Quickfix. First of all, associate *.js with the tool by putting this line in your personal .vimrc:

au FileType javascript set makeprg=jslint\ %

Now open a JavaScript file and run :make (or whatever shortcut you map this into), which will launch jslint with the current file. After a while, use :cope to open the quickfix little window, move up and down, and press Enter to bring you back to the main editor and set the cursor at the specified problem. Use standard window navigation, e.g. Ctrl+W W to switch to quickfix pane again. Check the quickfix documentation for details. All in all, you may want to map mostly used commands to some shortcuts for faster access.

Note that since this is dynamic JavaScript, rather than matching errorformat, technically I just tweaked the tool to spit something similar to what a C/C++ compiler would do. Also, if you need different jslint options, simply edit the invocation to suit your needs.

It's been a while since I blogged about vim. The last one was about the project plugin, which is surprisingly still quite popular. Hopefully this one also teaches you a trick or two, especially if you work a lot with JavaScript code.

Note 1: It does not work on Windows yet. No idea if I would have the time to do it, patch is welcomed.

Note 2: This is not a replacement for NodeJS, nor would it grow to include more functions.

Note 3: For the sake of completeness, let me mention that there are already other countless solutions for command-line jslint (using Rhino, SpiderMonkey, JSC, etc), even with vim integration.

Tuesday, November 09, 2010

chunks inside PNG

Here is a few minutes of hack which would hopefully help someone else:

pngchunks logo.png
File size: 5967 byte(s)

Offset    Chunk    Size
      8    IHDR      13
     33    iCCP    2627
   2672    IDAT    3271
   5955    IEND       0

Useful to quickly find out if we can further strip unnecessary chunks from the PNG image. Or even as a warming up before you fire your favorite hex viewer/editor.

It's pure, stand-alone, self-contained C code (i.e. compile using gcc -o pngchunks pngchunks.c), available at the usual X2 repository, find it under graphics/pngchunks.

Friday, November 05, 2010

the fun of remote JavaScript debugging

Remote feature of Web Inspector, whereby you use an instance of WebKit and debug another one in different machine, is one important feature (that is being worked on) of WebKit I can't wait to start using. Till that day, remote debugging is always a challenge. There are of course assorted workarounds out there. At Sencha we decide to have and share with you a little tool that helps JavaScript remote debugging. It is available in two flavors: GUI-based (using Qt obviously) and Python-based for scripts and automation. Right now, the target is Android WebKit but there is no reason why we should not march to other platforms as well (e.g. QtWebKit on Symbian and MeeGo). Get it while it's hot!

Thursday, October 28, 2010

morphing clock revisited

If you can't see the clock below, visit the stand alone demo.

Technically, I had wanted to wait till it can display the actual time and perhaps ask some designer to polish it. But rather than keeping this lunch-break hack in a safe deposit box forever, let me just release this ugly clock transition (since everyone is on the animation frenzy). So far it works only if you use latest version of Safari, Chrome, Opera, Firefox. Canvas and/or VML fallback (which sadly will require JavaScript) for other browser are in the pipeline.

Basically it is another version of my previous morphing clock attempt (see the video). The principle is the same, except now I modified that C++ program to also output an HTML which renders the clock as above.

Also it morphs only once. Reload the page to enjoy the morphing once more. Maybe I'll find the time (in another lunch break) to toggle the two clock modes. Update: morphing from/to both analog and digital mode is implemented.

Like I said, it's a creepy, machine-generated, ugly looking clock. You've been warned, but feel free to write me anything (should you need to vent your anger).

Wednesday, October 27, 2010

Look ma, no JavaScript!

Take a look at the following CSS 3 demo. No Flash. No JavaScript. No image.

Hungry for more? Enjoy some other demos created using Sencha Animator.

Monday, October 18, 2010

Qt Developer Days, Bay Area Mobile meetup

We heard that Munich Qt Developer Days was an awesome event, which is why I look forward to the San Francisco Qt Developer Days, which will be held November 1-3.

Now, if you are from outside US, drop me an email in case you fancy some quality tea/coffee time. Even better, on the next day (November 4), Sencha will host the first Meet the Sencha Team, the first Bay Area Mobile meetup. Our team will give an overview of Sencha and the mobile technologies we are developing. RSVP and drop by!

Thursday, October 14, 2010

sencha touch hackathon

Are you in the Bay Area? Don't miss our Sencha Touch Hackathon this Saturday (Oct 16) in our Palo Alto Office, 1pm to 5pm. There will be food and drinks as well.

Drop by and upgrade your Sencha Touch kungfu!

yet another command-line JavaScript beautifier (based on V8)

While we're still on the topic of JavaScript, I took the afternoon break to create a command-line runner for jsbeautifier.org . In case you miss it, I did the similar thing using Qt Script module. This time however, the command-line tool uses and exploits Google V8 instead.

If you update your clone of js-beautify repository, check out the fresh v8 subdirectory. I also mirror the code in the usual X2 repository, under the javascript/jsbeautify8 subdirectory. Also, grok the included README.txt first.

Update: I added --overwrite option which (surprise!) will overwrite the original source file (and thus, use it with care). This is useful if you invoke the beautifier tool from your text editor. Nicolas also implemented various settings support so you can specify the indentation level, braces placement, etc.

This is probably the last thing the world needs now, but hey, it was a fun break.

Wednesday, October 13, 2010

on JavaScript engines

If you are using a modern browser, likely you already have the (arguably) most widely deployed scripting environment: JavaScript engine (or ECMAScript, if you insist). There are many things you can do with it (just look at tons of cool web apps out there). However, since it is contained in the browser, there are also things the embedded JavaScript engine can not do for you.

If you are using KDE, you also have two excellent JavaScript engines: KJS and Qt Script. You can embed either of them (i.e. KJSEmbed) and make your application scriptable. In a not-so-strange twist, they both relate (distantly) to each other via JavaScriptCore, WebKit's default JavaScript engine, because long time ago Apple forked KJS and used it as the base for JavaScriptCore, and Qt Script (for version 4.6 and 4.7) also uses JavaScriptCore as the back-end.

If you are interested in learning, using, and/or dissecting other open-source JavaScript engines, have a look at JavaScript Engines: How to Compile Them I wrote for our Sencha blog, which covers Mozilla's SpiderMonkey, WebKit's JavaScriptCore, and Google V8. The instructions should work on the supported platforms, including ARM, in case (just like me) you want to have and carry around every JavaScript engines in this planet on your Maemo-powered Nokia N900. That is fun.

As the closing, just remember, "Ask not what the JavaScript engine can do for you — ask what you can do for the JavaScript engine".

Wednesday, October 06, 2010

color inversion for web pages

Something I worked on during my last few weeks with Qualcomm was color inversion for the web browser in Android. The patch was then integrated by Enrico (see the diff) because I switched job.

Later on this feature was also pulled into CyanogenMod. Thus, if you are running CyanogenMod 6 on your shiny Android device, you can try this feature already! In the web browser, just pick the Settings menu and then scroll a bit until you see a checkbox for Invert Color. You should get something like the captured screens below:

The idea behind this is to reduce the power consumption of Organic LED display, because on mostly-white web page, it hungrily grabs to 3x more power compared to LCD. This is similar to Jeff's trick of applying color filter in SurfaceFlinger.

Doing it at the user-space level gives one advantage: we can keep the embedded images non-inverted. Blindly inverting the entire screen would result in web pages look rather funky, especially those new sites with photos to accompany the articles. Of course, this hackish approach will not work 100%, (hint: double XOR?) since the web designer likely never intend the page to be color inverted. However it seems to work most of the time, at least with pages which do not have ueberartistic look-and-feel.

Faithful followers of my blog know that I already played with the color inversion ages ago, in the form of giving night mode appearance for QWebView. Thus, it happened that in one afternoon break I played with QtWebKit to do something similar to this selective color inversion.

Now, in the case of Android WebKit, the effect was rather easy to achieve. This is because Skia's SkCanvas is basically an interface which can be subclassed easily, while none of the functions in QPainter is virtual. The trick using Skia was to use a proxy canvas (a slight variation of Skia's built-in SkProxyCanvas) which I invented for this purpose but somehow also useful for another feature.

For QtWebKit however, we need to tweak it with some QPaintEngine voodoo. Check out the code at the usual X2 repository, find it under webkit/nightcapture (it still has some rooms for improvement, left as exercises for the adventurous readers). For simplicity, I made it as capturing tool so you need to pass a URL and the output filename. Unless you do something wrong, expect to get something like this:

The trick is the same as my approach for the Android patch: invert the colors of each image before drawing it, at the end invert the entire viewport. This seems like slow, but it's the best compromise I found out working with most sites. Note how we skip inverting any brush pixmap as usually brush is for the tiled background (and thus we want to keep it that way, i.e. not inverted). You can do some fancy magic with clipping and whatnot, but I doubt the end result is much better. Again, this whole stuff is a hack anyway and there will be always corner cases which will not work, no matter what approach you pick, thus there is no need to make it more complicated that it should be.

Just like they say, we code for life, i.e. the battery life.

Sunday, October 03, 2010

quattroporte and hummingbird

time is money

Fermi problem of the day, anyone?

Assume there is this large organization, say with over ten thousands employees. For some (legal) reason, each employee needs to write down what she has been doing for the week, usually by Friday afternoon. Some record everything in details (down to the hours), some prefer to just express "8 hours doing FooBar" for every working day.

Since this is 2010, usually the system is web-based. To prevent abuse, some login/credential check and anti-bot system are also in place. It is often unheard that people use their beloved smartphones to do the job.

Let us say it takes one minute to do this. With a really conservative $30/hour rate, this is worth 50 cents. Assume ten thousands do that, so it's worth $5,000. This translates to $260,000 per year.

Of course this is just a gross approximation. It does not even include/exclude the extra time the managers spend to double-check their staff's entries, typically (much) higher hourly rates, non-working (also known as vacation time), wasted effort to setup (and forget) the reminders, occasional weekend shock at times you forgot it, and other similar (intangible) overhead. Or if you just need 5 seconds to accomplish the task. But you get the idea.

Now, $260,000 is a lot of money. You can buy a decent house in San Diego. Or two shiny Maserati Quattroporte. Or several hundreds Hummingbird-powered phones. Or, in some parts of the world, access to fresh water for the entire city all year long.

Surely for a quarter million per year some smart people will figure something out?

Friday, September 24, 2010

invade & destroy

Developing games using HTML5 Canvas and JavaScript is simply the future. Something classic like Egor Balishev's RGB Invader, an entry in the 10K Apart, is usually my favorite.

If for some reasons (which I would not elaborate in this post) you need to deploy the game as a desktop or a mobile application, using Canvas and JavaScript gives another advantage: just package it with WebKit, for example QtWebKit if you do not mind using Qt.

However, since usually it is just about Canvas, often it is enough to run the game logic with a JavaScript interpreter and use some Canvas implementation for the display. This was something that I demonstrated before, i.e. running the Monster Evolution demo via JavaScriptCore and V8. Applying the same technique, and adjusting the shim so that it layers whatever RGB Invader requires, gives the following:

Basically it is using Qt Script (also in attempt to popularize it even more) along with a mix of C++/QObject and JavaScript machinery to fool the game code to think it's running in a browser environment. It was a nice afternoon fun project.

The code is in the X2 repository, find it under the javascript/invader directory. Get it while it's hot, and save our Earth!

Monday, September 20, 2010

offline, command-line beautifier for JavaScript code

There are many different ways to autoformat JavaScript code, my favorite is always jsbeautifier.org. Apparently, you can also use it locally without a web browser since it supports running it with Rhino.

It took me just few minutes to reimplement the same functionality, but using Qt Script, the fantastic ECMAScript support built into Qt.

The code is in the usual X2 repository, under the javascript/jsbeautify. Note that this is just a convenient mirror as Einar's js-beautify repository already includes this Qt Script driver.

With the rise of server-side JavaScript and desktop-esque JavaScript tools, I hope Qt Script will become more popular. It is sadly still "underrated" right now.

Saturday, September 18, 2010

san francisco

I have been in Qt Developer Days twice, in the previous two years. This year I am still going there, but only the San Francisco event, for the first time as a participant (as opposed to as a speaker). I'll bring other new engineers at Sencha, too.

Since I live in the Bay Area these days, feel free to email me should you want to meet for coffee/lunch/dinner. See you there!

Monday, September 13, 2010

geocoding based on IP address

Given an IP address, there are different ways to obtain the approximate location: online web service or offline database. It is far from perfect, but it is very useful to give some initial guess before locking into GPS signals or using WiFi-based tracking.

Today's example for X2 is actually an old code lying around which does the former: relying on IpInfoDB web service to guess where your computer is. Combined with the previous example, MapSnap, the guessed position is used to center the shown map (OpenStreetMap, of course).

Of course, as with other examples, it works fine on Maemo-powered Nokia N900 as well. Feel free to give it a try on Symbian or other supported Qt platforms.

The code is found in the usual X2 repository, under the sensor/ipgeocoder subdirectory.

For completeness' sake, let me mention also that Matteo did something similar, using hostip.info and Google Maps via QtWebKit.

capture OpenStreetMap and MapQuest (and Ovi Maps)

Over a year ago, I showed how to render OpenStreetMap on your Qt application. While there were few follow-ups after that, I never found some time to clean it up. But worry no more, here is one OpenStreetMap-related example (at roughly 250 lines of code) I just made public, freshly available from X2 repository under the graphics/mapsnap. It's operated from command line, basically you pass the center latitude and longitude, zoom level (1..17, with 17 is the detailed, street-level zoom), output filename (e.g. mymap.png), and the size.

The following image is the result of running:

mapsnap 37.45108 -122.15917 12 sample.png 600 450

The tool will grab the tiles, more precisely Mapnik-rendered tile images, and stitch them for the final outcome:

Few weeks ago I wrote about MapQuest embracing OpenStreetMap. One positive impact of this awesome move is that you can show OpenStreetMap-based MapQuest tiles in your application. It's just the same map data but rendered using different styles. Running the previous example but with MapQuest flavor gives the following:

When checking out Qt Mobility after its 1.1 TP announcement, I found out that its Maps/Navigation API actually uses the tile data from Ovi Maps. If you read the source code, the tile server encoding scheme is pretty obvious. Since it is also based on Mercator projection, changing this MapSnap example to use tiles from Ovi Maps is a breeze: it's a matter of setting up the correct tileURL.

I'm curious about the terms of such Ovi Maps tile usage, though. Although it is more or less "exposed" via Qt Mobility and there is no API key whatsoever, surely it should not mean the tiles are free for everyone, should it? As a comparison, Google Static Maps API specifically allows only browser-based application. Feel free to share your investigation!

Saturday, September 11, 2010

minimalistic JavaScript editing widget

In the spirit of clean-up-and-publish, here is another code example of X2: a subclass of QPlainTextEdit which acts as a nice and minimalistic JavaScript editor. Basically it just adds a sidebar for the line number and a syntax highlighter. Thanks to QPlainTextEdit and QSyntaxHighlighter, this editing widget is quite performant. At just about 500 lines, think about it as another example on how to use these two classes.

It does support specifying different colors so you can have funky color scheme if you want:

The widget is BSD licensed. Find it out in the X2 repository under the javascript/jsedit subdirectory.

It does not have fancy features such as code folding or autocomplete (not sure I would have time to add them, so patches are welcomed!), but if you want feature packed editor, use QScintilla, KDE's Kate, Qt Creator's editor, or grab something else or even write your own.

Thursday, September 09, 2010

the art of blurring the shadow

In the recent weeks, sporadically I have been working on QtWebKit to fix the missing blur support for Canvas and CSS shadow (see the tracking bug 34479). This brings some good memory; before I left Nokia, I was involved in prototyping the special effect stuff, both for the low-level (non-public) QPixmapFilter and the high-level QGraphicsEffect.

Usually blurring drop shadow for a shape is a very typical: grab the alpha channel of the shape, apply the blur filter, and finally tint it with the intended shadow color. The last step is trivial using the SourceIn composition mode. The blur filter is supposed to follow the SVG specification on feGaussianBlur. The said specification mentions one possible way to approximate the perfect Gaussian blur: three successive box blurs.

Since QPixmapFilter is private anyway and QGraphicsEffect is not suitable for this task, an attempt to implement what the specification outlines became my hobby for a few evenings. This is basically what emerges as the shadow blur implementation in QtWebKit. For the sake of code reuse, I pushed the implementation to the X2 repository under the graphics/shadowblur subdirectory. The shadowBlur() function itself is BSD licensed, there is a demo program included for your pleasure:

Performance-wise, the code is as satisfactory (for such a portable implementation). Another good approach is to use stack blur, adopted among others by AGG. KHTML notably uses stack blur for its Canvas shadow blur support. Exponential blur is known to be very fast, although quality-wise it deviates farther from a true Gaussian one. The portable, raster version of QGraphicsDropShadowEffect (via QPixmapFilter) is using this algorithm.

For this particular use-case, namely blurring the shadow (as opposed to generic blur filter), I'm surprised that the Gaussian blur approximation is not necessary slower than KHTML's stack blur approach or even QGraphicsDropShadowEffect's exponential blur. I did a quick benchmark, measuring the time spent creating the shadow for two images (horizontal 149x13 and vertical 13x149) for different radii (small 4px and medium 17px), on a Core i7 machine. The outcome is shown in the following bar chart. The result was from several runs, with the overall confidence level observed to make sure it was statistically sound. Still, take it with a pinch of salt.

With a very large blur radius, e.g. 50, stack blur performance deteriorates quickly, probably because the pre-loop initial setup. Exponential blur is pretty much radius-agnostic, although I can't find cases where it wins against my shadow blur code (which is BTW only 60 lines). Larger source images would highlight the performance difference even more. Maybe I am doing something wrong, or maybe that's how it is. In any case, I insert a low-priority entry in my (already infinite) TODO list: spend some quality evenings with callgrind and examine those blur implementations.

On mobile devices however the situation is reversed. The approximated Gaussian blur is consistently slower, around 10%, compared to exponential or stack blur, when tested on 600 MHz Cortex A8-powered Nokia N900. Due to slower memory speed and smaller cache, the repetitive memory access for the successive box blurs cancels its fast processing benefit. Hopefully the 1 GHz generation CPU (like in Nokia N8) and improved memory bus will eliminate this minor slow down.

Anyway, in all cases, just like Andreas mentioned, now you can enjoy the fancy Parcycle demo in its full glory:

Wednesday, September 08, 2010

Sencha Touch and N900

Being part of the awesome Sencha Team, I did shoot a quick attempt to run Sencha Touch, more precisely its Kitchen Sink demo, on Maemo-powered Nokia N900. Since Sencha Touch targets WebKit but Maemo default browser is Gecko/Firefox-based, I crafted a mini launcher which wraps Sencha Touch in QtWebKit. The screenshots below serve as the proof:

Most of the stuff works just fine. There are some minor issues and performance problems, but I worry not. With the amazing amount of optimizations Qt+Nokia put in place for Qt 4.7 and QtWebKit 2.x, writing applications for Maemo/MeeGo will be fun (again).

Wednesday, August 18, 2010

box of marbles redux

If you enjoy the box of marbles demo, now we extend it to include some basic network support. The premise is simple, look at this short video first (or watch on YouTube):

The code to handle the physics of the marbles remains the same, i.e. we just use Chipmunk physics engine. However, I added a simple feature to transfer marbles from one place to another. To keep it simple, it is done using UDP. The Qt network module supports UDP quite well, making the datagram code short and readable.

The intended use of this example is easy: run the desktop version and then run the mobile version (tested with Nokia N900). Each instance should find each other and start communicating. Again, we simplify the situation here and handle only 2 (two) peers. To facilitate troubleshooting, the application window title will contain the network address information, if the two peers are fully connected. To avoid complicated setup, discovery is carried out automagically through broadcast. This makes such a demo runs only under the same subnet, which is not a big deal.

It would have been much more fun doing the transfer between two smartphones (instead of a phone and my laptop). However, I own only one Nokia N900. Hint: I will not refuse your donation of Nokia N8 or (preferably) MeeGo-powered Nokia N9 (i.e. the N900's successor, whatever the real name is).

If you want to give it a try, head to the usual X2 repository and look at demo/marblenet subdirectory. Again, have the patient to follow the README file before you start compiling it.

Of course, feel free to extend this example to suit your (more wild) fantasy!

Wednesday, August 11, 2010

adventure to the land of green tea

Now I work for Sencha, the company behind the leading JavaScript frameworks such as Sencha Touch, Ext JS, Ext GWT, Ext Designer, jQTouch, Raphaël, Connect, which empower developers to create, deploy and optimize application using web-standard technologies (HTML5, CSS, JavaScript). Beside, it's a hot startup to work for.

quattro cinque

It's released!

Tuesday, August 10, 2010

box of marbles

The next logical step after simple bouncing ball example is something which uses a real, full-featured physics engine. Box2D is usually the popular choice. Combining Box2D with Qt has been done by many people, recently demonstrated before by Andreas and Thorbjørn. I decided to pick something else, i.e. Chipmunk physics engine.

Because this is supposed to an example, I tried to make it as simple as possible (you'd be able to extend it, once you grab the basics). Basically we have a box full of colorful marbles (yes, I loved to play marbles when I was a kid, there was not any PlayStation back then). A mouse click, or a screen tap, will generated a new marble with a random color. If you run the example on Nokia N900, you can control how the marbles move and hit each other by tilting and shaking the phone.

Check the code yourself at the usual X2 repository under the demo/marblebox subdirectory. Make sure you open and follow the instructions in the included README file.

For a sneak peek, just watch this video (or enjoy on YouTube).

There is still a sequel to this marble box. And still with Chipmunk.

what is it with this froyo obsession

Eclair still rocks :)

Eclair

Monday, August 09, 2010

bouncing ball with accelerometer on N900

First of all, I apologize for my laziness in updating X2 with new code example. I have actually written quite a number of interesting examples, some of which have even been shown back in March, during my talk at Bossa Conference 10, though I did not find the time to clean up and polish them. Although I'd face new challenges in my upcoming adventure, I am quite confident I will reach the designated rate of new X2 example fortnightly.

Now let's focus on the newest example: a minor modification to the previous accelerometer code on Nokia N900 [1]. There has been confusion with my statement there: put this function is a separate thread. This is the alternative to a non-blocking D-Bus code. The main goal of course is not to be able to get faster acceleration values per second, it is only to prevent your code from being blocked by the synchronous D-Bus call.

Rather than just updating the code with the threaded version, I also added some high-school Newtonian physics. Instead of boring sliders, you'll get a ball which moves based on the acceleration [2], i.e. it follows the gravity if you keep your N900 straight.

Here is the obligatory video. Or watch directly on YouTube.

The code can be found in the X2 repository under the sensor/bouncingball subdirectory.

In the next installment, we will integrate a third-party real physics engine and make the example more alive!

[1] Another approach is to use Qt Mobility. However, QTMOBILITY-381 (which was spawn from QTMOBILITY-326) has not been solved yet (as of today).
[2] The overall math is not too scientifically correct, but hey, I always need to leave out something, for your homework :P

Friday, August 06, 2010

even LOST has its season finale

the final countdown

Today is my last day at Qualcomm.

It still feels like yesterday when I set foot in this continent, started some fun with X2, enjoyed Brazil, had this meet-up in Cupertino, did little exploration around San Diego, and then got blessed with a cute boy. Time really flies. Now it's already time to move on, again (though this time without a geeky resignation).

I will miss Snapdragon (the pictured HTC EVO is powered by the said platform). Or any other dragons.

Those who are annoyed by a certain obsession of mine probably can guess where I'm heading to. In the grand mission of inspiring and pushing developers to write better and more exciting applications, a particular productivity barrier needs to be broken. And I dropped enough (subtle) hints in my previous blog entries already.

Stay tuned.

Monday, August 02, 2010

crowdsourcing for the win

In some news, MapQuest embraces OpenStreetMap, launches the maps site at open.mapquest.co.uk using the data from OpenStreetMap, as well as sets aside $1 million funding to improve the maps situation in USA. Let's see if other maps services will follow.

Friday, July 16, 2010

var Adam = new Child(Ariya);

> Adam.prototype
Human
> Adam.timestamp
1279148700
> Adam.length
50.17
> Adam.weight
3.4
> Adam.health
Checking.... Good
> Adam.mother.health
Checking... Good
> Adam.father.status
"Happy"

Friday, July 09, 2010

faster quaternion multiplication

Sweet memories, it was fun to derive it.

Faster here however must be taken with a grain of salt as the new code is not always guaranteed to be better pipelined.

And of course, it's trivial to beat this generic C code with architecture-specific hand-rolled assembly.

git show cbc22908
commit cbc229081a9df67a577b4bea61ad6aac52d470cb
Author: Ariya Hidayat 
Date:   Tue Jun 30 11:18:03 2009 +0200

    Faster quaternion multiplications.
    
    Use the known factorization trick to speed-up quaternion multiplication.
    Now we need only 9 floating-point multiplications, instead of 16 (but
    at the cost of extra additions and subtractions).
    
    Callgrind shows that the function now takes 299 instructions instead of
    318 instructions, which is not a big win. However I assume the speed-up
    has a better effect for mobile CPU, where multiplications are more
    expensive.
    
    Reviewed-by: Rhys Weatherley

diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index 55c871d..9a1b590 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -198,24 +198,17 @@ inline QQuaternion &QQuaternion::operator*=(qreal factor)
 
 inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2)
 {
-    // Algorithm from:
-    // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q53
-    float x = q1.wp * q2.xp +
-                    q1.xp * q2.wp +
-                    q1.yp * q2.zp -
-                    q1.zp * q2.yp;
-    float y = q1.wp * q2.yp +
-                    q1.yp * q2.wp +
-                    q1.zp * q2.xp -
-                    q1.xp * q2.zp;
-    float z = q1.wp * q2.zp +
-                    q1.zp * q2.wp +
-                    q1.xp * q2.yp -
-                    q1.yp * q2.xp;
-    float w = q1.wp * q2.wp -
-                    q1.xp * q2.xp -
-                    q1.yp * q2.yp -
-                    q1.zp * q2.zp;
+    float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp);
+    float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp);
+    float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp);
+    float xx = ww + yy + zz;
+    float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp));
+
+    float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp);
+    float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp);
+    float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp);
+    float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp);
+
     return QQuaternion(w, x, y, z, 1);
 }

Monday, June 21, 2010

proxy server with filtering feature

Beside exploring San Diego, I had done some coding intermittently only. My apology if I do not update X2 with fresh new examples often enough.

Having said that, here is one network-related example: a minor tweak to the previous example of Qt-based proxy server. Basically it adds a minimalistic URL filtering support, in the form of blacklisting certain URLs which start with some predefined strings. The code is available in the usual place, X2 repository, under the directory network/filterproxy.

While major browsers support some variants of content blocking, be it via an extension like AdBlock or as a feature built-in into the browser itself, this new filterproxy should work with any browser that supports proxy. Alas, I did not bother to implement an AdBlock-compatible rule system because it would complicate the code. Again, consider this is a proof of concept only. A challenging exercise would be to fully support the most known subscription filters.

It is unheard that content filtering can dramatically improve your browsing experience. Because it cuts the bandwidth usage, it does translate to lower cost for those who are not lucky enough to get unlimited data plan. But most importantly, throwing garbage out of the web pages definitely speeds up the page loading. For this filterproxy example, I did a very unscientific benchmark and test it with Detik.com news site (now you get the answer why the included blacklist.txt contains only some basic advertisement-laden sites). The screenshots below (click to enlarge) show the unfiltered version (left) and the filtered version (right). Notice also the whopping 40% of bandwith saving!

My promise was to post two variations from that simple proxy example. This counts as one of them, and when the time allows me to clean-up to the other, you'll know it. Stay tuned and happy proxying!

spring-to-summer: photo blog

Since I've not been blogging for a while, let me do a post on some pictures (plus the stories) instead.

On a weekend, Balboa Park is a very nice attraction. Rather than explaining it in details, I suggest to just drop the park a visit. Beside a lot of different types of museum, there is also this Japanese Friendship Garden. A small cafe there, the Tea Pavillion, is a very nice place to relax and enjoy the surrounding. They serve sencha and other types of tea. Hungry? Get a rice bowl:

rice bowl

If you are more a beach person instead, then there is a plenty of choices, for example Silver Strand Beach. It is rather small, but it is always a nice spot to enjoy the sunset.

silhouette @ sunset

When I was at Google IO, I took some pictures of the large overhang banners because I wanted to test the 8 megapixel camera of HTC EVO 4G that Google gave away (see more in the complete set):

api

Getting a fantastic gift for the Father's day? Thinking of something for the next Mother's Day? What about a beautiful pendant (get one from LuShae Jewelry) like what my other better half elegantly captured below?

pendant

Tuesday, May 18, 2010

google io 2010

In few hours, I am scheduled to fly to San Francisco, bracing for the impact of Google I/O 2010!

Quake and WebGL

While I'm there, let me just quickly blog about it. Using the developer version of Chromium on OpenSUSE, I just run it with the following arguments:

/usr/bin/chromium --enable-webgl --in-process-webgl

and then I have WebGL at my fingertip. You can test it with some O3D samples (the pool one is pretty cool).

In fact, just go ahead and play Quake II at http://playwebgl.com/games/quake-2-webgl/.

I got bad FPS because I own a cheap laptop (8 FPS is more than what I expect from a $330 box). Obviously you can get 25 FPS or more on a much better machine!

Saturday, May 15, 2010

QNetworkAccessManager, tracenet, Speed Tracer

Just like Rich's trick with QNetworkAccessManager, I have done something similar which I call tracenet (around 150 lines of code). Though I have committed this example to X2 some time ago, only now I have the chance to blog about it.

The idea is to subclass QNetworkAccessManager and reimplement its createRequest method so that we can keep track all the network responses and replies. This is useful for your network-based application, or even for e.g. QtWebKit. As a matter of fact, the tracenet example captures the network traffic as you load a URL into a web page.

Now, the next step is how to visualize the result. While it's certainly possible to craft a Qt-based fancy GUI for this (maybe using Qt Quick?), let's think outside the box. Unless you live in a cave, I am sure you are aware that there is this nice tool called Speed Tracer, part of GWT, an extension for Google Chrome or Chromium. For this purpose, we won't use the live profiling feature of Speed Tracer, but rather its ability to visualize network requests and replies (with nice timeline and so on). All we have to do is to carefully spit some JSON-formatted data that match the Speed Tracer data dump format. And that is exactly what tracenet does!

The screenshot below gives an exemplary result from running tracenet on my Nokia N900 when it accesses New York Times front website, a notoriously complicated web page. All I did was to execute "tracenet > nytimes.htm", transfer back the HTML file to the laptop and then open it with Chromium on OpenSUSE, click on "Network (resources)" line, and voila! You can click on each entry to get detailed timing info, use zoom in/out, and many other features of Speed Tracer. Refer to some tutorials if you are new to Speed Tracer.

If you want some follow-up and challenging exercise, try to split Speed Tracer code so that the pure GWT-part can run on any browser. Then you can just package it with QtWebKit and use it to show the outcome of all your network sniffing. Have fun!

Sunday, May 09, 2010

vittoria: tiger in color

Continuing from the saga I started some time ago, at least now I got to the point where it's rendered anti-aliased in full color:

Stay tuned, I'd clean-up and release the code soon-ish.

Thursday, May 06, 2010

vector graphics, tiger in wireframe

At the risk of starting another yet-will-be-unmaintained project, sometime ago I decided to continue learning about graphics stuff in my spare time. I will not announce it of course until its code is better for public consumption. However, I really can't contain my excitement when it reaches an important milestone:

This sounds like childish, but as a graphics n00b, the above screenshot means a lot to me.

Stay tuned!

Saturday, April 10, 2010

cupertino

Tomorrow, we (a bunch of Qualcomm folks working on WebKit) will go up north. We'll be at Apple HQ in Cupertino for the WebKit contributors meeting. I look forward to meeting all the great WebKit hackers (again) face-to-face!

Monday, April 05, 2010

simple http proxy server in 100 lines

I guess a simple proxy server should have been an example in Qt Network module. What I mean of course a real proxy server based on Qt, not about using a proxy server via QNetworkProxy class. After all, there are other more complex examples like the torrent client and Google suggest (yeah, blame me for the latter). As a matter of fact, there are e.g. a gazillion proxy servers written in Python.

Look no more. I posted an example in the X2 repository, under the directory network/webproxy. The code is written for clarity and not for performance. In fact, fancy error handling is even omitted (minimalism rulez!). There is no support for pipelining, or in-memory cache, or per-connection thread, or even secure connection via https. I leave them as exercises for the curious readers.

If we focus on things which work, here they are: asynchronous socket handling, different request methods (GET/PUT/POST/HEAD), persistent connection aka keep alive, and even Flash and HTML 5 video streaming. Yes, you can still watch YouTube or Vimeo if you hook your browser into this little proxy. For a few hours of hacking and 92 lines of code (as reported by sloccount) and certain ways to abuse QObject, I could not be more happier.

There will be two other offspring examples based on this one. So stay tuned. Meanwhile let's just hope nobody would ask me for a colorful UML diagram for this snippet...

PS: Special thanks to Jan Erik for his feedback and review.

Friday, March 26, 2010

multiples of 3 or 5

One day Helder showed me Project Euler, a collection of interesting math problems to be solved using computer programs.

I took a look at the first problem: find the sum of all the multiples of 3 or 5 below 1000. Getting the linear time solution was trivial, the constant time solution was also not hard. However, I could not help it, I continued by applying some obfuscation voodoo and came up with this answer (of course, constant time as well):

return "uncopyrightable"[n % 15] - 'a' + 44 - "xzoxy}pge]_LAKD"[n% 15] +
'A' - (!(n % 15)) * 9 + 15 * ((n / 15) * (4 + ("aaabbcdddeffggg"[n % 15] - 'a')) +
(n / 15) * (n / 15 - 1) * 7 / 2);

How did a word ("uncopyrightable") end up in that solution? Believe me, it was (a lot of) fun! :)

Saturday, March 20, 2010

morphing clock

As I promised before, here is a fresh X2 example. Those who attended Bossa Conference 10 and followed my talk are lucky to have seen it for the first time there. In fact, this example is ridiculously simple that I am not surprised at all if somebody has done this ages ago.

Let's start with a screen capture, or two:

Basically the above shows an analog and digital clock running on my Nokia N900, hardly a shock. However, the fun part is when you switch the clock from analog to digital and vice versa. Check out this video, or watch directly on YouTube, courtesy of Signor Portale from Nokia/Qt, showing the morphing on Nokia 5800:

The trick is simple. Actually it's not even generic enough, meaning that you can't morph from an arbitrary path to another arbitrary path. However, for this clock use-case, the gross approximation is good enough. First, we need to convert the path into a polygon, which is done easily via QPainterPath::toFillPolygon() function. Then any line segment in the polygon longer than a certain tolerance is further split into smaller segments. As I claimed above, the result is not perfect, i.e. it does not approximate the original path into line segments with equal length. But hey, it is good enough for this animation purpose (unless your user has ueberhuman eyes).

The target path needs to be sliced into segments as well. Since we have only two types, circle (for the analog clock frame) and solid block (for the hour and minute hands), it is easier to special-case both. The secret is to have the same number of segments as the source path. The following figure shows the digit '7' and a circle, each splitted to 28 line segments. Small dots indicate the start and end points of those segments. The animation is now a matter of doing tweening, or linear interpolation, between each segment.

The flaw of this trick is when the source path contains holes inside it, e.g. for digits like 0, 4, 6, 8, and 9. Again, we are cheating here for the sake of keeping the code simple, so I leave the code as it is. Doing a more advanced, better handling for those cases is left as a motivational exercise for the perfectionist readers. Another bonus puzzle: find out why 503 ms is the morphing time (hint: find the same number in Qt source tree).

The code is in the X2 repository, check the sub-directory widget/morphingclock. You need Qt 4.5 or later. It is not long at all (surprise!), sloccount reports 191 lines of code. A morphing-clock plasmoid is also underway, just be patient.

For the sake of completeness, let me mentioned Dali Clock (even in Canvas and JavaScript version) from the famous Jamie Zawinski (jwz). It is similar, however Dali Clock just morphs the digits of the digital clock.

Also, if you just prefer a normal (but old-fashioned!) digital clock with the flipping effect, check the digiflip example I did back then. You already have it if you install Qt 4.6 for Symbian.

Last but not least, I'd like to mention my "special thanks to Delta Airlines for such a long (but safe) flight to Brazil so I had the chance to write this example while I was bored", but then I was told by the Trolls that this kind of intro line can't be funny anymore.

Thursday, March 11, 2010

new X2 logo

I got few proposed designs after I announced X2 project back then. It is tough to pick the winner cause they are all very good. In the end, the one from Elvis Stansvik becomes the new official logo of X2:

Thank you to everyone who has sent me the logo design!

Monday, March 08, 2010

manaus and bossa conf

Right now I am in Manaus, in the middle of the Amazon, Brazil. Good weather, beautiful nature. Fresh tropical rain, feels just like home.

Yes, I am here for the (legendary) Bossa Conference '10 from the awesome INdT folks. I had delivered my talk, Redefining Mobile Graphics Stack this morning. I used the chance to preview (and got feedback) some of upcoming graphics example for X2 from Ofi Labs (what's X2? read the explanation), even straight from my N900, so just watch its git repository in the next few weeks. BTW, Radeon HD 3200 of my new toy and TV output of N900 worked out-the-box with the projector.

It is also nice to meet few INdT guys I knew, and get to know new folks as well. Since a few Trolls are also here, I also catch up (and share more jokes) with them. Gosh, feels like ages since I left Oslo.

This is my first visit to Brazil. Looks like it won't be the last time!

Friday, March 05, 2010

n900 and its accelerometer

There is a bunch of code out there (which can be copied and pasted) to grab the acceleration values from Nokia N900. Here I contribute one more, it's Qt-based and using the QtDBus module. The values in x, y, z will have the unit of G.

    QDBusConnection connection(QDBusConnection::systemBus());
    QDBusInterface interface("com.nokia.mce", "/com/nokia/icd", QString(), connection);
    QDBusPendingReply<QString, QString, QString, int, int, int> reply;
    reply = interface.asyncCall("get_device_orientation");
    reply.waitForFinished();
    x = static_cast<qreal>(reply.argumentAt<3>()) / 1000;
    y = static_cast<qreal>(reply.argumentAt<4>()) / 1000;
    z = static_cast<qreal>(reply.argumentAt<5>()) / 1000;

As usual, error checking is omitted (left as an exercise for the reader). Like Star Wars, there is also a reason I skip the first 3 QStrings. Debug it yourself to see what you would get. In addition, I found out that at most it would take 25 ms to grab all three values. It means, if you run your application at > 40 fps, then better put this function is a separate thread. Actually, consider that you don't want QDBusPendingReply::waitForFinished() to block your entire GUI, this is likely a good idea anyway.

For a full-version of an accelerometer tool, check out the X2 repository under the sub-directory sensor/accelview. Note that technically acceleration > 1 G is always possible, I clamp the values in this example to keep the UI simple.

Sunday, February 28, 2010

(q)palette viewer

Qt documentation mentions QPalette as the class that contains color groups, Active, Inactive, and Disabled, for each widget state. Knowing the color for many different color roles is important. For example, a style author might want to tweak the colors of each buttons depending on QPalette::Button, QPalette::ButtonText, QPalette::Highlight and likely play with the shades and the saturation. There are probably few different ways to get the RGB values of those colores, here I show one of them: using a small tool that display all the color roles for active, inactive and disabled states:

And here how it looks like on Nokia N900:

The code is in the X2 repository, check the sub-directory widget/palview. A possible exercise for the brave reader: allow the user to choose other color spaces such as HSL or HSV.

Have fun with the colors!