Long Time no See (好久不見)

Long Time no See (好久不見)

Almost a year ago I took my Qt/DirectFB Jenkins down. With that CI for MIPS/uclibc and DirectFB stopped being done (as far as I know). It was a difficult decision but it reflected my situation. I didn’t do a Qt project for a long time and didn’t have any Qt related work on the horizon.

My main work involves using Smalltalk (GNU Smalltalk and Pharo) and writing a lot of a C code for the various Osmocom/GSM related projects and the joy of integrating software to build  HW products. I didn’t think I would use/write/develop using Qt anytime soon. For sentimental reasons I stayed on the qt-devel mailinglist (I still read it day to day) and followed the work done by Lars, Simon and all the others with great joy.

For an internal project of sysmocom I needed to parse, generate and stream (through HTTP) JSON content. I built a first prototype using GNU Smalltalk and the Iliad Framework. The system was quickly built and we were able to gain some experience with it. Given the amount of data we intended to pipe through the system we wanted to move to a fully compiled version (instead of spending the time tuning the VM). I decided to use the Json support of QtCore, QtNetwork for the HTTP client and planned to use libsoup as the HTTP Server. After some research I stumbled across Tufao and used that one instead and don’t regret it. Thanks to QThread and queued signal and slots I was able to make use of more than one CPU core and the application was fun to develop.

I am a Unix Dinosaur so for the buildsystem I shortly considered using qmake but then ended up using autotools. Thanks to the autotroll m4 macros building Qt applications is not that bad. I decided against using cmake as it still feels backward (e.g. no config.log, most scripts don’t use pkg-config but some hand rolled magic like the FindBoost thing).

We are building Debian packages using an internal OBS appliance and this way can easily update/deploy our software thanks to that. After deploying every couple of hours the application/thread would crash. The backtrace pointed to QNAM, deleteLater and QObject.. David Faure had documented and fixed various race conditions and after we upgraded our application to use Qt5.2 the crashes stopped occurring. The application was last re-started on the 5th of February and works quite reliable.

This month we started a simple REST server using Qt and Tufao. Maybe I should search for a nice Qt consumer related project too? Qt is definitely here to stay.

Spring cleaning of the qt-jenkins.moiji-mobile.com

Spring cleaning of the qt-jenkins.moiji-mobile.com

About a week ago I asked for help/support on the Continuous Integration of Qt for the combination of Linux/MIPS/UCLIBC/DirectFB and due the lack of feedback I have removed the DNS entry and cleaned up my system.

This means that currently there is no (public) build testing for any of DirectFB, MIPS, UCLIBC and the bitrot will increase over time. I have asked on the mailinglist about the removal of the Broadcom 97425 device support as it likely to be unused now.

Interested in MIPS/UCLIBC/DirectFB becoming a Tier1 platform?

Interested in MIPS/UCLIBC/DirectFB becoming a Tier1 platform?

Are you running Qt on a MIPS based system? Is your toolchain using UCLIBC? Do plan to use Qt with DirectFB? If not you can probably stop reading.

During the Qt5 development the above was my primary development platform and I spent hours improving the platform and the Qt support. I descended down to the kernel and implemented (and later moved) userspace callchain support for MIPS [1][2] in perf. This allows to get stacktraces/callchains for userspace binaries even when there is no framepointer. I stress-tested the DirectFB platform plugin and found various issues in DirectFB, e.g. this memleak. I modified the V8 MIPS JIT to provide the necessary routines for QML. While doing this I noticed that the ARM implementation is broken and helped to fix it.

At the time Nokia was still using Puls. This meant that getting an external build to integrate with their infrastructure was not possible. So I started to setup a Jenkins for DirectFB and Qt myself. The Qt Jenkins is compiling QtBase, QtJsBackend, QtXmlPatterns, QtDeclarative and QtWebKit for MIPS/Linux/UCLIBC. On top of these there a daily builds for the various QtBase configurations (dist, large, full, medium, small, minimal) and running the V8 unit tests using the built-in simulator for ARM and MIPS. The goal was to extend this to run the all the Qt tests on real hardware. The unit that supported my work was shut-down before I could implement it and the platform work has mostly been in maintenance mode since then.

This has all worked nicely for the release up to Qt 5.0 but when Qt5.1 got merged into the stable branch and received some updates the build started to break and I don’t have enough spare time to fix that.

