My blog has been moved to ariya.ofilabs.com.
Showing posts with label n900. Show all posts
Showing posts with label n900. Show all posts

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".

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.

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!

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.

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

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!

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.

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.