Bill King
Qt
News
SQL
Posted by Bill King
 in Qt, News, SQL
 on Tuesday, February 09, 2010 @ 02:34

Those of you who have an interest in the SQL functionality of Qt may have seen my name floating around a bit for the last year or three. I’ve taken over the care and tending of the SQL subsystem. Sometimes you have to make hard decisions. Decisions to prune parts of the garden that you’ve taken into your care. One of those decisions is coming up for the 4.7 release.

The QTDS driver is in dire need of a full rewrite or a deprecation in favour of another system that provides equivalent functionality. As QODBC offers that system, we’ve decided that this is the path to go down. The biggest problem with the driver is that it’s based upon the very old, and across the board very neglected db-lib interface. Sybase, Microsoft, and FreeTDS have all marked this interface as legacy and unsupported. Further down the track (especially if someone feels generous enough to provide this as a code contribution), QTDS may resurrect, rewritten with the ct-lib interface, but seeing as QODBC provides all the functionality we need this is an unlikely state of affairs.

Please feel free to discuss, we are listening, and would like your opinions on this matter.

Harald Fernengel
Qt
 in Qt
 on Monday, February 08, 2010 @ 19:54

Last time, I showed a very hacky way to get Qt 4.6 applications built for Maemo 5 on Mac OS X using MADDE, the stand-alone cross-compilation toolkit for Maemo 5.

The newly released technical preview of MADDE fixed some of the issues (bugs #7821 and #7773) that made Qt 4.6 development painful. Also, I’ve finally found some time to package the Mac OS X host tools required to build Qt apps, so it has never been easier to build applications on top of an unstable (beta) Qt release on top of an unstable (tech-preview) tool chain :)

Instructions:

  1. Install MADDE, version 0.6.14.
  2. Download fetch-qt4.6.2~git20100208-0maemo1.sh and execute it (e.g. with /bin/sh $HOME/Downloads/fetch-qt4.6.2~git20100208-0maemo1.sh). This shell script will download the Qt 4.6 2010-02-08 packages from repository.maemo.org and uncompress them into your MADDE sysroot (fremantle-arm-sysroot-2.2009-51-1-qt453).
  3. Download qt4-maemo5.tar.gz. These are the host tools required to build Qt applications (qmake, moc, rcc, uic and the make specs). Uncompress this file to /opt (e.g. tar -C /opt -zvf $HOME/Downloads/qt4-maemo5.tar.gz)

Run /opt/qt4-maemo5/bin/qmake on your qmake based project to get going. Happy hacking :)

Disclaimer: Building Qt 4.6 on MADDE is not officially supported yet. Proper Qt 4.6 support for the official Maemo SDK and for MADDE will come when Qt 4.6 is promoted from it’s /opt/qt4-maemo5 ghetto into /usr, which will most probably happen with the next firmware update.

Donald Carr
OpenGL
Embedded
Build system
Posted by Donald Carr
 in OpenGL, Embedded, Build system
 on Friday, February 05, 2010 @ 10:49

Requirements

1) Tegra 2 platform
2) The latest Nvidia Tegra2 SDK (11.0074_devlite_eula_Beta-RC.zip at this time)

Board bring up

Nvidia have done a pretty good job in documenting bring up and I will not
paraphrase them. I personally used their dev environment exactly as
intended (answering every question posed during installation with an
affirmative), so my dev machine became a DHCP/NFS server serving out on a
secondary network interface. Be sure to select an X enabled SDK during installation as we
currently don’t work out of the box with their OpenKode drivers.

Their supplied documentation (in chm format) is thorough and documents
flashing the latest bootloader to the device (amongst other things) which I would
recommended on every update, to ensure targetfs/bootloader compatibility.

Initial rootfs adjustment/configuration

Once you have installed both packages included in
11.0074_devlite_eula_Beta-RC.zip you should have 2 dirs:

emPower-devlite-p1138
toolchains

Go into:

./emPower-devlite-p1138