If anyone is interested in either taking over the CI or helping to make this part of my work again I would be very happy.

Device profiles in Qt5

Device profiles in Qt5

OpenGL and Devices

The future of Qt’s graphic stack is OpenGL (ES 2.0), but this makes things more complicated in the device space. The library names and low level initialization needed for OpenGL is not standardized. This means that for a given board one needs to link libQtGui to different libraries and one needs to patch the QPA platform plugins to add device specific bits. The GPU vendor might provide DirectFB/eGL integration but one needs to call a special function to bind eGL to DirectFB.

Historic Approach

The historic Qt approach is to keep patches out of tree, custom mkspecs files that need to be copied into Qt before building. I have had two issues with this approach:
  1. Device support should be an essential part of Qt5.
  2. Build testing (and later unit testing) is more complicated.

Device Profile Proposal

The approach we took is a pragmatic one, it should be easy for device manufacturers to do the right thing, it should not be a burden for the maintainability of Qt. After some iterations we ended up with device profile proposal and began to implement to it. Most of it is merged by now.

Key Features

It begins with the ./configure script that now has the -device=DEVICE and -device-option KEY=VALUE to select a device and to pass options, e.g. additional include paths, BSP package, to Qt. The second part is a device to influence the behavior of QPA platform plugins. Right now this applies to the DirectFB and EGLFS plugin. A device can install hooks that are called as part of the initialization of these plugins. The hook is the pragmatic approach to get a mix-in with the existing code base.

Supported Devices

Right now we have completed device support for the RaspberryPi,BCM97425 and AMLogic 8726-M. We do support some more devices but they might still require external patches.
QtMediaHub on MIPS with Qt5 and DirectFb

QtMediaHub on MIPS with Qt5 and DirectFb

Ever since the start of the Qt project I am working on DirectFB in Qt5 (and Qt4) with the remote goal of getting QtMediaHub to run. It started with catching up with the rather nice refactoring of lighthouse in Qt5, fixing memory and resource leaks in Qt5, DirectFB and mostly in the DirectFB lighthouse plugin.

It moved to dealing with broken “make install”, broken QML2 examples and documentation, figuring out how to get patches for QtV8/V8 into the project, adding MIPS code for the Qml mode (a new global object), global compare for MIPS and finally working on OpenGL integration for QML2.

In this specific case I had an OpenGL ES 2.0 library coming from a vendor and created the ‘directfbegl’ plugin to use EGL to go from IDirectFBSurface to an eglSurface. I think in this specific case there is unified 2D and 3D buffer space which should allow a lot of cool stuff.

It mostly works, QML2 has some way to go to work on battery powered devices but it is looking quite nice.

DirectFB contribution to the Qt Project

DirectFB contribution to the Qt Project

The Qt project was launched today, I got my 15 DirectFB patches merged, got some first experience with Gerrit, created an account for the Qt wiki, fixed some documentation, so all in all I think it is the great start of the Qt Project we have been waiting for! So thank you very much for all you involved with it!

Now to something completely else, somehow I like to see the parts that are not great yet. But most importantly it is a great opportunity for everyone to get involved with the Qt project and improve things. So here is my short wishlist for the Qt project.

  • Single account for the Bugtracker, Wiki, other services.
  • Read-Only access to gerrit.
  • Public CI based on Jenkins, right now build failures will still point to internal Nokia servers. I assume KDE can help a bit with the Jenkins setup.
  • Make it possible for non-mainstream QPA backends and platforms to be part of the CI System, if proven stable be considered core builders.
  • The wiki being part of the Qt project should be part of the Qt Project, the license should probably be made compatible with the license of the Qt documentation, to allow copying from one to the other.

Once again, thank you Nokia, thanks everyone involved!

Creating a small GUI for the SIMtrace application

Creating a small GUI for the SIMtrace application

Earlier this year I created a Hardware company with a friend to supply to our GSM community and beyond. One of our first products is the SIMtrace Hardware (CC Licensed, actually it should work with any Smartcard). Today I had to wait a bit and decided to convert the CLI application that talks to the firmware to a GUI application. I did this by running the CLI part in a QThread and using QMetaObject::invokeMethod to callback to my GUI.

I started off creating the Qt application with VIM and a browser to help me to remember some function names. After a while I had enough of this and used Qt Creator and enjoyed the auto completion, it had no problem reading our C header files of libosmocore and provided auto completion for these too. Once again I am amazed how nice Qt Creator is and how little code I needed to create the below.

From October 13, 2011
QPixmap and what I did not know

QPixmap and what I did not know

In general QPixmap is the class I dislike the most in the Qt graphics stack. It is not because it did anything wrong, or has annoying bugs. It is merely that painting on a QPixmap can produce a huge slowdown. Maybe it is even the immediate painting model I dislike so much.

In theory the QPixmap should represent the graphics memory and in theory painting this to another piece of graphics memory should be very fast. But reality is different, e.g. with directFB/X it is possible that your graphics memory resides in the host memory because you have allocated too much. X (EXA, UXA…) has migration strategies, directFB will just allocate it in system memory and it will stay there. So your graphics memory class might not be always allocated in graphics memory.

The athur painting capabilities of Qt4 were very nice but Hardware/X/directFB might not be capable of handling all the advanced concepts (perspective transformation, drawing other pixmaps scaled) and the paintengines then need to fallback into the raster path, but the raster path needs to work on a QImage and this is where stuff get terrible. There will be a download of the memory (slow), there might be a change in color (ARGB -> pre multiplied ARGB?), then the fallback, and then uploading of the memory again. So even classes like QGraphicsBlurEffect go through QPixmap -> QImage -> QPixmap (or at least used to).

So the basic problem with QPixmap and the immediate painting model is, only once you are done with painting everything, you know if starting with a QPixmap would have made sense. If Qt5 wouldn’t be all about OpenGL, I would have lobbied hard to make QPixmap an internal class and use it to ‘cache’ QImage that have peen painted a lot.

After all this love/hate with QPixmap there were still things I didn’t know. For Qt5 I am working on the directFB lighthouse plugin and started to work on make more tests pass. The thing I did not know was that by default the QPixmap has no alpha channel, only if either a mask is set or the pixmap is filled with a color that has an alpha channel the QPixmap will end up having an alpha channel and be ARGB. This means that a lighouse plugin providing a QPlatformPixmap implementation needs to be able to provide an ARGB and a RGB based pixmap and switch between them.

Qt, QPA and some notes to myself

Qt, QPA and some notes to myself

QT_QPA_PLATFORM_PLUGIN_PATH, QT_QPA_PLATFORM and QT_QPA_FONTDIR variables are used by QApplication/QPA to find the plugin. They are also available as arguments but there is no help entry for them (Qt5 needs some polishing).

When building a plugin and Qt insists to tell you that the plugin is not there, you are likely to have some undefined symbols, the best hint is to build your plugins with -Wl,–no-undefined in the linker line. Obviously we should plan to use dlerror to also report why Qt is seeing the file but not listing it as available plugin.

cheers

Cross compiling Qt and dealing with teams

Cross compiling Qt and dealing with teams

Let me share some notes on how Embedded Linux programming can be, if you decide the war/pain is over. We do this by looking at the desktop build and then look at the tons of stuff that you need for embedded programming.

Desktop

$ pkg-config –cflags libpng12

$ qmake && make

Embedded
$ . /usr/local/angstrom/arm/environment
$ pkg-config –cflags libpng12..

$ qmake-qt4 && make

Where is the difference?
There is little, you just use a cross compiler. The GNU/Linux Toolchain is prepared for cross compilation, pkg-config works with cross compilation.

What if I want different options
You can decide to use different -mtune and -march values, or you can easily regenerate the SDK targeting a different CPU architecture or just the instruction set level of it.

How is this possible
One creates a level of abstraction. The question is why do you want to suffer and don’t use the abstraction known from the desktop? The above is given to you by the Yocto/OpenEmbedded and details can be found in the OpenEmbedded Manual. Read here for more details on creating a Qt Toolchain/SDK and using it.

But I want to recompile Qt
Maybe you want to change the qconfig.h, or you have a bug in Qt where you want to test things more interactively. You could either do this in the build directory of Qt of Yocto/OpenEmbedded but then again the created SDK contains all the dependencies for building Qt. All that is missing is the generic qmake spec (that takes its values from the environment) that would need to be copied into mkspecs.

But my application needs libpainful-to-build
The SDK is deployed from header files of packages, you can install more -dev packages into your toolchain. If you use any of armv4t, armv5te, armv6, armv6-nofp, armv7, armv7a, … chances are high that there is already a build for your machine…

So why is it so painful?
I really don’t know, tell me.