cp -r include/* targetfs/usr/include
cp -r lib-target/* targetfs/usr/lib

your targetfs is now primed for GL compilation. You will need to boot your
target prior to proceeding though, as on first boot a host of packages
are installed into the targetfs including all the X11 headers required to
compile Qt/X11.

Additional headers (dbus, glib, freetype, gstreamer) might be
required for a full featured Qt build, but the packages installed on first
boot will suffice for a OpenGL ES 2 enabled Qt/X11 build with all of Qt’s
core functionality.

Go to town with apt-get according to your needs
(apt-get build-dep libqt4-gui unfortunately fails due to unmet
dependencies) and please be aware of the fact that the chm documentation
covers forwarding net traffic between your Tegra2 target and the external
world via your host machine.

Once this is done, we are ready to build qt.

Configuring build environment

I use Scratchbox 2 for reasons qualified in the appendix.

1) Change to your targetfs directory (cd $NV_ROOT/emPower-devlite-p1138/targetfs)

2) Run:

sb2-init -c /usr/bin/qemu-arm $SB2-TARGETNAME $NV_ROOT/toolchains/tegra2-4.3.2-nv/bin/arm-none-linux-gnueabi-gcc

within this directory, where:

$SB2-TARGETNAME is a suitable name for your target’s scratchbox environment
$NV_ROOT is where you unpacked the archive

You now have a sane scratchbox 2 env when you can compile Qt/X11. If you
were to enter the scratchbox env and build Qt now, it would get through
every module up until QtOpenGL was reached, at which point you would
witness spaghetti breakage referencing the inclusion of the qdebug/text
streaming classes.

This is because

targetfs/usr/include/EGL/eglplatform.h

includes several X11 headers:

Xlib.h
Xutil.h

as it explicitly references native X11 types. I initially tried to move
these headers out of this header file, but the path of least resistance
ended up being the undefining of conflicting defines at the end of the
eglplatform.h header file.

I introduced the following 4 lines:

#undef None
#undef Status
#undef Unsorted
#undef GrayScale

immediately prior to the final #endif in this file. I know this is dirty,
but it circumvents the point of breakage and resolves all remaining build failures.

Having done this, we are ready to build Qt/X11.

Building Qt

1) Enter scratchbox 2 with: sb2 -t $SB2-TARGETNAME
2) Enter your Qt directory
3) Configure Qt with (at a minimum):
./configure -xplatform linux-g++ -platform linux-host-g++ -opengl es2 -force-pkg-config ..
(The utilized mkspecs are discussed in the Appendix)
4) Check the output of configure to verify OpenGL ES2 (and any other
functionality you wish to build) has been correctly detected and enabled by
the configure tests.
5) run “make” (Qt should build through to completion)
6) “make install” Qt to its prefix path on the host (if necessary)
7) Use Qt to compile any appropriate Qt applications within the
scratchbox env
8 ) Deploy Qt to its prefix path (on the target) with any desired
applications

When you boot your Tegra2 platform, start X and launch your
OpenGL ES2 enabled Qt application (Either GLES2 content directly
in QGLWidget ala hellogl_es2, a QGLWidget fronted QGraphicsView
or via explicit use of the OpenGL ES2 graphics system), everything
should simply work to a greater or lesser extent and work at pace
at that.

We have not done any profiling of Qt on the Tegra2
hardware in order to quantify where we are today, nor any
dedicated integration in order to be maximize our use of the
underlying hardware but the baseline performance is very solid.

Appendix

mkspec information

linux-g++

the generic linux X11 mkspec, which behind the curtains of scratchbox
is mapped to the (environment creation time) specified cross compiler.

linux-host-g++

a modification of the generic linux X11 mkspec, which maps to the host machines compiler. This
mkspec is already present in the Qt maemo5 branch on our git repository. This
mkspec is basically a modification of linux-g++, with “host-” prefixed on
all the compiler variables. (included from ../common/g++.conf) The only
noteworthy thing about this mkspec is that instead of including
“../common/g++.conf” and modifying select variables accordingly, the
complete include is inlined. This is due to a known issue where overriding
QMAKE_CXX variables in not respected during the qmake boot strapping
process.

The linux-host-g++ mkspec looks roughly like this:

=============================================

#
# qmake configuration for linux-g++
#

MAKEFILE_GENERATOR = UNIX
TEMPLATE = app
CONFIG += qt warn_on release incremental link_prl
QT += core gui
QMAKE_INCREMENTAL_STYLE = sublib

#
# qmake configuration for common gcc
#

#inlined ../common/g++.conf follows

QMAKE_CC = host-gcc
QMAKE_CFLAGS += -pipe
QMAKE_CFLAGS_DEPS += -M
QMAKE_CFLAGS_WARN_ON += -Wall -W
QMAKE_CFLAGS_WARN_OFF += -w
QMAKE_CFLAGS_RELEASE += -O2
QMAKE_CFLAGS_DEBUG += -g
QMAKE_CFLAGS_SHLIB += -fPIC
QMAKE_CFLAGS_STATIC_LIB += -fPIC
QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE}

QMAKE_CXX = host-g++
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE

QMAKE_LINK = host-g++
QMAKE_LINK_SHLIB = host-g++
QMAKE_LINK_C = host-gcc
QMAKE_LINK_C_SHLIB = host-gcc
QMAKE_LFLAGS +=
QMAKE_LFLAGS_RELEASE += -Wl,-O1
QMAKE_LFLAGS_DEBUG +=
QMAKE_LFLAGS_APP +=
QMAKE_LFLAGS_SHLIB += -shared
QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME += -Wl,-soname,
QMAKE_LFLAGS_THREAD +=
QMAKE_LFLAGS_NOUNDEF += -Wl,–no-undefined
QMAKE_RPATH = -Wl,-rpath,

QMAKE_PCH_OUTPUT_EXT = .gch

# -Bsymbolic-functions (ld) support
QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,–dynamic-list,

include(../common/linux.conf)

=============================================

Scratchbox

I personally use Scratchbox 2 rather than Scratchbox 1 since I use a 64 bit
distro, and Scratchbox 2 exists in the Ubuntu repositories.

http://packages.ubuntu.com/search?keywords=scratchbox&searchon=names&suite=karmic&section=all

You might get equally good mileage with Scratchbox 1, or entirely without
Scratchbox. I personally opt for the path of least resistance, and this blog is a cart
following that path.

Arguments in favour of Scratchbox

1) pkg-config in Ubuntu 9.10 does not support prefixes (sysroot) correctly,
so you have to directly modify the .pc files or build pkg-config yourself
2) The Nvidia targetfs/usr/lib entries often have fully qualified symlinks which link
into your host machines libs without a chroot safety net
3) There were some toolchain/targetfs anomalies which simply vanished when adopting this build approach

Known issues

1)The aforementioned qmake bootstrapping issue preventing QMAKE_CXX being over ridden in linux-host-g++
2) 16 bit X is the only environment tested and known to work. Qt GLES2 applications currently segfault
on launch under a 24 bit X session. I am busy investigating this issue. Please ensure that your xorg.conf file is using
16 bit as the default/selected color depth if you intend to run Qt apps.
3) libEGL.so prints a spurious error message:

“”Couldn’t load implementation for OpenGL_ES”

due to the absence of an libGLES(1).so which, it appears, can be safely ignored

AndersBakken
Uncategorized
Posted by AndersBakken
 in Uncategorized
 on Thursday, February 04, 2010 @ 17:50

As of Qt 4.6 massive improvements have been made to the QWS/DirectFB driver.

While there has been some support of DirectFB since Qt 4.3, 4.6 comes with significant improvements in terms of performance, stability and features. This release has been validated on several media platforms in the home entertainment sphere like DTVs, set-top boxes and Blu-Ray players. We even got the code reviewed by Denis Oliver Kropp of www.directfb.org during a “hackathon” in Oslo this summer.

http://www.directfb.org

DirectFB is an open source project that provides an abstraction on top of proprietary graphics hardware acceleration. It has proven to be particularly successful on embedded systems that provide specialized 2D/video playback acceleration. It is the de-facto standard on internet-connected HD TVs and set-top boxes that run Linux. From Qt’s perspective it provides a nice way to abstract out proprietary interfaces. We’ve achieved animations with upwards of 30 fps on High Definition resolutions (1080/720) mass-market hardware.

Qt uses DirectFB for the following operations:
- Access to hw-accelerated blitting and paint operations (QPainter)
- Video memory buffer management and image decoding(QPixmaps)
- Window composition/management and synchronization with screen refresh rates (QWS)
- Input device events (keyboard/mouse/joystick/touchscreen/remote control) (QEvents)

Planned features in future releases include support for NPAPI plugins (Flash) and better integration with the native DirectFB window management.

- Do you use Qt/DirectFB?
- Would you want to use multiple processes painting to the screen concurrently?
- Do you have feature or documentation requests?
- Do you have bug-reports?

We would love to hear from you! Please report via the normal support channels.

For more technical details on the QWS/DirectFB driver consult:

http://doc.trolltech.com/4.6/qt-embeddedlinux-directfb.html

This contains debugging and profiling aids as well as best practices guidelines. You can explicitly profile when painting operations are accelerated or when they fall back to the underlying raster engine

Benjamin
WebKit
Performance
Posted by Benjamin
 in WebKit, Performance
 on Tuesday, February 02, 2010 @ 11:13

Like for the other parts of Qt, having great performance is important for QtWebKit.

Traditionally, QtWebKit has been mostly used on desktop computers for advanced layouting, hybrid applications or simply to browse the web. On a modern computer, the speed of WebKit is not a problem.

The world has changed, and QtWebKit is now used on mobile phones running Maemo, Symbian or Windows CE, and it is more and more used in embedded application on various devices.

Working on what matters

To improve the performance of WebKit, we works with benchmarks. Those benchmarks are used as use cases when profiling WebKit and to evaluate the gain of our patches.

Those benchmarks and the tools are available on Gitorious, in the QtWebkit performance repository.

WebKit gives a lot of possibilities, and we try to focus our work on what matters. For the performance work, we use real webpages, and look for ways to improve WebKit in the way it is used on the Web.

How we benchmark WebKit

The performance suite has three kinds of tools:

  • host tools: to manage the data used by the benchmarks
  • tests: the benchmarks
  • reductions: some benchmarks for specific components of WebKit

Let’s have a look at the tools and the tests. The full documentation of the performance suite is on the WebKit’s wiki.

Mirroring the web

For the benchmark, we do not want to access Internet directly. We want to compare the results from one run to the other, so we don’t want the pages to change arbitrarily. Using the Web for benchmarking would also create an important load on the servers.

To use real pages without going online, we create databases of web pages with the mirror application:

Process of webpage mirroring

Those databases are snapshots of webpages at a given point in time, and they are used as input of the benchmarks.

The mirror application uses WebKit to load the pages and intercept all network requests. This means the database also includes resources that are loaded lazily via Javascript.

Using the benchmarks

There are two ways to exploit the databases with the benchmark: the online and offline modes. The difference lies in the way we provide the database’s content to the benchmarks:

Modes of benchmarking

In the “online mode“, we use a basic web server to serve the database over HTTP. The benchmarks use the complete stack to load pages, as they would if we were loading the page from Internet.

In the “offline mode“, the database is loaded directly by the benchmarks and is used as the source of data. In that case, the network is not involved. This mode is mostly useful for the benchmarks that do not involve the network (like measuring the rendering speed).

What is measured

The benchmark suite is still a work in progress. Currently, there are benchmarks for:

  • the page loading performance (with or without rendering)
  • the rendering performance
  • the scrolling performance

How you can use that?

If you use WebKit, and are interested in great performance, you can use the performance suite to profile the use case you are interested in, and optimize those cases.

If you evaluate the use of WebKit for embedded, you can use the benchmark to evaluate how good WebKit performs on the hardware.

If you make patches for WebKit’s performance, have a look on how to contribute. You can also join us on IRC in #qtwebkit on freenode.

Simon
WebKit
Posted by Simon
 in WebKit
 on Monday, February 01, 2010 @ 12:56

Hi!

Here’s the weekly summary of Qt related changes to WebKit trunk. Big changes include Yael’s patch for WebSockets support, the beginnings of QtScript on top of JavaScriptCore’s C API, Maemo 5 tweaks and layout test fixes:

  • Janne added the necessary meta-data to make QtWebKit play nicely with Symbian backups (34077).
  • I did some code cleanups in RenderThemeQt and fixed a bug with combo boxes not showing up in Maemo5 (34088).
  • Holger fixed a regression in the JavaScript prompt handling (30914).
  • Jedrzej landed the first files for building QtScript on top of JavaScriptCore’s C API (32565).
  • Diego added history support to the Qt DRT, we now pass the http/tests/history layout tests! (34167)
  • Daniel fixed a bug with the height of button elements (29564).
  • Kent fixed support for ES5 style introspection with QMetaObject methods (34087).
  • Yael implemented the Qt part of WebSocket support, we now pass websocket/tests in the layout tests (34180).
  • Diego fixed more worker layout tests by adding support for counting worker threads in the Qt DRT (34221).
  • Holger found a neat way to speed up the conversion from KURL to QUrl (33873).
  • Trond fixed an endless loop in QWebPage printing (r53997).
  • Kenneth fixed incorrect fonts on comboboxes on Maemo5 and Symbian (r53999).
  • Andreas upstreamed Ralf and Robert’s kinetic scrolling support for QWebView using QAbstractKineticScroller (34267).
  • Benjamin implemented support for the display() method in the Qt DRT (34258).
  • Oswald speed up the conversion between WebCore::String and QString by avoiding QString::fromUtf16() (r54060).
  • Kenneth landed a patch to disable auto-uppercasing and text prediction for password input fields (r54064).
  • Kenneth also continued to clean up the QtLauncher for a future merge with QGVLauncher
  • Andreas and Kenneth submitted tweaks to the look’n'feel of QtLauncher on Maemo5.
kkoehne
QtCreator
Kinetic
Declarative UI
Posted by kkoehne
 in QtCreator, Kinetic, Declarative UI
 on Wednesday, January 27, 2010 @ 11:45

Declarative UI is one of the big things on the Qt Roadmap for Qt 4.7 and 4.6.x. I already enjoyed working with the Qml language and the developers behind it for quite some time - and believe me, this one will fundamentally change the way slick Qt UIs are designed and look like! If you have not checked it out yet, do so … although it is not yet part of the Qt package, it is very mature, and just fun to experiment with :)

Anyhow, a technology like this of course does not come out of the blue, neither do the tools to support it - I think the first discussions about a Visual Editor for a language yet-to-be-invented on the basis of the QGraphicsView framework started in summer 2008! In early 2009 I first heard about the name “Qml”, and was soon the lead of a development project, with right now 5 people working full time in this project. One of the most important decisions we had to make early on was for a cool project name - we eventually settled for “Bauhaus”, as a reminiscence to the famous German school for design.

Back to the facts: What I want to share with you today are our plans for supporting Declarative UI / Qml in QtCreator. This is an important one, because with Declarative UI we target not only the traditional Qt/C++ developers, but also more design centric people - the goal is to let both share the same language, from early prototyping until the final product. We can only achieve this with good tools in place.

Here are the things we are currently working on for the next major version of QtCreator:

Qml Text Editor - We already have some basic syntax highlighting / formatting support in QtCreator 1.3, but in the QtCreator master branch we are right now working on really mature Qml/JavaScript support. This will include all the goodies you kind of expect these days: Code completion, context sensitive help, …

Visual Qml Editor - After all, we are talking about graphical user interfaces, and you will not make UI designers happy just with a text editor ;-) . Here we decided for a fresh start and developed the components for the Visual Editor from the ground up. Interestingly, we are using Qml heavily ourselves here - e.g. in the Property Editor and States View.

Seamless Integration - It is no either text, or visual editing: You want to use both, and quickly switch between both. This is why we deeply integrate the Visual Editor into QtCreator, share the same Undo/Redo history and are also preserving the Qml file formatting as much as possible when doing file changes.

Debugging - We integrate the Qml debugger, which allows you to inspect the qml item tree and its properties at runtime, to check framerates, to evaluate JavaScript expressions and so on inside QtCreator.

Enough said - Nigel recorded a nice video showing you how the support currently looks like:

If you want to try it out yourself, we also packaged a technical preview of creator, qmlviewer/qmldebugger and the declarative examples & demos in one installer:

qt-creator-win-opensource-1.3.80-qml-tp1.exe (Windows 32 bit)
qt-creator-linux-x86-opensource-1.3.80-qml–tp1.bin (Linux 32 bit)
qt-creator-mac-opensource-1.3.80-qml-tp1.dmg (Mac OS X)

Disclaimer: The binaries are unsupported, and are only meant for early testing. In fact they are based on an untested snapshot of Qt, and an (almost) untested version of QtCreator! If you want to use qml for production work, stay with QtCreator 1.3.1.

Of course we are interested in all kind of feedback, preferably via the bug tracker or on the qt-creator mailing list.

Simon
WebKit
Posted by Simon
 in WebKit
 on Sunday, January 24, 2010 @ 09:38

This week has been a very busy week! Here’s a list of the landed changes that affect the Qt port, in chronological order:

  • Tor Arne has ported the Qt build of DumpRenderTree to run on Windows. (r53526, r53543).
  • Luiz continued with cleaning up the combobox popup handling.(33418).
  • Ben from the Google Team fixed a bug where touch events weren’t sent to iframes (33894).
  • No’am landed support in the Qt bindings that allows passing pixmaps and images as arguments in signals/slots/properties, which can then easily be turned into image elements or data urls. (32461).
  • Benjamin cleaned up the QWebPage autotest (32216).
  • On Thursday we landed No’am’s implementation of GraphicsLayer. This accelerates the composition of layers with animated opacity or transform attributes, through content caching in pixmaps. Layers are mapped to QGraphicsItems with enabled CacheMode and the animation is driven by the Qt Animation Framework.The feature is disabled by default currently as it’s not stable yet, but it’s a fantastic start! (33514).
  • Diego continued implementing missing functions in the Qt DRT (33945).
  • Jakub fixed a crash with video elements and phonon (33842).
  • Girish fixed a bug with combobox popups in transformed QGraphicsWebViews (r53703, 33887).
  • Robert fixed 5 layout tests by fixing support for window.close() and window.closed() in the Qt DRT (32953).
  • Kent fixed bugs with Object.getOwnPropertyDescriptor (33948, 33946).
gunnar
Threads
Painting
Graphics Dojo
Performance
Posted by gunnar
 in Threads, Painting, Graphics Dojo, Performance
 on Thursday, January 21, 2010 @ 08:18

Previous posts in this topic:

In this series that we’ve been doing, I wanted to cover threading, a topic that has been actively discussed amongst some of the trolls over the last few months. We’ve had support for rendering into QImage’s from non-GUI threads since the early Qt 4.0 days, but its only in recent versions of Qt, I think, 4.4 that we got support for rendering text into images. Now that support is there, it begs the question how to make proper use of it. Generating the actual content in a thread is one usecase, here is an example of it.

What it means is that instead of rendering all the content of a certain view in the QWidget::paintEvent() or in the QGraphicsItem::paint() function, we use a background thread which produces the cache. The benefit is that even though drawing the actual content can be quite costly, drawing a pre-rendered image is fast, making it possible for the UI to stay 100% responsive while the heavy loading is happening in the background. It does imply that not all content is available at all times, but for many scenarios this is perfectly fine. There is nothing novel about this approach, I just think its a nice way to solve a problem that often comes up when dealing with user experience.

This approach is used by Google Maps (actually, what the server does I don’t know, but it sends individual tiles to the browser at least), iPhone and N900 web browsers, and I’ve talked to customers in the past that use this approach for usecases where generating the content is costly, but the user interface needs to stay responsive. In fact, this approach applies to pretty much anything where it is ok that the content is not immediately there, such as data tables like an mp3-index or a contact list, images in a data folder, etc.

The Task

Lets first look at the task. I’ve done a trivial implementation which looks in a directory and displays all the images in there. Each image is a separate content piece and I’ve put a background, a small frame around it and a drop shadow under it. Just so that there is a bit of active work going on. If you are into it, here is the Source Code

The content pieces could have been tiles in a map of Norway or tiles composing a webpage, but I choose images, because I already had some images around and I figured it made for an ok example. The demo is run on an N900 with compositor disabled using the following command lines:

  • Non-Threaded: ./threaded_tile_generation -no-thread -graphicssystem opengl MyImageFolder
  • Threaded: ./threaded_tile_generation -graphicssystem opengl MyImageFolder

Here’s how it looks when the content is generated in the GUI thread:


The UI is running super-smooth as long as I show only the content that is already loaded. Once work is needed, the entire UI stops and the user experience is really bad. Here is how it looks if we move the work into a background thread.

The algorithm

Don’t use this particular algorithm. It is very crude and written to show an idea. First of all, because I was lazy, I used queued connections rather than a synchronized queue to schedule the pieces to be rendered. This means that the queue is managed by Qt’s event loop, out of my control. So if I pan far out, I will schedule a lot of images to be rendered, then pan beyond them before they are done. In a decent implementation, I would dequeue these and make sure that only the pieces that are directly visible are being processed.

The other thing is that there is no logic to “peek ahead”. I schedule images to be generated only when I need them. If I instead scheduled them based on the current panning direction, in addition to not discarding so aggressively, it would probably result in a situation most images are rendered ahead of time.

QGraphicsView

It would be kinda cool if this could be applied directly to QGraphicsView. You set a flag on the item and instead of generating its cache pixmap in the GUI thread, it was offloaded to the worker thread. This is not straight forward however, because the GUI thread can, pr today at least, continue to modify the state of the item, while its being rendered in the worker thread. Synching these two becomes a bit of a mess, and how to solve it, if at all, is not something we have a plan for. That doesn’t prevent people from doing this kind of work in their own custom paint() functions of course.

cduclos
Uncategorized
Posted by cduclos
 in Uncategorized
 on Wednesday, January 20, 2010 @ 13:01

Last time I wrote here I was still a member of the QA team and I was announcing the launch of the qt-stable branch. Well, after two very successful years on the QA department I decided to change directions and I joined the platform team working on the Mac platform.
So, one of my first tasks required me to investigate a bug in full screen mode which only affected Cocoa applications. This led me to dig into the code and find some things that needed to be improved. While looking at that, I remembered that when developing the Cocoa port we reused as much code as it was possible from the original carbon port. This saved us a lot of time, however as time passed both ports started diverging and now the code has grown a little bit “confusing”. So, I started looking at the way of separating both ports completely and create completely different code paths for both of them. The more I looked at it, the more I realized that the task was not a small one and it would take quite a lot of work. Then I asked myself, why do we need to keep the Carbon port? After all, Carbon is the past in OS X and it has been completely replaced by the Cocoa framework. I talked to my manager, who told me this had been an ongoing discussion for a while, and the main reason for the Carbon port to exist is to support customers deploying applications in OS X 10.4 aka “Tiger”. Cocoa is available from OS X 10.5 (aka “Leopard”), before that the only available framework is Carbon. Doing some research on the Internet we found out that OS X 10.4 hasn’t been updated for about two years, and it seems very unlikely that Apple will release a new update after the last released version 10.4.11 (2 years ago).
Since we are aware that for some people Tiger support might be very important, we are reaching to you to find out the reasons why support for Tiger and/or Carbon are important to you. Could you please let us know the reasons this port and Tiger support are vital to you?
In case you are wondering, no decision has been taken yet so this is the time when you can influence the future.



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.